diff options
Diffstat (limited to '')
626 files changed, 36778 insertions, 50141 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 31a0dfa0..5ecd6340 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,6 +45,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 + with: + submodules: recursive # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -60,8 +62,8 @@ jobs: run: | sudo apt-get update sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo - sudo apt-get -y install gcc g++ libconfig++-dev libboost-all-dev - sudo apt-get -y install gpgsm + sudo apt-get -y install gcc g++ libconfig++-dev libboost-all-dev ninja-build + sudo apt-get -y install gpg - name: Cache Qt id: cache-qt @@ -75,44 +77,14 @@ jobs: with: cached: ${{ steps.cache-qt.outputs.cache-hit }} - - name: Build gpg-error (Linux) - run: | - cd ${{github.workspace}}/.. - git clone https://github.com/saturneric/libgpg-error - cd libgpg-error - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - - - name: Build assuan (Linux) - run: | - cd ${{github.workspace}}/.. - git clone https://github.com/saturneric/libassuan - cd libassuan - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - - - name: Build GpgME (Linux) - run: | - cd ${{github.workspace}}/.. - git clone https://github.com/saturneric/gpgme - cd gpgme - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp && make -j2 - sudo make install - cd ${{github.workspace}} - - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DEXECUTABLE_OUTPUT_PATH=${{env.EXECUTABLE_OUTPUT_PATH}} + run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON - name: Build GpgFrontend # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -j 2 + run: cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml index 4871fc8b..e96cfb6f 100644 --- a/.github/workflows/debug.yml +++ b/.github/workflows/debug.yml @@ -27,6 +27,12 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Set git to use LF(Windows) or CRLF(MacOS) line endings + run: | + git config --global core.autocrlf false + git config --global core.eol lf + if: matrix.os == 'windows-latest' || matrix.os == 'macos-10.15' + - uses: actions/checkout@v2 with: submodules: recursive @@ -35,14 +41,13 @@ jobs: run: | sudo apt-get update sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo - sudo apt-get -y install gcc g++ libconfig++-dev libboost-all-dev - sudo apt-get -y install gpgsm + sudo apt-get -y install gcc g++ libconfig++-dev libboost-all-dev ninja-build + sudo apt-get -y install gpg if: matrix.os == 'ubuntu-latest' - name: Git Sumbodule Update run: | git submodule update --init --recursive - - name: Codesign Configuration (macOS) run: | echo ${{secrets.MACOS_CERTIFICATE}} | base64 --decode > certificate.p12 @@ -56,12 +61,11 @@ jobs: - name: Install Dependence (macOS) run: | - brew install cmake git autoconf automake qt@5 gcc texinfo gettext libgpg-error libassuan gpgme openssl - brew install boost libconfig gettext + brew install cmake git autoconf automake qt@5 texinfo gettext [email protected] + brew install boost ninja brew unlink gettext && brew link --force gettext brew link qt@5 - brew link gcc - brew link openssl --force + brew link [email protected] --force if: matrix.os == 'macos-10.15' - name: Cache Qt @@ -88,65 +92,42 @@ jobs: - name: Set up Dependence (Windows) shell: msys2 {0} run: | - pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf automake mingw-w64-x86_64-gpgme - pacman --noconfirm -S --needed make texinfo mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost mingw-w64-x86_64-gnupg gettext-devel libintl msys2-runtime-devel - pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 + pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf + pacman --noconfirm -S --needed make texinfo mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost automake + pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 libintl msys2-runtime-devel gettext-devel + pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-gpgme + pacman --noconfirm -S --needed mingw-w64-x86_64-libarchive if: matrix.os == 'windows-latest' - - name: Build gpg-error (Linux) - run: | - cd ${{github.workspace}}/third_party/libgpg-error - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - if: matrix.os == 'ubuntu-latest' - - - name: Build assuan (Linux) - run: | - cd ${{github.workspace}}/third_party/libassuan - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - if: matrix.os == 'ubuntu-latest' - - - name: Build GpgME (Linux & macOS) - run: | - cd ${{github.workspace}}/third_party/gpgme - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp && make -j2 - sudo make install - cd ${{github.workspace}} - if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-10.15' - - name: Build GpgME (Windows) shell: msys2 {0} run: | - git clone https://github.com/saturneric/gpgme - cd gpgme + cd $(echo "/${{github.workspace}}/third_party/gpgme" | sed 's/\\/\//g' | sed 's/://') ./autogen.sh ./configure --enable-maintainer-mode --enable-static=yes --disable-gpg-test --enable-languages=cpp LDFLAGS="-static" && make -j2 make install if: matrix.os == 'windows-latest' - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON - if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-10.15' + - name: Build GpgFrontend (Linux) + # Build your GpgFrontend with the given configuration + run: | + cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON + cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v + if: matrix.os == 'ubuntu-latest' - - name: Build GpgFrontend - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config $env.BUILD_TYPE}} -- -j 2 - if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-10.15' + - name: Build GpgFrontend (macOS) + # Build your GpgFrontend with the given configuration + run: | + cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected] + cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v + if: matrix.os == 'macos-10.15' - name: Configure CMake & Build Binary(Windows) shell: msys2 {0} run: | cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://') mkdir build && cd build - cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON .. + cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON .. # Build your program with the given configuration cmake --build . --config ${{env.BUILD_TYPE}} -- -j 2 if: matrix.os == 'windows-latest' diff --git a/.github/workflows/release-deb-package.yml b/.github/workflows/release-deb-package.yml index ae23cec7..02fb69bc 100644 --- a/.github/workflows/release-deb-package.yml +++ b/.github/workflows/release-deb-package.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@v2 with: - submodules: recursive + submodules: 'recursive' - name: Get Short SHA of Commit id: vars @@ -38,47 +38,19 @@ jobs: - name: Install Dependence (Ubuntu 20.04) run: | sudo apt-get update - sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo qt5-default + sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo qt5-default ninja-build sudo apt-get -y install gcc g++ libconfig++-dev libboost-all-dev - sudo apt-get -y install gpgsm libxcb-xinerama0 libxcb-icccm4-dev libcups2-dev libdrm-dev libegl1-mesa-dev - sudo apt-get -y install libgcrypt20-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev gyp ninja-build - sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-image0 - sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-* + sudo apt-get -y install gpg if: matrix.os == 'ubuntu-20.04' - - name: Build gpg-error - run: | - cd ${{github.workspace}}/third_party/libgpg-error - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - - - name: Build assuan - run: | - cd ${{github.workspace}}/third_party/libassuan - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - - - name: Build GpgME - run: | - cd ${{github.workspace}}/third_party/gpgme - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp && make -j2 - sudo make install - cd ${{github.workspace}} - - name: Build & Package GpgFrontend (Linux DEB Package) # Build your program with the given configuration run: | - cmake -B ${{github.workspace}}/build-deb-${{matrix.os}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_BUILD_TYPE="Release" -DGENERATE_LINUX_INSTALL_SOFTWARE=ON - cmake --build ${{github.workspace}}/build-deb-${{matrix.os}} --config {{$env.BUILD_TYPE}} -- -j 2 + cmake -B ${{github.workspace}}/build-deb-${{matrix.os}} -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGENERATE_LINUX_INSTALL_SOFTWARE=ON -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}} + cmake --build ${{github.workspace}}/build-deb-${{matrix.os}} --config {{$env.BUILD_TYPE}} -- -v cd ${{github.workspace}}/build-deb-${{matrix.os}} - make package + ninja package cd ${{github.workspace}} - - name: Upload Artifact(Linux DEB) uses: actions/upload-artifact@master with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 63ccfbe3..70a883d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,9 +23,14 @@ jobs: build: strategy: matrix: - os: [ 'ubuntu-18.04', 'macos-10.15', 'windows-latest' ] + os: [ 'ubuntu-18.04', 'macos-10.15', 'windows-2019' ] runs-on: ${{ matrix.os }} steps: + - name: Set git to use LF(Windows) or CRLF(MacOS) line endings + run: | + git config --global core.autocrlf false + git config --global core.eol lf + if: matrix.os == 'windows-2019' || matrix.os == 'macos-10.15' - uses: actions/checkout@v2 with: @@ -63,12 +68,11 @@ jobs: - name: Install Dependence (macOS) run: | - brew install cmake git autoconf automake qt@5 gcc texinfo gettext libgpg-error libassuan gpgme openssl - brew install boost libconfig gettext + brew install cmake git autoconf automake qt@5 texinfo gettext [email protected] + brew install boost ninja brew unlink gettext && brew link --force gettext brew link qt@5 - brew link gcc - brew link openssl --force + brew link [email protected] --force if: matrix.os == 'macos-10.15' - name: Cache Qt @@ -90,63 +94,39 @@ jobs: with: install: git msys2-devel base-devel binutils mingw-w64-x86_64-toolchain release: false - if: matrix.os == 'windows-latest' + if: matrix.os == 'windows-2019' - name: Set up Dependence (Windows) shell: msys2 {0} run: | - pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf automake mingw-w64-x86_64-gpgme - pacman --noconfirm -S --needed make texinfo mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost mingw-w64-x86_64-gnupg gettext-devel libintl msys2-runtime-devel - pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 - if: matrix.os == 'windows-latest' - - - name: Build gpg-error (Linux) - run: | - cd ${{github.workspace}}/third_party/libgpg-error - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - if: matrix.os == 'ubuntu-18.04' - - - name: Build assuan (Linux) - run: | - cd ${{github.workspace}}/third_party/libassuan - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes && make -j2 - sudo make install - cd ${{github.workspace}} - if: matrix.os == 'ubuntu-18.04' - - - name: Build GpgME (Linux & macOS) - run: | - cd ${{github.workspace}}/third_party/gpgme - ./autogen.sh - ./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp && make -j2 - sudo make install - cd ${{github.workspace}} - if: matrix.os == 'ubuntu-18.04' || matrix.os == 'macos-10.15' + pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf + pacman --noconfirm -S --needed make texinfo mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost automake + pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 libintl msys2-runtime-devel gettext-devel mingw-w64-x86_64-gpgme + pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-libarchive + if: matrix.os == 'windows-2019' - name: Build GpgME (Windows) shell: msys2 {0} run: | - git clone https://github.com/saturneric/gpgme - cd gpgme + cd $(echo "/${{github.workspace}}/third_party/gpgme" | sed 's/\\/\//g' | sed 's/://') ./autogen.sh ./configure --enable-maintainer-mode --enable-static=yes --disable-gpg-test --enable-languages=cpp LDFLAGS="-static" && make -j2 make install - if: matrix.os == 'windows-latest' + if: matrix.os == 'windows-2019' - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON - if: matrix.os == 'ubuntu-18.04' || matrix.os == 'macos-10.15' + - name: Build GpgFrontend (Linux) + # Build your GpgFrontend with the given configuration + run: | + cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v + if: matrix.os == 'ubuntu-18.04' - - name: Build GpgFrontend - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -j 2 - if: matrix.os == 'ubuntu-18.04' || matrix.os == 'macos-10.15' + - name: Build GpgFrontend (macOS) + # Build your GpgFrontend with the given configuration + run: | + cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected] + cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v + if: matrix.os == 'macos-10.15' - name: Build & Sign App Bundle (macOS) run: | @@ -185,10 +165,10 @@ jobs: run: | cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://') mkdir build && cd build - cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON .. + cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON .. # Build your program with the given configuration cmake --build . --config ${{env.BUILD_TYPE}} -- -j 2 - if: matrix.os == 'windows-latest' + if: matrix.os == 'windows-2019' - name: Upload Artifact(Linux) uses: actions/upload-artifact@master @@ -209,4 +189,4 @@ jobs: with: name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}} path: ${{github.workspace}}/build/release/* - if: matrix.os == 'windows-latest' + if: matrix.os == 'windows-2019' @@ -2,7 +2,7 @@ src/GpgFrontend.h src/GpgFrontendBuildInfo.h src/GpgFrontendBuildInstallInfo.h -third_party/AppImageUpdate +docs/ # gettext *.mo @@ -113,4 +113,3 @@ target_wrapper.* # QtCreator *.autosave - diff --git a/.gitmodules b/.gitmodules index f559522f..3815e764 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "third_party/AppImageUpdate"] - path = third_party/AppImageUpdate - url = https://github.com/AppImage/AppImageUpdate [submodule "third_party/gpgme"] path = third_party/gpgme url = https://github.com/saturneric/gpgme @@ -10,3 +7,24 @@ [submodule "third_party/libgpg-error"] path = third_party/libgpg-error url = https://github.com/saturneric/libgpg-error +[submodule "third_party/vmime"] + path = third_party/vmime + url = https://github.com/saturneric/vmime.git +[submodule "third_party/json"] + path = third_party/json + url = https://github.com/saturneric/json +[submodule "third_party/easyloggingpp"] + path = third_party/easyloggingpp + url = https://github.com/saturneric/easyloggingpp +[submodule "third_party/qt-aes"] + path = third_party/qt-aes + url = https://github.com/saturneric/Qt-AES +[submodule "third_party/smtp-mime"] + path = third_party/smtp-mime + url = https://github.com/saturneric/SmtpClient-for-Qt.git +[submodule "third_party/libarchive"] + path = third_party/libarchive + url = https://github.com/saturneric/libarchive.git +[submodule "third_party/libconfig"] + path = third_party/libconfig + url = https://github.com/saturneric/libconfig diff --git a/CMakeLists.txt b/CMakeLists.txt index 38df1d65..7ceb9d00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,48 @@ +# +# Copyright (C) 2021 Saturneric +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric<[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + cmake_minimum_required(VERSION 3.16) -project(GpgFrontend VERSION 2.0.4 LANGUAGES CXX) +# define project +project(GpgFrontend VERSION 2.0.5 LANGUAGES CXX) +# show cmake version message(STATUS "GpgFrontend Build Configuration Started CMAKE Version ${CMAKE_VERSION}") +INCLUDE(CheckIncludeFiles) +INCLUDE(CheckIncludeFileCXX) +INCLUDE(CheckFunctionExists) +INCLUDE(CheckSymbolExists) +INCLUDE(CheckTypeSize) +INCLUDE(CheckLibraryExists) +INCLUDE(CheckCXXSourceCompiles) + +# generate compile_commands.json +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + # options option(GPGFRONTEND_BUILD_TYPE_TEST_CORE "Only compile the core and generate the unit test program" OFF) @@ -15,9 +54,10 @@ option(GPGFRONTEND_BUILD_TYPE_TEST_ALL "Generate a graphical interface with all functions" OFF) option(GPGFRONTEND_BUILD_TYPE_STABLE "Generate release version" ON) -option(GENERATE_LINUX_INSTALL_SOFTWARE "Generate an installable version" OFF) -option(GENERATE_APP_PACKAGE_DEB "Generate DEB package" OFF) -option(CONFIGURE_FOR_XCODE_BUILD "Generate a version that can be successfully compiled and packaged in Xcode" OFF) +option(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE "Generate an installable version" OFF) +option(GPGFRONTEND_GENERATE_APP_PACKAGE_DEB "Generate DEB package" OFF) +option(GPGFRONTEND_CONFIGURE_FOR_XCODE_BUILD "Generate a version that can be successfully compiled and packaged in Xcode" OFF) +option(GPGFRONTEND_USE_QT_DEFAULT_ENV "Build with the qt version provided by the qt-default package" ON) # analyse options if (GPGFRONTEND_BUILD_TYPE_TEST_CORE) @@ -40,6 +80,7 @@ if (GPGFRONTEND_BUILD_TYPE_TEST_ALL) set(GPGFRONTEND_BUILD_CONFIG "test_all") endif () +# stable features if (GPGFRONTEND_BUILD_TYPE_STABLE) set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0) @@ -51,7 +92,8 @@ if (GPGFRONTEND_BUILD_TYPE_STABLE) set(STABLE_APPLICATION_BUILD 1) endif () -if (GENERATE_LINUX_INSTALL_SOFTWARE) +# linux package build +if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE) set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0) set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0) @@ -60,16 +102,18 @@ if (GENERATE_LINUX_INSTALL_SOFTWARE) unset(GPGFRONTEND_BUILD_CONFIG) set(LINUX_INSTALL_SOFTWARE 1) - set(GENERATE_APP_PACKAGE_DEB 1) + set(GPGFRONTEND_GENERATE_APP_PACKAGE_DEB 1) endif () -if (GENERATE_LINUX_INSTALL_SOFTWARE AND GENERATE_APP_PACKAGE_DEB) +# linux package build +if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE AND GPGFRONTEND_GENERATE_APP_PACKAGE_DEB) set(APP_PACKAGE_DEB 1) endif () -if (CONFIGURE_FOR_XCODE_BUILD) - set(GENERATE_LINUX_INSTALL_SOFTWARE 0) - set(GENERATE_APP_PACKAGE_DEB 0) +# xcode archive build +if (GPGFRONTEND_CONFIGURE_FOR_XCODE_BUILD) + set(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE 0) + set(GPGFRONTEND_GENERATE_APP_PACKAGE_DEB 0) set(LINUX_INSTALL_SOFTWARE 0) set(APP_PACKAGE_DEB 0) @@ -83,21 +127,33 @@ if (CONFIGURE_FOR_XCODE_BUILD) endif () # C++ -#Detect Compiler + +# options for ccache +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif(CCACHE_FOUND) + +# detect compiler if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - # using Clang - message(STATUS "Using Complier Clang") + # using clang + message(STATUS "Using Compiler clang") + message(STATUS "clang version ${CMAKE_CXX_COMPILER_VERSION}") set(USING_COMPILER_CLANG 1) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # using GCC - message(STATUS "Using Complier Gcc") + # using gcc + message(STATUS "Using Compiler gcc") + message(STATUS "gcc version ${CMAKE_CXX_COMPILER_VERSION}") set(USING_COMPILER_GCC 1) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") # using Intel C++ - message(STATUS "Using Complier Intel") + message(STATUS "Using Compiler Intel") + message(WARNING "Compilation with this compiler is untested, which may create some problems that need to be solved by the user.") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # using Visual Studio C++ - message(STATUS "Using Complier Msvc") + message(STATUS "Using Compiler MSVC") + message(WARNING "Compilation with this compiler is untested, which may create some problems that need to be solved by the user.") endif () # Using Standard C++-17 (Consider compatibility) @@ -164,7 +220,7 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Release") else () set(BUILD_FLAG 1) ADD_DEFINITIONS(-DDEBUG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") # Generate branch coverage information using gcc if (TEST_COVERAGE_BUILD) if (USING_COMPILER_GCC) @@ -209,6 +265,7 @@ message(STATUS "GpgFrontend Build Timestamp ${BUILD_TIMESTAMP}") message(STATUS "GpgFrontend Build Version ${BUILD_VERSION}") message(STATUS "GpgFrontend Git Repo Version ${GIT_VERSION}") +# Windows IF (MINGW) message(STATUS "GpgFrontend Configuration For OS Platform Microsoft Windows") message(STATUS "Build Environment MINGW") @@ -224,10 +281,12 @@ IF (MINGW) /mingw64/include ) link_directories( + ${CMAKE_SOURCE_DIR}/lib/mingw /mingw64/lib ) endif () +# macOS if (APPLE) message(STATUS "GpgFrontend Configuration For OS Platform MacOS") @@ -251,7 +310,6 @@ if (APPLE) ) link_directories( /usr/local/lib - /usr/local/opt/openssl/lib ) endif () @@ -291,11 +349,13 @@ if (GPG_STANDALONE_MODE) add_compile_definitions(GPG_STANDALONE_MODE) endif () + if (LINUX_INSTALL_SOFTWARE) message(STATUS "Configure Linux Install ON") include(GNUInstallDirs) set(INSTALL_GPGFRONTEND_APP 1) set(APP_INSTALL_FLAG LINUX_INSTALL) + set(GPGFRONTEND_USE_QT_DEFAULT_ENV ON) add_compile_definitions(LINUX_INSTALL_BUILD) set(Boost_USE_STATIC_LIBS ON) else () @@ -303,10 +363,9 @@ else () add_compile_definitions(BUNDLE_BUILD) endif () -# Basic Environment Configure +# Basic ENV Configure set(BASIC_ENV_CONFIG 1) set(QT_MOC_CONFIG 1) -set(EASY_LOGGING_PP 1) if (FULL_APPLICATION_BUILD) message(STATUS "Build Full Application") @@ -320,6 +379,7 @@ if (FULL_APPLICATION_BUILD) set(BASIC_ENV_CONFIG 1) set(MULTI_LANG_SUPPORT 1) elseif (MINIMUM_APPLICATION_BUILD) + message(STATUS "Build Minimum Application") set(QT5_ENV_SUPPORT 1) set(GPG_CORE 1) set(UI_CORE 1) @@ -330,6 +390,7 @@ elseif (MINIMUM_APPLICATION_BUILD) # set(APP_IMAGE_UPDATE 1) # endif () elseif (STABLE_APPLICATION_BUILD) + message(STATUS "Build Stable Application") set(QT5_ENV_SUPPORT 1) set(GPG_CORE 1) set(UI_CORE 1) @@ -349,11 +410,14 @@ elseif (TEST_CORE_BUILD) endif () # Introduce boost -find_package(Boost COMPONENTS date_time filesystem REQUIRED) +find_package(Boost COMPONENTS date_time system REQUIRED) + +# Introduce OpenSSL +find_package(OpenSSL REQUIRED) if (QT5_ENV_SUPPORT) # Support Qt version Both 5.12.x and 5.15.x - if (LINUX_INSTALL_SOFTWARE) + if (GPGFRONTEND_USE_QT_DEFAULT_ENV) find_package(Qt5 COMPONENTS Core Test Widgets PrintSupport Network REQUIRED) else () find_package(Qt5 5.15 COMPONENTS Core Test Widgets PrintSupport Network REQUIRED) @@ -387,10 +451,13 @@ if (MULTI_LANG_SUPPORT) add_compile_definitions(MULTI_LANG_SUPPORT) endif () - +# third_party add_subdirectory(third_party) + +# source code add_subdirectory(src) +# build to test gpgfrontend core if (TEST_CORE_BUILD) include(CTest) enable_testing() diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 00000000..f00643e1 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,2579 @@ +# Doxyfile 1.8.17 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "GpgFrontend Project" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "A Free, Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free OpenPGP(pgp) Crypto Tool." + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./docs + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# (including Cygwin) ands Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ./src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen +# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.doc \ + *.txt \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files +# were built. This is equivalent to specifying the "-p" option to a clang tool, +# such as clang-check. These options will then be passed to the parser. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using JavaScript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: YES. + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = YES + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = YES + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, +# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, +# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = YES + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES @@ -72,28 +72,90 @@ read the [User Manual](https://www.gpgfrontend.pub/#/quick-start) instead of REA ## Build Source Code -### For Ubuntu 20.04 +For some capable users, building Gpg Frontend from source code is a good option. We encourage people to freely build, +package and distribute their own versions. The way we build in common systems is as follows: + +Note: "$" Symbols indicate commands to be executed with a normal user. Before you start, please clone the latest stable +version code for users around the world. + +```shell +$ git clone --recurse-submodules https://github.com/saturneric/GpgFrontend.git +``` + +如果你在中国大陆,可以使用这个仓库 + +```shell +$ git clone --recurse-submodules https://git.codesdream.com/GpgFrontend.git +``` + +### For Windows + +Before building, you need to install MSYS2. After installation, open the MSYS2 terminal (MSYS2 MinGW 64-bit), enter the +MSYS2 directory, and execute the following commands: + +```shell +pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf +pacman --noconfirm -S --needed make texinfo mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost automake +pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 libintl msys2-runtime-devel gettext-devel mingw-w64-x86_64-gpgme +pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-libarchive +``` + +After executing these commands, you will start compiling. + +```shell +$ cd GpgFrontend +$ mkdir build && cd build +$ cmake -G Ninja -DCMAKE_BUILD_TYPE="Release" .. +$ ninja +``` + +After compiling, a release directory will be generated, which contains executable files that can be run directly. + +```shell +$ ./release/GpgFrontend.exe +``` + +### For macOS Install and compile dependencies. ```shell -$ sudo apt-get update -$ sudo apt-get -y install gettext texinfo git ninja-build cmake -$ sudo apt-get -y install gcc g++ build-essential binutils autoconf automake -$ sudo apt-get -y libconfig++-dev libboost-all-dev qt5-default -$ sudo apt-get -y install gpg # If you need to run directly after building. +$ brew install cmake git autoconf automake qt@5 texinfo gettext [email protected] +$ brew install boost ninja +$ brew unlink gettext && brew link --force gettext +$ brew link qt@5 ``` -Clone the latest stable version code for users around the world. +Build the code separately for debug. ```shell -$ git clone --recurse-submodules https://github.com/saturneric/GpgFrontend.git +$ cd GpgFrontend +$ mkdir build && cd build +$ cmake -G Ninja -DCMAKE_BUILD_TYPE="Debug" -DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected] .. +$ ninja +$ ./release/GpgFrontend # run the program ``` -如果你在中国大陆,可以使用这个仓库 +Build the code and make the App Bundle. ```shell -$ git clone --recurse-submodules https://git.codesdream.com/GpgFrontend.git +$ cd GpgFrontend +$ mkdir build && cd build +$ cmake -G Ninja -DCMAKE_BUILD_TYPE="Release" -DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected] .. +$ ninja +$ macdeployqt ./release/GpgFrontend.app +``` + +### For Ubuntu 18.04 And Later + +Install and compile dependencies. + +```shell +$ sudo apt-get update +$ sudo apt-get -y install gettext texinfo git ninja-build cmake +$ sudo apt-get -y install gcc g++ build-essential binutils autoconf automake +$ sudo apt-get -y libboost-all-dev qt5-default +$ sudo apt-get -y install gpg # If you need to run directly after building. ``` Build the code and make the deb package. @@ -116,6 +178,20 @@ $ ninja $ ./release/GpgFrontend # run the program ``` +Package the AppImage. + +```shell +$ cd GpgFrontend +$ mkdir build && cd build +$ cmake -G Ninja -DCMAKE_BUILD_TYPE="Release" .. +$ ninja +$ mkdir ./AppImageOut +$ cd ./AppImageOut +$ wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage +$ chmod u+x linuxdeployqt-continuous-x86_64.AppImage +$ ./linuxdeployqt-continuous-x86_64.AppImage ../release/gpgfrontend/usr/share/applications/*.desktop -appimage +``` + ## Languages Support The supported languages are listed here. Some languages use machine translation and have not been verified. If you want @@ -123,10 +199,10 @@ to join translation and verification work, please refer to [here](https://gpgfr ### Supported Languages -'zh_CN', 'es_ES', 'zh_TW', 'zh_HK', 'fr_FR', 'de_DE', 'pl_PL', 'ru_RU', 'ja_JP', 'it_IT', +'zh_CN', 'zh_TW', 'zh_HK', 'es_ES', 'fr_FR', 'de_DE', 'pl_PL', 'ru_RU', 'ja_JP', 'it_IT', 'ko_KR', 'pt_BR', 'ar_SA', 'ar_IQ', 'hi_IN', 'af_ZA', 'sq_AL', 'be_BY', 'bg_BG', 'ca_ES', 'hr_HR', 'cs_CZ', 'da_DK', 'nl_NL', 'et_EE', 'fa_IR', 'fi_FI', 'fr_CA', 'he_IL', 'id_ID', -'lt_LT', 'De_AT', 'De_CH', 'El_GR', 'Es_MX', 'Iw_IL', 'UK_UA' +'lt_LT', 'de_AT', 'de_CH', 'el_GR', 'es_MX', 'iw_IL', 'uk_UA', 'en_US', 'en_GB', 'en_AU', Notice: Most translations are generated by Google's automatic translation machine.If you find that a certain translation is wrong, you are welcome to join the translation work to provide a more suitable human translation. diff --git a/cmake/cotire.cmake b/cmake/cotire.cmake new file mode 100644 index 00000000..7551e4a7 --- /dev/null +++ b/cmake/cotire.cmake @@ -0,0 +1,4212 @@ +# - cotire (compile time reducer) +# +# See the cotire manual for usage hints. +# +#============================================================================= +# Copyright 2012-2018 Sascha Kratky +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +#============================================================================= + +if(__COTIRE_INCLUDED) + return() +endif() +set(__COTIRE_INCLUDED TRUE) + +# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode +# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(PUSH) +endif() +cmake_minimum_required(VERSION 2.8.12) +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(POP) +endif() + +set (COTIRE_CMAKE_MODULE_FILE "cotire.cmake") +set (COTIRE_CMAKE_MODULE_VERSION "1.8.1") + +# activate select policies +if (POLICY CMP0025) + # Compiler id for Apple Clang is now AppleClang + cmake_policy(SET CMP0025 NEW) +endif() + +if (POLICY CMP0026) + # disallow use of the LOCATION target property + cmake_policy(SET CMP0026 NEW) +endif() + +if (POLICY CMP0038) + # targets may not link directly to themselves + cmake_policy(SET CMP0038 NEW) +endif() + +if (POLICY CMP0039) + # utility targets may not have link dependencies + cmake_policy(SET CMP0039 NEW) +endif() + +if (POLICY CMP0040) + # target in the TARGET signature of add_custom_command() must exist + cmake_policy(SET CMP0040 NEW) +endif() + +if (POLICY CMP0045) + # error on non-existent target in get_target_property + cmake_policy(SET CMP0045 NEW) +endif() + +if (POLICY CMP0046) + # error on non-existent dependency in add_dependencies + cmake_policy(SET CMP0046 NEW) +endif() + +if (POLICY CMP0049) + # do not expand variables in target source entries + cmake_policy(SET CMP0049 NEW) +endif() + +if (POLICY CMP0050) + # disallow add_custom_command SOURCE signatures + cmake_policy(SET CMP0050 NEW) +endif() + +if (POLICY CMP0051) + # include TARGET_OBJECTS expressions in a target's SOURCES property + cmake_policy(SET CMP0051 NEW) +endif() + +if (POLICY CMP0053) + # simplify variable reference and escape sequence evaluation + cmake_policy(SET CMP0053 NEW) +endif() + +if (POLICY CMP0054) + # only interpret if() arguments as variables or keywords when unquoted + cmake_policy(SET CMP0054 NEW) +endif() + +if (POLICY CMP0055) + # strict checking for break() command + cmake_policy(SET CMP0055 NEW) +endif() + +include(CMakeParseArguments) +include(ProcessorCount) + +function (cotire_get_configuration_types _configsVar) + set (_configs "") + if (CMAKE_CONFIGURATION_TYPES) + list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) + endif() + if (CMAKE_BUILD_TYPE) + list (APPEND _configs "${CMAKE_BUILD_TYPE}") + endif() + if (_configs) + list (REMOVE_DUPLICATES _configs) + set (${_configsVar} ${_configs} PARENT_SCOPE) + else() + set (${_configsVar} "None" PARENT_SCOPE) + endif() +endfunction() + +function (cotire_get_source_file_extension _sourceFile _extVar) + # get_filename_component returns extension from first occurrence of . in file name + # this function computes the extension from last occurrence of . in file name + string (FIND "${_sourceFile}" "." _index REVERSE) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) + else() + set (_sourceExt "") + endif() + set (${_extVar} "${_sourceExt}" PARENT_SCOPE) +endfunction() + +macro (cotire_check_is_path_relative_to _path _isRelativeVar) + set (${_isRelativeVar} FALSE) + if (IS_ABSOLUTE "${_path}") + foreach (_dir ${ARGN}) + file (RELATIVE_PATH _relPath "${_dir}" "${_path}") + if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) + set (${_isRelativeVar} TRUE) + break() + endif() + endforeach() + endif() +endmacro() + +function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) + if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") + else() + set (_languageExtensions "") + endif() + if (CMAKE_${_language}_IGNORE_EXTENSIONS) + set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") + else() + set (_ignoreExtensions "") + endif() + if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) + set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") + else() + set (_excludeExtensions "") + endif() + if (COTIRE_DEBUG AND _languageExtensions) + message (STATUS "${_language} source file extensions: ${_languageExtensions}") + endif() + if (COTIRE_DEBUG AND _ignoreExtensions) + message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") + endif() + if (COTIRE_DEBUG AND _excludeExtensions) + message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") + endif() + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_allSourceFiles ${ARGN}) + else() + # as of CMake 3.1 target sources may contain generator expressions + # since we cannot obtain required property information about source files added + # through generator expressions at configure time, we filter them out + string (GENEX_STRIP "${ARGN}" _allSourceFiles) + endif() + set (_filteredSourceFiles "") + set (_excludedSourceFiles "") + foreach (_sourceFile ${_allSourceFiles}) + get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) + get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) + get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) + if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) + cotire_get_source_file_extension("${_sourceFile}" _sourceExt) + if (_sourceExt) + list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) + if (_ignoreIndex LESS 0) + list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) + if (_excludeIndex GREATER -1) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) + if (_sourceIndex GREATER -1) + # consider source file unless it is excluded explicitly + get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) + if (_sourceIsExcluded) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _filteredSourceFiles "${_sourceFile}") + endif() + else() + get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) + if ("${_sourceLanguage}" STREQUAL "${_language}") + # add to excluded sources, if file is not ignored and has correct language without having the correct extension + list (APPEND _excludedSourceFiles "${_sourceFile}") + endif() + endif() + endif() + endif() + endif() + endif() + endforeach() + # separate filtered source files from already cotired ones + # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire + set (_sourceFiles "") + set (_cotiredSourceFiles "") + foreach (_sourceFile ${_filteredSourceFiles}) + get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + if (_sourceIsCotired) + list (APPEND _cotiredSourceFiles "${_sourceFile}") + else() + get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) + if (_sourceCompileFlags) + # add to excluded sources, if file has custom compile flags + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + get_source_file_property(_sourceCompileOptions "${_sourceFile}" COMPILE_OPTIONS) + if (_sourceCompileOptions) + # add to excluded sources, if file has list of custom compile options + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _sourceFiles "${_sourceFile}") + endif() + endif() + endif() + endforeach() + if (COTIRE_DEBUG) + if (_sourceFiles) + message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}") + endif() + if (_excludedSourceFiles) + message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}") + endif() + if (_cotiredSourceFiles) + message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}") + endif() + endif() + set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) + set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) + set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (NOT _propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_file_property_values _valuesVar _property) + set (_values "") + foreach (_sourceFile ${ARGN}) + get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) + if (_propertyValue) + list (APPEND _values "${_propertyValue}") + endif() + endforeach() + set (${_valuesVar} ${_values} PARENT_SCOPE) +endfunction() + +function (cotire_resolve_config_properties _configurations _propertiesVar) + set (_properties "") + foreach (_property ${ARGN}) + if ("${_property}" MATCHES "<CONFIG>") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}") + list (APPEND _properties ${_configProperty}) + endforeach() + else() + list (APPEND _properties ${_property}) + endif() + endforeach() + set (${_propertiesVar} ${_properties} PARENT_SCOPE) +endfunction() + +function (cotire_copy_set_properties _configurations _type _source _target) + cotire_resolve_config_properties("${_configurations}" _properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) + set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") + endif() + endforeach() +endfunction() + +function (cotire_get_target_usage_requirements _target _config _targetRequirementsVar) + set (_targetRequirements "") + get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) + while (_librariesToProcess) + # remove from head + list (GET _librariesToProcess 0 _library) + list (REMOVE_AT _librariesToProcess 0) + if (_library MATCHES "^\\$<\\$<CONFIG:${_config}>:([A-Za-z0-9_:-]+)>$") + set (_library "${CMAKE_MATCH_1}") + elseif (_config STREQUAL "None" AND _library MATCHES "^\\$<\\$<CONFIG:>:([A-Za-z0-9_:-]+)>$") + set (_library "${CMAKE_MATCH_1}") + endif() + if (TARGET ${_library}) + list (FIND _targetRequirements ${_library} _index) + if (_index LESS 0) + list (APPEND _targetRequirements ${_library}) + # BFS traversal of transitive libraries + get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) + if (_libraries) + list (APPEND _librariesToProcess ${_libraries}) + list (REMOVE_DUPLICATES _librariesToProcess) + endif() + endif() + endif() + endwhile() + set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE) +endfunction() + +function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + set (_flagPrefix "[/-]") + else() + set (_flagPrefix "--?") + endif() + set (_optionFlag "") + set (_matchedOptions "") + set (_unmatchedOptions "") + foreach (_compileFlag ${ARGN}) + if (_compileFlag) + if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") + # option with separate argument + list (APPEND _matchedOptions "${_compileFlag}") + set (_optionFlag "") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") + # remember option + set (_optionFlag "${CMAKE_MATCH_2}") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") + # option with joined argument + list (APPEND _matchedOptions "${CMAKE_MATCH_3}") + set (_optionFlag "") + else() + # flush remembered option + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + set (_optionFlag "") + endif() + # add to unfiltered options + list (APPEND _unmatchedOptions "${_compileFlag}") + endif() + endif() + endforeach() + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + endif() + if (COTIRE_DEBUG AND _matchedOptions) + message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}") + endif() + if (COTIRE_DEBUG AND _unmatchedOptions) + message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}") + endif() + set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) + set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) +endfunction() + +function (cotire_is_target_supported _target _isSupportedVar) + if (NOT TARGET "${_target}") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_imported ${_target} IMPORTED) + if (_imported) + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_targetType ${_target} TYPE) + if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + set (${_isSupportedVar} TRUE PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_flags _config _language _target _flagsVar) + string (TOUPPER "${_config}" _upperConfig) + # collect options from CMake language variables + set (_compileFlags "") + if (CMAKE_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") + endif() + if (CMAKE_${_language}_FLAGS_${_upperConfig}) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") + endif() + if (_target) + # add target compile flags + get_target_property(_targetflags ${_target} COMPILE_FLAGS) + if (_targetflags) + set (_compileFlags "${_compileFlags} ${_targetflags}") + endif() + endif() + if (UNIX) + separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") + elseif(WIN32) + separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") + else() + separate_arguments(_compileFlags) + endif() + # target compile options + if (_target) + get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endif() + # interface compile options from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endforeach() + endif() + # handle language standard properties + if (CMAKE_${_language}_STANDARD_DEFAULT) + # used compiler supports language standard levels + if (_target) + get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD) + if (_targetLanguageStandard) + set (_type "EXTENSION") + get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET) + if (_isSet) + get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS) + if (NOT _targetUseLanguageExtensions) + set (_type "STANDARD") + endif() + endif() + if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION) + list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}") + endif() + endif() + endif() + endif() + # handle the POSITION_INDEPENDENT_CODE target property + if (_target) + get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) + if (_targetPIC) + get_target_property(_targetType ${_target} TYPE) + if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") + elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") + endif() + endif() + endif() + # handle visibility target properties + if (_target) + get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET) + if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}") + endif() + get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN) + if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}") + endif() + endif() + # platform specific flags + if (APPLE) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) + if (NOT _architectures) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES) + endif() + if (_architectures) + foreach (_arch ${_architectures}) + list (APPEND _compileFlags "-arch" "${_arch}") + endforeach() + endif() + if (CMAKE_OSX_SYSROOT) + if (CMAKE_${_language}_SYSROOT_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") + else() + list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") + endif() + endif() + if (CMAKE_OSX_DEPLOYMENT_TARGET) + if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + else() + list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() + endif() + endif() + if (COTIRE_DEBUG AND _compileFlags) + message (STATUS "Target ${_target} compile flags: ${_compileFlags}") + endif() + set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar) + set (_includeDirs "") + set (_systemIncludeDirs "") + # default include dirs + if (CMAKE_INCLUDE_CURRENT_DIR) + list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}") + list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + # parse additional include directories from target compile flags + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _includeDirs ${_dirs}) + endif() + endif() + endif() + # parse additional system include directories from target compile flags + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _systemIncludeDirs ${_dirs}) + endif() + endif() + endif() + # target include directories + get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES) + if (_target) + get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endif() + # interface include directories from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_linkedTargetType ${_linkedTarget} TYPE) + if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND + _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR + # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR + # which are only available with CMake 3.4 or later. + get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endforeach() + endif() + if (dirs) + list (REMOVE_DUPLICATES _dirs) + endif() + list (LENGTH _includeDirs _projectInsertIndex) + foreach (_dir ${_dirs}) + if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) + cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") + if (_isRelative) + list (LENGTH _includeDirs _len) + if (_len EQUAL _projectInsertIndex) + list (APPEND _includeDirs "${_dir}") + else() + list (INSERT _includeDirs _projectInsertIndex "${_dir}") + endif() + math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") + else() + list (APPEND _includeDirs "${_dir}") + endif() + else() + list (APPEND _includeDirs "${_dir}") + endif() + endforeach() + list (REMOVE_DUPLICATES _includeDirs) + list (REMOVE_DUPLICATES _systemIncludeDirs) + if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) + list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) + endif() + if (WIN32 AND NOT MINGW) + # convert Windows paths in include directories to CMake paths + if (_includeDirs) + set (_paths "") + foreach (_dir ${_includeDirs}) + file (TO_CMAKE_PATH "${_dir}" _path) + list (APPEND _paths "${_path}") + endforeach() + set (_includeDirs ${_paths}) + endif() + if (_systemIncludeDirs) + set (_paths "") + foreach (_dir ${_systemIncludeDirs}) + file (TO_CMAKE_PATH "${_dir}" _path) + list (APPEND _paths "${_path}") + endforeach() + set (_systemIncludeDirs ${_paths}) + endif() + endif() + if (COTIRE_DEBUG AND _includeDirs) + message (STATUS "Target ${_target} include dirs: ${_includeDirs}") + endif() + set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) + if (COTIRE_DEBUG AND _systemIncludeDirs) + message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}") + endif() + set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_export_symbol _target _exportSymbolVar) + set (_exportSymbol "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_enableExports ${_target} ENABLE_EXPORTS) + if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR + (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) + get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) + if (NOT _exportSymbol) + set (_exportSymbol "${_target}_EXPORTS") + endif() + string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol) + endif() + set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_definitions _config _language _target _definitionsVar) + string (TOUPPER "${_config}" _upperConfig) + set (_configDefinitions "") + # CMAKE_INTDIR for multi-configuration build systems + if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") + endif() + # target export define symbol + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + list (APPEND _configDefinitions "${_defineSymbol}") + endif() + # directory compile definitions + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # target compile definitions + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # interface compile definitions from linked library targets + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + endforeach() + # parse additional compile definitions from target compile flags + # and do not look at directory compile definitions, which we already handled + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + list (REMOVE_DUPLICATES _configDefinitions) + if (COTIRE_DEBUG AND _configDefinitions) + message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}") + endif() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar) + # parse target compile flags omitting compile definitions and include directives + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + set (_flagFilter "D") + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + set (_compilerFlags "") + cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags}) + if (COTIRE_DEBUG AND _compilerFlags) + message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}") + endif() + set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) +endfunction() + +function (cotire_add_sys_root_paths _pathsVar) + if (APPLE) + if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) + foreach (_path IN LISTS ${_pathsVar}) + if (IS_ABSOLUTE "${_path}") + get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) + if (EXISTS "${_path}") + list (APPEND ${_pathsVar} "${_path}") + endif() + endif() + endforeach() + endif() + endif() + set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) + set (_extraProperties ${ARGN}) + set (_result "") + if (_extraProperties) + list (FIND _extraProperties "${_sourceFile}" _index) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + list (LENGTH _extraProperties _len) + math (EXPR _len "${_len} - 1") + foreach (_index RANGE ${_index} ${_len}) + list (GET _extraProperties ${_index} _value) + if (_value MATCHES "${_pattern}") + list (APPEND _result "${_value}") + else() + break() + endif() + endforeach() + endif() + endif() + set (${_resultVar} ${_result} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) + set (_compileDefinitions "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + string (TOUPPER "${_config}" _upperConfig) + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + if (COTIRE_DEBUG AND _compileDefinitions) + message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}") + endif() + set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) + set (_configDefinitions "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) + if (_sourceDefinitions) + list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") + endif() + endforeach() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) + set (_sourceUndefs "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + get_source_file_property(_undefs "${_sourceFile}" ${_property}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + if (COTIRE_DEBUG AND _sourceUndefs) + message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}") + endif() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_undefs _property _sourceUndefsVar) + set (_sourceUndefs "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) + if (_undefs) + list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") + endif() + endforeach() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +macro (cotire_set_cmd_to_prologue _cmdVar) + set (${_cmdVar} "${CMAKE_COMMAND}") + if (COTIRE_DEBUG) + list (APPEND ${_cmdVar} "--warn-uninitialized") + endif() + list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>") + if (XCODE) + list (APPEND ${_cmdVar} "-DXCODE:BOOL=TRUE") + endif() + if (COTIRE_VERBOSE) + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") + elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") + endif() +endmacro() + +function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1) + if (NOT _compilerLauncher) + set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER}) + endif() + if (NOT _compilerExe) + set (_compilerExe "${CMAKE_${_language}_COMPILER}") + endif() + if (NOT _compilerArg1) + set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) + endif() + if (WIN32) + file (TO_NATIVE_PATH "${_compilerExe}" _compilerExe) + endif() + string (STRIP "${_compilerArg1}" _compilerArg1) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # compiler launcher is only supported for Makefile and Ninja + set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + else() + set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_add_definitions_to_cmd _cmdVar _language) + foreach (_definition ${ARGN}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + list (APPEND ${_cmdVar} "/D${_definition}") + else() + list (APPEND ${_cmdVar} "-D${_definition}") + endif() + endforeach() +endmacro() + +function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}}) + if (_includeDirs) + list (REMOVE_DUPLICATES _includeDirs) + foreach (_include ${_includeDirs}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + file (TO_NATIVE_PATH "${_include}" _include) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + else() + set (_index -1) + if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+") + list (FIND ${_systemIncludesVar} "${_include}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + else() + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + endif() + endif() + endforeach() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() + +function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + if (APPLE) + set (_frameworkDirs "") + foreach (_include ${${_includesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _frameworkDirs "${_frameworkDir}") + endif() + endforeach() + set (_systemFrameworkDirs "") + foreach (_include ${${_systemIncludesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _systemFrameworkDirs "${_frameworkDir}") + endif() + endforeach() + if (_systemFrameworkDirs) + list (APPEND _frameworkDirs ${_systemFrameworkDirs}) + endif() + if (_frameworkDirs) + list (REMOVE_DUPLICATES _frameworkDirs) + foreach (_frameworkDir ${_frameworkDirs}) + set (_index -1) + if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+") + list (FIND _systemFrameworkDirs "${_frameworkDir}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + else() + list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + endif() + endforeach() + endif() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() + +macro (cotire_add_compile_flags_to_cmd _cmdVar) + foreach (_flag ${ARGN}) + list (APPEND ${_cmdVar} "${_flag}") + endforeach() +endmacro() + +function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) + if (EXISTS "${_file}") + set (_triggerFile "") + foreach (_dependencyFile ${ARGN}) + if (EXISTS "${_dependencyFile}") + # IS_NEWER_THAN returns TRUE if both files have the same timestamp + # thus we do the comparison in both directions to exclude ties + if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND + NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}") + set (_triggerFile "${_dependencyFile}") + break() + endif() + endif() + endforeach() + if (_triggerFile) + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") + endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + else() + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} is up-to-date.") + endif() + set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) + endif() + else() + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} does not exist yet.") + endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) + set (${_relPathVar} "") + foreach (_includeDir ${_includeDirs}) + if (IS_DIRECTORY "${_includeDir}") + file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") + if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") + string (LENGTH "${${_relPathVar}}" _closestLen) + string (LENGTH "${_relPath}" _relLen) + if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) + set (${_relPathVar} "${_relPath}") + endif() + endif() + elseif ("${_includeDir}" STREQUAL "${_headerFile}") + # if path matches exactly, return short non-empty string + set (${_relPathVar} "1") + break() + endif() + endforeach() +endmacro() + +macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside) + # check header path against ignored and honored include directories + cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath) + if (_insideRelPath) + # header is inside, but could be become outside if there is a shorter outside match + cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath) + if (_outsideRelPath) + string (LENGTH "${_insideRelPath}" _insideRelPathLen) + string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) + if (_outsideRelPathLen LESS _insideRelPathLen) + set (${_headerIsInside} FALSE) + else() + set (${_headerIsInside} TRUE) + endif() + else() + set (${_headerIsInside} TRUE) + endif() + else() + # header is outside + set (${_headerIsInside} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) + if (NOT EXISTS "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif (IS_DIRECTORY "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed") + # heuristic: ignore headers with embedded parent directory references or "-fixed" or "_fixed" in path + # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation + # with the error message "error: no include path in which to search for header" + set (${_headerIsIgnoredVar} TRUE) + else() + set (${_headerIsIgnoredVar} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) + # check header file extension + cotire_get_source_file_extension("${_headerFile}" _headerFileExt) + set (${_headerIsIgnoredVar} FALSE) + if (_headerFileExt) + list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) + if (_index GREATER -1) + set (${_headerIsIgnoredVar} TRUE) + endif() + endif() +endmacro() + +macro (cotire_parse_line _line _headerFileVar _headerDepthVar) + if (MSVC) + # cl.exe /showIncludes produces different output, depending on the language pack used, e.g.: + # English: "Note: including file: C:\directory\file" + # German: "Hinweis: Einlesen der Datei: C:\directory\file" + # We use a very general regular expression, relying on the presence of the : characters + if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + else() + if (_line MATCHES "^(\\.+) (.*)$") + # GCC like output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + if (IS_ABSOLUTE "${CMAKE_MATCH_2}") + set (${_headerFileVar} "${CMAKE_MATCH_2}") + else() + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) + endif() + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + endif() +endmacro() + +function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) + if (WIN32) + # prevent CMake macro invocation errors due to backslash characters in Windows paths + string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") + endif() + # canonize slashes + string (REPLACE "//" "/" _scanOutput "${_scanOutput}") + # prevent semicolon from being interpreted as a line separator + string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") + # then separate lines + string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") + list (LENGTH _scanOutput _len) + # remove duplicate lines to speed up parsing + list (REMOVE_DUPLICATES _scanOutput) + list (LENGTH _scanOutput _uniqueLen) + if (COTIRE_VERBOSE OR COTIRE_DEBUG) + message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") + if (_ignoredExtensions) + message (STATUS "Ignored extensions: ${_ignoredExtensions}") + endif() + if (_ignoredIncludeDirs) + message (STATUS "Ignored paths: ${_ignoredIncludeDirs}") + endif() + if (_honoredIncludeDirs) + message (STATUS "Included paths: ${_honoredIncludeDirs}") + endif() + endif() + set (_sourceFiles ${ARGN}) + set (_selectedIncludes "") + set (_unparsedLines "") + # stack keeps track of inside/outside project status of processed header files + set (_headerIsInsideStack "") + foreach (_line IN LISTS _scanOutput) + if (_line) + cotire_parse_line("${_line}" _headerFile _headerDepth) + if (_headerFile) + cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside) + if (COTIRE_DEBUG) + message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") + endif() + # update stack + list (LENGTH _headerIsInsideStack _stackLen) + if (_headerDepth GREATER _stackLen) + math (EXPR _stackLen "${_stackLen} + 1") + foreach (_index RANGE ${_stackLen} ${_headerDepth}) + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endforeach() + else() + foreach (_index RANGE ${_headerDepth} ${_stackLen}) + list (REMOVE_AT _headerIsInsideStack -1) + endforeach() + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerIsInsideStack}") + endif() + # header is a candidate if it is outside project + if (NOT _headerIsInside) + # get parent header file's inside/outside status + if (_headerDepth GREATER 1) + math (EXPR _index "${_headerDepth} - 2") + list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) + else() + set (_parentHeaderIsInside TRUE) + endif() + # select header file if parent header file is inside project + # (e.g., a project header file that includes a standard header file) + if (_parentHeaderIsInside) + cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) + if (NOT _headerIsIgnored) + cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) + if (NOT _headerIsIgnored) + list (APPEND _selectedIncludes "${_headerFile}") + else() + # fix header's inside status on stack, it is ignored by extension now + list (REMOVE_AT _headerIsInsideStack -1) + list (APPEND _headerIsInsideStack TRUE) + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") + endif() + endif() + endif() + else() + if (MSVC) + # for cl.exe do not keep unparsed lines which solely consist of a source file name + string (FIND "${_sourceFiles}" "${_line}" _index) + if (_index LESS 0) + list (APPEND _unparsedLines "${_line}") + endif() + else() + list (APPEND _unparsedLines "${_line}") + endif() + endif() + endif() + endforeach() + list (REMOVE_DUPLICATES _selectedIncludes) + set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) + set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) +endfunction() + +function (cotire_scan_includes _includesVar) + set(_options "") + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES + IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) + # only consider existing source files for scanning + set (_existingSourceFiles "") + foreach (_sourceFile ${_sourceFiles}) + if (EXISTS "${_sourceFile}") + list (APPEND _existingSourceFiles "${_sourceFile}") + endif() + endforeach() + if (NOT _existingSourceFiles) + set (${_includesVar} "" PARENT_SCOPE) + return() + endif() + # add source files to be scanned + if (WIN32) + foreach (_sourceFile ${_existingSourceFiles}) + file (TO_NATIVE_PATH "${_sourceFile}" _sourceFileNative) + list (APPEND _cmd "${_sourceFileNative}") + endforeach() + else() + list (APPEND _cmd ${_existingSourceFiles}) + endif() + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC") + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result + OUTPUT_QUIET + ERROR_VARIABLE _output) + if (_result) + message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") + endif() + cotire_parse_includes( + "${_option_LANGUAGE}" "${_output}" + "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" + "${_option_IGNORE_EXTENSIONS}" + _includes _unparsedLines + ${_sourceFiles}) + if (_option_INCLUDE_PRIORITY_PATH) + set (_sortedIncludes "") + foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH}) + foreach (_include ${_includes}) + string (FIND ${_include} ${_priorityPath} _position) + if (_position GREATER -1) + list (APPEND _sortedIncludes ${_include}) + endif() + endforeach() + endforeach() + if (_sortedIncludes) + list (INSERT _includes 0 ${_sortedIncludes}) + list (REMOVE_DUPLICATES _includes) + endif() + endif() + set (${_includesVar} ${_includes} PARENT_SCOPE) + if (_option_UNPARSED_LINES) + set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) + endif() + if (_option_SCAN_RESULT) + set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_append_undefs _contentsVar) + set (_undefs ${ARGN}) + if (_undefs) + list (REMOVE_DUPLICATES _undefs) + foreach (_definition ${_undefs}) + list (APPEND ${_contentsVar} "#undef ${_definition}") + endforeach() + endif() +endmacro() + +macro (cotire_comment_str _language _commentText _commentVar) + if ("${_language}" STREQUAL "CMAKE") + set (${_commentVar} "# ${_commentText}") + else() + set (${_commentVar} "/* ${_commentText} */") + endif() +endmacro() + +function (cotire_write_file _language _file _contents _force) + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) + cotire_comment_str("${_language}" "${_file}" _header2) + set (_contents "${_header1}\n${_header2}\n${_contents}") + if (COTIRE_DEBUG) + message (STATUS "${_contents}") + endif() + if (_force OR NOT EXISTS "${_file}") + file (WRITE "${_file}" "${_contents}") + else() + file (READ "${_file}" _oldContents) + if (NOT "${_oldContents}" STREQUAL "${_contents}") + file (WRITE "${_file}" "${_contents}") + else() + if (COTIRE_DEBUG) + message (STATUS "${_file} unchanged") + endif() + endif() + endif() +endfunction() + +function (cotire_generate_unity_source _unityFile) + set(_options "") + set(_oneValueArgs LANGUAGE) + set(_multiValueArgs + DEPENDS SOURCES_COMPILE_DEFINITIONS + PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) + if (_unityFileIsUpToDate) + return() + endif() + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_PRE_UNDEFS) + set (_option_PRE_UNDEFS "") + endif() + if (NOT _option_SOURCES_PRE_UNDEFS) + set (_option_SOURCES_PRE_UNDEFS "") + endif() + if (NOT _option_POST_UNDEFS) + set (_option_POST_UNDEFS "") + endif() + if (NOT _option_SOURCES_POST_UNDEFS) + set (_option_SOURCES_POST_UNDEFS "") + endif() + set (_contents "") + if (_option_PROLOGUE) + list (APPEND _contents ${_option_PROLOGUE}) + endif() + if (_option_LANGUAGE AND _sourceFiles) + if ("${_option_LANGUAGE}" STREQUAL "CXX") + list (APPEND _contents "#ifdef __cplusplus") + elseif ("${_option_LANGUAGE}" STREQUAL "C") + list (APPEND _contents "#ifndef __cplusplus") + endif() + endif() + set (_compileUndefinitions "") + foreach (_sourceFile ${_sourceFiles}) + cotire_get_source_compile_definitions( + "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions + ${_option_SOURCES_COMPILE_DEFINITIONS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) + if (_option_PRE_UNDEFS) + list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) + endif() + if (_sourcePreUndefs) + list (APPEND _compileUndefinitions ${_sourcePreUndefs}) + endif() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_sourcePostUndefs) + list (APPEND _compileUndefinitions ${_sourcePostUndefs}) + endif() + if (_option_POST_UNDEFS) + list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) + endif() + foreach (_definition ${_compileDefinitions}) + if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") + list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") + list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") + else() + list (APPEND _contents "#define ${_definition}") + list (INSERT _compileUndefinitions 0 "${_definition}") + endif() + endforeach() + # use absolute path as source file location + get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) + if (WIN32) + file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) + endif() + list (APPEND _contents "#include \"${_sourceFileLocation}\"") + endforeach() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_option_LANGUAGE AND _sourceFiles) + list (APPEND _contents "#endif") + endif() + if (_option_EPILOGUE) + list (APPEND _contents ${_option_EPILOGUE}) + endif() + list (APPEND _contents "") + string (REPLACE ";" "\n" _contents "${_contents}") + if (COTIRE_VERBOSE) + message ("${_contents}") + endif() + cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) +endfunction() + +function (cotire_generate_prefix_header _prefixFile) + set(_options "") + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION) + set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS + INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH + IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + if (_option_DEPENDS) + cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) + if (_prefixFileIsUpToDate) + # create empty log file + set (_unparsedLinesFile "${_prefixFile}.log") + file (WRITE "${_unparsedLinesFile}" "") + return() + endif() + endif() + set (_prologue "") + set (_epilogue "") + if (_option_COMPILER_ID MATCHES "Clang") + set (_prologue "#pragma clang system_header") + elseif (_option_COMPILER_ID MATCHES "GNU") + set (_prologue "#pragma GCC system_header") + elseif (_option_COMPILER_ID MATCHES "MSVC") + set (_prologue "#pragma warning(push, 0)") + set (_epilogue "#pragma warning(pop)") + elseif (_option_COMPILER_ID MATCHES "Intel") + # Intel compiler requires hdrstop pragma to stop generating PCH file + set (_epilogue "#pragma hdrstop") + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + cotire_scan_includes(_selectedHeaders ${_sourceFiles} + LANGUAGE "${_option_LANGUAGE}" + COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" + COMPILER_ARG1 "${_option_COMPILER_ARG1}" + COMPILER_ID "${_option_COMPILER_ID}" + COMPILER_VERSION "${_option_COMPILER_VERSION}" + COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} + COMPILE_FLAGS ${_option_COMPILE_FLAGS} + INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} + SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} + IGNORE_PATH ${_option_IGNORE_PATH} + INCLUDE_PATH ${_option_INCLUDE_PATH} + IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} + INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH} + UNPARSED_LINES _unparsedLines + SCAN_RESULT _scanResult) + cotire_generate_unity_source("${_prefixFile}" + PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) + set (_unparsedLinesFile "${_prefixFile}.log") + if (_unparsedLines) + if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders) + list (LENGTH _unparsedLines _skippedLineCount) + if (WIN32) + file (TO_NATIVE_PATH "${_unparsedLinesFile}" _unparsedLinesLogPath) + else() + set (_unparsedLinesLogPath "${_unparsedLinesFile}") + endif() + message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesLogPath}") + endif() + string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") + endif() + file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n") +endfunction() + +function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + # cl.exe options used + # /nologo suppresses display of sign-on banner + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # /showIncludes list include files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /showIncludes") + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fdirectives-only do not expand macros, requires GCC >= 4.3 + if (_flags) + # append to list + list (APPEND _flags -H -E) + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + list (APPEND _flags -fdirectives-only) + endif() + else() + # return as a flag string + set (_flags "-H -E") + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + set (_flags "${_flags} -fdirectives-only") + endif() + endif() + elseif (_compilerID MATCHES "Clang") + if (UNIX) + # Clang options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fno-color-diagnostics do not print diagnostics in color + # -Eonly just run preprocessor, no output + if (_flags) + # append to list + list (APPEND _flags -H -E -fno-color-diagnostics -Xclang -Eonly) + else() + # return as a flag string + set (_flags "-H -E -fno-color-diagnostics -Xclang -Eonly") + endif() + elseif (WIN32) + # Clang-cl.exe options used + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # -H print the name of each header file used + # -fno-color-diagnostics do not print diagnostics in color + # -Eonly just run preprocessor, no output + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags "${_sourceFileType${_language}}" /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly") + endif() + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + # Windows Intel options used + # /nologo do not display compiler version information + # /QH display the include file order + # /EP preprocess to stdout, omitting #line directives + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /QH") + endif() + else() + # Linux / Mac OS X Intel options used + # -H print the name of each header file used + # -EP preprocess to stdout, omitting #line directives + # -Kc++ process all source or unrecognized file types as C++ source files + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags -H -EP) + else() + # return as a flag string + if ("${_language}" STREQUAL "CXX") + set (_flags "-Kc++ ") + endif() + set (_flags "${_flags}-H -EP") + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /Zs syntax check only + # /Zm precompiled header memory allocation scaling factor + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may + # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}") + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + endif() + elseif (_compilerID MATCHES "Clang") + if (UNIX) + # Clang options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + # -fno-pch-timestamp disable inclusion of timestamp in precompiled headers (clang 4.0.0+) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0") + list (APPEND _flags -Xclang -fno-pch-timestamp) + endif() + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0") + set (_flags "${_flags} -Xclang -fno-pch-timestamp") + endif() + endif() + elseif (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # Clang-cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /Zs syntax check only + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags "${_sourceFileType${_language}}" + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + endif() + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # Windows Intel options used + # /nologo do not display compiler version information + # /Yc create a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + # /Zs syntax check only + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-create name of the precompiled header (PCH) to create + # -Kc++ process all source or unrecognized file types as C++ source files + # -fsyntax-only check only for correct syntax + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + set (_pchSuppressMessages FALSE) + if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") + set(_pchSuppressMessages TRUE) + endif() + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + list (APPEND _flags -Wpch-messages) + endif() + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /Zm precompiled header memory allocation scaling factor + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -include process include file as the first line of the primary source file + # -Winvalid-pch warns if precompiled header is found but cannot be used + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags -Winvalid-pch -include "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Clang") + if (UNIX) + # Clang options used + # -include process include file as the first line of the primary source file + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags -include "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + elseif (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # Clang-cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # Windows Intel options used + # /Yu use a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-use name of the precompiled header (PCH) to use + # -include process include file as the first line of the primary source file + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_pchSuppressMessages FALSE) + if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") + set(_pchSuppressMessages TRUE) + endif() + if (_flags) + # append to list + list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + list (APPEND _flags -Wpch-messages) + endif() + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags -include "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) + set(_options "") + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_pch_compilation_flags( + "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC") + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0") + if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR + _option_COMPILER_EXECUTABLE MATCHES "ccache") + # Newer versions of Clang embed a compilation timestamp into the precompiled header binary, + # which results in "file has been modified since the precompiled header was built" errors if ccache is used. + # We work around the problem by disabling ccache upon pre-compiling the prefix header. + set (ENV{CCACHE_DISABLE} "true") + endif() + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result) + if (_result) + message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") + endif() +endfunction() + +function (cotire_check_precompiled_header_support _language _target _msgVar) + set (_unsupportedCompiler + "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # PCH supported since Visual Studio C++ 6.0 + # and CMake does not support an earlier version + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC PCH support requires version >= 3.4 + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + if (UNIX) + # all Unix Clang versions have PCH support + set (${_msgVar} "" PARENT_SCOPE) + elseif (WIN32) + # only clang-cl is supported under Windows + get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE) + if (NOT _compilerName MATCHES "cl$") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE) + endif() + endif() + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel PCH support requires version >= 8.0.0 + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + else() + set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) + endif() + # check if ccache is used as a compiler launcher + get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER) + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH) + if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache") + # verify that ccache configuration is compatible with precompiled headers + # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache + # do not report the "sloppiness" setting correctly upon printing ccache configuration + if (DEFINED ENV{CCACHE_SLOPPINESS}) + if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR + NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros") + set (${_msgVar} + "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + else() + if (_realCompilerExe MATCHES "ccache") + set (_ccacheExe "${_realCompilerExe}") + else() + set (_ccacheExe "${_launcher}") + endif() + # ccache 3.7.0 replaced --print-config with --show-config + # use -p instead, which seems to work for all version for now, sigh + execute_process( + COMMAND "${_ccacheExe}" "-p" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if (_result) + set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE) + elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR + NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines") + set (${_msgVar} + "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + endif() + endif() + if (APPLE) + # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) + cotire_get_configuration_types(_configs) + foreach (_config ${_configs}) + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) + list (LENGTH _architectures _numberOfArchitectures) + if (_numberOfArchitectures GREATER 1) + string (REPLACE ";" ", " _architectureStr "${_architectures}") + set (${_msgVar} + "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." + PARENT_SCOPE) + break() + endif() + endforeach() + endif() +endfunction() + +macro (cotire_get_intermediate_dir _cotireDir) + # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types + get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) +endmacro() + +macro (cotire_setup_file_extension_variables) + set (_unityFileExt_C ".c") + set (_unityFileExt_CXX ".cxx") + set (_prefixFileExt_C ".h") + set (_prefixFileExt_CXX ".hxx") + set (_prefixSourceFileExt_C ".c") + set (_prefixSourceFileExt_CXX ".cxx") +endmacro() + +function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") + cotire_get_intermediate_dir(_baseDir) + set (_unityFile "${_baseDir}/${_unityFileName}") + set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + cotire_get_intermediate_dir(_baseDir) + set (_startIndex 0) + set (_index 0) + set (_unityFiles "") + set (_sourceFiles ${ARGN}) + foreach (_sourceFile ${_sourceFiles}) + get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) + math (EXPR _unityFileCount "${_index} - ${_startIndex}") + if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) + if (_index GREATER 0) + # start new unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (_startIndex ${_index}) + endif() + math (EXPR _index "${_index} + 1") + endforeach() + list (LENGTH _sourceFiles _numberOfSources) + if (_startIndex EQUAL 0) + # there is only a single unity file + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) + elseif (_startIndex LESS _numberOfSources) + # end with final unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) + if (COTIRE_DEBUG AND _unityFiles) + message (STATUS "unity files: ${_unityFiles}") + endif() +endfunction() + +function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_prefixFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") + string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") + set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) +endfunction() + +function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _prefixSourceFileExt_${_language}) + set (${_prefixSourceFileVar} "" PARENT_SCOPE) + return() + endif() + string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") + set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) + cotire_setup_file_extension_variables() + if (NOT _language) + set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") + elseif (DEFINED _prefixFileExt_${_language}) + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") + else() + set (_prefixFileBaseName "") + set (_prefixFileName "") + endif() + set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) + set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_path _language _target _prefixFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_prefixFileVar} "" PARENT_SCOPE) + if (_prefixFileName) + if (NOT _language) + set (_language "C") + endif() + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC") + cotire_get_intermediate_dir(_baseDir) + set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (cotire_make_pch_file_path _language _target _pchFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_pchFileVar} "" PARENT_SCOPE) + if (_prefixFileBaseName AND _prefixFileName) + cotire_check_precompiled_header_support("${_language}" "${_target}" _msg) + if (NOT _msg) + if (XCODE) + # For Xcode, we completely hand off the compilation of the prefix header to the IDE + return() + endif() + cotire_get_intermediate_dir(_baseDir) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # MSVC uses the extension .pch added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel uses the extension .pchi added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + +function (cotire_select_unity_source_files _unityFile _sourcesVar) + set (_sourceFiles ${ARGN}) + if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") + set (_startIndex ${CMAKE_MATCH_1}) + set (_endIndex ${CMAKE_MATCH_2}) + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _startIndex LESS _numberOfSources) + math (EXPR _startIndex "${_numberOfSources} - 1") + endif() + if (NOT _endIndex LESS _numberOfSources) + math (EXPR _endIndex "${_numberOfSources} - 1") + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${_endIndex}) + list (GET _sourceFiles ${_index} _file) + list (APPEND _files "${_file}") + endforeach() + else() + set (_files ${_sourceFiles}) + endif() + set (${_sourcesVar} ${_files} PARENT_SCOPE) +endfunction() + +function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target's generated source files + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + # but omit all generated source files that have the COTIRE_EXCLUDED property set to true + cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) + if (_excludedGeneratedSources) + list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) + endif() + # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly + cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) + if (_excludedNonDependencySources) + list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) + endif() + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target source files marked with custom COTIRE_DEPENDENCY property + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles}) + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar) + set (_targetSources ${ARGN}) + cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources}) + cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources}) + # set up variables to be configured + set (COTIRE_TARGET_LANGUAGE "${_language}") + get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) + get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) + get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) + get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) + get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources}) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources}) + set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + cotire_get_target_include_directories( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) + cotire_get_target_compile_definitions( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) + cotire_get_target_compiler_flags( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) + cotire_get_source_files_compile_definitions( + "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources}) + endforeach() + get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER) + # set up COTIRE_TARGET_SOURCES + set (COTIRE_TARGET_SOURCES "") + foreach (_sourceFile ${_targetSources}) + get_source_file_property(_generated "${_sourceFile}" GENERATED) + if (_generated) + # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}") + else() + list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}") + endif() + endforeach() + # copy variable definitions to cotire target script + get_cmake_property(_vars VARIABLES) + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") + # omit COTIRE_*_INIT variables + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}") + if (_initVars) + list (REMOVE_ITEM _matchVars ${_initVars}) + endif() + # omit COTIRE_VERBOSE which is passed as a CMake define on command line + list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) + set (_contents "") + set (_contentsHasGeneratorExpressions FALSE) + foreach (_var IN LISTS _matchVars ITEMS + XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES + CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION + CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language} + CMAKE_INCLUDE_SYSTEM_FLAG_${_language} + CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + if (DEFINED ${_var}) + string (REPLACE "\"" "\\\"" _value "${${_var}}") + set (_contents "${_contents}set (${_var} \"${_value}\")\n") + if (NOT _contentsHasGeneratorExpressions) + if ("${_value}" MATCHES "\\$<.*>") + set (_contentsHasGeneratorExpressions TRUE) + endif() + endif() + endif() + endforeach() + # generate target script file + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") + cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) + if (_contentsHasGeneratorExpressions) + # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time + set (_configNameOrNoneGeneratorExpression "$<$<CONFIG:>:None>$<$<NOT:$<CONFIG:>>:$<CONFIGURATION>>") + set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") + file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") + else() + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() + set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) + set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) +endfunction() + +function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file + # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion + if (_sourceFiles) + set (_flags "") + cotire_add_pch_compilation_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) + set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + if (COTIRE_DEBUG) + message (STATUS "set_property: SOURCE ${_hostFile} APPEND_STRING COMPILE_FLAGS ${_flags}") + endif() + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") + # make object file generated from host file depend on prefix header + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") + # mark host file as cotired to prevent it from being used in another cotired target + set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generator, we add a custom command to precompile the prefix header + if (_targetScript) + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath) + else() + file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + endif() + # make precompiled header compilation depend on the actual compiler executable used to force + # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable" + # warnings when the precompiled header is included. + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + endif() + set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) + add_custom_command( + OUTPUT "${_pchFile}" + COMMAND ${_cmds} + DEPENDS "${_prefixFile}" "${_realCompilerExe}" + IMPLICIT_DEPENDS ${_language} "${_prefixFile}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}" + VERBATIM) + endif() + endif() +endfunction() + +function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file + # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation + set (_sourceFiles ${ARGN}) + list (LENGTH _sourceFiles _numberOfSourceFiles) + if (_numberOfSourceFiles GREATER 0) + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + set (_flags "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + if (COTIRE_DEBUG) + message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}") + endif() + # make object files generated from source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + set (_sourceFiles ${_hostFile} ${ARGN}) + if (NOT _wholeTarget) + # for makefile based generator, we force the inclusion of the prefix header for a subset + # of the source files, if this is a multi-language target or has excluded files + set (_flags "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + if (COTIRE_DEBUG) + message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}") + endif() + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + endif() + # make object files generated from source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() +endfunction() + +function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) + set (_sourceFiles ${ARGN}) + # force the inclusion of the prefix header for the given source files + set (_flags "") + set (_pchFile "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + if (COTIRE_DEBUG) + message (STATUS "set_property: SOURCE ${_sourceFiles} APPEND_STRING COMPILE_FLAGS ${_flags}") + endif() + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + # make object files generated from source files depend on prefix header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") +endfunction() + +function (cotire_get_first_set_property_value _propertyValueVar _type _object) + set (_properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) + return() + endif() + endforeach() + set (${_propertyValueVar} "" PARENT_SCOPE) +endfunction() + +function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar) + set (_files ${ARGN}) + set (_filesPaths "") + foreach (_file ${_files}) + get_filename_component(_filePath "${_file}" ABSOLUTE) + list (APPEND _filesPaths "${_filePath}") + endforeach() + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") + if (_targetScript) + list (APPEND _prefixCmd "${_targetScript}") + endif() + list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") + endif() + set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath) + else() + file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + endif() + get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) + get_filename_component(_joinedFileExt "${_joinedFile}" EXT) + if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}") + elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") + if (_joinedFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}") + endif() + else() + set (_comment "Generating ${_joinedFileLogPath}") + endif() + add_custom_command( + OUTPUT "${_joinedFile}" + COMMAND ${_prefixCmd} + DEPENDS ${_files} + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_target_pch_usage _languages _target _wholeTarget) + if (XCODE) + # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers + set (_prefixFiles "") + foreach (_language ${_languages}) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + list (APPEND _prefixFiles "${_prefixFile}") + endif() + endforeach() + set (_cmds ${ARGN}) + list (LENGTH _prefixFiles _numberOfPrefixFiles) + if (_numberOfPrefixFiles GREATER 1) + # we also generate a generic, single prefix header which includes all language specific prefix headers + set (_language "") + set (_targetScript "") + cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader) + cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles}) + else() + set (_prefixHeader "${_prefixFiles}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") + endif() + # because CMake PRE_BUILD command does not support dependencies, + # we check dependencies explicity in cotire script mode when the pre-build action is run + add_custom_command( + TARGET "${_target}" + PRE_BUILD ${_cmds} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Updating target ${_target} prefix headers" + VERBATIM) + # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generator, we force inclusion of the prefix header for all target source files + # if this is a single-language target without any excluded files + if (_wholeTarget) + set (_language "${_languages}") + # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level + # see cotire_setup_pch_file_inclusion + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) + set (_options COMPILE_OPTIONS) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _options) + set_property(TARGET ${_target} APPEND PROPERTY ${_options}) + if (COTIRE_DEBUG) + message (STATUS "set_property: TARGET ${_target} APPEND PROPERTY ${_options}") + endif() + endif() + endif() + endif() + endif() +endfunction() + +function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar) + set (_dependencySources "") + cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) + foreach (_unityFile ${_unityFiles}) + set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) + # set up compiled unity source dependencies via OBJECT_DEPENDS + # this ensures that missing source files are generated before the unity file is compiled + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") + endif() + if (_dependencySources) + # the OBJECT_DEPENDS property requires a list of full paths + set (_objectDependsPaths "") + foreach (_sourceFile ${_dependencySources}) + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND _objectDependsPaths "${_sourceLocation}") + endforeach() + set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) + endif() + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # unity file compilation results in potentially huge object file, + # thus use /bigobj by default unter cl.exe and Windows Intel + set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") + endif() + cotire_set_cmd_to_prologue(_unityCmd) + list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_unityCmdDepends "${_targetScript}") + else() + # CMake 3.1.0 supports generator expressions in arguments to DEPENDS + set (_unityCmdDepends "${_targetConfigScript}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath) + else() + file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") + endif() + add_custom_command( + OUTPUT "${_unityFile}" + COMMAND ${_unityCmd} + DEPENDS ${_unityCmdDepends} + COMMENT "Generating ${_language} unity source ${_unityFileLogPath}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) + endforeach() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + set (_dependencySources "") + cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles}) + set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) + # make prefix header generation depend on the actual compiler executable used to force + # re-generation when the compiler executable is updated. This prevents "file not found" + # errors for compiler version specific system header files. + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath) + else() + file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") + endif() + get_filename_component(_prefixFileExt "${_prefixFile}" EXT) + if (_prefixFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}") + endif() + # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist + # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence + # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files + set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre") + if (TARGET ${_preTargetName}) + # custom helper target has already been generated while processing a different language + list (APPEND _dependencySources ${_preTargetName}) + else() + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources}) + cotire_init_target("${_preTargetName}") + list (APPEND _dependencySources ${_preTargetName}) + endif() + endif() + add_custom_command( + OUTPUT "${_prefixFile}" "${_prefixFile}.log" + COMMAND ${_prefixCmd} + DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}" + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_prefix_generation_command( + ${_language} ${_target} "${_targetScript}" + "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar) + set (_prefixHeaderFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_init_cotire_target_properties _target) + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") + cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") + if (NOT _isRelative) + set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") + endif() + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) + if (NOT _isSet) + if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") + else() + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") + endif() + endif() +endfunction() + +function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + string (REPLACE ";" " " _languagesStr "${_languages}") + math (EXPR _numberOfExcludedFiles "${ARGC} - 4") + if (_numberOfExcludedFiles EQUAL 0) + set (_excludedStr "") + elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) + string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") + else() + set (_excludedStr "excluding ${_numberOfExcludedFiles} files") + endif() + set (_targetMsg "") + if (NOT _languages) + set (_targetMsg "Target ${_target} cannot be cotired.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH AND NOT _targetAddSCU) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") + endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetAddSCU) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") + endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + else() + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired.") + endif() + endif() + set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) +endfunction() + +function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar) + set (_languages ${ARGN}) + set (_allSourceFiles "") + set (_allExcludedSourceFiles "") + set (_allCotiredSourceFiles "") + set (_targetLanguages "") + set (_pchEligibleTargetLanguages "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + set (_disableMsg "") + foreach (_language ${_languages}) + get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) + get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) + if (_prefixHeader OR _unityBuildFile) + message (STATUS "cotire: target ${_target} has already been cotired.") + set (${_targetLanguagesVar} "" PARENT_SCOPE) + return() + endif() + if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID) + if (CMAKE_${_language}_COMPILER_ID) + cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg) + if (_disableMsg) + set (_targetUsePCH FALSE) + endif() + endif() + endif() + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _excludedSources OR _cotiredSources) + list (APPEND _targetLanguages ${_language}) + endif() + if (_sourceFiles) + list (APPEND _allSourceFiles ${_sourceFiles}) + endif() + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + list (APPEND _pchEligibleTargetLanguages ${_language}) + endif() + if (_excludedSources) + list (APPEND _allExcludedSourceFiles ${_excludedSources}) + endif() + if (_cotiredSources) + list (APPEND _allCotiredSourceFiles ${_cotiredSources}) + endif() + endforeach() + set (_targetMsgLevel STATUS) + if (NOT _targetLanguages) + string (REPLACE ";" " or " _languagesStr "${_languages}") + set (_disableMsg "No ${_languagesStr} source files.") + set (_targetUsePCH FALSE) + set (_targetAddSCU FALSE) + endif() + if (_targetUsePCH) + if (_allCotiredSourceFiles) + cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) + list (REMOVE_DUPLICATES _cotireTargets) + string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") + set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") + set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") + set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") + set (_targetMsgLevel SEND_ERROR) + set (_targetUsePCH FALSE) + elseif (NOT _pchEligibleTargetLanguages) + set (_disableMsg "Too few applicable sources.") + set (_targetUsePCH FALSE) + elseif (XCODE AND _allExcludedSourceFiles) + # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target + set (_disableMsg "Exclusion of source files not supported for generator Xcode.") + set (_targetUsePCH FALSE) + elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") + # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target + set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") + set (_targetUsePCH FALSE) + endif() + endif() + if (_targetAddSCU) + # disable unity builds if automatic Qt processing is used + get_target_property(_targetAutoMoc ${_target} AUTOMOC) + get_target_property(_targetAutoUic ${_target} AUTOUIC) + get_target_property(_targetAutoRcc ${_target} AUTORCC) + if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) + if (_disableMsg) + set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.") + else() + set (_disableMsg "Target uses automatic CMake Qt processing.") + endif() + set (_targetAddSCU FALSE) + endif() + endif() + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) + cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) + if (_targetMsg) + if (NOT DEFINED COTIREMSG_${_target}) + set (COTIREMSG_${_target} "") + endif() + if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR + NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") + # cache message to avoid redundant messages on re-configure + set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") + message (${_targetMsgLevel} "${_targetMsg}") + endif() + endif() + list (LENGTH _targetLanguages _numberOfLanguages) + if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) + set (${_wholeTargetVar} FALSE PARENT_SCOPE) + else() + set (${_wholeTargetVar} TRUE PARENT_SCOPE) + endif() + set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) +endfunction() + +function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) + set (_sourceFiles ${ARGN}) + get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") + if (DEFINED CMAKE_MATCH_2) + set (_numberOfThreads "${CMAKE_MATCH_2}") + else() + set (_numberOfThreads "") + endif() + if (NOT _numberOfThreads) + # use all available cores + ProcessorCount(_numberOfThreads) + endif() + list (LENGTH _sourceFiles _numberOfSources) + math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") + elseif (NOT _maxIncludes MATCHES "[0-9]+") + set (_maxIncludes 0) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_target} unity source max includes: ${_maxIncludes}") + endif() + set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) +endfunction() + +function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar) + set (${_cmdsVar} "" PARENT_SCOPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (NOT _sourceFiles AND NOT _cotiredSources) + return() + endif() + set (_cmds "") + # check for user provided unity source file list + get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) + if (NOT _unitySourceFiles) + set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) + endif() + cotire_generate_target_script( + ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) + # set up unity files for parallel compilation + cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) + cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles EQUAL 0) + return() + elseif (_numberOfUnityFiles GREATER 1) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + endif() + # set up single unity file for prefix header generation + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles}) + cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) + # set up prefix header + if (_prefixFile) + # check for user provided prefix header files + get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + if (_prefixHeaderFiles) + cotire_setup_prefix_generation_from_provided_command( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + else() + cotire_setup_prefix_generation_from_unity_command( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles}) + endif() + # check if selected language has enough sources at all + list (LENGTH _sourceFiles _numberOfSources) + if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_targetUsePCH FALSE) + else() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + endif() + if (_targetUsePCH) + cotire_make_pch_file_path(${_language} ${_target} _pchFile) + if (_pchFile) + # first file in _sourceFiles is passed as the host file + cotire_setup_pch_file_compilation( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + cotire_setup_pch_file_inclusion( + ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + endif() + elseif (_prefixHeaderFiles) + # user provided prefix header must be included unconditionally + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) + endif() + endif() + # mark target as cotired for language + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") + if (_prefixFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") + if (_targetUsePCH AND _pchFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") + endif() + endif() + set (${_cmdsVar} ${_cmds} PARENT_SCOPE) +endfunction() + +function (cotire_setup_clean_target _target) + set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") + if (NOT TARGET "${_cleanTargetName}") + cotire_set_cmd_to_prologue(_cmds) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") + add_custom_target(${_cleanTargetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up target ${_target} cotire generated files" + VERBATIM) + cotire_init_target("${_cleanTargetName}") + endif() +endfunction() + +function (cotire_setup_pch_target _languages _configurations _target) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generators, we add a custom target to trigger the generation of the cotire related files + set (_dependsFiles "") + foreach (_language ${_languages}) + set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) + # MSVC, Intel and clang-cl only create precompiled header as a side effect + list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) + endif() + cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) + if (_dependsFile) + list (APPEND _dependsFiles "${_dependsFile}") + endif() + endforeach() + if (_dependsFiles) + set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") + add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) + cotire_init_target("${_pchTargetName}") + cotire_add_to_pch_all_target(${_pchTargetName}) + endif() + else() + # for other generators, we add the "clean all" target to clean up the precompiled header + cotire_setup_clean_all_target() + endif() +endfunction() + +function (cotire_filter_object_libraries _target _objectLibrariesVar) + set (_objectLibraries "") + foreach (_source ${ARGN}) + if (_source MATCHES "^\\$<TARGET_OBJECTS:.+>$") + list (APPEND _objectLibraries "${_source}") + endif() + endforeach() + set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_unityTargetSources ${_targetSourceFiles}) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + # remove source files that are included in the unity source + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _cotiredSources) + list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) + endif() + # add unity source files instead + list (APPEND _unityTargetSources ${_unityFiles}) + endif() + endforeach() + # handle object libraries which are part of the target's sources + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$") + cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles}) + if (_objectLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries}) + list (REMOVE_ITEM _unityTargetSources ${_objectLibraries}) + list (APPEND _unityTargetSources ${_unityObjectLibraries}) + endif() + endif() + set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE) +endfunction() + +function (cotire_setup_unity_target_pch_usage _languages _target) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_userPrefixFile AND _prefixFile) + # user provided prefix header must be included unconditionally by unity sources + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles}) + endif() + endif() + endforeach() +endfunction() + +function (cotire_setup_unity_build_target _languages _configurations _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (NOT _unityTargetName) + set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") + endif() + # determine unity target sub type + get_target_property(_targetType ${_target} TYPE) + if ("${_targetType}" STREQUAL "EXECUTABLE") + set (_unityTargetSubType "") + elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (_unityTargetSubType "${CMAKE_MATCH_1}") + else() + message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") + return() + endif() + # determine unity target sources + set (_unityTargetSources "") + cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources) + # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created + set (CMAKE_AUTOMOC OFF) + set (CMAKE_AUTOUIC OFF) + set (CMAKE_AUTORCC OFF) + if (COTIRE_DEBUG) + message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") + endif() + # generate unity target + if ("${_targetType}" STREQUAL "EXECUTABLE") + add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + else() + add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + endif() + # copy output location properties + set (_outputDirProperties + ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG> + LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG> + RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>) + if (COTIRE_UNITY_OUTPUT_DIRECTORY) + set (_setDefaultOutputDir TRUE) + if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + else() + # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties}) + foreach (_property ${_properties}) + get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) + if (_outputDir) + get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") + set (_setDefaultOutputDir FALSE) + endif() + endforeach() + if (_setDefaultOutputDir) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + endif() + endif() + if (_setDefaultOutputDir) + set_target_properties(${_unityTargetName} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" + LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" + RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") + endif() + else() + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ${_outputDirProperties}) + endif() + # copy output name + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG> + LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG> + OUTPUT_NAME OUTPUT_NAME_<CONFIG> + RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG> + PREFIX <CONFIG>_POSTFIX SUFFIX + IMPORT_PREFIX IMPORT_SUFFIX) + # copy compile stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG> + COMPILE_FLAGS COMPILE_OPTIONS + Fortran_FORMAT Fortran_MODULE_DIRECTORY + INCLUDE_DIRECTORIES + INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG> + POSITION_INDEPENDENT_CODE + C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER + C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE + C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN + C_CLANG_TIDY CXX_CLANG_TIDY) + # copy compile features + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED + CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED + COMPILE_FEATURES) + # copy interface stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN + COMPATIBLE_INTERFACE_STRING + INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS + INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES + INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED) + # copy link stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR + INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH + LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED + LINK_FLAGS LINK_FLAGS_<CONFIG> + LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG> + LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG> + LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC + STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG> + NO_SONAME SOVERSION VERSION + LINK_WHAT_YOU_USE BUILD_RPATH) + # copy cmake stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) + # copy Apple platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR + MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH + OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST + IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE) + # copy Windows platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + GNUtoMS + COMPILE_PDB_NAME COMPILE_PDB_NAME_<CONFIG> + COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG> + PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG> + VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION + VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE + VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK + VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION + VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER + VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION + VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES + WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS + DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE + VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY) + # copy Android platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ANDROID_API ANDROID_API_MIN ANDROID_GUI + ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES + ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR + ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES + ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH + ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE) + # copy CUDA platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS + CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED) + # use output name from original target + get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) + if (NOT _targetOutputName) + set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") + endif() + # use export symbol from original target + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") + if ("${_targetType}" STREQUAL "EXECUTABLE") + set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) + endif() + endif() + # enable parallel compilation for MSVC + if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio") + list (LENGTH _unityTargetSources _numberOfUnityTargetSources) + if (_numberOfUnityTargetSources GREATER 1) + set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP") + endif() + endif() + cotire_init_target(${_unityTargetName}) + cotire_add_to_unity_all_target(${_unityTargetName}) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") +endfunction(cotire_setup_unity_build_target) + +function (cotire_target _target) + set(_options "") + set(_oneValueArgs "") + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGES) + get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + endif() + if (NOT _option_CONFIGURATIONS) + cotire_get_configuration_types(_option_CONFIGURATIONS) + endif() + # check if cotire can be applied to target at all + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + get_target_property(_imported ${_target} IMPORTED) + get_target_property(_targetType ${_target} TYPE) + if (_imported) + message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.") + else() + message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.") + endif() + return() + endif() + # resolve alias + get_target_property(_aliasName ${_target} ALIASED_TARGET) + if (_aliasName) + if (COTIRE_DEBUG) + message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") + endif() + set (_target ${_aliasName}) + endif() + # check if target needs to be cotired for build type + # when using configuration types, the test is performed at build time + cotire_init_cotire_target_properties(${_target}) + if (NOT CMAKE_CONFIGURATION_TYPES) + if (CMAKE_BUILD_TYPE) + list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) + else() + list (FIND _option_CONFIGURATIONS "None" _index) + endif() + if (_index EQUAL -1) + if (COTIRE_DEBUG) + message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") + endif() + return() + endif() + endif() + # when not using configuration types, immediately create cotire intermediate dir + if (NOT CMAKE_CONFIGURATION_TYPES) + cotire_get_intermediate_dir(_baseDir) + file (MAKE_DIRECTORY "${_baseDir}") + endif() + # choose languages that apply to the target + cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) + if (NOT _targetLanguages) + return() + endif() + set (_cmds "") + foreach (_language ${_targetLanguages}) + cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd) + if (_cmd) + list (APPEND _cmds ${_cmd}) + endif() + endforeach() + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + if (_targetAddSCU) + cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + endif() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + if (_targetUsePCH) + cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds}) + cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + if (_targetAddSCU) + cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target}) + endif() + endif() + get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) + if (_targetAddCleanTarget) + cotire_setup_clean_target(${_target}) + endif() +endfunction(cotire_target) + +function (cotire_map_libraries _strategy _mappedLibrariesVar) + set (_mappedLibraries "") + foreach (_library ${ARGN}) + if (_library MATCHES "^\\$<LINK_ONLY:(.+)>$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly TRUE) + set (_objectLibrary FALSE) + elseif (_library MATCHES "^\\$<TARGET_OBJECTS:(.+)>$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly FALSE) + set (_objectLibrary TRUE) + else() + set (_libraryName "${_library}") + set (_linkOnly FALSE) + set (_objectLibrary FALSE) + endif() + if ("${_strategy}" MATCHES "COPY_UNITY") + cotire_is_target_supported(${_libraryName} _isSupported) + if (_isSupported) + # use target's corresponding unity target, if available + get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + if (_linkOnly) + list (APPEND _mappedLibraries "$<LINK_ONLY:${_libraryUnityTargetName}>") + elseif (_objectLibrary) + list (APPEND _mappedLibraries "$<TARGET_OBJECTS:${_libraryUnityTargetName}>") + else() + list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + endforeach() + list (REMOVE_DUPLICATES _mappedLibraries) + set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_target_link_libraries _target) + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + return() + endif() + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_unityTargetName}") + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") + endif() + if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + if (_linkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}") + endif() + endif() + get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) + if (_interfaceLinkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}") + endif() + endif() + get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES) + if (_manualDependencies) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies}) + if (_unityManualDependencies) + add_dependencies("${_unityTargetName}" ${_unityManualDependencies}) + endif() + endif() + endif() + endif() +endfunction(cotire_target_link_libraries) + +function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) + if (_targetName) + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") + else() + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") + endif() + # filter files in intermediate directory + set (_filesToRemove "") + foreach (_file ${_cotireFiles}) + get_filename_component(_dir "${_file}" DIRECTORY) + get_filename_component(_dirName "${_dir}" NAME) + if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") + list (APPEND _filesToRemove "${_file}") + endif() + endforeach() + if (_filesToRemove) + if (COTIRE_VERBOSE) + message (STATUS "cleaning up ${_filesToRemove}") + endif() + file (REMOVE ${_filesToRemove}) + endif() +endfunction() + +function (cotire_init_target _targetName) + if (COTIRE_TARGETS_FOLDER) + set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") + endif() + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE) + if (MSVC_IDE) + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endfunction() + +function (cotire_add_to_pch_all_target _pchTargetName) + set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_pchTargetName}) +endfunction() + +function (cotire_add_to_unity_all_target _unityTargetName) + set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_unityTargetName}) +endfunction() + +function (cotire_setup_clean_all_target) + set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") + add_custom_target(${_targetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up all cotire generated files" + VERBATIM) + cotire_init_target("${_targetName}") + endif() +endfunction() + +function (cotire) + set(_options "") + set(_oneValueArgs "") + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_targets ${_option_UNPARSED_ARGUMENTS}) + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}) + else() + message (WARNING "cotire: ${_target} is not a target.") + endif() + endforeach() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target_link_libraries(${_target}) + endif() + endforeach() +endfunction() + +if (CMAKE_SCRIPT_MODE_FILE) + + # cotire is being run in script mode + # locate -P on command args + set (COTIRE_ARGC -1) + foreach (_index RANGE ${CMAKE_ARGC}) + if (COTIRE_ARGC GREATER -1) + set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") + math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") + elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") + set (COTIRE_ARGC 0) + endif() + endforeach() + + # include target script if available + if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") + # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) + include("${COTIRE_ARGV2}") + endif() + + if (COTIRE_DEBUG) + message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") + endif() + + if (NOT COTIRE_BUILD_TYPE) + set (COTIRE_BUILD_TYPE "None") + endif() + string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) + set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) + set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) + # check if target has been cotired for actual build type COTIRE_BUILD_TYPE + list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) + if (_index GREATER -1) + set (_sources ${COTIRE_TARGET_SOURCES}) + set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) + else() + if (COTIRE_DEBUG) + message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") + endif() + set (_sources "") + set (_sourcesDefinitions "") + endif() + set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) + set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) + set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) + set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) + + if ("${COTIRE_ARGV1}" STREQUAL "unity") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on target script + set (_dependsOption DEPENDS "${COTIRE_ARGV2}") + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) + + cotire_generate_unity_source( + "${COTIRE_ARGV3}" ${_sources} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} + PRE_UNDEFS ${_targetPreUndefs} + POST_UNDEFS ${_targetPostUndefs} + SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} + SOURCES_POST_UNDEFS ${_sourcesPostUndefs} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies + set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + set (_files "") + foreach (_index RANGE 4 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_generate_prefix_header( + "${COTIRE_ARGV3}" ${_files} + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" + INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} + IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" + INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH} + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") + + set (_files "") + foreach (_index RANGE 5 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_precompile_prefix_header( + "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "combine") + + if (COTIRE_TARGET_LANGUAGE) + set (_combinedFile "${COTIRE_ARGV3}") + set (_startIndex 4) + else() + set (_combinedFile "${COTIRE_ARGV2}") + set (_startIndex 3) + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + if (XCODE) + # executing pre-build action under Xcode, check dependency on files to be combined + set (_dependsOption DEPENDS ${_files}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + if (COTIRE_TARGET_LANGUAGE) + cotire_generate_unity_source( + "${_combinedFile}" ${_files} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + ${_dependsOption}) + else() + cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption}) + endif() + + elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") + + cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") + + else() + message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") + endif() + +else() + + # cotire is being run in include mode + # set up all variable and property definitions + + if (NOT DEFINED COTIRE_DEBUG_INIT) + if (DEFINED COTIRE_DEBUG) + set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) + else() + set (COTIRE_DEBUG_INIT FALSE) + endif() + endif() + option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) + + if (NOT DEFINED COTIRE_VERBOSE_INIT) + if (DEFINED COTIRE_VERBOSE) + set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) + else() + set (COTIRE_VERBOSE_INIT FALSE) + endif() + endif() + option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING + "Ignore headers with the listed file extensions from the generated prefix header.") + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING + "Ignore headers from these directories when generating the prefix header.") + + set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING + "Ignore sources with the listed file extensions from the generated unity source.") + + set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING + "Minimum number of sources in target required to enable use of precompiled header.") + + if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) + if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) + elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") + # enable parallelization for generators that run multiple jobs by default + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") + else() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") + endif() + endif() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING + "Maximum number of source files to include in a single unity source file.") + + if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) + set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") + endif() + if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) + set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") + endif() + if (NOT COTIRE_INTDIR) + set (COTIRE_INTDIR "cotire") + endif() + if (NOT COTIRE_PCH_ALL_TARGET_NAME) + set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) + set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") + endif() + if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) + set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") + endif() + if (NOT COTIRE_CLEAN_TARGET_SUFFIX) + set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") + endif() + if (NOT COTIRE_PCH_TARGET_SUFFIX) + set (COTIRE_PCH_TARGET_SUFFIX "_pch") + endif() + if (MSVC) + # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code + # use a bigger default factor of 170 percent (128 MB) + if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170") + endif() + endif() + if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) + set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") + endif() + if (NOT DEFINED COTIRE_TARGETS_FOLDER) + set (COTIRE_TARGETS_FOLDER "cotire") + endif() + if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) + if ("${CMAKE_GENERATOR}" MATCHES "Ninja") + # generated Ninja build files do not work if the unity target produces the same output file as the cotired target + set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") + else() + set (COTIRE_UNITY_OUTPUT_DIRECTORY "") + endif() + endif() + + # define cotire cache variables + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of include directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "If not defined, defaults to empty list." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" + BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a header file extension matches one in the list, it will be excluded from the generated prefix header." + "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored." + "If not defined, defaults to inc;inl;ipp." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" + BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a source file extension matches one in the list, it will be excluded from the generated unity source file." + "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded." + "If not defined, defaults to m;mm." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" + BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." + FULL_DOCS + "The variable can be set to an integer > 0." + "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." + "If not defined, defaults to 2." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer >= 0." + "If 0, cotire will only create a single unity source file." + "If a target contains more than that number of source files, cotire will create multiple unity source files for it." + "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." + "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." + "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." + ) + + # define cotire directory properties + + define_property( + DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" + BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." + FULL_DOCS + "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" + BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_UNITY_BUILD." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" + BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_CLEAN." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" + BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" + BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." + FULL_DOCS + "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." + ) + + # define cotire target properties + + define_property( + TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED + BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." + FULL_DOCS + "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." + "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." + "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." + "The target name will be set to this target's name with the suffix _pch appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED + BRIEF_DOCS "Add a new target that performs a unity build for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." + "Most of the relevant target properties will be copied from this target to the new unity build target." + "Target dependencies and linked libraries have to be manually set up for the new unity build target." + "The unity target name will be set to this target's name with the suffix _unity appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED + BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." + "The clean target name will be set to this target's name with the suffix _clean_cotire appended." + "Inherited from directory." + "Defaults to FALSE." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "Inherited from directory." + "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." + "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," + "the option which yields the closer relative path match wins." + "Inherited from directory." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED + BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header." + "Header files are sorted according to the order of the directories in the property." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer > 0." + "If a target contains more than that number of source files, cotire will create multiple unity build files for it." + "If not set, cotire will only create a single unity source file." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT" + BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will only add the given file(s) to the generated unity source file." + "If not set, cotire will add all the target source files to the generated unity source file." + "The property can be set to a user provided unity source file." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT" + BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will add the given header file(s) to the generated prefix header file." + "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." + "The property can be set to a user provided prefix header file (e.g., stdafx.h)." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED + BRIEF_DOCS "Define strategy for setting up unity target's link libraries." + FULL_DOCS + "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually." + "If this property is set to COPY, the unity target's link libraries will be copied from this target." + "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE" + BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)." + FULL_DOCS + "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER" + BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file." + FULL_DOCS + "cotire sets this property to the full path of the generated <LANG> language prefix header for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER" + BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file." + FULL_DOCS + "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" + BRIEF_DOCS "The name of the generated unity build target corresponding to this target." + FULL_DOCS + "This property can be set to the desired name of the unity target that will be created by cotire." + "If not set, the unity target name will be set to this target's name with the suffix _unity appended." + "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." + "Defaults to empty string." + ) + + # define cotire source properties + + define_property( + SOURCE PROPERTY "COTIRE_EXCLUDED" + BRIEF_DOCS "Do not modify source file's build command." + FULL_DOCS + "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." + "The source file will also be excluded from the generated unity source file." + "Source files that have their COMPILE_FLAGS property set will be excluded by default." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_DEPENDENCY" + BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." + FULL_DOCS + "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." + "If the file is modified, cotire will re-generate the prefix header source upon build." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" + BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." + FULL_DOCS + "If this property is set to TRUE, cotire will complete the current unity file and start a new one." + "The new unity source file will include this source file as the first one." + "This property essentially works as a separator for unity source files." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_TARGET" + BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." + FULL_DOCS + "cotire sets this property to the name of target, that the source file's build command has been altered for." + "Defaults to empty string." + ) + + message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") + +endif() diff --git a/gpgfrontend.qrc b/gpgfrontend.qrc index 461c488d..f034cf37 100644 --- a/gpgfrontend.qrc +++ b/gpgfrontend.qrc @@ -11,7 +11,9 @@ <file alias="keys3.jpg">resource/icons/keys13.jpg</file> <file alias="error.png">resource/icons/error.png</file> <file alias="info.png">resource/icons/info.png</file> + <file alias="inbox.png">resource/icons/inbox.png</file> <file alias="warning.png">resource/icons/warning.png</file> + <file alias="archive.png">resource/icons/archive.png</file> <file alias="button_cancel.png">resource/icons/button_cancel.png</file> <file alias="button_cut.png">resource/icons/button_cut.png</file> <file alias="button_ok.png">resource/icons/button_ok.png</file> @@ -19,6 +21,7 @@ <file alias="button_delete.png">resource/icons/button_delete.png</file> <file alias="configure.png">resource/icons/configure.png</file> <file alias="decrypted.png">resource/icons/decrypted.png</file> + <file alias="drafts.png">resource/icons/drafts.png</file> <file alias="edit.png">resource/icons/edit.png</file> <file alias="email.png">resource/icons/email.png</file> <file alias="encrypted.png">resource/icons/encrypted.png</file> @@ -33,14 +36,18 @@ <file alias="fileprint.png">resource/icons/fileprint.png</file> <file alias="filesave.png">resource/icons/filesave.png</file> <file alias="filesaveas.png">resource/icons/filesaveas.png</file> + <file alias="flag.png">resource/icons/flag-fill.png</file> + <file alias="folder.png">resource/icons/folder.png</file> <file alias="format-line-spacing-double.png">resource/icons/format-line-spacing-double.png</file> <file alias="format-line-spacing-normal.png">resource/icons/format-line-spacing-normal.png</file> <file alias="format-line-spacing-triple.png">resource/icons/format-line-spacing-triple.png</file> <file alias="gpgfrontend.png">resource/icons/gpgfrontend.png</file> + <file alias="importance.png">resource/icons/importance.png</file> <file alias="importkey_editor.png">resource/icons/importkey_editor.png</file> <file alias="import_key_from_clipboard.png">resource/icons/import_key_from_clipboard.png</file> <file alias="import_key_from_file.png">resource/icons/import_key_from_file.png</file> <file alias="import_key_from_server.png">resource/icons/import_key_from_server.png</file> + <file alias="junk.png">resource/icons/junk.png</file> <file alias="key_export.png">resource/icons/key_export.png</file> <file alias="key_generate.png">resource/icons/key_generate.png</file> <file alias="key_import.png">resource/icons/key_import.png</file> @@ -48,9 +55,13 @@ <file alias="key_package.png">resource/icons/key_package.png</file> <file alias="misc_doc.png">resource/icons/misc_doc.png</file> <file alias="quote.png">resource/icons/quote.png</file> + <file alias="receive_email.png">resource/icons/receive_email.png</file> + <file alias="sent.png">resource/icons/sent.png</file> + <file alias="server.png">resource/icons/server.png</file> <file alias="signature.png">resource/icons/signature.png</file> <file alias="ssh-key.png">resource/icons/ssh-key.png</file> <file alias="statusbar_icon.png">resource/icons/statusbar_icon.png</file> + <file alias="trash.png">resource/icons/trash.png</file> <file alias="txt.png">resource/icons/txt.png</file> <file alias="undo.png">resource/icons/undo.png</file> <file alias="verify.png">resource/icons/verify.png</file> diff --git a/manual/.nojekyll b/manual/.nojekyll new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/manual/.nojekyll diff --git a/manual/CNAME b/manual/CNAME new file mode 100644 index 00000000..91bbe11c --- /dev/null +++ b/manual/CNAME @@ -0,0 +1 @@ +gpgfrontend.pub
\ No newline at end of file diff --git a/manual/_coverpage.md b/manual/_coverpage.md new file mode 100644 index 00000000..53544d54 --- /dev/null +++ b/manual/_coverpage.md @@ -0,0 +1,33 @@ + + +# GpgFrontend + + + + +[](https://www.codacy.com/gh/saturneric/GpgFrontend/dashboard?utm_source=github.com&utm_medium=referral&utm_content=saturneric/GpgFrontend&utm_campaign=Badge_Grade) + +**A Free, Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free [OpenPGP(pgp)](https://www.openpgp.org/) +Crypto Tool.** + +**Also, it's one of the excellent GUI Frontends for Modern GnuPG(gpg).** + +## Brief Introduction + +You can quickly make encrypted documents or email. + +You can digitally sign your text or documents. + +You can easily and intuitively manage all your keys on your computer. + +## Features + +- Cross-Platform, can run on **Windows, Linux and macOS**. +- Open source, installation-free and free forever. +- Supports multiple languages. Languages spoken by most people in the world. + +[Download](https://github.com/saturneric/GpgFrontend/releases/latest) +[Manual](overview.md) + +<!-- 背景色 --> + diff --git a/manual/_media/_coverpage/gpgfrontend-logo.png b/manual/_media/_coverpage/gpgfrontend-logo.png Binary files differnew file mode 100644 index 00000000..7e9841be --- /dev/null +++ b/manual/_media/_coverpage/gpgfrontend-logo.png diff --git a/manual/_media/icon.svg b/manual/_media/icon.svg new file mode 100644 index 00000000..67375a64 --- /dev/null +++ b/manual/_media/icon.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1641046753295" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="732" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M763.52 968.96H261.248C147.2 968.96 54.784 876.544 54.784 762.496V260.224C54.784 146.176 147.2 53.76 261.248 53.76h502.272c114.048 0 206.464 92.416 206.464 206.464v502.272c0 114.048-92.416 206.464-206.464 206.464z" fill="#89898E" p-id="733"></path><path d="M671.36 365.44c0-88.576-72.32-160.128-161.536-158.976-81.024 1.152-150.656 66.688-156.288 147.456-5.504 79.104 46.336 146.56 118.016 165.12h0.128v224.128c0 5.12 1.92 9.984 5.376 13.824l45.568 49.92c4.48 4.992 12.288 4.992 16.768 0l65.664-71.68c4.608-4.992 4.352-12.672-0.384-17.408l-33.536-33.536c-5.248-5.248-5.248-13.952 0-19.2l36.096-36.096c7.04-7.04 7.04-18.304 0-25.216l-43.392-43.392c-4.224-4.224-6.528-9.856-6.528-15.744v-26.368c65.92-19.328 114.048-80.384 114.048-152.832zM512.256 294.4c22.528 0 40.832 18.176 40.832 40.576 0 22.528-18.304 40.576-40.832 40.576-22.272 0-40.576-18.176-40.576-40.576 0-22.528 18.304-40.576 40.576-40.576z" fill="#FFFFFF" p-id="734"></path></svg>
\ No newline at end of file diff --git a/manual/_media/trademark.png b/manual/_media/trademark.png Binary files differnew file mode 100644 index 00000000..7e9841be --- /dev/null +++ b/manual/_media/trademark.png diff --git a/manual/_navbar.md b/manual/_navbar.md new file mode 100644 index 00000000..6c0b410e --- /dev/null +++ b/manual/_navbar.md @@ -0,0 +1,9 @@ +<!-- _navbar.md --> + +* [Source Code(Global CDN)](https://global.git.codesdream.com/GpgFrontend.git) +* [源代码(国内服务器)](https://git.codesdream.com/GpgFrontend.git) +* [GitHub Repository](https://github.com/saturneric/GpgFrontend) +* [Manual](overview.md) +* [Download](https://github.com/saturneric/GpgFrontend/releases/latest) +* [Contract](contract.md) + diff --git a/manual/_sidebar.md b/manual/_sidebar.md new file mode 100644 index 00000000..399909b7 --- /dev/null +++ b/manual/_sidebar.md @@ -0,0 +1,29 @@ +- Getting Start + - [Overview](overview.md) + - [Quick Start](quick-start.md) + - [Basic concepts](basic-concepts.md) +- Manual + - [Understand Interface](manual/understand-interface.md) + - [Encrypt & Decrypt Text](manual/encrypt-decrypt-text.md) + - Symmetric Encrypt & Decrypt Text + - [Sign & Verify Text](manual/sign-verify-text.md) + - [Encrypt & Decrypt File](manual/encrypt-decrypt-file.md) + - [Sign & Verify File](manual/sign-verify-file.md) + - [Generate Key Pair & Subkey](manual/generate-key.md) + - [View Key Pair Details](manual/view-keypair-info.md) + - [Import & Export Key Pair](manual/import-export-key-pair.md) + - [Key Server Operations](manual/key-server-operations.md) + - [Email Operations](manual/email-operations.md) + - [Advanced Key Operation](manual/advance-key-opera.md) +- Features Guides + - [Introduce](features/introduce.md) + - [Short Cipher-text](features/short-ciphertext.md) + - [Sync ALL Public Key](features/sync-all-public-keys.md) + - Export As Key Package +- Contribute + - [Translate Interface](translate-interface.md) + - Contribute Code +- About + - [FAQ](faq.md) + - [Code & Binary Verify](about/code-binary-verify.md) + - [Contract](contract.md) diff --git a/manual/about/code-binary-verify.md b/manual/about/code-binary-verify.md new file mode 100644 index 00000000..02b2474e --- /dev/null +++ b/manual/about/code-binary-verify.md @@ -0,0 +1,152 @@ +# Code & Binary Verify + +Some users of this software have relatively high requirements for security, so here are instructions on how to verify +whether the code and executable files have been tampered with.If you find that the signature is incorrect, please stop +using it immediately. + +## Code compilation + +When you see the document, every binary file version released on github is automatically compiled after submission using **Github Actions**. The generation of the final code is completely done by Github Actions. I will not compile the code on my local machine, but may use my machine to sign the packaged code. The code for all release versions comes from the main branch of the Github repository. + +All commands and environment configuration at compile time can be consulted in the project +code(`.github/workflow/release.yml`). + +## Introduction of third-party libraries + +For safety reasons, GnuPG will not be available in the major releases of GpgFrontned. GpgFrontnend will not use insecure or non-open source third-party libraries. The compiled version of the third-party library comes from the public code repository. + +## Verify Code + +If you have the need, interest or time, you are welcome to review the code that I use and write. When you have any +questions, please feel free to [Contact ME](../contract.md). + +I will sign most new git commit. The key I use is the key that I use to perform Git related operations: +Saturneric\<[email protected]\>. It will be given at the end of this description. For information about signing git commits, you +can see it on the github interface. + +The fingerprint of the key is now given: + +```text +E3379489C39B7270E70E2E303AAF1C64137CEE57 +``` + +## Verify Release Binary Verify + +### ZIP package Sign + +Starting from version 1.0.5, I will use the Gpg key to sign the ZIP package that contains the binary executable file. +Each ZIP compressed package will be accompanied by a signature file in the Release (end with sig suffix). You can use +the gpg command tool to verify them before use. + +The key used for binary signature is Saturneric\<[email protected]\>. This is my official key and will be given below. + +The fingerprint of the key is now given: + +```text +E3379489C39B7270E70E2E303AAF1C64137CEE57 +``` + +## Check on About Interface + +There is an About interface under the help option in the top menu.You can check the version and platform of this binary +file. More importantly, you can view the github repository branch and commit hash code corresponding to the source code +used for compilation of this binary version on the second line. + + + +## Pubkey Mentioned Above + +#### Fingerprint + +```text +E3379489C39B7270E70E2E303AAF1C64137CEE57 +``` + +#### Pubkey Content (OpenPGP) + +```text +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGNBGCVnvEBDACuEcjxckb4rocHGU7VPT/OOOOZapNG/0ViB3XhmzNh7q8QJiq6 +M4z0fpC5sf1pHXbbKtehLETrAUTFuaEp19askZI0ISoz5+qKGZuaM3bDZWBjwUpt +woVgUphfeZy2DFsnmTtVj9CRU9Nma6smXVFud3Roj2ImZ0NFrkdETvprfLJ7jqk/ +mXgznNbbJdqmQ4l0I1E91VmrqHHHSakh3grzRDj/GuDookQl2JZfLA0J55qOYdkF +5mmnqbYURGVcP2oot/wSrrWH0F/WatwRx9w+jZjrJWgKjJoqWwvzG8WGop1XkRn1 +Ea3Nzj/KsSL7C5YRu03BL7wNu6UNIJ/zsAnNLp87nCY85w+HnNGHkL3QcnqNQbQP +3aySOkIjXdT8AlGIV5r5wO/RBg4e+xASGzQXx9lYbjJiiIOP2uLxYGGFbalDoiCa +sonlXzMZTJrK7VvZ2UsnSnBJ8l/EPsY/AeZdWbmswQaFsJlfNsZZ6T5Rfyjtu8a3 +fwPJTTsbfIB6N3EAEQEAAbQbU2F0dXJuZXJpYyA8ZXJpY0Bia3R1cy5jb20+iQHO +BBMBCAA4AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE4zeUicObcnDnDi4w +Oq8cZBN87lcFAmCWg1kACgkQOq8cZBN87leJfQv/ShjV9PRi8ixlJ1Ez1TDG+4N9 +EHoi2IwVK1UF51kA9lxyD+8n1ZHpcz7bRXV+YhHAO4A2l1ENrkCJVIZK9OO+Z64l +TPKCV9JVSkxcpnr6sqKJ76Zplwah1ZkwAG9tdK9H95wgeIkO4oSRutX/cCJ35Gko +FfhbV+/OyPYTT2562SZeQ2VqnptGLm0eF+FVt0HP4uxvRyGfgHQD46Ki6dr/JOXQ +j57S06CIHGj1RT4uQVSx53gbFvfIgweHsWraRWwY8jMrgOazlo/KRHG4N04eQdzM +K+WA80ODKuXdhnlGFMhn3RCFZpRV+Upso9syJ1FFChzsuX69+mRPvAojEDnREgd9 +s61nx5xWy6vKMB9oZiomNuPw2EScBwS9EK0M6APqgBaIdL6HOC7kjxBLfqgyhulD +qGZXWNvFj5P2FNMVwSvK1cYftYz+QWqB5BhbJT2H/HpF2xNsH7jfTxwUp6KrN1Bz +geNWgpQDXS5ZXU7dk22BwSah3nXs+LJi3Sloeh/piQHUBBMBCAA+FiEE4zeUicOb +cnDnDi4wOq8cZBN87lcFAmCVnvECGwMFCQPC1M8FCwkIBwIGFQoJCAsCBBYCAwEC +HgECF4AACgkQOq8cZBN87le3zAv/fMnxVMORS5rz/vsc0X8YSldmM1MqdIKSNghK +nQKKnzTBtTKA/oHEyPhjnQRaCfi4eUGeUsdZq8fwbN6sWSmbhJ6cOVgIps9YcS/U +sCV4egUHGy/+ozgDSh563v82ROWxXjszcnFz0F2d4stgroe8A//3OgQDv1wuhMJe +vtSZe8W8ebj7mt0zNjccGQzNkWo82mOyZfjgvK//vWisW4JwP8gfEKBgAktj5MCY +iGS2NbWPAToDIPCA6hKPb3sHQIY2/tGkKwyvr4oxwYRkNq4T5PWcV0p3qRsQudHp +ZXGiL3VNIW04ihLcn8uxSE6sQK2eq5wp/6Wnt1EWG1xb0pU2nPFuAlULHsGxM+bB +YJOk5WzYST1xdgXW3QxVsIoTuVqA+ehqrzvu+gGCz4uenFt6OAswqR7ii8D/Tpso +RAU0nTEOAVpCxXAMgsdUS6jOjtyfTHixGlVL6U3dY3wTuqWdbxmYX/g00PnOTYF0 +1plvf21NHMeYLk68+1nRbtqoLnPVuQGNBGCVnvEBDAC8zNpSGRHUp+X7hit0bCDP +P8HR+rxH50rOVFtQNyXw32lkIrwnHq0Y7FR4t7OSWTkX1xvxhXMILQdTBxKKrBtF +IpQ44cO1UcklkYdCwE/F0lasLLfleo2NlG7ISwNEOxmJcWiwmkLHN3CnqXpXXqpG +DTRavbuhE7yRewp/jNSCsikrvL7NedB5Ef5EZmSkvx7kXibXKzgKcyft5OlylRMU +JS8gzzTPA+xMH/Cl1zFCSgymJw1DK1wx+u0ye2Oj7NDdrYtRR1qLpCq7kaGIPvIW +556/58sj+/YRGeP5JTjhYFk/K8QQr8cK6HWuJQVASJUP+KBk8CiaqzbOPjlq69eG +Oymraa8H7JvSR5ArJWPczOxQyiEbYABOtJk1ZSz4v4pa7+RLUfwFOYuTMyBoY3rJ +uGhVxA77oHftfjteH1YcKyJXrWnJEA2UbUmyRa5cwZ8S7HXOIvMhCQS897Tzjpab +lfnIKE0n99c2ylJ4y4fHYSXYDKiCPKniFio8CxfqY+cAEQEAAYkBvAQYAQgAJhYh +BOM3lInDm3Jw5w4uMDqvHGQTfO5XBQJglZ7xAhsMBQkDwtTPAAoJEDqvHGQTfO5X +FbAL/0XZJW6XUca9d7f6Ft/0crMILRKID5uuSaLN1jG7BuLTwyWPhi7eSWbZQmlD +Fun/E3vHFj3U/WG13DJL6M89f3707R6rKxT1B17Ht53bO9zHqJ9KesP1G+mR3phk +hnxoQFlFvfSASZbDFtwEm3eZs55UBY4EPYf9MV+qPT0iNu1KPVX427uQfI0Ic/m4 +xFAO2XI11wMunDQoXi7rjknjYWxqVyGgqgRLrBD1Bb/aLenKN9Wn4FajEDaYrgpH +46HHyhAOJ2RZbenWO689rZY6/0qPwDGRL7B2xiktu2G+e5JMJjuRhwEB0g63G8M1 +MVuRGr/PvrBjs58kF47rxWpp2xmo8dqCHjNS3ze9pl6oyshPa1J5zeDTNk3Ujgr9 +IJEzWLDWv9PP9ApcSD15Ia60bxSvsC8FJAZh81JEadLywx0QNBLmnMP3Dxpd21LK +W8cWXa31F6E6eNf/45h7UGxVBRoOdPQ/Kwg4z69V9T/AXOuK65XgtG5ajwlmoQcv +Vx7KIrkCDQRgloMRARAAtRIaNwOpLKA1ogvpzgx8/A8PeXCKvKPZ/ls+8sJ8RSZb +b8lmd+HN52sotj3h9XGZXO1123WLW5F7n/M3HazRBRLlIoUf5kWnuQmXXmUZ6DEC +mq9VoZ30CPHWDEZv/BoScXEHMZNEppziebe2r57SqY9cIONt7B2wzi3sVcYOtDye +c+9BUQoEEv/grSfRN/1Lzezb8Ac9XY0Jet9XK/ImKbGCoxMNzszGQeFO2Neg4hVG +65NIHjTRwzMUOp2D9GV14z/mu2xj5z0mP8zTLw2nzjSW8b0s9ewsvawH45s+XBS8 +ndMU3R+pnHqZBJXU1OR9XjSSMZhaNk+cpOgVwlmbGhNUZ4jSPNVZr/fABpgpY7Bh +ctY42Q3DZVSMwSmiGZA2Uoy7kKx2qtm1Q0ogh6x5mq9QKHODuh+Uc1XhbqxheySv +/jWxvnWhRqaRMBIY+H6vFbXRkQvYjdtwwHZvBRyF5VOsdSUbdLunjyIeKTl2wMqR +hm0y2li+nbTE+zbCcguGPtIMZq6V08M3OZZGxT1jZZocOi3y0qwuApaQvAvk7GpC +mjjbSsq/ykbPUMSQHqAh77YY/9/v2kBh5u21fBPmtPyndAeZTNyukJ2dq8pecVgP +eqT/sSs/Gn56T1cekPEIuUkUxQ4K1sLah1z4G+jg8VqCPIj4yBH6pfd6zBEPx70A +EQEAAYkD8gQYAQgAJhYhBOM3lInDm3Jw5w4uMDqvHGQTfO5XBQJgloMRAhsCBQkH +hh93AkAJEDqvHGQTfO5XwXQgBBkBCAAdFiEExEoeTMpVzDyCCrnkOlA5Ga/6SF8F +AmCWgxEACgkQOlA5Ga/6SF9U+hAAs59FJP2pCQDnrFCrmk38mVePAyPNceSm7IEl +zJWuoxf6XOkz7SP7Vh4mPxyRj3yltEnFN5tLvDOF8W+AwMMMHrK9TnXxnJ2HwCbY +ifLgAGmNrMq+IoagTJDAZvlkp4m3gHe6zDYv9UIbFKdnB48FbwtahNm9LjMbqNDc +nLBt+IuiO/PXUu6c56Wl+L9ntOSVLb1ySnRisI4iYx4J80GcFaMjlJFjQ5uGt0jh +Ardq4zFLYgJfTTl6cM8WTANiKO2a6DgpZxb1knfKOjdasqeQcEs4ZcB6Nf9Bcw/X +Qe2Ee85FA+qClxuIMTT5l6fDw+DXgZfSR0clwA4rMY7hCUvuRxCjc1LDOCbyHe/Z +PUAntlNNKrXEicXxi8Odpzcq0/rDR53OMyzFhGXpbbxa89F/B96H249IW/waefN6 +VKpSb693VOyl8AtQ2tRAvy7YxYyhUQIKKCuahjdoib3GmFNE67rjW9MUVfefIhvp +nBJaY8tp8YhYrDF0U9DMuYrTLcPu5VsR7gvlFY30If1XCavpAnq+eNaxIdTDIKfJ +Q2cgALPBfzogEOeR+RY4Lo46dIGCaEYTpbImcJdum0GVACoMb0T1oOXIHWd1hy46 +ianYKGxMmjfS1f13cr6F1U18l8QKMBZhNTBazw2IdXaugdnbqryEsp20zPQ+caGR ++E1wZmOLMAv+JMPJSK7Ra9cQf6GEos1XurjhaoegPh0Y9U4p1Dk1pQduI7togmJ/ +bhvIpawfi52rI/4I4g1HqjcU8iG6ZjTVE7kVVvDISex71czbmV9isWvW0HJlDgTQ +piZbTCPqvgyEZRF0eIA+VTXOKD/qUwxvw3jo75KEcmW+sezqctREgH02EBPuD5GC +Qyxi7+nNq37FTNYReydCEGEDfJXZ6x12FkW9nPe2fkxx7WT/ceVT2jGtSG4re5vk +wYtnfgKvfHXYmTudoMuVmIsJc9zcdvhL1Nmrd1BOyeJmQCNyvwP48OkU5TqIGHc4 +PcbwniPKO8tozjuwE+iO2TjgwWc/Eg5hLPGYlyqalysP4nOO/KYLBwvgTrPse40N +jg4/3Ew4DKxsrHtCGfhx+i5pXVYwbWklPd7mDmmvxnM5gFEqs0VMMGsjElCzDsmm +v3fSDNozRpd0LXK7J4QGwtOBVivNf7XDQOx5ZXbh/HTQuTG2/8FMCbwUwPYFLx07 +hHHFn9+/wu20 +=bgvm +-----END PGP PUBLIC KEY BLOCK----- + +```
\ No newline at end of file diff --git a/manual/basic-concepts.md b/manual/basic-concepts.md new file mode 100644 index 00000000..638c19e3 --- /dev/null +++ b/manual/basic-concepts.md @@ -0,0 +1,58 @@ +# Basic Concepts + +If you don't know GPG, or PGP, you may need to learn some basic concepts here before using Gpg Frontend. This reduces +the chance of you making mistakes, such as distributing your private key to the world. + +## The most basic concepts you must know + +First, you need to generate a key pair, which you can imagine as a key ring. Each key pair has at least two keys, a +public key and a corresponding private key. These two keys form a key pair. There can also be multiple public keys and +their (one-to-one correspondence) private keys in a key pair, which will be described later. The public key can be +released to the outside world. Others can use your public key to encrypt the information they want to give you. The +private key is kept by yourself. If it is leaked, your encryption will no longer be meaningful. + +What you need to know is that the public key is used to encrypt information, and the ciphertext encrypted by others +using the public key you released is guaranteed to be decrypted only by the corresponding private key of your key pair. +This process involves some The principle of cryptography, you can trust this process unless no one knows your private +key except you. The reverse of this process is also valid, you can encrypt a message with your private key, and someone +else decrypts the message with your public key. The significance of this inverse process is that if the person using the +public key cannot normally decrypt a message encrypted with the private key, then it is certain that the message does +not come from the person who owns the private key corresponding to the public key. . This process can also be trusted. +It can be seen that this reverse process establishes a process of signing and then verifying. Information encrypted with +the private key can be seen as a signature. Others can use the public key to verify that the signature is valid. + +If you just want to use the tool, you don't need to understand the cryptography behind it, you just need to remember the +above. + +If you want to know more, you can read on. + +## Multiple pairs of public and private keys in a key pair + +In a key pair, there is at least one pair of public key and private key, but there is no limit to the maximum number of +pairs. You can generate another pair of public and private keys (we call them subkeys), and then add them to the key +pair, but it is worth noting that the newly added public and private key pairs are the same as the first pair. Pairs +have a public key and private key (which we call the primary key) pair associated. + +You can specify which process a subkey pair is used for. For example, the first key pair is used for encryption and +decryption, the second key pair is used for signing and verification, or the third key pair can be used for encryption +and decryption. Used to do the above two key pairs at the same time. Please specify these things when generating the +subkey. + +The master key is automatically generated when the key pair is generated, and the subkey can be added by the user at +will. + +When generating the master key or subkey, you can choose some algorithms such as RSA, DSA, etc. You do not need to +understand the specific principles of these. You just need to know that subkeys generated by certain algorithms cannot +perform certain processes (such as encryption and decryption), but can only perform certain processes (such as signing +and verification). It is worth mentioning that for RSA, you can choose the key length when using the algorithm, you can +think that the key + +## The first pair of public and private keys in a key pair (primary key) + +The first pair of public and private keys (master key) in a key pair is very critical, because subsequent public and +private keys (sub-keys) are linked to them, you can think that if someone else gets yours Master key (including public +and private key information), he can generate sub-keys based on the information of the master key, and then he can use +the sub-keys he generated to impersonate you and communicate with others. + +Therefore, the private key of the master key (the public key can be released to others) must not be leaked. The +disclosure of its private key means that the entire key pair is no longer safe and must be stopped immediately. diff --git a/manual/contract.md b/manual/contract.md new file mode 100644 index 00000000..bb9de59b --- /dev/null +++ b/manual/contract.md @@ -0,0 +1,136 @@ +# Contract + +Contents related to business and politics are rejected. This tool belongs to all mankind. If you have any questions +about technology and improving this software, please feel free to contact me. + +It is recommended to use plain text to contact me by email, but HTML is not recommended. + +## About ME + +Name: Saturneric, Eric or Erich. + +Email: [[email protected]](mailto:[email protected]) + +Tips: BKTUS(Bakantu Union) is not a company, it is my personal domain name. + +## Languages + +You can write to me in the following language. + +1. English +2. Chinese +3. Deutsch + +## GPG Public Key Info + +This is the PGP public key that I support for a long time. You can use this public key to establish encrypted +communication with me. Please use plain text for encrypted communication, do not use rich text formats such as HTML. + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGNBGCVnvEBDACuEcjxckb4rocHGU7VPT/OOOOZapNG/0ViB3XhmzNh7q8QJiq6 +M4z0fpC5sf1pHXbbKtehLETrAUTFuaEp19askZI0ISoz5+qKGZuaM3bDZWBjwUpt +woVgUphfeZy2DFsnmTtVj9CRU9Nma6smXVFud3Roj2ImZ0NFrkdETvprfLJ7jqk/ +mXgznNbbJdqmQ4l0I1E91VmrqHHHSakh3grzRDj/GuDookQl2JZfLA0J55qOYdkF +5mmnqbYURGVcP2oot/wSrrWH0F/WatwRx9w+jZjrJWgKjJoqWwvzG8WGop1XkRn1 +Ea3Nzj/KsSL7C5YRu03BL7wNu6UNIJ/zsAnNLp87nCY85w+HnNGHkL3QcnqNQbQP +3aySOkIjXdT8AlGIV5r5wO/RBg4e+xASGzQXx9lYbjJiiIOP2uLxYGGFbalDoiCa +sonlXzMZTJrK7VvZ2UsnSnBJ8l/EPsY/AeZdWbmswQaFsJlfNsZZ6T5Rfyjtu8a3 +fwPJTTsbfIB6N3EAEQEAAbQbU2F0dXJuZXJpYyA8ZXJpY0Bia3R1cy5jb20+iQHO +BBMBCAA4AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE4zeUicObcnDnDi4w +Oq8cZBN87lcFAmCWg1kACgkQOq8cZBN87leJfQv/ShjV9PRi8ixlJ1Ez1TDG+4N9 +EHoi2IwVK1UF51kA9lxyD+8n1ZHpcz7bRXV+YhHAO4A2l1ENrkCJVIZK9OO+Z64l +TPKCV9JVSkxcpnr6sqKJ76Zplwah1ZkwAG9tdK9H95wgeIkO4oSRutX/cCJ35Gko +FfhbV+/OyPYTT2562SZeQ2VqnptGLm0eF+FVt0HP4uxvRyGfgHQD46Ki6dr/JOXQ +j57S06CIHGj1RT4uQVSx53gbFvfIgweHsWraRWwY8jMrgOazlo/KRHG4N04eQdzM +K+WA80ODKuXdhnlGFMhn3RCFZpRV+Upso9syJ1FFChzsuX69+mRPvAojEDnREgd9 +s61nx5xWy6vKMB9oZiomNuPw2EScBwS9EK0M6APqgBaIdL6HOC7kjxBLfqgyhulD +qGZXWNvFj5P2FNMVwSvK1cYftYz+QWqB5BhbJT2H/HpF2xNsH7jfTxwUp6KrN1Bz +geNWgpQDXS5ZXU7dk22BwSah3nXs+LJi3Sloeh/piQHUBBMBCAA+FiEE4zeUicOb +cnDnDi4wOq8cZBN87lcFAmCVnvECGwMFCQPC1M8FCwkIBwIGFQoJCAsCBBYCAwEC +HgECF4AACgkQOq8cZBN87le3zAv/fMnxVMORS5rz/vsc0X8YSldmM1MqdIKSNghK +nQKKnzTBtTKA/oHEyPhjnQRaCfi4eUGeUsdZq8fwbN6sWSmbhJ6cOVgIps9YcS/U +sCV4egUHGy/+ozgDSh563v82ROWxXjszcnFz0F2d4stgroe8A//3OgQDv1wuhMJe +vtSZe8W8ebj7mt0zNjccGQzNkWo82mOyZfjgvK//vWisW4JwP8gfEKBgAktj5MCY +iGS2NbWPAToDIPCA6hKPb3sHQIY2/tGkKwyvr4oxwYRkNq4T5PWcV0p3qRsQudHp +ZXGiL3VNIW04ihLcn8uxSE6sQK2eq5wp/6Wnt1EWG1xb0pU2nPFuAlULHsGxM+bB +YJOk5WzYST1xdgXW3QxVsIoTuVqA+ehqrzvu+gGCz4uenFt6OAswqR7ii8D/Tpso +RAU0nTEOAVpCxXAMgsdUS6jOjtyfTHixGlVL6U3dY3wTuqWdbxmYX/g00PnOTYF0 +1plvf21NHMeYLk68+1nRbtqoLnPViQG5BBABCgAjFiEEnGCv/tNBLyJzYTX+0QUx +Uz7XYkoFAmG6ODgFg2shizAACgkQ0QUxUz7XYkq+BQwAxEzCMKxa21iKv9P7S6Vh +/ZrPMWPzRMoNjMGFeNHxYzyO6lKojoCVsdHaRvqqSota8wVGHglsg4FEZgkqEy+S +kTwMsorqzVhxAtzG9K1pU+wGouT5UPBXFGjusbLfxigxvuIGEVD2025FroE4xvMG +WnyD7r0leWkbF0z1crms2jbPcH0E7nbiiVHA6iOuBV5jo6qm1UxvJH3izSCocrDC +/yqPXg5cng6BPnctcWFzXbVGcB1HQ4LdiN4HWvB7q1mwRG2+qwL+UBybGsMpP+oa +YlIGP0FxNureXJgg8bVGcOOLITmuQ1xTOFu/1lUzk1QBqNql0mvqqScSYsAJxQcy +d95MFFeRLnQ3fJU18YrvlLtJIFxrLE+9IVCQsM3XGblXLCltIEgAunp1ylaVtb/w +4ScbQ/a5vWILh80L3dxcvVe1RlZe6cRwOb4aXRQm7osVaZ/boiaJ1nHYGdrh+qxi +QprHmOXeSPVV708VRaY9t8tSiLCRwVQO1e5e8GeXzIv/uQINBGCWgxEBEAC1Eho3 +A6ksoDWiC+nODHz8Dw95cIq8o9n+Wz7ywnxFJltvyWZ34c3nayi2PeH1cZlc7XXb +dYtbkXuf8zcdrNEFEuUihR/mRae5CZdeZRnoMQKar1WhnfQI8dYMRm/8GhJxcQcx +k0SmnOJ5t7avntKpj1wg423sHbDOLexVxg60PJ5z70FRCgQS/+CtJ9E3/UvN7Nvw +Bz1djQl631cr8iYpsYKjEw3OzMZB4U7Y16DiFUbrk0geNNHDMxQ6nYP0ZXXjP+a7 +bGPnPSY/zNMvDafONJbxvSz17Cy9rAfjmz5cFLyd0xTdH6mcepkEldTU5H1eNJIx +mFo2T5yk6BXCWZsaE1RniNI81Vmv98AGmCljsGFy1jjZDcNlVIzBKaIZkDZSjLuQ +rHaq2bVDSiCHrHmar1Aoc4O6H5RzVeFurGF7JK/+NbG+daFGppEwEhj4fq8VtdGR +C9iN23DAdm8FHIXlU6x1JRt0u6ePIh4pOXbAypGGbTLaWL6dtMT7NsJyC4Y+0gxm +rpXTwzc5lkbFPWNlmhw6LfLSrC4ClpC8C+TsakKaONtKyr/KRs9QxJAeoCHvthj/ +3+/aQGHm7bV8E+a0/Kd0B5lM3K6QnZ2ryl5xWA96pP+xKz8afnpPVx6Q8Qi5SRTF +DgrWwtqHXPgb6ODxWoI8iPjIEfql93rMEQ/HvQARAQABiQPyBBgBCAAmAhsCFiEE +4zeUicObcnDnDi4wOq8cZBN87lcFAmG6N+8FCQTmG90CQMF0IAQZAQgAHRYhBMRK +HkzKVcw8ggq55DpQORmv+khfBQJgloMRAAoJEDpQORmv+khfVPoQALOfRST9qQkA +56xQq5pN/JlXjwMjzXHkpuyBJcyVrqMX+lzpM+0j+1YeJj8ckY98pbRJxTebS7wz +hfFvgMDDDB6yvU518Zydh8Am2Iny4ABpjazKviKGoEyQwGb5ZKeJt4B3usw2L/VC +GxSnZwePBW8LWoTZvS4zG6jQ3JywbfiLojvz11LunOelpfi/Z7TklS29ckp0YrCO +ImMeCfNBnBWjI5SRY0ObhrdI4QK3auMxS2ICX005enDPFkwDYijtmug4KWcW9ZJ3 +yjo3WrKnkHBLOGXAejX/QXMP10HthHvORQPqgpcbiDE0+Zenw8Pg14GX0kdHJcAO +KzGO4QlL7kcQo3NSwzgm8h3v2T1AJ7ZTTSq1xInF8YvDnac3KtP6w0edzjMsxYRl +6W28WvPRfwfeh9uPSFv8GnnzelSqUm+vd1TspfALUNrUQL8u2MWMoVECCigrmoY3 +aIm9xphTROu641vTFFX3nyIb6ZwSWmPLafGIWKwxdFPQzLmK0y3D7uVbEe4L5RWN +9CH9Vwmr6QJ6vnjWsSHUwyCnyUNnIACzwX86IBDnkfkWOC6OOnSBgmhGE6WyJnCX +bptBlQAqDG9E9aDlyB1ndYcuOomp2ChsTJo30tX9d3K+hdVNfJfECjAWYTUwWs8N +iHV2roHZ26q8hLKdtMz0PnGhkfhNcGZjCRA6rxxkE3zuV1CBC/0aOW74yuxVTBhi +c+UNCjbHAZxc6gB8DnhuFp/h0FFfWR5SPKE7KjiZSAH38fzp9i1JT2KMfcDBrs4m +PPCaN7KHViU8Z9YF2FDCn+xqhDvm9j64FNYnTihWttgMM3AbZI+LPbwGl+Uaa4vF +n+sXrUqag8hu7fnCzoE+YPj03CUxSzCw4jXHh0Dyan33msEN6n6G6/XRG073HXxt +xiEaAeNDE+izq98WIfH1c4DVpKFPlD9DVdaCWHzl6vzU3d04g+sUQuMqrScm+rcm +BYCa+SRWnyl2q0dhnG1XjONOBNAZGorB9ooKH5HBFUVeFNsM4ufA+oRp+1XlaqXo +Tc7l+JeDEsVK1fmQljNRhBshaxk8fLPmCi1rmApME33aEGDsg8uc3IZXPe3r8cmY +D/AVSQI5MdPpXqq1VWv+faXL0lZtECtfOXp6l81OX5hqCC7hp6eW7gMofi02YiXU +aBwg2Kx/x2IxG7u9givkBV4oysiedKLNYWUTqjB2aKcRyWISCn+4MwRhujfiFgkr +BgEEAdpHDwEBB0DvyZqcMWkH1WlSfOywXkKTbITdzBKzaf4jtd3g+kjaC4kCMwQY +AQoAJhYhBOM3lInDm3Jw5w4uMDqvHGQTfO5XBQJhujfiAhsiBQkDwtdvAIEJEDqv +HGQTfO5XdiAEGRYIAB0WIQQKoW+sJgfi4tfYq0XFuG82AZ5SpwUCYbo34gAKCRDF +uG82AZ5Sp8xMAQCc6Q7vJXYXIoShHk4RmT1vkAy68k8XgHn9Kw+jbAze4gD9F22u +wWfbsFjiMLUOE2uWlwuLmJN827DBaVw5eOx9HA1F1AwAgFTv4dNTS0jKKIncUN4Y +XX4fA7UbBrwLY8jTAV49V+D+hoFfv09hG+q4xwKwe1yFrgacsHOXnXpTJz6ipU08 +GP9vTheyxSfQUvaWXLzHcGXkaV6aCBsDVWdQ8MHXujOsx/hjQSTDruygmEyc1nFi +aF1BLQDtTXW7GIiQX/l/uLVlnMNI4kdt7YUxjkUL6xD+U5q43B4KyGVIU9+ps4Mr +9wCWS/lot66VLT4FUVTFDF0c8hwEdxVZagZvExlv2SaW3XidRWL5xVAElRs/fgRn +dKFCFDJ1rOLUwj25r6zgu2zXlQ2RHWjgzhLzZmhzv3IX0mI9s5D6bJWy+6/HNCs8 +bTSq0Af79FCdZfPT8GVlY9NWcwsMthxiYJ/cbc/D+w4dX771lP2dU/KZkKuGxdhA +jGWqnGt8lqL3PEIsf1ylPDx6b7peFABWfGlPVUmpik2lTemlqWNPLX5gGmiiktGm +lZ6+bATms7izrrSs521ZKWoUT5TI+qQ7Paq/qsF5zIBGuQGNBGCVnvEBDAC8zNpS +GRHUp+X7hit0bCDPP8HR+rxH50rOVFtQNyXw32lkIrwnHq0Y7FR4t7OSWTkX1xvx +hXMILQdTBxKKrBtFIpQ44cO1UcklkYdCwE/F0lasLLfleo2NlG7ISwNEOxmJcWiw +mkLHN3CnqXpXXqpGDTRavbuhE7yRewp/jNSCsikrvL7NedB5Ef5EZmSkvx7kXibX +KzgKcyft5OlylRMUJS8gzzTPA+xMH/Cl1zFCSgymJw1DK1wx+u0ye2Oj7NDdrYtR +R1qLpCq7kaGIPvIW556/58sj+/YRGeP5JTjhYFk/K8QQr8cK6HWuJQVASJUP+KBk +8CiaqzbOPjlq69eGOymraa8H7JvSR5ArJWPczOxQyiEbYABOtJk1ZSz4v4pa7+RL +UfwFOYuTMyBoY3rJuGhVxA77oHftfjteH1YcKyJXrWnJEA2UbUmyRa5cwZ8S7HXO +IvMhCQS897TzjpablfnIKE0n99c2ylJ4y4fHYSXYDKiCPKniFio8CxfqY+cAEQEA +AYkBvAQYAQgAJhYhBOM3lInDm3Jw5w4uMDqvHGQTfO5XBQJglZ7xAhsMBQkDwtTP +AAoJEDqvHGQTfO5XFbAL/0XZJW6XUca9d7f6Ft/0crMILRKID5uuSaLN1jG7BuLT +wyWPhi7eSWbZQmlDFun/E3vHFj3U/WG13DJL6M89f3707R6rKxT1B17Ht53bO9zH +qJ9KesP1G+mR3phkhnxoQFlFvfSASZbDFtwEm3eZs55UBY4EPYf9MV+qPT0iNu1K +PVX427uQfI0Ic/m4xFAO2XI11wMunDQoXi7rjknjYWxqVyGgqgRLrBD1Bb/aLenK +N9Wn4FajEDaYrgpH46HHyhAOJ2RZbenWO689rZY6/0qPwDGRL7B2xiktu2G+e5JM +JjuRhwEB0g63G8M1MVuRGr/PvrBjs58kF47rxWpp2xmo8dqCHjNS3ze9pl6oyshP +a1J5zeDTNk3Ujgr9IJEzWLDWv9PP9ApcSD15Ia60bxSvsC8FJAZh81JEadLywx0Q +NBLmnMP3Dxpd21LKW8cWXa31F6E6eNf/45h7UGxVBRoOdPQ/Kwg4z69V9T/AXOuK +65XgtG5ajwlmoQcvVx7KIg== +=syqc +-----END PGP PUBLIC KEY BLOCK----- +``` + diff --git a/manual/faq.md b/manual/faq.md new file mode 100644 index 00000000..b53c149a --- /dev/null +++ b/manual/faq.md @@ -0,0 +1,46 @@ +# FAQ + +## What is GpgFrontend? + +GpgFrontend is a cross-platform encryption tool that conforms to the OpenPGP standard. It is committed to making OpenPGP +easier to use, so that more people can use the tool to protect their privacy. + +## Relationship with OpenPGP(pgp) and Gnupg(gpg)? + +OpenPGP is a data encryption and decryption standard, and GpgFrontend supports it. GnuPG is a cryptographic software +used to encrypt, sign communication content and manage keys for asymmetric cryptography. It follows the OpenPGP +standard. GpgFrontend drives gnupg at runtime to implement operations such as encryption and decryption. + +## How to obtain and use GpgFrontend? + +The various versions of GpgFrontend will be released in the GitHub repository, and you can find and download the latest +version in Releases. After downloading, you can refer to the instructions in ReadME and you can start using it in just a +few steps. + +## I found some flaws in GpgFrontend, what should I do? + +If you find a defect in GpgFrontend, you are welcome to create an issue in the GitHub repository to describe the +problem. When I see your issue, I will respond as soon as possible. If you do not have a GitHub account, please email my +personal mailbox. For contact information, please see [Contract](contract.md). + +## Can I modify the code of GpgFrontend? + +If you have any good ideas, you are free to modify the code of GpgFrontend. You are welcome to submit a Pull Request to +add your good ideas to the next version. + +You can contribute completely anonymously, and you can email me patches. + +## Why should I install GnuPG additionally? + +The source code of GpgFrontend does not contain operations such as encryption and decryption, which requires Gnupg to +provide support. In addition, for users with higher security requirements, they can let GpgFrontend drive their trusted +copy of Gnupg. This design improves the security of GpgFrontend. + +## What is the release version with BETA? + +The release version with the word "beta" means that some modules of this version have not yet been thoroughly tested. In +addition, some support for the beta version may not be complete. But rest assured, I will test after the beta version is +released, and release a stable version at an appropriate time. + +But starting from 2.0.0, BETA versions will not be released unless there are special circumstances. + diff --git a/manual/features/introduce.md b/manual/features/introduce.md new file mode 100644 index 00000000..eb250877 --- /dev/null +++ b/manual/features/introduce.md @@ -0,0 +1,4 @@ +# Introduce Features + +GpgFrontend provides some advanced functions that can meet the needs of certain scenarios. +These features will be gradually introduced as the version is updated. diff --git a/manual/features/short-ciphertext.md b/manual/features/short-ciphertext.md new file mode 100644 index 00000000..8e301966 --- /dev/null +++ b/manual/features/short-ciphertext.md @@ -0,0 +1,14 @@ +# Short Cipher-text + +**NOTICE: As of version 2.0.0, GpgFrontend has eliminated this feature.** + +The short ciphertext function allows OpenPGP to transfer ciphertext quickly and conveniently in instant messaging software. +After successfully configuring the own key and obtaining the Service Token, you can use the short cipher text function. + +After the encryption and signature operations, you can click the short crypto button in the additional operations menu. +GpgFrontend will return a very short ciphertext, and you can publish the short ciphertext anywhere. + +You can paste the ciphertext into the text tab of GpgFrontend and select decryption and verification operations. +At this time, GpgFrontend will perform the corresponding operations. + +Note: The short ciphertext is valid within seven days of being generated. The short ciphertext function has restrictions on the length of the ciphertext. diff --git a/manual/features/sync-all-public-keys.md b/manual/features/sync-all-public-keys.md new file mode 100644 index 00000000..cfc87d60 --- /dev/null +++ b/manual/features/sync-all-public-keys.md @@ -0,0 +1,26 @@ +# Public Key Sync + +Sometimes, you need to keep your local key consistent with the one on the key server. This is critical in cases where a +key owner revokes its key, at which point you need to stop using the key immediately. This avoids potential +man-in-the-middle attacks. Or, if the key owner creates a new subkey for signing, gpg will not be able to verify the +validity of the ciphertext if the ciphertext he sends to you signs with the subkey and you do not have local information +about the subkey. + +## How to use + +It's very simple, after clicking the Sync Public Key button in the the Key Management interface, things will be done +automatically. + + + +This feature will check all the public keys you now have (only the public key, not any private keys) and then search for +it in the key server. If the corresponding public key is found in the key server, GpgFrontend will import the latest +public key from the key server to the local. + +### Which Key Server Was Used + +How do I know which key server GpgFrontend accessed? It's simple, GpgFrontend will exchange keys using the default key +server you set up. If you need to change the key server you need to access, you just need to add your key server in the +settings and set it as the default. + + diff --git a/manual/index.html b/manual/index.html new file mode 100644 index 00000000..2e07158b --- /dev/null +++ b/manual/index.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>GpgFrontend - An OpenPGP Frontend Tool</title> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> + <meta name="description" content="Description"> + <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"> + <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"> + <link rel="shortcut icon" href="/_media/icon.svg" type="image/x-icon"> +</head> +<body> + <div id="app"></div> + <script> + window.$docsify = { + logo: '/_media/trademark.png', + name: 'GpgFrontend', + loadNavbar: true, + loadSidebar: true, + coverpage: true, + onlyCover: true, + subMaxLevel: 3, + alias: { + '/.*/_sidebar.md': '/_sidebar.md' + } + } + </script> + <script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script> + <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/emoji.min.js"></script> + <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script> + <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-php.min.js"></script> +</body> +</html> diff --git a/manual/manual/advance-key-opera.md b/manual/manual/advance-key-opera.md new file mode 100644 index 00000000..c8b646a4 --- /dev/null +++ b/manual/manual/advance-key-opera.md @@ -0,0 +1,3 @@ +# Advance Key Operation + +Some advanced key operations will be introduced in this module.
\ No newline at end of file diff --git a/manual/manual/email-operations.md b/manual/manual/email-operations.md new file mode 100644 index 00000000..6d460e60 --- /dev/null +++ b/manual/manual/email-operations.md @@ -0,0 +1 @@ +# Email Operations
\ No newline at end of file diff --git a/manual/manual/encrypt-decrypt-file.md b/manual/manual/encrypt-decrypt-file.md new file mode 100644 index 00000000..230480b1 --- /dev/null +++ b/manual/manual/encrypt-decrypt-file.md @@ -0,0 +1,52 @@ +# Encrypt & Sign File + +Gpg Frontend provides a convenient and fast way to operate on files. The concept of encryption and decryption files is +almost the same as text, except that the input and output of file operations can be binary. + +## File Extension Introduction + +For ciphertext in ASCII format, its filename suffix is usually asc, and you can directly open such files with a text +editor. However, if the ciphertext is binary, its file extension will be gpg. Usually, binary ciphertext files are +smaller than ASCII format. + +Before v2.0.4, the ciphertext files generated by GpgFrontend are all in ASCII format. But starting from v2.0.4, +GpgFrontend will generate ciphertext files in binary format by default. you can change this setting in settings. + + + +## File Browser + +In the top menu file option, you can open the file browser(Ctrl/Command + B). Then by using the file browser, first +enter your working directory. Then right-click the file you need to operate, and then select the operation you want in +the pop-up menu. + + + +There are two control buttons at the top of the file tab. The one on the left is the up level, and the one on the right +is to enter or refresh the corresponding path in the input box on the left. + +On the far right is a button with useful options that you can tick to show system files or hidden files. + + + +### Encrypt & Sign + +This method provides encryption and signature functions, which GpgFrontend recommend, so that the receiver can know that +the ciphertext comes from you. You can select one or more recipients' public key and your own private key to complete +this operation. + +This operation generates a file with the gpg extension. The file with this suffix contains both encrypted content and +signed content. + + + +### Decrypt & Verify + +This ciphertext is verified while decrypting, which can improve security. In addition, you can also perform Only Verify +operations and this operation will verify without decryption. To use this operation, you need to select a file with a +gpg or asc extension, which contains the ciphertext and signature content. + +In order to encourage users to check whether the ciphertext is signed or not when decrypting, Gpg Frontend does not +provide a separate decryption operation here. + + diff --git a/manual/manual/encrypt-decrypt-text.md b/manual/manual/encrypt-decrypt-text.md new file mode 100644 index 00000000..ad36880a --- /dev/null +++ b/manual/manual/encrypt-decrypt-text.md @@ -0,0 +1,83 @@ +# Encrypt & Decrypt Text + +To start encryption and decryption operations, you need to prepare your plain text. In addition, you also need a public +key that can perform encryption operations. How to generate such a key can be found in the chapter on generating a key +pair. + +## Encrypt + +The Encrypt operation itself uses a public key and does not require a private key. Remember that whoever you want to +send it to encrypts it with whose public key. For people who don't use gpg very often, they often get confused and use +their own keys to encrypt ciphertext. + +Note that if you want to encrypt your text and send it to "foo", you need to know foo's public key first. Then you need +to encrypt your text with foo's public key instead of using your public key. Before encrypting, check to see if the +public key has cryptographic capabilities. This can be viewed in the usage column of the key toolbox (the letter E +stands for encryption). + +It is worth mentioning that if you only use foo's public key to encrypt the ciphertext, no one but foo's own private key +can decrypt the ciphertext. There is a situation where you want ciphertexts to be decrypted by multiple people ( +including yourself), please check their corresponding public keys before doing so. After an encryption operation, if you +misuse (some people's public keys are found to be missing), you can use the undo operation to restore your original +ciphertext before closing GpgFrontend. + +### Only Encrypt + +In this case, you only encrypt the ciphertext, and the ciphertext will be shorter. Because in operation, the ciphertext +does not contain additional signature information to determine the identity of the encryptor. If you don't want to +receive your graphemes knowing your identity, use this method to generate your ciphertexts. + +After the encrypted operation, there is no additional information display in the information board except for the prompt +of whether the operation is successful. + + + +### Encrypt Sign + +By encrypting and signing at the same time, not only can the text be protected, but the recipient can also know that +thecipher text is from your hand. This encryption is often used in scenarios where both parties need to ensure that the +decrypted text is credible, and in general, in that scenario, the upper reaches know each other. The ciphertext +generated by this operation is longer because of the additional signature information attached to it. + +Before doing so, you only need to select the public key(s) you need to use for encryption. Halfway through the +encryption operation, you'll be asked to choose the private key you need to use for signing. That is, the signer. If you +don't find the key you want in the Signaler list, confirm that your private key can be used for encryption and is valid. +To check whether the key can be used for signing, please check the usage column in the key toolbox on the right (letter +S stands for signature). You can select the public key to use for encryption, or you can select the public key to use +for signing. + +For this type of ciphertext, you can use the validate operation to see if the ciphertext is trustworthy before +decryption. + +When the operation is complete, information about the cryptographic operation and the signature operation is displayed +in the Infomation Board. You can view information about the signature, such as the pattern of your signature and the +algorithm used (you can indirectly see which subkey you used to sign). Please note the distinction between the dates +used in your signature messages in UTC and not your local time. + + + +## Decrypt + +Paste the ciphertext you obtained directly, gpg will automatically select the appropriate key in the list for +decryption. Always remember to decrypt with the private key. + + + +Whether a key pair can be used for decryption will not be displayed in the usage column. You only need to remember that +a valid private key can be used to decrypt the ciphertext encrypted with the related public key. + +Regarding whether this key is a public key or a private key, you can check the type column in the key toolbox. However, +you do not need to check the corresponding key before decryption. And when all your local keys cannot be used for +decryption, the program will prompt decryption failure. + +## Decrypt Verify + +While decrypting, you can learn some information about the encryptor of the key (if you signed it during encryption). + +Whether a key pair can be used for verification will not be displayed in the usage column, you only need to remember a +valid public key can be used for verification. + +This is a good habit regardless of whether the encryptor has signed in advance. Because you cannot infer from the format +of the ciphertext whether it has been signed or not. So, use decryption operations with verification whenever possible. + + diff --git a/manual/manual/generate-key.md b/manual/manual/generate-key.md new file mode 100644 index 00000000..848e6a8c --- /dev/null +++ b/manual/manual/generate-key.md @@ -0,0 +1,118 @@ +# Generate Key Pair & Subkey + +For GpgFrontend, to understand the key, you must first understand two concepts: key pair and subkey. + +A key pair can be compared to a key ring. When it is generated, there is a key in the ring called the primary key. This +primary key can do the intended operation (encryption, decryption, etc.). At the same time, keep this in mind, only +through the primary key can you open the keychain to add new keys to it. + +The sub-keys can be analogous to the keys you add to the key pair later, and each of them can independently perform +operations such as encryption and decryption. It can be considered that the primary key mentioned above is a special +subkey. + +When there is no primary key in the key pair, you will not be able to open the key ring to add a new sub key, but you +can still use this sub key if it is changed to exist for your operations. This mechanism is very helpful to the security +of the key. + +Let's see how to generate them next. + +## Generate Key Pair + +You can quickly grasp the operation of generating a key pair through the following animation. + + + +### Name & Email & Comment + +These three fields are used to facilitate people to distinguish this key pair from the card key pair. For these three +options, except for name and email, which are required, comments are optional. + +In addition, the length of the name is required to be greater than 5 letters, as long as the email conforms to the +format (no actual existence is required). + + + +### Expiration Date + +You can set an expiration date for the key pair. After this date, the key may still be used normally, but the operation +it does will be logically invalid (especially for signature operations). GpgFrontend recommends and defaults this date +to two years later. If you wish, check the Never expire checkbox to make this key pair never expire. + +But don't worry, you can change this option at any time after generation, even long after the expiration date (as long +as the primary key exists). + + + +### Key Size & Algo + +These two options are related. In general, different encryption algorithms have different optional lengths. GpgFrontend +will give you sufficient hints on the UI so that you will not go wrong. + +Just remember that the larger the key length, the more secure, but it will be slower when performing operations. + + + +### Passphrase + +You can set a key to protect the primary key, which is very important when the primary key is leaked. When the Do not +set password check box is not checked, an interface for you to enter the password will pop up during the process of +generating the password. Just follow the prompts. After setting the password, when you need to use the primary key for +operation, you may enter the password to unlock it +(some systems have a password networkAccessManager to take over this process). + +You can also check the checkbox to not set a protection password for the primary key, but due to security +considerations, this is not recommended. + +### Usage + +In the option of generating a key pair, you can specify the usage for the first subkey of the key pair, which is the +primary key. There are four options: + + + +- Encryption: After generation, it can be used for encryption operations. + +- Signing: After generation, it can be used for signature operations. + +- Certification: Popular understanding can be used to unlock this key ring (key pair). Only the primary key can check + this function. + +- Authentication: It can perform authentication operations like SSH keys. + +The third of these four uses (authentication purposes) can only be owned by the primary key. In addition, some usages +are not available when using certain algorithms for encryption. For example, when the DSA algorithm is selected, the +encryption uses are disabled. + +## Generate Subkey + +We can add sub-keys to the generated key pair. The subkey does not need to fill in the name, email and comment options. +The rest is basically the same as generating the key pair. + + + +### Extra note + +Here are some tips you might want to know. These tips will help you better understand the above concepts and use this +tool correctly. + +#### primary key & Subkey + +A key pair can have multiple subkeys and one primary key. Using this design reduces the risk of key leakage. For subkey, +After the subkey is leaked, you can revoke it at any time to reduce the loss. However, when the primary key is leaked, +the entire key pair will be insecure (the popular reason is that the main force can be used to manage this key pair). + +Therefore, the recommended approach is to generate multiple subkeys after creating the key pair, and export the master +key separately and store it in a safe place. This operation is not yet supported by GpgFrontend, you need to use the gpg +command to perform it. But gpgfrontend can identify and prompt the user whether the primary key exists or not. This is +very important, because some special operations (adding subkeys, signing other keys, etc.) cannot be performed without +the primary key. + +#### Some practical tips + +The purpose of the primary key cannot be changed after it is generated. If the primary key of this key pair does not +have a certain purpose, but a certain sub-key has this purpose, this key pair can still be used for operations +corresponding to this purpose. + +For example, when you generated the key pair, you didn't check the encryption usage. Don't worry, you can generate a +subkey and check the encryption usage. In this way, this key pair can still perform encryption operations. + diff --git a/manual/manual/import-export-key-pair.md b/manual/manual/import-export-key-pair.md new file mode 100644 index 00000000..96e5ee35 --- /dev/null +++ b/manual/manual/import-export-key-pair.md @@ -0,0 +1,100 @@ +# Import & Export Key Pair + +GpgFrontend provides multiple ways for users to import or export key paris. Here we will introduce some classic +operations. Read the guide. + +## Import Key Pair + +You can find the import options in the toolbar. You can choose several import methods according to your actual +situation. Let’s introduce these methods. + + + +In fact, you can find this action menu in key management, and here you can do more actions. + + + +### File + +When you select this option, you need to select a public key or private key file that meets the standard. The file you +choose should be in text format, with any extension. + +### Editor + +You can paste the contents of the key file on a blank text label page. Then click this option, GpgFrontend will +automatically recognize and import the corresponding key. + +### Clipboard + +You can copy the contents of the key to your system clipboard somewhere else. Then, after selecting this option, the +corresponding key will be imported. + +### Keyserver + +After selecting this option, you can enter the email or ID corresponding to the key in the pop-up selection, and then +select the appropriate key server. Then after clicking the search button, GpgFrontend will list the public keys that can +be imported in the key server. You can import them together, or you can choose to double-click the table row to import +the corresponding public key. Note: The keys imported in this way are all public keys. + +A detailed description of this part can be found [Here](./key-server-operations.md). + +### Dropdown on Key Toolbox + +You can drag the key file directly to the key toolbox, and then follow the prompts of GpgFrontend to import the key. + +## Export Key Pair + +Deriving the public key of a key pair with the private key means deriving either the public key or the private key or +both of all the keys present in the key pair. If there are very many keys in the key pair, the exported data will be +very long. Similar to import, there are multiple export methods. + +For Gpg Frontend, the exported data is encoded in ASCII, which ensures data compatibility between computers. + +### Export Public Key + +you can find this operation in many places.The following will introduce them one by one. + +#### Append Public Key to Editor + +Right-click a row in the key toolbox, and click Append Select Key(s) to Editor in the pop-up menu item. You will find +that the public key that the key is right appears at the end of your text label page. You can freely copy the content to +any place. + +#### Export on the Key Pair at Operations Tab + +You can do this as shown in the screenshot below, which will store the data to a file. Please select a suitable +directory to store this file containing the public key data before going anywhere. + + + +### Export multiple public keys at once + +You can export all public key data in multiple key pairs at one time, and you can select the key pairs you want to +export on the key management interface. Then, you can click Export to Clipboard. + + + +### Export Private Key + +You can find private key options everywhere in the detail's page that contains the private key (primary key or subkey). +Then you can select a location, and GpgFrontend will export the corresponding private key content to that location +later. + + + +Exporting the private key also exports the public key and private key data, because the private key data without the +public key is meaningless by itself, you cannot deduce the public key from the private key. + +Generally speaking, the private key content will be bundled with the public key content to export and export. Please +note: the private key file can never be disclosed to others. If it is leaked, it means that all ciphertexts encrypted by +the key are no longer safe. + +You can export the private key data in your key pair in two ways. + +1. Full export: Include all key data and UID and UID signature in the key pair. +2. Minimal export: Only all key data in the key pair is included. + +### Securely export and transfer as a Key Package + +You can package the private key data or public key data of multiple key pairs into a Key Package to allow them to be +securely transferred between your PC devices. This part of the function will be introduced in the feature.
\ No newline at end of file diff --git a/manual/manual/key-server-operations.md b/manual/manual/key-server-operations.md new file mode 100644 index 00000000..856b01e6 --- /dev/null +++ b/manual/manual/key-server-operations.md @@ -0,0 +1,113 @@ +# Key Server Operations + +You want to use encrypted communication, but in some cases, you only know the email address to which your message is +sent, but you don't know what the public key of the owner of the email address is. + +This is one situation, and another situation is that your key is accidentally leaked. How do you notify the person who +holds your public key to stop using your public key to continue sending you encrypted information? For these people, you +may not even know their names or contact information. In the above cases, you may be able to use the key server to +complete the sharing of key information. You can upload your public key information to the key server, or search or pull +the public key you need from the key server by email address and key ID. + +Once the public key information is uploaded to the key server, it will be transmitted between the key servers until +finally all the key servers store your public key for access by people all over the world. + +GpgFrontend provides the ability to interact with the key server. Through mouse operation, you can quickly use the key +server to share your public key, or search and import the public key you want. It should be noted that once the public +key information is uploaded to the key server, it means that the public key information cannot be deleted from the key +server and will always be retained. but when you add a subkey to your key pair, the public key of the old key pair can +be overwritten by updating. + +## Import Public Key From Key Server + +In the main page or in the key manager's Import key operation mode, there is a key server option. After selecting this +option you can see such an interface. + + + +You can get a list of public keys associated with a key server by searching for Key ID, fingerprint or email address via +the search box. If there is a suitable public key in the list, you can import it by double-clicking it. + + + +When the import is complete, you can check whether the public key is actually imported through the pop-up window (no +need to import when the local public key is newer), and you can also check some brief information about the public key. + + + +It is worth noting that the public key you imported may be expired or revoked. You can view the status of the key +through the category tab in the key management interface. In addition to the search box, you also noticed that you can +choose which key server to grab the public key information from by clicking on the drop-down box. How to set or add this +candidate list, please refer to the last section of this document: Key server related settings. + +## Export My Public Key To The Keyserver + +When the current key pair has a master key, you can publish the public key information to the key server. Note that in +order to be able to let users know what they are actually doing, GpgFrontend specifies that this can only be done if a +master key exists for the local key pair. This avoids confusion about the function. + +### How To Use + +You can find the entry of this operation through the operation tab of the key pair detail interface, as shown in the +following figure. + + + +Perform the operation by clicking Upload key pair to key server. Note that the naming of operations here is a bit +confusing, but this is where your public key information (not your private key) will be uploaded. + +### Synchronize public key information from a key server + +Sometimes, before you perform an encryption operation, you want to know if the public key you are using is still valid. +At this point, you can get the latest information about the key from the key server (if the public key server has one). + +As above, you can find this action in the Actions tab of the key pair details screen, as shown in the image below. + +### Extra Information + +Gpg Frontend will upload the public key information to the default key server you set. The private key information is +not uploaded and should not be manually uploaded anywhere by the user. + +Refer to the last section of this document on how to set the default key server. + + + +By clicking Synchronize key pair with key server, the public key information can be automatically pulled from the key +server and compared with the local key information. After the operation is complete, you can check in the pop-up window +whether the key has actually been updated. It is worth noting that you will not be able to perform this operation if the +private key exists locally, the reason is that you already have the key pair and you should publish the latest +information for the key pair instead of accepting outdated information from the key server . + +### Extra Information + +Gpg Frontend will automatically communicate with the default keyserver you set and get the information it wants. Refer +to the last section of this document on how to set the default key server. + +## Sync ALL Public Key + +This is an advanced function provided by Gpg Frontend, it can synchronize all your local public key information at one +time, if you want to know, please read [this document](../features/sync-all-public-keys.md). + +## Key Server Related Settings + +如何What about setting a list of keyservers? Or set a default keyserver? At this point, you need to open the Settings +interface and find the Key Servers tab. Here you can see operations related to the key server candidate list, and see +which key server is the default key server. + + + +You can enter the http or https address of the key server you want to add in the input box, and then click Add to add a +candidate key server. In order to prevent man-in-the-middle attacks, users are strongly recommended to use the https +protocol. If you want to delete a candidate key server, you can right-click the row of the corresponding key server in +the table and click Delete in the pop-up menu. If you want to edit an existing candidate key server address, you can +double-click its address in the table and edit it. + +If you want to test the network connectivity of the servers in the key server candidate list, you can click the Test +button at the bottom. Note that the test here only tells you if the keyserver is reachable, not whether the address is a +valid keyserver. + +### Set Default Key Server + +If you want to set a candidate key server as your default key server, you can right-click the row of the corresponding +key server in the table, and click Set as Default in the pop-up menu. You can see if a candidate keyserver is the +default keyserver in the first column of the table.
\ No newline at end of file diff --git a/manual/manual/sign-verify-file.md b/manual/manual/sign-verify-file.md new file mode 100755 index 00000000..b62d62ae --- /dev/null +++ b/manual/manual/sign-verify-file.md @@ -0,0 +1,48 @@ +# Sign & Verify File + +Gpg Frontend provides a convenient and fast way to operate on files. The concept of signing and verifying files is +almost the same as text, except that the input and output of file operations can be binary. + +## File Extension Introduction + +For ciphertext in ASCII format, its filename suffix is usually asc, and you can directly open such files with a text +editor. However, if the ciphertext is binary, its file extension will be sig or gpg. Usually, binary ciphertext files +are smaller than ASCII format. + +Before v2.0.4, the ciphertext files generated by GpgFrontend are all in ASCII format. But starting from v2.0.4, +GpgFrontend will generate ciphertext files in binary format by default. you can change this setting in settings. + + + +## File Browser + +In the top menu file option, you can open the file browser(Ctrl/Command + B). Then by using the file browser, first +enter your working directory. Then right-click the file you need to operate, and then select the operation you want in +the pop-up menu. + + + +There are two control buttons at the top of the file tab. The one on the left is the up level, and the one on the right +is to enter or refresh the corresponding path in the input box on the left. + +On the far right is a button with useful options that you can tick to show system files or hidden files. + + + +### Sign + +Through the right-click menu, you can quickly sign a file. This operation will generate a file with a sig or asc suffix, +which contains the signature content. In this case, you need to pass this file along with the original file so that the +other party can verify it. + + + +### Verify + +This operation needs to select a file with a gpg suffix (maybe invalid for the ciphertext of a binary file) or a file +with a sig suffix for verification. + +When selecting a file with the sig suffix, make sure that the source file is also in this directory. This means that the +name of the source file is just missing a sig suffix. + +
\ No newline at end of file diff --git a/manual/manual/sign-verify-text.md b/manual/manual/sign-verify-text.md new file mode 100644 index 00000000..f3ed699f --- /dev/null +++ b/manual/manual/sign-verify-text.md @@ -0,0 +1,46 @@ +# Sign & Verify Text + +In general, the process of signing and verifying is the reverse process of encryption and decryption. When signing, the +private key is used, and when verifying, the public key is used. And just like signing one name after another on a +document, multiple private keys can be selected when signing. But there are some differences. Digital signatures can be +used to verify whether the content of the signature has changed, while handwritten signatures are difficult to do. + +## Only Sign + +By signing the text, you can show that you are the only and unchangeable certification with this text. You can just sign +the text without encrypting the text like the following. + + + +To check whether the key can be used for signing, please check the usage column in the key toolbox on the right (letter +S stands for signature). + +## Sign With Encrypt + +You can also encrypt this short text while signing, which is equivalent to signing while encrypting. A typical usage +method is to check two key pairs, one is someone else's public key, which is used for encryption; the other is your own +private key, which is used for signing. If you do not check any key that can be used for signing, this is possible ( +equivalent to encryption only). The only difference is that you will receive a warning. + + + +## Verify + +After obtaining a plaintext and its signature, you can verify the signature. Please keep in mind that this form of +signature is not suitable for use in emails as it will make the email less readable, if you need to sign your email, +please use the "New Message" function to generate the OpenPGP/MIME format sign for your email. + + + +To verify a signature with text, you need to have the corresponding public key for all included signatures. If a +suitable public key for a signature is not found locally during verification, Gpg Frontend will remind you to import it. + + + +## Verify With Decrypt + +After obtaining a ciphertext, you can try to verify it while decrypting it. This is a good habit regardless of whether +the encryptor has signed in advance. Because you cannot infer from the format of the ciphertext whether it has been +signed or not. So, use decryption operations with verification whenever possible. + + diff --git a/manual/manual/understand-interface.md b/manual/manual/understand-interface.md new file mode 100644 index 00000000..fcbc269c --- /dev/null +++ b/manual/manual/understand-interface.md @@ -0,0 +1,134 @@ +# Understand Interface + +As a novice, you only need to quickly grasp the meaning of a few important parts of the page. You will gradually +discover other functions in the next exploration. The interface may not be the same for different versions. + + + +## Text Editor + +In the text editing area, you can type text at will. Or create a new tab through the New option in the top file menu. +Tabs can be moved, closed, and so on. + +You can operate your text through the options in the Operations Bar. Or you can use some common shortcuts(ctrl+c/v/s) to +copy-paste save or even find operations. + +The text edited in the text box is UTF8 encoded and does not have any formatting. Not providing any formatting (plain +text) ensures that the reality of redaction in a message is not confusing. I plan to join rich text editors in the +future, but the details are still under consideration. + +### Large text file support + +Here, GpgFrontend supports opening some of the larger files without being stuck. However, when opening a relatively +large file, you cannot edit this tab until the file has been totally read. Although this will make you unable to edit +the file, you can still view it. + +## Information Board + +The result of your operation on the current tab page will be printed in the Information Board: success or failure. In +addition to the success and failure information, its text will also contain other information to help you understand the +details of your encryption, decryption, signature and other operations. Depending on your language settings, the output +in the dashboard will vary. + +I used the information board as a solution to be able to display more information in the same space. In the future, a +graphical interface display of this information will be introduced, which can help users understand the actual role of +this information. + +### Font Color + +- **Green**: When the operation succeeds and the results of the operation are verified and no problems are found, the + font color will be green. +- **Yellow**: When the operation succeeds and there are some problems with the result testing of the operation at that + time, the font turns yellow, which is a reminder to the user. At this time, the user needs to check the details of the + operation. +- **Red**: When the operation is unsuccessful or there is a serious conflict with the result of the operation, the font + color will turn red, and the user will need to carefully check the details of the operation to ensure security. + +### Font Size + +When you feel that the font of the information board is too small, you can set the font size in the Application column +of the settings. The font size defaults to 10 and can be set to a range of between 9 and 18. + +### Information Board Actions Menu + +The dashboard actions menu provides some commonly used actions for information board content. This enables users to +quickly record large pieces of content in the Information Board for other uses. + +#### Copy + +This enables users to quickly record large pieces of content in the Information Board for other uses. + +#### Save File + +The operation stores the contents of the information board in the file system in UTF-8 format. Although the output file +does not have a suffix name, in fact this file is in plain text format. + +#### Clear + +This action immediately empties the information board. The empty operation includes the contents of the information +board and all the statuses. The emptying operation occurs automatically when you make the next operation (encryption, +etc.). + +### Optional Actions Menu + +There will also be a column of Optional Actions Menu below the Information Board. If there are other auxiliary +operations that can be done after your operation is completed (display more detailed information, send encrypted text +through email, etc.), the entry points for these auxiliary operations will be displayed here. + +## Key ToolBox + +Here is a list of key pairs stored on your machine that can be used for Gpg operations. The key lists in the Toolbox +have multiple categories that correspond to different usage scenarios. The toolbox also provides some commonly used +operations, all of which are in the Key List Menu. + +### Usage + +Most operations related to Gpg need to specify a key pair (such as encryption, decryption, signature, etc.). You can +select the check box in the first column of the table in the key toolbox to specify one or more keys for your operation. +Classifications that contain only public keys are often used in cryptographic scenarios. + +### Classification + +The Toolbox provides a categorical display through tabs. All classifications do not include all expired or revoked keys. +If you want to view expired or revoked keys, use the Key Manager. The default classification contains all private and +public keys. The operation takes only the key from the currently selected classification as input. + +### Columns + +It is important to understand this list. Now let me take you to understand it step by step. + +- Select: Turn the checkbox in this column to let Gpg Frontend know that you specify the key of this row for your next + operation. + +- Type: See this column to let you know the type of key and whether the primary key exists in your key pair. + - `pub` means this is a public key, Can be used for encryption or verification operations. + - `pub/sec` The key pair contains both public and private keys. It can be used for almost all operations(Need to + combine the usage column to determine this). + - `pub/sec#` The key pair contains a public key and a private key, but the primary key is not in the key pair. This + shows that you will not be able to do some special (add subkeys, sign other key pairs, etc.) + - `pub/sec^` A key pair has one or more keys (subkeys or master keys) in the smart card. + - `pub/sec#^`The above two situations occur at the same time. +- Name: The identity information of the key pair. +- Email Address: The identity information of the key pair. +- Usage: This determines which operations the key pair can use. Composed of four capital letters, each capital letter + represents a usage. + - `C` Certificate. Generally, the key pair that contains the primary key will have this usage + - `E` Encrypt. The key pair can be used for encryption operations. + - `S` Sign. The key pair can be used for sign operations. + - `A` Authenticate. The key pair can be used to perform operations like SSH authentication. + +- Validity: One of the concepts of Gpg, simply put it represents the degree of trust in this key. + +## Operations Bar + +Here, you can perform corresponding operations by clicking the buttons above. For example, after typing text in a text +editor and setting the key you want to use in the key toolbox, you can click the encryption button to perform the +operation. + +Some operations need to specify the key, and some are not used, which will be explained in other corresponding parts of +the document. + +### Customize + +Some operations you may not use for a long time, at which point you can uncheck the relevant function group in the view +of the top menu. Conversely, for some of the operations you use frequently, you can also add here.
\ No newline at end of file diff --git a/manual/manual/view-keypair-info.md b/manual/manual/view-keypair-info.md new file mode 100644 index 00000000..008f8d37 --- /dev/null +++ b/manual/manual/view-keypair-info.md @@ -0,0 +1,174 @@ +# View Key Pair Details + +Right-click the key pair in the key toolbox or key management interface and click Show key details to view the +information about the key pair. + +This part may involve a brief introduction to gpg-related concepts, and it will be relatively long. + +The screenshot below is my friend's public key that I got from the key server. + + + +Below is a private key I randomly generated. You can find that the biggest difference between him and the above is that +the key pair with only the public key is only used for encryption, and if you have the private key, you can do more +things (it also depends on your algorithm, DSA can only for signature). + + + +## General Info + +This interface provides some useful information to assist you in proper management of the key pair. + +### Owner + +Through this section, you can understand the owner of this key pair. This information is not fixed and unchangeable. You +can create a new UID in the UID section and set it as the main UID to change it. + +According to the OpenPGP protocol, this part is divided into Name, Email, and Comment. + + + +### Primary key + +This part is the information of the primary key of the key pair. The primary key is very important, because without it, +the key pair cannot perform related management operations such as adding and revoking sub-keys (similar to the key ring +cannot be opened). Let's introduce the information of the primary key separately below. If you want to learn more, see +the [Basic Concepts](../basic-concepts.md) section. + +The absence of the master key means that the private key of the master key does not exist, but neither the public key +nor the private key exists. Please remember: Each subkey and primary key consists of a pair of public and private keys. + + + +#### Key ID + +The unique identifier of the key is fixed and unchanging. Note that this key ID is the key ID of the primary key. The +key ID is uniquely determined after the key is generated. Compared with the fingerprint, the key ID will be shorter and +more user-friendly. + +#### Algorithm + +Algorithm used for key generation. Note that this also refers to the generation algorithm of the primary key. The +generation algorithm determines the properties and capabilities of the key. Algorithms such as RSA can be used for +encryption and signature, but DSA can only be used for signature, but the DSA key length can be shorter. + +#### Key Size + +The length of the primary key. It can be said that the longer the key, the harder it is to crack the ciphertext, but at +the same time, the more time it takes for a single operation. Generally speaking, a length of 2048 bits is safe enough ( +This refers to the key generated using the RSA algorithm). + +#### Normal Usage + +What can the key pair conceptually be used for (including the conceptual usage of the primary key and sub-key). When the +primary key or subkey generation can be used to sign, but it has already expired or does not exist, the signature usage +will still be displayed here. + +#### Actual Usage + +The actual usage of the primary key and all subkeys. It is the union of their usage. If there is only one primary key in +the key pair that can be used for signing, but this primary key does not exist. Then the signature usage will not appear +here, only in Normal Usage. In addition, when there is only one subkey that can be used for signing, if it has expired, +the signature purpose will not be displayed here. + +#### Expires on + +The expiration time of the primary key. When the primary key expires, it will be invalid. You cannot use it for any +operation. In addition, the subkeys in the key pair will also be unavailable. Fortunately, you can change the expiration +time of the primary key at any time, or even set it to never expire. The prerequisite for this is that the primary key +exists in the key pair. + +#### Last Update + +The time when the content of the key pair was last updated. Operations such as adding a UID or subkey will modify the +content of the key pair. + +#### Secret Key Existence + +Shows whether the actual content of the primary key exists. When the primary key does not exist, if there are still +available subkeys in the key pair, the key pair can still be used for normal operations. However, in the above case, the +content of the key pair cannot be modified (that is, operations such as adding UID or subkey cannot be performed), and +the key pair cannot sign other key pairs. + +### Fingerprint + + + +The fingerprint of the key pair is used for humans to quickly compare whether the key pair is the expected key pair. +This field is unique for all keys in the world. You can absolutely do this with the key ID mentioned above. + +This also refers to the fingerprint of the primary key. + +## UID Info + +UID is used to identify the key, and this mechanism is mainly used to facilitate human identification. You can compare +the UID to the accompanying name tag on a key ring, indicating who the key ring belongs to. Humans can roughly identify +whether a key pair is what he expected by looking at the UID, but to accurately identify it, fingerprints or key id need +to be compared. A key can have one or more UIDs. A key pair has one and only one primary UID. + +The primary UID on the interface is always the first in the list. + + + +UID has three elements, Name, Email, Comment. The name must be greater than or equal to five characters, and the email +must conform to the format. Comment rules are relatively loose. + +### Signature of UID + +The bottom half of the interface is the signature of the UID you checked in the list of UIDs (not checked in the box). + +This is a key trust system. The person who gets your public key actually gets a copy of your key ring, but only the +public key and your nameplate are on the key ring. He can sign your brand with his private key, which means he +recognizes your brand and the public key on the entire key ring. He can then upload the keyring with his signature to +the keyserver, and if a lot of people do this one after another, the public key on the keyserver will have a bunch of +signatures. If there are a lot of signatures on the nameplate, it means that many people recognize the public key and +endorse it, so that the public key can be trusted by everyone. + +You can use the primary key of another key pair to sign a UID. In repeating, in general. When the primary UID of a key +pair has many valid signatures attached, it will be more trustworthy than without a valid key pair. + +## Subkey Info + +The sub-key mechanism is an important content of gpg, which enhances flexibility and security, but also brings a certain +degree of complexity, making it difficult for beginners to understand.If you have absolutely no idea about this, you can +refer to the [Basic Concepts](../basic-concepts.md) section first. + + + +In order to help you understand this concept and get a preliminary grasp, you only need to read the following points: + +- A key pair can be compared to a key ring, with a primary key(a pair of public and private keys) and multiple subkeys ( + or no subkeys). +- Each subkey and primary key consists of a pair of public and private keys. +- The sub-key can do relate operations (such as signing, encryption) when the primary key is not present or cannot. +- The functions of the sub-keys can overlap. When both sub-keys can be used for signing, the earliest generated one is + selected for this operation. +- The sub-key can use more algorithms than the primary key, but generally they have the same effect on daily operations. +- The disclosure of the subkey only affects the subkey, and the entire key pair is in danger after the disclosure of the + primary key. + +The primary key and all subkeys in the key pair are listed on the interface. The first key in the list must be the main +key, regardless of whether it actually exists or not. Some information about the key is listed below. In fact, you can +know by observation that the information of the primary key here is exactly the same as the information of the first +tab. + +### Key In smart card + +Whether it is in the smart card refers to whether the key is moved to the smart card. Moving the key to the smart card +will change the structure of the key and is irreversible. + +### Operations + +In this column, what you can do is different for a key pair that has only a public key or a key pair that includes a +private key. + +Here's what you can do with a public key-only key pair. + + + +And the screenshot below lists what a key pair containing a private key can do. + + + +These operations will be scattered in the documentation to explain in detail. + diff --git a/manual/overview.md b/manual/overview.md new file mode 100644 index 00000000..197ab7f0 --- /dev/null +++ b/manual/overview.md @@ -0,0 +1,77 @@ +# Overview of GpgFrontend +--- + + + + +[](https://www.codacy.com/gh/saturneric/GpgFrontend/dashboard?utm_source=github.com&utm_medium=referral&utm_content=saturneric/GpgFrontend&utm_campaign=Badge_Grade) +[](https://app.fossa.com/projects/git%2Bgithub.com%2Fsaturneric%2FGpgFrontend?ref=badge_shield) + +**GpgFrontend** is a Powerful, Easy-to-Use, Compact, Cross-Platform, and +Installation-Free [OpenPGP](https://www.openpgp.org/) Crypto Tool. + +By using GpgFrontend, you can quickly encrypt and decrypt text or files. Or at the same time as the above operations, +you can add your own signature to let others know that this document or this paragraph of text was issued by you. + +Furthermore, it visualizes most of the common operations of gpg commands. It aims to allow ordinary users to quickly use +gpg and make professional users more convenient. GpgFrontend supports new features of GnuPG 2.x. + +**The corresponding release version for this +Document: [v2.0.4](https://github.com/saturneric/GpgFrontend/releases/tag/v2.0.4)** + +## Interface + +Note: For different operating system and system style settings, GpgFrontend may look different.Documentation can also +vary widely from release to release. Please check the corresponding program release version for the document. + + + +## Origin + +The GpgFrontend project inherit from a relatively mature but not maintained [gpg4usb](https://www.gpg4usb.org/) project. +It inherits the stable, easy-to-use, compact, and installation-free features of gpg4usb, and plans to support some new +features of OpenPGP based on it and continue to improve it. + +## Purpose + +Let more people all over the world (even if they don't know the command line and programming) can use GnuPG to safely +send information to the destination in a safe way. Free software belongs to the common wealth of all mankind, but there +are still many people who cannot use these wealths due to the limitation of knowledge and usage habits. We should break +this pattern. GpgFrontend is committed to improving the ease of use and intuitiveness of the free software GnuPG, so +that more and more people can use it. + +The GpgFrontend project is as open source, and it also insists on using open source codes and libraries. + +### Free forever + +GpgFrontend will be free forever, and you don't need to worry about being asked to pay a fee to use the software one +day. + +## Source Code + +The original code repository of Gpg Frontend is hosted on the server of Codes Dream, and each submission will be +submitted to the code repository first. You can click [Here](https://global.git.codesdream.com/GpgFrontend.git) to visit +the original code repository and track development progress. + +注意:中国用户请访问[这里](https://git.codesdream.com/GpgFrontend.git) + +### License + +GpgFrontend source code is under a GPL-3.0 license, which means that GpgFrontend is free software. You may exercise the +rights set forth in the Licence under the conditions of compliance with the rules of the Licence. + +### Contribution + +At the same time, the addition of new functions does not affect the old basic functions. My personal strength is always +limited. GpgFrontend welcomes volunteers to join. You can use the GitHub platform to file an issue, or submit a pull +request. + +You can also submit questions and code contributions by email, please send me problem reports and patches. + +## Privacy Guarantee + +GpgFrontend has no servers and does not require servers to run. In addition to the public key transfers allowed by the +OpenPGP protocol to the public key server unexpectedly, GpgFrontend does not collect and upload any additional +information. + +For users with high security requirements, a version with no Internet access capability will be available in the future.
\ No newline at end of file diff --git a/manual/quick-start.md b/manual/quick-start.md new file mode 100644 index 00000000..f3850100 --- /dev/null +++ b/manual/quick-start.md @@ -0,0 +1,123 @@ +# Quick Start + +Getting started with GpgFrontend is very simple, you only need a few very simple steps. Moreover, it is oriented to all +PC platforms. + +## Get channels + +The current mainstream distribution channel is the Release feature available through GitHub. It's free and accessible to +most people in the world, without me having to worry about servers and bandwidth, which allows me to save a lot of +money. + +When you click on the [download](https://github.com/saturneric/GpgFrontend/releases/latest), you can see such an +interface. It identifies the current version number of the latest release, the release date of that version, and so on. + + + +You can see some notable features or fixes for the version in the main text, or if you're a programmer, you can also +click change log to get how the source code differs from the previous version. It is worth mentioning that you can see +two green tick marks, which represent that I have personally signed up to the source code of the version. This may be +important for some people with high security needs. + +Then, if you swipe down, you can see a lot of Assets, which are releases for GpgFrontned for different operating +systems. As you can see, the parts of the file name are separated by separators. You need to know that the second +section(e.g. 6171479) provides a unique identification number for the version's source code, and when pointing out +problems with a version, you need to provide the 7-digit unique identification number of the released version you are +using. + + + +Files with sig as the suffix are gpg separate signatures for the released version of the file of the same name. You can +use gpg to check if the changed file is signed and approved by me. + +Follow your needs or follow the instructions below to click on the name of the corresponding release version to +download. + +## Install & Run + +GpgFrontend is cross-platform, which is one of its differences. For your operating system, you'll need to choose +different ways to lay out GpgFrontend. It is worth noting that GpgFrontend only supports 64-bit operating systems. +Please check your hardware with your operating system. + +### Pre-conditions + +GpgFrontend runs dependent on the basic features provided by GnuPG, so you need to install GnuPG before you can install +GpgFrontend. Why does GpgFronend require users to install GnuPG separately?Starting with GnuPG 2.0, gpg relies on +separate modules to do all of its functions. This requires that when using gpg, these modules all need to be in the +correct location on your operating system so that the gpg can find them. + +GnuPG is not included by default in some operating systems (e.g. Windows and macOS), so this situation has caused +GpgFrontend to be temporarily unavailable in the Apple Store and Microsoft Store. I have plans to launch GnuPG-based +version 1.4 in the future, which will enable GpgFrontend users to start using it when they get it. + +In general, the latest Linux distributions offer a GnuPG 2.0 environment. You can check by typing `gpg --version` in the +command line tool. **In general, it is recommended to install versions of GnuPG 2.1 and above.** + +### Windows (No Setup) + +0. If you haven't installed gnupg, + please [Download](https://gnupg.org/ftp/gcrypt/binary/gnupg-w32-2.3.1_20210420.exe) `gnupg-w32-******.exe` and + install it. +1. [Download](https://github.com/saturneric/GpgFrontend/releases/latest)`GpgFrontend-*******-Windows-NoSetup.zip` +2. Unzip `GpgFrontend-*******-Windows-NoSetup.zip` +3. Go into the directory and double click `GpgFrontend.exe`. + +### Windows(Setup) + +1. [Download](https://github.com/saturneric/GpgFrontend/releases/latest) `GpgFrontend-*******-Windows-Setup.exe` +2. Install it and you can find GpgFrontend on your desktop. + +### macOS + +1. [Download](https://github.com/saturneric/GpgFrontend/releases) `GpgFrontend-*******-x86_64.dmg` +2. Double-Click GpgFrontend.dmg to load it + - macOS will automatically decompress the zip file and then you will be able to see the dmg +3. Double click and run it. All published app packages have passed Apple's check, which means you can open it directly. +4. If it satisfies you, you can drag it into your Application folder. + +#### Debian/Ubuntu/CentOS (AppImage) + +AppImage is a format used in Linux systems to distribute portable software without the need for superuser privileges to +install them. The core idea of AppImage is a file as an application. Each AppImage contains the application and all the +files needed for the application to run. In other words, in addition to the underlying components of the operating +system itself, AppImage runs without dependency. This is convenient for users. + +0. Install gnupg (If you have already followed please skip) + - For Debian/Ubuntu + ```shell + $ sudo apt update + $ sudo apt install gpg + ``` + - For CentOS + ```shell + $ sudo yum install gnupg + ``` +1. [Download](https://github.com/saturneric/GpgFrontend/releases) `GpgFrontend-*******-x86_64.AppImage` +2. Give `GpgFrontend-***.AppImage` permission to execute + ```shell + $ chmod u+x ./GpgFrontend-***-x86_64.AppImage + ``` +3. Just double-click `GpgFrontend-***-x86_64.AppImage` to run it. + +### Debian/Ubuntu (DEB) + +With deb, you can easily manage dependencies using the apt tool. Deb packages are small compared to AppImage. + +0. Install gnupg (If you have already followed please skip) + + - For Debian/Ubuntu + + ```shell + $ sudo apt update + $ sudo apt install gpg + ``` + +1. [Download](https://github.com/saturneric/GpgFrontend/releases) `GpgFrontend-*******-x86_64.deb` + +2. Use apt to install GpgFrontned. + + ```shell + $ apt install ./GpgFrontend-*******-x86_64.deb + ``` + +3. At this point, you can find the GpgFrontend icon in your app menu.
\ No newline at end of file diff --git a/manual/translate-interface.md b/manual/translate-interface.md new file mode 100644 index 00000000..0238835c --- /dev/null +++ b/manual/translate-interface.md @@ -0,0 +1,37 @@ +# Translate Interface + +GpgFrontend is designed to support multiple languages, but requires volunteer contributions to achieve this goal. +Fortunately, translation work does not require an understanding of difficult technology. Volunteers only need to move +their fingers to complete. + +There are two ways to translate, through a translation tool with a GUI interface or directly through a text editor. + +## What you need to know about translation work + +From v2.0.1, Gpg Frontend uses the popular translation support +library [GNU gettext](https://www.gnu.org/software/gettext/) in the GNU project. Before starting everything, you need to +know something about this library. After you are sure about the content of the document, you can first try to see how +GpgFrontned uses the tools provided by this library. + +### Facts + +Most of the translation work is carried out by Google Translate. In most cases, what you have to do is to correct some +of the bad aspects of Google Translate. + +## About translation files + +1. Download or clone source code [Here](https://github.com/saturneric/GpgFrontend) +2. You will find some po files(.po) at path `resource/locale/po` +2. You will find some template file(.pot) at path `resource/locale/template` + +## Before starting your work + +In order to facilitate coordination, please contact me via email before you start this work. This is very important, +please contact me first so that the work you do can be better used by GpgFrontend. + +## Hand in your work + +You can submit your great work in two ways: + +1. Raise a pull request and merge the changed translation file(s) to the repository. +2. [Email ME](mailto:[email protected]). Please attach the changed ts file on the email.
\ No newline at end of file diff --git a/resource/certs/02265526.0 b/resource/certs/02265526.0 new file mode 100644 index 00000000..2e23a605 --- /dev/null +++ b/resource/certs/02265526.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- diff --git a/resource/certs/03179a64.0 b/resource/certs/03179a64.0 new file mode 100644 index 00000000..315f6658 --- /dev/null +++ b/resource/certs/03179a64.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- diff --git a/resource/certs/062cdee6.0 b/resource/certs/062cdee6.0 new file mode 100644 index 00000000..8afb2190 --- /dev/null +++ b/resource/certs/062cdee6.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- diff --git a/resource/certs/064e0aa9.0 b/resource/certs/064e0aa9.0 new file mode 100644 index 00000000..df5a27fa --- /dev/null +++ b/resource/certs/064e0aa9.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- diff --git a/resource/certs/06dc52d5.0 b/resource/certs/06dc52d5.0 new file mode 100644 index 00000000..14c92c44 --- /dev/null +++ b/resource/certs/06dc52d5.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- diff --git a/resource/certs/080911ac.0 b/resource/certs/080911ac.0 new file mode 100644 index 00000000..ffa4dbe4 --- /dev/null +++ b/resource/certs/080911ac.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- diff --git a/resource/certs/09789157.0 b/resource/certs/09789157.0 new file mode 100644 index 00000000..f7519150 --- /dev/null +++ b/resource/certs/09789157.0 @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- diff --git a/resource/certs/0a775a30.0 b/resource/certs/0a775a30.0 new file mode 100644 index 00000000..7d540a41 --- /dev/null +++ b/resource/certs/0a775a30.0 @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- diff --git a/resource/certs/0b1b94ef.0 b/resource/certs/0b1b94ef.0 new file mode 100644 index 00000000..198d1bf2 --- /dev/null +++ b/resource/certs/0b1b94ef.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- diff --git a/resource/certs/0bf05006.0 b/resource/certs/0bf05006.0 new file mode 100644 index 00000000..e20d85cb --- /dev/null +++ b/resource/certs/0bf05006.0 @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- diff --git a/resource/certs/0c31d5ce b/resource/certs/0c31d5ce new file mode 100644 index 00000000..b92f351b --- /dev/null +++ b/resource/certs/0c31d5ce @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbigAwIBAgIUSzh1ULkST6atWX943hjSit8Qf30wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGdWJ1bnR1MB4XDTIxMTEyMjAzMTgxNVoXDTMxMTEyMDAz +MTgxNVowETEPMA0GA1UEAwwGdWJ1bnR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxO7yD9njwu0flf4fNGhizU6s3vp/SyITjiMn/SXH5QQ90JorkNeI +/PflDWFZcZTiz4foCSgezb5LBiqk9z+DLfYxqgT75A3CEV2xiP7kbIUSr9bIw+KJ +pKVvV9Dio0XaKB9383zOY1YgCFJc27WZPukzP9w4cWlAeWYKO60ZPa10LQ8pzIHk +o0bCzLkjq6dzJB7CynQ8Fr+/TLiGKE8k2lTAkDfFDAua4HYr4XeWusRlEvR+wTVQ +8EbKUvCUrqFXO0XNb/I8Gst+88Fa/cMYhchc+Xf+PeSXLbEehtuphik4bVyVWlFO +NrgPuvl5a0Z5OMI3HfEf1Wt53sru1TbceQIDAQABoyAwHjAJBgNVHRMEAjAAMBEG +A1UdEQQKMAiCBnVidW50dTANBgkqhkiG9w0BAQsFAAOCAQEAeNJJEc6hp6/cWRV2 +5AQsVv5LY9BGBoCuoaZ1CqzLDxsnEyZwYGw/IzDiNXwCoFv7pAAwFgPd5yiES68L +7VY1BzwA03EgT4O7U9iTfkS/Q7J1lG9VodKVtpl5QmRDyQduz5EMQnQZX/a1whH1 +Pa5OvUwQdMACiygPfQDeC/6sPvbr6iC5YYwpLHAJSexQQ6b921WxtcQ8SXCA+IsL +MJ12qQnQZSS4KoTVnFAT4OtcMhxvEfUgSPOFQUSEyVKHW4DJii12TdBnm/T3XIHO +dDvegXT322H0A7UCaQkD0TzVQD3npZMyF4YDD8Nac1uETgxhtfYSaIsAswsEKni0 +M2Okyw== +-----END CERTIFICATE----- diff --git a/resource/certs/0c4c9b6c.0 b/resource/certs/0c4c9b6c.0 new file mode 100644 index 00000000..70b4ce41 --- /dev/null +++ b/resource/certs/0c4c9b6c.0 @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- diff --git a/resource/certs/0f5dc4f3.0 b/resource/certs/0f5dc4f3.0 new file mode 100644 index 00000000..04c38ff9 --- /dev/null +++ b/resource/certs/0f5dc4f3.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- diff --git a/resource/certs/0f6fa695.0 b/resource/certs/0f6fa695.0 new file mode 100644 index 00000000..4dd1c718 --- /dev/null +++ b/resource/certs/0f6fa695.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- diff --git a/resource/certs/1001acf7.0 b/resource/certs/1001acf7.0 new file mode 100644 index 00000000..54967036 --- /dev/null +++ b/resource/certs/1001acf7.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- diff --git a/resource/certs/106f3e4d.0 b/resource/certs/106f3e4d.0 new file mode 100644 index 00000000..b2043ac3 --- /dev/null +++ b/resource/certs/106f3e4d.0 @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- diff --git a/resource/certs/116bf586.0 b/resource/certs/116bf586.0 new file mode 100644 index 00000000..f9364c08 --- /dev/null +++ b/resource/certs/116bf586.0 @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- diff --git a/resource/certs/14bc7599.0 b/resource/certs/14bc7599.0 new file mode 100644 index 00000000..060e943b --- /dev/null +++ b/resource/certs/14bc7599.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- diff --git a/resource/certs/1636090b.0 b/resource/certs/1636090b.0 new file mode 100644 index 00000000..5ecc81c3 --- /dev/null +++ b/resource/certs/1636090b.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- diff --git a/resource/certs/18856ac4.0 b/resource/certs/18856ac4.0 new file mode 100644 index 00000000..aff52a8e --- /dev/null +++ b/resource/certs/18856ac4.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- diff --git a/resource/certs/1c7314a2 b/resource/certs/1c7314a2 new file mode 100644 index 00000000..b92f351b --- /dev/null +++ b/resource/certs/1c7314a2 @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbigAwIBAgIUSzh1ULkST6atWX943hjSit8Qf30wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGdWJ1bnR1MB4XDTIxMTEyMjAzMTgxNVoXDTMxMTEyMDAz +MTgxNVowETEPMA0GA1UEAwwGdWJ1bnR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxO7yD9njwu0flf4fNGhizU6s3vp/SyITjiMn/SXH5QQ90JorkNeI +/PflDWFZcZTiz4foCSgezb5LBiqk9z+DLfYxqgT75A3CEV2xiP7kbIUSr9bIw+KJ +pKVvV9Dio0XaKB9383zOY1YgCFJc27WZPukzP9w4cWlAeWYKO60ZPa10LQ8pzIHk +o0bCzLkjq6dzJB7CynQ8Fr+/TLiGKE8k2lTAkDfFDAua4HYr4XeWusRlEvR+wTVQ +8EbKUvCUrqFXO0XNb/I8Gst+88Fa/cMYhchc+Xf+PeSXLbEehtuphik4bVyVWlFO +NrgPuvl5a0Z5OMI3HfEf1Wt53sru1TbceQIDAQABoyAwHjAJBgNVHRMEAjAAMBEG +A1UdEQQKMAiCBnVidW50dTANBgkqhkiG9w0BAQsFAAOCAQEAeNJJEc6hp6/cWRV2 +5AQsVv5LY9BGBoCuoaZ1CqzLDxsnEyZwYGw/IzDiNXwCoFv7pAAwFgPd5yiES68L +7VY1BzwA03EgT4O7U9iTfkS/Q7J1lG9VodKVtpl5QmRDyQduz5EMQnQZX/a1whH1 +Pa5OvUwQdMACiygPfQDeC/6sPvbr6iC5YYwpLHAJSexQQ6b921WxtcQ8SXCA+IsL +MJ12qQnQZSS4KoTVnFAT4OtcMhxvEfUgSPOFQUSEyVKHW4DJii12TdBnm/T3XIHO +dDvegXT322H0A7UCaQkD0TzVQD3npZMyF4YDD8Nac1uETgxhtfYSaIsAswsEKni0 +M2Okyw== +-----END CERTIFICATE----- diff --git a/resource/certs/1c7314a2.0 b/resource/certs/1c7314a2.0 new file mode 100644 index 00000000..b92f351b --- /dev/null +++ b/resource/certs/1c7314a2.0 @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbigAwIBAgIUSzh1ULkST6atWX943hjSit8Qf30wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGdWJ1bnR1MB4XDTIxMTEyMjAzMTgxNVoXDTMxMTEyMDAz +MTgxNVowETEPMA0GA1UEAwwGdWJ1bnR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxO7yD9njwu0flf4fNGhizU6s3vp/SyITjiMn/SXH5QQ90JorkNeI +/PflDWFZcZTiz4foCSgezb5LBiqk9z+DLfYxqgT75A3CEV2xiP7kbIUSr9bIw+KJ +pKVvV9Dio0XaKB9383zOY1YgCFJc27WZPukzP9w4cWlAeWYKO60ZPa10LQ8pzIHk +o0bCzLkjq6dzJB7CynQ8Fr+/TLiGKE8k2lTAkDfFDAua4HYr4XeWusRlEvR+wTVQ +8EbKUvCUrqFXO0XNb/I8Gst+88Fa/cMYhchc+Xf+PeSXLbEehtuphik4bVyVWlFO +NrgPuvl5a0Z5OMI3HfEf1Wt53sru1TbceQIDAQABoyAwHjAJBgNVHRMEAjAAMBEG +A1UdEQQKMAiCBnVidW50dTANBgkqhkiG9w0BAQsFAAOCAQEAeNJJEc6hp6/cWRV2 +5AQsVv5LY9BGBoCuoaZ1CqzLDxsnEyZwYGw/IzDiNXwCoFv7pAAwFgPd5yiES68L +7VY1BzwA03EgT4O7U9iTfkS/Q7J1lG9VodKVtpl5QmRDyQduz5EMQnQZX/a1whH1 +Pa5OvUwQdMACiygPfQDeC/6sPvbr6iC5YYwpLHAJSexQQ6b921WxtcQ8SXCA+IsL +MJ12qQnQZSS4KoTVnFAT4OtcMhxvEfUgSPOFQUSEyVKHW4DJii12TdBnm/T3XIHO +dDvegXT322H0A7UCaQkD0TzVQD3npZMyF4YDD8Nac1uETgxhtfYSaIsAswsEKni0 +M2Okyw== +-----END CERTIFICATE----- diff --git a/resource/certs/1d3472b9.0 b/resource/certs/1d3472b9.0 new file mode 100644 index 00000000..111991b2 --- /dev/null +++ b/resource/certs/1d3472b9.0 @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- diff --git a/resource/certs/1e08bfd1.0 b/resource/certs/1e08bfd1.0 new file mode 100644 index 00000000..38093391 --- /dev/null +++ b/resource/certs/1e08bfd1.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- diff --git a/resource/certs/1e09d511.0 b/resource/certs/1e09d511.0 new file mode 100644 index 00000000..98fceb25 --- /dev/null +++ b/resource/certs/1e09d511.0 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- diff --git a/resource/certs/244b5494.0 b/resource/certs/244b5494.0 new file mode 100644 index 00000000..9e6810ab --- /dev/null +++ b/resource/certs/244b5494.0 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- diff --git a/resource/certs/2923b3f9.0 b/resource/certs/2923b3f9.0 new file mode 100644 index 00000000..c50d2e6d --- /dev/null +++ b/resource/certs/2923b3f9.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- diff --git a/resource/certs/2ae6433e.0 b/resource/certs/2ae6433e.0 new file mode 100644 index 00000000..0d94600e --- /dev/null +++ b/resource/certs/2ae6433e.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- diff --git a/resource/certs/2b349938.0 b/resource/certs/2b349938.0 new file mode 100644 index 00000000..73a33674 --- /dev/null +++ b/resource/certs/2b349938.0 @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- diff --git a/resource/certs/32888f65.0 b/resource/certs/32888f65.0 new file mode 100644 index 00000000..2cc7e068 --- /dev/null +++ b/resource/certs/32888f65.0 @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- diff --git a/resource/certs/349f2832.0 b/resource/certs/349f2832.0 new file mode 100644 index 00000000..87a13f62 --- /dev/null +++ b/resource/certs/349f2832.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- diff --git a/resource/certs/3513523f.0 b/resource/certs/3513523f.0 new file mode 100644 index 00000000..fd4341df --- /dev/null +++ b/resource/certs/3513523f.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/resource/certs/3bde41ac.0 b/resource/certs/3bde41ac.0 new file mode 100644 index 00000000..de97f841 --- /dev/null +++ b/resource/certs/3bde41ac.0 @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- diff --git a/resource/certs/3e44d2f7.0 b/resource/certs/3e44d2f7.0 new file mode 100644 index 00000000..aa392abc --- /dev/null +++ b/resource/certs/3e44d2f7.0 @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- diff --git a/resource/certs/3e45d192.0 b/resource/certs/3e45d192.0 new file mode 100644 index 00000000..a28e9a0e --- /dev/null +++ b/resource/certs/3e45d192.0 @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- diff --git a/resource/certs/3fb36b73.0 b/resource/certs/3fb36b73.0 new file mode 100644 index 00000000..59f8ce3e --- /dev/null +++ b/resource/certs/3fb36b73.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- diff --git a/resource/certs/40193066.0 b/resource/certs/40193066.0 new file mode 100644 index 00000000..126e948a --- /dev/null +++ b/resource/certs/40193066.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- diff --git a/resource/certs/4042bcee.0 b/resource/certs/4042bcee.0 new file mode 100644 index 00000000..b85c8037 --- /dev/null +++ b/resource/certs/4042bcee.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/resource/certs/40547a79.0 b/resource/certs/40547a79.0 new file mode 100644 index 00000000..6146dcb5 --- /dev/null +++ b/resource/certs/40547a79.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- diff --git a/resource/certs/406c9bb1.0 b/resource/certs/406c9bb1.0 new file mode 100644 index 00000000..02bd4a71 --- /dev/null +++ b/resource/certs/406c9bb1.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- diff --git a/resource/certs/4304c5e5.0 b/resource/certs/4304c5e5.0 new file mode 100644 index 00000000..11289bcd --- /dev/null +++ b/resource/certs/4304c5e5.0 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- diff --git a/resource/certs/48bec511.0 b/resource/certs/48bec511.0 new file mode 100644 index 00000000..a04e656d --- /dev/null +++ b/resource/certs/48bec511.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- diff --git a/resource/certs/4a6481c9.0 b/resource/certs/4a6481c9.0 new file mode 100644 index 00000000..6f0f8db0 --- /dev/null +++ b/resource/certs/4a6481c9.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- diff --git a/resource/certs/4b718d9b.0 b/resource/certs/4b718d9b.0 new file mode 100644 index 00000000..517c0e1c --- /dev/null +++ b/resource/certs/4b718d9b.0 @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- diff --git a/resource/certs/4bfab552.0 b/resource/certs/4bfab552.0 new file mode 100644 index 00000000..c1a0a481 --- /dev/null +++ b/resource/certs/4bfab552.0 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- diff --git a/resource/certs/4f316efb.0 b/resource/certs/4f316efb.0 new file mode 100644 index 00000000..d7211878 --- /dev/null +++ b/resource/certs/4f316efb.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- diff --git a/resource/certs/5273a94c.0 b/resource/certs/5273a94c.0 new file mode 100644 index 00000000..97485999 --- /dev/null +++ b/resource/certs/5273a94c.0 @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- diff --git a/resource/certs/5443e9e3.0 b/resource/certs/5443e9e3.0 new file mode 100644 index 00000000..e068f844 --- /dev/null +++ b/resource/certs/5443e9e3.0 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- diff --git a/resource/certs/54657681.0 b/resource/certs/54657681.0 new file mode 100644 index 00000000..9daec241 --- /dev/null +++ b/resource/certs/54657681.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- diff --git a/resource/certs/57bcb2da.0 b/resource/certs/57bcb2da.0 new file mode 100644 index 00000000..67a172cb --- /dev/null +++ b/resource/certs/57bcb2da.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- diff --git a/resource/certs/5a4d6896.0 b/resource/certs/5a4d6896.0 new file mode 100644 index 00000000..bc6a756f --- /dev/null +++ b/resource/certs/5a4d6896.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- diff --git a/resource/certs/5ad8a5d6.0 b/resource/certs/5ad8a5d6.0 new file mode 100644 index 00000000..f4ce4ca4 --- /dev/null +++ b/resource/certs/5ad8a5d6.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- diff --git a/resource/certs/5cd81ad7.0 b/resource/certs/5cd81ad7.0 new file mode 100644 index 00000000..8bc52c39 --- /dev/null +++ b/resource/certs/5cd81ad7.0 @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- diff --git a/resource/certs/5d3033c5.0 b/resource/certs/5d3033c5.0 new file mode 100644 index 00000000..23969fe3 --- /dev/null +++ b/resource/certs/5d3033c5.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- diff --git a/resource/certs/5e98733a.0 b/resource/certs/5e98733a.0 new file mode 100644 index 00000000..7ac10cc3 --- /dev/null +++ b/resource/certs/5e98733a.0 @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- diff --git a/resource/certs/5f15c80c.0 b/resource/certs/5f15c80c.0 new file mode 100644 index 00000000..fd06b8c3 --- /dev/null +++ b/resource/certs/5f15c80c.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- diff --git a/resource/certs/5f618aec.0 b/resource/certs/5f618aec.0 new file mode 100644 index 00000000..573ec331 --- /dev/null +++ b/resource/certs/5f618aec.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- diff --git a/resource/certs/607986c7.0 b/resource/certs/607986c7.0 new file mode 100644 index 00000000..798e0027 --- /dev/null +++ b/resource/certs/607986c7.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- diff --git a/resource/certs/626dceaf.0 b/resource/certs/626dceaf.0 new file mode 100644 index 00000000..984f1d18 --- /dev/null +++ b/resource/certs/626dceaf.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- diff --git a/resource/certs/653b494a.0 b/resource/certs/653b494a.0 new file mode 100644 index 00000000..519028c6 --- /dev/null +++ b/resource/certs/653b494a.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- diff --git a/resource/certs/68dd7389.0 b/resource/certs/68dd7389.0 new file mode 100644 index 00000000..22c7c73a --- /dev/null +++ b/resource/certs/68dd7389.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- diff --git a/resource/certs/6b99d060.0 b/resource/certs/6b99d060.0 new file mode 100644 index 00000000..855485cf --- /dev/null +++ b/resource/certs/6b99d060.0 @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- diff --git a/resource/certs/6d41d539.0 b/resource/certs/6d41d539.0 new file mode 100644 index 00000000..efe3c9fe --- /dev/null +++ b/resource/certs/6d41d539.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- diff --git a/resource/certs/6fa5da56.0 b/resource/certs/6fa5da56.0 new file mode 100644 index 00000000..77ec988e --- /dev/null +++ b/resource/certs/6fa5da56.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- diff --git a/resource/certs/706f604c.0 b/resource/certs/706f604c.0 new file mode 100644 index 00000000..f21e6d8b --- /dev/null +++ b/resource/certs/706f604c.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- diff --git a/resource/certs/749e9e03.0 b/resource/certs/749e9e03.0 new file mode 100644 index 00000000..2f89a044 --- /dev/null +++ b/resource/certs/749e9e03.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- diff --git a/resource/certs/75d1b2ed.0 b/resource/certs/75d1b2ed.0 new file mode 100644 index 00000000..42142274 --- /dev/null +++ b/resource/certs/75d1b2ed.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- diff --git a/resource/certs/76cb8f92.0 b/resource/certs/76cb8f92.0 new file mode 100644 index 00000000..edbeb27e --- /dev/null +++ b/resource/certs/76cb8f92.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- diff --git a/resource/certs/76faf6c0.0 b/resource/certs/76faf6c0.0 new file mode 100644 index 00000000..bda7b1aa --- /dev/null +++ b/resource/certs/76faf6c0.0 @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- diff --git a/resource/certs/7719f463.0 b/resource/certs/7719f463.0 new file mode 100644 index 00000000..5e5bc74c --- /dev/null +++ b/resource/certs/7719f463.0 @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- diff --git a/resource/certs/773e07ad.0 b/resource/certs/773e07ad.0 new file mode 100644 index 00000000..a9dcb26e --- /dev/null +++ b/resource/certs/773e07ad.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- diff --git a/resource/certs/7aaf71c0.0 b/resource/certs/7aaf71c0.0 new file mode 100644 index 00000000..ba7bddb8 --- /dev/null +++ b/resource/certs/7aaf71c0.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- diff --git a/resource/certs/7f3d5d1d.0 b/resource/certs/7f3d5d1d.0 new file mode 100644 index 00000000..244c99b2 --- /dev/null +++ b/resource/certs/7f3d5d1d.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- diff --git a/resource/certs/8160b96c.0 b/resource/certs/8160b96c.0 new file mode 100644 index 00000000..aa844e75 --- /dev/null +++ b/resource/certs/8160b96c.0 @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- diff --git a/resource/certs/8cb5ee0f.0 b/resource/certs/8cb5ee0f.0 new file mode 100644 index 00000000..a45da707 --- /dev/null +++ b/resource/certs/8cb5ee0f.0 @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- diff --git a/resource/certs/8d86cdd1.0 b/resource/certs/8d86cdd1.0 new file mode 100644 index 00000000..0a38740b --- /dev/null +++ b/resource/certs/8d86cdd1.0 @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- diff --git a/resource/certs/8d89cda1.0 b/resource/certs/8d89cda1.0 new file mode 100644 index 00000000..e3be2a5b --- /dev/null +++ b/resource/certs/8d89cda1.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- diff --git a/resource/certs/930ac5d2.0 b/resource/certs/930ac5d2.0 new file mode 100644 index 00000000..5762f37e --- /dev/null +++ b/resource/certs/930ac5d2.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- diff --git a/resource/certs/93bc0acc.0 b/resource/certs/93bc0acc.0 new file mode 100644 index 00000000..04f4a812 --- /dev/null +++ b/resource/certs/93bc0acc.0 @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- diff --git a/resource/certs/988a38cb.0 b/resource/certs/988a38cb.0 new file mode 100644 index 00000000..56b9ee47 --- /dev/null +++ b/resource/certs/988a38cb.0 @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- diff --git a/resource/certs/9b5697b0.0 b/resource/certs/9b5697b0.0 new file mode 100644 index 00000000..8f308f54 --- /dev/null +++ b/resource/certs/9b5697b0.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- diff --git a/resource/certs/9c2e7d30.0 b/resource/certs/9c2e7d30.0 new file mode 100644 index 00000000..36a998d2 --- /dev/null +++ b/resource/certs/9c2e7d30.0 @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- diff --git a/resource/certs/9c8dfbd4.0 b/resource/certs/9c8dfbd4.0 new file mode 100644 index 00000000..4bcc6a43 --- /dev/null +++ b/resource/certs/9c8dfbd4.0 @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- diff --git a/resource/certs/9d04f354.0 b/resource/certs/9d04f354.0 new file mode 100644 index 00000000..fc60fb51 --- /dev/null +++ b/resource/certs/9d04f354.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- diff --git a/resource/certs/ACCVRAIZ1.pem b/resource/certs/ACCVRAIZ1.pem new file mode 100644 index 00000000..baf74db7 --- /dev/null +++ b/resource/certs/ACCVRAIZ1.pem @@ -0,0 +1,44 @@ +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- diff --git a/resource/certs/AC_RAIZ_FNMT-RCM.pem b/resource/certs/AC_RAIZ_FNMT-RCM.pem new file mode 100644 index 00000000..666cf67c --- /dev/null +++ b/resource/certs/AC_RAIZ_FNMT-RCM.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- diff --git a/resource/certs/Actalis_Authentication_Root_CA.pem b/resource/certs/Actalis_Authentication_Root_CA.pem new file mode 100644 index 00000000..5762f37e --- /dev/null +++ b/resource/certs/Actalis_Authentication_Root_CA.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- diff --git a/resource/certs/AffirmTrust_Commercial.pem b/resource/certs/AffirmTrust_Commercial.pem new file mode 100644 index 00000000..73a33674 --- /dev/null +++ b/resource/certs/AffirmTrust_Commercial.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- diff --git a/resource/certs/AffirmTrust_Networking.pem b/resource/certs/AffirmTrust_Networking.pem new file mode 100644 index 00000000..04f4a812 --- /dev/null +++ b/resource/certs/AffirmTrust_Networking.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- diff --git a/resource/certs/AffirmTrust_Premium.pem b/resource/certs/AffirmTrust_Premium.pem new file mode 100644 index 00000000..516ecf55 --- /dev/null +++ b/resource/certs/AffirmTrust_Premium.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- diff --git a/resource/certs/AffirmTrust_Premium_ECC.pem b/resource/certs/AffirmTrust_Premium_ECC.pem new file mode 100644 index 00000000..4bcc6a43 --- /dev/null +++ b/resource/certs/AffirmTrust_Premium_ECC.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- diff --git a/resource/certs/Amazon_Root_CA_1.pem b/resource/certs/Amazon_Root_CA_1.pem new file mode 100644 index 00000000..a6f3e92a --- /dev/null +++ b/resource/certs/Amazon_Root_CA_1.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- diff --git a/resource/certs/Amazon_Root_CA_2.pem b/resource/certs/Amazon_Root_CA_2.pem new file mode 100644 index 00000000..efe3c9fe --- /dev/null +++ b/resource/certs/Amazon_Root_CA_2.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- diff --git a/resource/certs/Amazon_Root_CA_3.pem b/resource/certs/Amazon_Root_CA_3.pem new file mode 100644 index 00000000..a45da707 --- /dev/null +++ b/resource/certs/Amazon_Root_CA_3.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- diff --git a/resource/certs/Amazon_Root_CA_4.pem b/resource/certs/Amazon_Root_CA_4.pem new file mode 100644 index 00000000..fcbdeccd --- /dev/null +++ b/resource/certs/Amazon_Root_CA_4.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- diff --git a/resource/certs/Atos_TrustedRoot_2011.pem b/resource/certs/Atos_TrustedRoot_2011.pem new file mode 100644 index 00000000..988cc68a --- /dev/null +++ b/resource/certs/Atos_TrustedRoot_2011.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- diff --git a/resource/certs/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem b/resource/certs/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem new file mode 100644 index 00000000..de97f841 --- /dev/null +++ b/resource/certs/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- diff --git a/resource/certs/Baltimore_CyberTrust_Root.pem b/resource/certs/Baltimore_CyberTrust_Root.pem new file mode 100644 index 00000000..519028c6 --- /dev/null +++ b/resource/certs/Baltimore_CyberTrust_Root.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- diff --git a/resource/certs/Buypass_Class_2_Root_CA.pem b/resource/certs/Buypass_Class_2_Root_CA.pem new file mode 100644 index 00000000..9daec241 --- /dev/null +++ b/resource/certs/Buypass_Class_2_Root_CA.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- diff --git a/resource/certs/Buypass_Class_3_Root_CA.pem b/resource/certs/Buypass_Class_3_Root_CA.pem new file mode 100644 index 00000000..23b53062 --- /dev/null +++ b/resource/certs/Buypass_Class_3_Root_CA.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- diff --git a/resource/certs/CA_Disig_Root_R2.pem b/resource/certs/CA_Disig_Root_R2.pem new file mode 100644 index 00000000..0d94600e --- /dev/null +++ b/resource/certs/CA_Disig_Root_R2.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- diff --git a/resource/certs/CFCA_EV_ROOT.pem b/resource/certs/CFCA_EV_ROOT.pem new file mode 100644 index 00000000..198d1bf2 --- /dev/null +++ b/resource/certs/CFCA_EV_ROOT.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- diff --git a/resource/certs/COMODO_Certification_Authority.pem b/resource/certs/COMODO_Certification_Authority.pem new file mode 100644 index 00000000..6146dcb5 --- /dev/null +++ b/resource/certs/COMODO_Certification_Authority.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- diff --git a/resource/certs/COMODO_ECC_Certification_Authority.pem b/resource/certs/COMODO_ECC_Certification_Authority.pem new file mode 100644 index 00000000..546c95e3 --- /dev/null +++ b/resource/certs/COMODO_ECC_Certification_Authority.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- diff --git a/resource/certs/COMODO_RSA_Certification_Authority.pem b/resource/certs/COMODO_RSA_Certification_Authority.pem new file mode 100644 index 00000000..6508d1e8 --- /dev/null +++ b/resource/certs/COMODO_RSA_Certification_Authority.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- diff --git a/resource/certs/Certigna.pem b/resource/certs/Certigna.pem new file mode 100644 index 00000000..220d95f9 --- /dev/null +++ b/resource/certs/Certigna.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- diff --git a/resource/certs/Certigna_Root_CA.pem b/resource/certs/Certigna_Root_CA.pem new file mode 100644 index 00000000..4b40f56d --- /dev/null +++ b/resource/certs/Certigna_Root_CA.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- diff --git a/resource/certs/Certum_Trusted_Network_CA.pem b/resource/certs/Certum_Trusted_Network_CA.pem new file mode 100644 index 00000000..a04e656d --- /dev/null +++ b/resource/certs/Certum_Trusted_Network_CA.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- diff --git a/resource/certs/Certum_Trusted_Network_CA_2.pem b/resource/certs/Certum_Trusted_Network_CA_2.pem new file mode 100644 index 00000000..126e948a --- /dev/null +++ b/resource/certs/Certum_Trusted_Network_CA_2.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- diff --git a/resource/certs/Chambers_of_Commerce_Root_-_2008.pem b/resource/certs/Chambers_of_Commerce_Root_-_2008.pem new file mode 100644 index 00000000..7d3a2491 --- /dev/null +++ b/resource/certs/Chambers_of_Commerce_Root_-_2008.pem @@ -0,0 +1,42 @@ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- diff --git a/resource/certs/Comodo_AAA_Services_root.pem b/resource/certs/Comodo_AAA_Services_root.pem new file mode 100644 index 00000000..33c71ba9 --- /dev/null +++ b/resource/certs/Comodo_AAA_Services_root.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- diff --git a/resource/certs/Cybertrust_Global_Root.pem b/resource/certs/Cybertrust_Global_Root.pem new file mode 100644 index 00000000..edbeb27e --- /dev/null +++ b/resource/certs/Cybertrust_Global_Root.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- diff --git a/resource/certs/D-TRUST_Root_Class_3_CA_2_2009.pem b/resource/certs/D-TRUST_Root_Class_3_CA_2_2009.pem new file mode 100644 index 00000000..e084d98b --- /dev/null +++ b/resource/certs/D-TRUST_Root_Class_3_CA_2_2009.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- diff --git a/resource/certs/D-TRUST_Root_Class_3_CA_2_EV_2009.pem b/resource/certs/D-TRUST_Root_Class_3_CA_2_EV_2009.pem new file mode 100644 index 00000000..0a1a2b2d --- /dev/null +++ b/resource/certs/D-TRUST_Root_Class_3_CA_2_EV_2009.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Assured_ID_Root_CA.pem b/resource/certs/DigiCert_Assured_ID_Root_CA.pem new file mode 100644 index 00000000..2731638b --- /dev/null +++ b/resource/certs/DigiCert_Assured_ID_Root_CA.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Assured_ID_Root_G2.pem b/resource/certs/DigiCert_Assured_ID_Root_G2.pem new file mode 100644 index 00000000..fc60fb51 --- /dev/null +++ b/resource/certs/DigiCert_Assured_ID_Root_G2.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Assured_ID_Root_G3.pem b/resource/certs/DigiCert_Assured_ID_Root_G3.pem new file mode 100644 index 00000000..244c99b2 --- /dev/null +++ b/resource/certs/DigiCert_Assured_ID_Root_G3.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Global_Root_CA.pem b/resource/certs/DigiCert_Global_Root_CA.pem new file mode 100644 index 00000000..fd4341df --- /dev/null +++ b/resource/certs/DigiCert_Global_Root_CA.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Global_Root_G2.pem b/resource/certs/DigiCert_Global_Root_G2.pem new file mode 100644 index 00000000..798e0027 --- /dev/null +++ b/resource/certs/DigiCert_Global_Root_G2.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Global_Root_G3.pem b/resource/certs/DigiCert_Global_Root_G3.pem new file mode 100644 index 00000000..bc20c1e1 --- /dev/null +++ b/resource/certs/DigiCert_Global_Root_G3.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_High_Assurance_EV_Root_CA.pem b/resource/certs/DigiCert_High_Assurance_EV_Root_CA.pem new file mode 100644 index 00000000..9e6810ab --- /dev/null +++ b/resource/certs/DigiCert_High_Assurance_EV_Root_CA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- diff --git a/resource/certs/DigiCert_Trusted_Root_G4.pem b/resource/certs/DigiCert_Trusted_Root_G4.pem new file mode 100644 index 00000000..42142274 --- /dev/null +++ b/resource/certs/DigiCert_Trusted_Root_G4.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- diff --git a/resource/certs/E-Tugra_Certification_Authority.pem b/resource/certs/E-Tugra_Certification_Authority.pem new file mode 100644 index 00000000..97485999 --- /dev/null +++ b/resource/certs/E-Tugra_Certification_Authority.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- diff --git a/resource/certs/EC-ACC.pem b/resource/certs/EC-ACC.pem new file mode 100644 index 00000000..87a13f62 --- /dev/null +++ b/resource/certs/EC-ACC.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- diff --git a/resource/certs/Entrust.net_Premium_2048_Secure_Server_CA.pem b/resource/certs/Entrust.net_Premium_2048_Secure_Server_CA.pem new file mode 100644 index 00000000..2ed99ca1 --- /dev/null +++ b/resource/certs/Entrust.net_Premium_2048_Secure_Server_CA.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- diff --git a/resource/certs/Entrust_Root_Certification_Authority.pem b/resource/certs/Entrust_Root_Certification_Authority.pem new file mode 100644 index 00000000..855485cf --- /dev/null +++ b/resource/certs/Entrust_Root_Certification_Authority.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- diff --git a/resource/certs/Entrust_Root_Certification_Authority_-_EC1.pem b/resource/certs/Entrust_Root_Certification_Authority_-_EC1.pem new file mode 100644 index 00000000..b2043ac3 --- /dev/null +++ b/resource/certs/Entrust_Root_Certification_Authority_-_EC1.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- diff --git a/resource/certs/Entrust_Root_Certification_Authority_-_G2.pem b/resource/certs/Entrust_Root_Certification_Authority_-_G2.pem new file mode 100644 index 00000000..2e23a605 --- /dev/null +++ b/resource/certs/Entrust_Root_Certification_Authority_-_G2.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- diff --git a/resource/certs/Entrust_Root_Certification_Authority_-_G4.pem b/resource/certs/Entrust_Root_Certification_Authority_-_G4.pem new file mode 100644 index 00000000..7ac10cc3 --- /dev/null +++ b/resource/certs/Entrust_Root_Certification_Authority_-_G4.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- diff --git a/resource/certs/GDCA_TrustAUTH_R5_ROOT.pem b/resource/certs/GDCA_TrustAUTH_R5_ROOT.pem new file mode 100644 index 00000000..4dd1c718 --- /dev/null +++ b/resource/certs/GDCA_TrustAUTH_R5_ROOT.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- diff --git a/resource/certs/GTS_Root_R1.pem b/resource/certs/GTS_Root_R1.pem new file mode 100644 index 00000000..54967036 --- /dev/null +++ b/resource/certs/GTS_Root_R1.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- diff --git a/resource/certs/GTS_Root_R2.pem b/resource/certs/GTS_Root_R2.pem new file mode 100644 index 00000000..984f1d18 --- /dev/null +++ b/resource/certs/GTS_Root_R2.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- diff --git a/resource/certs/GTS_Root_R3.pem b/resource/certs/GTS_Root_R3.pem new file mode 100644 index 00000000..7d540a41 --- /dev/null +++ b/resource/certs/GTS_Root_R3.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- diff --git a/resource/certs/GTS_Root_R4.pem b/resource/certs/GTS_Root_R4.pem new file mode 100644 index 00000000..07372d35 --- /dev/null +++ b/resource/certs/GTS_Root_R4.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- diff --git a/resource/certs/GeoTrust_Primary_Certification_Authority_-_G2.pem b/resource/certs/GeoTrust_Primary_Certification_Authority_-_G2.pem new file mode 100644 index 00000000..f9364c08 --- /dev/null +++ b/resource/certs/GeoTrust_Primary_Certification_Authority_-_G2.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- diff --git a/resource/certs/GlobalSign_ECC_Root_CA_-_R4.pem b/resource/certs/GlobalSign_ECC_Root_CA_-_R4.pem new file mode 100644 index 00000000..e9d0c33a --- /dev/null +++ b/resource/certs/GlobalSign_ECC_Root_CA_-_R4.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- diff --git a/resource/certs/GlobalSign_ECC_Root_CA_-_R5.pem b/resource/certs/GlobalSign_ECC_Root_CA_-_R5.pem new file mode 100644 index 00000000..111991b2 --- /dev/null +++ b/resource/certs/GlobalSign_ECC_Root_CA_-_R5.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- diff --git a/resource/certs/GlobalSign_Root_CA.pem b/resource/certs/GlobalSign_Root_CA.pem new file mode 100644 index 00000000..f4ce4ca4 --- /dev/null +++ b/resource/certs/GlobalSign_Root_CA.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- diff --git a/resource/certs/GlobalSign_Root_CA_-_R2.pem b/resource/certs/GlobalSign_Root_CA_-_R2.pem new file mode 100644 index 00000000..6f0f8db0 --- /dev/null +++ b/resource/certs/GlobalSign_Root_CA_-_R2.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- diff --git a/resource/certs/GlobalSign_Root_CA_-_R3.pem b/resource/certs/GlobalSign_Root_CA_-_R3.pem new file mode 100644 index 00000000..8afb2190 --- /dev/null +++ b/resource/certs/GlobalSign_Root_CA_-_R3.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- diff --git a/resource/certs/GlobalSign_Root_CA_-_R6.pem b/resource/certs/GlobalSign_Root_CA_-_R6.pem new file mode 100644 index 00000000..f3d2024a --- /dev/null +++ b/resource/certs/GlobalSign_Root_CA_-_R6.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- diff --git a/resource/certs/Global_Chambersign_Root_-_2008.pem b/resource/certs/Global_Chambersign_Root_-_2008.pem new file mode 100644 index 00000000..70b4ce41 --- /dev/null +++ b/resource/certs/Global_Chambersign_Root_-_2008.pem @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- diff --git a/resource/certs/Go_Daddy_Class_2_CA.pem b/resource/certs/Go_Daddy_Class_2_CA.pem new file mode 100644 index 00000000..42e8d1ee --- /dev/null +++ b/resource/certs/Go_Daddy_Class_2_CA.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- diff --git a/resource/certs/Go_Daddy_Root_Certificate_Authority_-_G2.pem b/resource/certs/Go_Daddy_Root_Certificate_Authority_-_G2.pem new file mode 100644 index 00000000..c2b29078 --- /dev/null +++ b/resource/certs/Go_Daddy_Root_Certificate_Authority_-_G2.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- diff --git a/resource/certs/Hellenic_Academic_and_Research_Institutions_ECC_RootCA_2015.pem b/resource/certs/Hellenic_Academic_and_Research_Institutions_ECC_RootCA_2015.pem new file mode 100644 index 00000000..5e5bc74c --- /dev/null +++ b/resource/certs/Hellenic_Academic_and_Research_Institutions_ECC_RootCA_2015.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- diff --git a/resource/certs/Hellenic_Academic_and_Research_Institutions_RootCA_2011.pem b/resource/certs/Hellenic_Academic_and_Research_Institutions_RootCA_2011.pem new file mode 100644 index 00000000..5ecc81c3 --- /dev/null +++ b/resource/certs/Hellenic_Academic_and_Research_Institutions_RootCA_2011.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- diff --git a/resource/certs/Hellenic_Academic_and_Research_Institutions_RootCA_2015.pem b/resource/certs/Hellenic_Academic_and_Research_Institutions_RootCA_2015.pem new file mode 100644 index 00000000..2cc7e068 --- /dev/null +++ b/resource/certs/Hellenic_Academic_and_Research_Institutions_RootCA_2015.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- diff --git a/resource/certs/Hongkong_Post_Root_CA_1.pem b/resource/certs/Hongkong_Post_Root_CA_1.pem new file mode 100644 index 00000000..a28e9a0e --- /dev/null +++ b/resource/certs/Hongkong_Post_Root_CA_1.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- diff --git a/resource/certs/Hongkong_Post_Root_CA_3.pem b/resource/certs/Hongkong_Post_Root_CA_3.pem new file mode 100644 index 00000000..22c7c73a --- /dev/null +++ b/resource/certs/Hongkong_Post_Root_CA_3.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- diff --git a/resource/certs/ISRG_Root_X1.pem b/resource/certs/ISRG_Root_X1.pem new file mode 100644 index 00000000..b85c8037 --- /dev/null +++ b/resource/certs/ISRG_Root_X1.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/resource/certs/IdenTrust_Commercial_Root_CA_1.pem b/resource/certs/IdenTrust_Commercial_Root_CA_1.pem new file mode 100644 index 00000000..de6f07dc --- /dev/null +++ b/resource/certs/IdenTrust_Commercial_Root_CA_1.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- diff --git a/resource/certs/IdenTrust_Public_Sector_Root_CA_1.pem b/resource/certs/IdenTrust_Public_Sector_Root_CA_1.pem new file mode 100644 index 00000000..38093391 --- /dev/null +++ b/resource/certs/IdenTrust_Public_Sector_Root_CA_1.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- diff --git a/resource/certs/Izenpe.com.pem b/resource/certs/Izenpe.com.pem new file mode 100644 index 00000000..76383219 --- /dev/null +++ b/resource/certs/Izenpe.com.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- diff --git a/resource/certs/Microsec_e-Szigno_Root_CA_2009.pem b/resource/certs/Microsec_e-Szigno_Root_CA_2009.pem new file mode 100644 index 00000000..aa844e75 --- /dev/null +++ b/resource/certs/Microsec_e-Szigno_Root_CA_2009.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- diff --git a/resource/certs/Microsoft_ECC_Root_Certificate_Authority_2017.pem b/resource/certs/Microsoft_ECC_Root_Certificate_Authority_2017.pem new file mode 100644 index 00000000..e3be2a5b --- /dev/null +++ b/resource/certs/Microsoft_ECC_Root_Certificate_Authority_2017.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- diff --git a/resource/certs/Microsoft_RSA_Root_Certificate_Authority_2017.pem b/resource/certs/Microsoft_RSA_Root_Certificate_Authority_2017.pem new file mode 100644 index 00000000..3bdfb23f --- /dev/null +++ b/resource/certs/Microsoft_RSA_Root_Certificate_Authority_2017.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- diff --git a/resource/certs/NAVER_Global_Root_Certification_Authority.pem b/resource/certs/NAVER_Global_Root_Certification_Authority.pem new file mode 100644 index 00000000..59f8ce3e --- /dev/null +++ b/resource/certs/NAVER_Global_Root_Certification_Authority.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- diff --git a/resource/certs/NetLock_Arany_=Class_Gold=_Főtanúsítvány.pem b/resource/certs/NetLock_Arany_=Class_Gold=_Főtanúsítvány.pem new file mode 100644 index 00000000..56b9ee47 --- /dev/null +++ b/resource/certs/NetLock_Arany_=Class_Gold=_Főtanúsítvány.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- diff --git a/resource/certs/Network_Solutions_Certificate_Authority.pem b/resource/certs/Network_Solutions_Certificate_Authority.pem new file mode 100644 index 00000000..11289bcd --- /dev/null +++ b/resource/certs/Network_Solutions_Certificate_Authority.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- diff --git a/resource/certs/OISTE_WISeKey_Global_Root_GB_CA.pem b/resource/certs/OISTE_WISeKey_Global_Root_GB_CA.pem new file mode 100644 index 00000000..7c1082b0 --- /dev/null +++ b/resource/certs/OISTE_WISeKey_Global_Root_GB_CA.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- diff --git a/resource/certs/OISTE_WISeKey_Global_Root_GC_CA.pem b/resource/certs/OISTE_WISeKey_Global_Root_GC_CA.pem new file mode 100644 index 00000000..a9dcb26e --- /dev/null +++ b/resource/certs/OISTE_WISeKey_Global_Root_GC_CA.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- diff --git a/resource/certs/QuoVadis_Root_CA.pem b/resource/certs/QuoVadis_Root_CA.pem new file mode 100644 index 00000000..ffa4dbe4 --- /dev/null +++ b/resource/certs/QuoVadis_Root_CA.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- diff --git a/resource/certs/QuoVadis_Root_CA_1_G3.pem b/resource/certs/QuoVadis_Root_CA_1_G3.pem new file mode 100644 index 00000000..2f89a044 --- /dev/null +++ b/resource/certs/QuoVadis_Root_CA_1_G3.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- diff --git a/resource/certs/QuoVadis_Root_CA_2.pem b/resource/certs/QuoVadis_Root_CA_2.pem new file mode 100644 index 00000000..35cc4eb5 --- /dev/null +++ b/resource/certs/QuoVadis_Root_CA_2.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- diff --git a/resource/certs/QuoVadis_Root_CA_2_G3.pem b/resource/certs/QuoVadis_Root_CA_2_G3.pem new file mode 100644 index 00000000..df5a27fa --- /dev/null +++ b/resource/certs/QuoVadis_Root_CA_2_G3.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- diff --git a/resource/certs/QuoVadis_Root_CA_3.pem b/resource/certs/QuoVadis_Root_CA_3.pem new file mode 100644 index 00000000..bda7b1aa --- /dev/null +++ b/resource/certs/QuoVadis_Root_CA_3.pem @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- diff --git a/resource/certs/QuoVadis_Root_CA_3_G3.pem b/resource/certs/QuoVadis_Root_CA_3_G3.pem new file mode 100644 index 00000000..7d6c5b49 --- /dev/null +++ b/resource/certs/QuoVadis_Root_CA_3_G3.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- diff --git a/resource/certs/SSL.com_EV_Root_Certification_Authority_ECC.pem b/resource/certs/SSL.com_EV_Root_Certification_Authority_ECC.pem new file mode 100644 index 00000000..0bfa8982 --- /dev/null +++ b/resource/certs/SSL.com_EV_Root_Certification_Authority_ECC.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- diff --git a/resource/certs/SSL.com_EV_Root_Certification_Authority_RSA_R2.pem b/resource/certs/SSL.com_EV_Root_Certification_Authority_RSA_R2.pem new file mode 100644 index 00000000..14c92c44 --- /dev/null +++ b/resource/certs/SSL.com_EV_Root_Certification_Authority_RSA_R2.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- diff --git a/resource/certs/SSL.com_Root_Certification_Authority_ECC.pem b/resource/certs/SSL.com_Root_Certification_Authority_ECC.pem new file mode 100644 index 00000000..e20d85cb --- /dev/null +++ b/resource/certs/SSL.com_Root_Certification_Authority_ECC.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- diff --git a/resource/certs/SSL.com_Root_Certification_Authority_RSA.pem b/resource/certs/SSL.com_Root_Certification_Authority_RSA.pem new file mode 100644 index 00000000..77ec988e --- /dev/null +++ b/resource/certs/SSL.com_Root_Certification_Authority_RSA.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- diff --git a/resource/certs/SZAFIR_ROOT_CA2.pem b/resource/certs/SZAFIR_ROOT_CA2.pem new file mode 100644 index 00000000..b2e3f203 --- /dev/null +++ b/resource/certs/SZAFIR_ROOT_CA2.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- diff --git a/resource/certs/SecureSign_RootCA11.pem b/resource/certs/SecureSign_RootCA11.pem new file mode 100644 index 00000000..aff52a8e --- /dev/null +++ b/resource/certs/SecureSign_RootCA11.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- diff --git a/resource/certs/SecureTrust_CA.pem b/resource/certs/SecureTrust_CA.pem new file mode 100644 index 00000000..37400921 --- /dev/null +++ b/resource/certs/SecureTrust_CA.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- diff --git a/resource/certs/Secure_Global_CA.pem b/resource/certs/Secure_Global_CA.pem new file mode 100644 index 00000000..1f4574e7 --- /dev/null +++ b/resource/certs/Secure_Global_CA.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- diff --git a/resource/certs/Security_Communication_RootCA2.pem b/resource/certs/Security_Communication_RootCA2.pem new file mode 100644 index 00000000..078bd0e3 --- /dev/null +++ b/resource/certs/Security_Communication_RootCA2.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- diff --git a/resource/certs/Security_Communication_Root_CA.pem b/resource/certs/Security_Communication_Root_CA.pem new file mode 100644 index 00000000..ad1424ac --- /dev/null +++ b/resource/certs/Security_Communication_Root_CA.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- diff --git a/resource/certs/Sonera_Class_2_Root_CA.pem b/resource/certs/Sonera_Class_2_Root_CA.pem new file mode 100644 index 00000000..36a998d2 --- /dev/null +++ b/resource/certs/Sonera_Class_2_Root_CA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- diff --git a/resource/certs/Staat_der_Nederlanden_EV_Root_CA.pem b/resource/certs/Staat_der_Nederlanden_EV_Root_CA.pem new file mode 100644 index 00000000..315f6658 --- /dev/null +++ b/resource/certs/Staat_der_Nederlanden_EV_Root_CA.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- diff --git a/resource/certs/Staat_der_Nederlanden_Root_CA_-_G3.pem b/resource/certs/Staat_der_Nederlanden_Root_CA_-_G3.pem new file mode 100644 index 00000000..bc6a756f --- /dev/null +++ b/resource/certs/Staat_der_Nederlanden_Root_CA_-_G3.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- diff --git a/resource/certs/Starfield_Class_2_CA.pem b/resource/certs/Starfield_Class_2_CA.pem new file mode 100644 index 00000000..d552e65d --- /dev/null +++ b/resource/certs/Starfield_Class_2_CA.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- diff --git a/resource/certs/Starfield_Root_Certificate_Authority_-_G2.pem b/resource/certs/Starfield_Root_Certificate_Authority_-_G2.pem new file mode 100644 index 00000000..c1a0a481 --- /dev/null +++ b/resource/certs/Starfield_Root_Certificate_Authority_-_G2.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- diff --git a/resource/certs/Starfield_Services_Root_Certificate_Authority_-_G2.pem b/resource/certs/Starfield_Services_Root_Certificate_Authority_-_G2.pem new file mode 100644 index 00000000..f7519150 --- /dev/null +++ b/resource/certs/Starfield_Services_Root_Certificate_Authority_-_G2.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- diff --git a/resource/certs/SwissSign_Gold_CA_-_G2.pem b/resource/certs/SwissSign_Gold_CA_-_G2.pem new file mode 100644 index 00000000..d7211878 --- /dev/null +++ b/resource/certs/SwissSign_Gold_CA_-_G2.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- diff --git a/resource/certs/SwissSign_Silver_CA_-_G2.pem b/resource/certs/SwissSign_Silver_CA_-_G2.pem new file mode 100644 index 00000000..67a172cb --- /dev/null +++ b/resource/certs/SwissSign_Silver_CA_-_G2.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- diff --git a/resource/certs/T-TeleSec_GlobalRoot_Class_2.pem b/resource/certs/T-TeleSec_GlobalRoot_Class_2.pem new file mode 100644 index 00000000..98fceb25 --- /dev/null +++ b/resource/certs/T-TeleSec_GlobalRoot_Class_2.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- diff --git a/resource/certs/T-TeleSec_GlobalRoot_Class_3.pem b/resource/certs/T-TeleSec_GlobalRoot_Class_3.pem new file mode 100644 index 00000000..e068f844 --- /dev/null +++ b/resource/certs/T-TeleSec_GlobalRoot_Class_3.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- diff --git a/resource/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem b/resource/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem new file mode 100644 index 00000000..63b136f6 --- /dev/null +++ b/resource/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- diff --git a/resource/certs/TWCA_Global_Root_CA.pem b/resource/certs/TWCA_Global_Root_CA.pem new file mode 100644 index 00000000..fd06b8c3 --- /dev/null +++ b/resource/certs/TWCA_Global_Root_CA.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- diff --git a/resource/certs/TWCA_Root_Certification_Authority.pem b/resource/certs/TWCA_Root_Certification_Authority.pem new file mode 100644 index 00000000..8d39bc6f --- /dev/null +++ b/resource/certs/TWCA_Root_Certification_Authority.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- diff --git a/resource/certs/TeliaSonera_Root_CA_v1.pem b/resource/certs/TeliaSonera_Root_CA_v1.pem new file mode 100644 index 00000000..8bc52c39 --- /dev/null +++ b/resource/certs/TeliaSonera_Root_CA_v1.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- diff --git a/resource/certs/TrustCor_ECA-1.pem b/resource/certs/TrustCor_ECA-1.pem new file mode 100644 index 00000000..ba7bddb8 --- /dev/null +++ b/resource/certs/TrustCor_ECA-1.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- diff --git a/resource/certs/TrustCor_RootCert_CA-1.pem b/resource/certs/TrustCor_RootCert_CA-1.pem new file mode 100644 index 00000000..23969fe3 --- /dev/null +++ b/resource/certs/TrustCor_RootCert_CA-1.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- diff --git a/resource/certs/TrustCor_RootCert_CA-2.pem b/resource/certs/TrustCor_RootCert_CA-2.pem new file mode 100644 index 00000000..aa392abc --- /dev/null +++ b/resource/certs/TrustCor_RootCert_CA-2.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- diff --git a/resource/certs/Trustis_FPS_Root_CA.pem b/resource/certs/Trustis_FPS_Root_CA.pem new file mode 100644 index 00000000..fb804c94 --- /dev/null +++ b/resource/certs/Trustis_FPS_Root_CA.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- diff --git a/resource/certs/Trustwave_Global_Certification_Authority.pem b/resource/certs/Trustwave_Global_Certification_Authority.pem new file mode 100644 index 00000000..85da7659 --- /dev/null +++ b/resource/certs/Trustwave_Global_Certification_Authority.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- diff --git a/resource/certs/Trustwave_Global_ECC_P256_Certification_Authority.pem b/resource/certs/Trustwave_Global_ECC_P256_Certification_Authority.pem new file mode 100644 index 00000000..8f308f54 --- /dev/null +++ b/resource/certs/Trustwave_Global_ECC_P256_Certification_Authority.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- diff --git a/resource/certs/Trustwave_Global_ECC_P384_Certification_Authority.pem b/resource/certs/Trustwave_Global_ECC_P384_Certification_Authority.pem new file mode 100644 index 00000000..e1ddb42f --- /dev/null +++ b/resource/certs/Trustwave_Global_ECC_P384_Certification_Authority.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- diff --git a/resource/certs/UCA_Extended_Validation_Root.pem b/resource/certs/UCA_Extended_Validation_Root.pem new file mode 100644 index 00000000..04c38ff9 --- /dev/null +++ b/resource/certs/UCA_Extended_Validation_Root.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- diff --git a/resource/certs/UCA_Global_G2_Root.pem b/resource/certs/UCA_Global_G2_Root.pem new file mode 100644 index 00000000..2aeab490 --- /dev/null +++ b/resource/certs/UCA_Global_G2_Root.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- diff --git a/resource/certs/USERTrust_ECC_Certification_Authority.pem b/resource/certs/USERTrust_ECC_Certification_Authority.pem new file mode 100644 index 00000000..b1cf1fd3 --- /dev/null +++ b/resource/certs/USERTrust_ECC_Certification_Authority.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- diff --git a/resource/certs/USERTrust_RSA_Certification_Authority.pem b/resource/certs/USERTrust_RSA_Certification_Authority.pem new file mode 100644 index 00000000..2795cf31 --- /dev/null +++ b/resource/certs/USERTrust_RSA_Certification_Authority.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- diff --git a/resource/certs/VeriSign_Universal_Root_Certification_Authority.pem b/resource/certs/VeriSign_Universal_Root_Certification_Authority.pem new file mode 100644 index 00000000..b5f18751 --- /dev/null +++ b/resource/certs/VeriSign_Universal_Root_Certification_Authority.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- diff --git a/resource/certs/XRamp_Global_CA_Root.pem b/resource/certs/XRamp_Global_CA_Root.pem new file mode 100644 index 00000000..f21e6d8b --- /dev/null +++ b/resource/certs/XRamp_Global_CA_Root.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- diff --git a/resource/certs/a3418fda.0 b/resource/certs/a3418fda.0 new file mode 100644 index 00000000..07372d35 --- /dev/null +++ b/resource/certs/a3418fda.0 @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- diff --git a/resource/certs/a94d09e5.0 b/resource/certs/a94d09e5.0 new file mode 100644 index 00000000..baf74db7 --- /dev/null +++ b/resource/certs/a94d09e5.0 @@ -0,0 +1,44 @@ +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- diff --git a/resource/certs/aee5f10d.0 b/resource/certs/aee5f10d.0 new file mode 100644 index 00000000..2ed99ca1 --- /dev/null +++ b/resource/certs/aee5f10d.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- diff --git a/resource/certs/b0e59380.0 b/resource/certs/b0e59380.0 new file mode 100644 index 00000000..e9d0c33a --- /dev/null +++ b/resource/certs/b0e59380.0 @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- diff --git a/resource/certs/b1159c4c.0 b/resource/certs/b1159c4c.0 new file mode 100644 index 00000000..2731638b --- /dev/null +++ b/resource/certs/b1159c4c.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- diff --git a/resource/certs/b66938e9.0 b/resource/certs/b66938e9.0 new file mode 100644 index 00000000..1f4574e7 --- /dev/null +++ b/resource/certs/b66938e9.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- diff --git a/resource/certs/b727005e.0 b/resource/certs/b727005e.0 new file mode 100644 index 00000000..516ecf55 --- /dev/null +++ b/resource/certs/b727005e.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- diff --git a/resource/certs/b7a5b843.0 b/resource/certs/b7a5b843.0 new file mode 100644 index 00000000..8d39bc6f --- /dev/null +++ b/resource/certs/b7a5b843.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- diff --git a/resource/certs/bf53fb88.0 b/resource/certs/bf53fb88.0 new file mode 100644 index 00000000..3bdfb23f --- /dev/null +++ b/resource/certs/bf53fb88.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- diff --git a/resource/certs/c01cdfa2.0 b/resource/certs/c01cdfa2.0 new file mode 100644 index 00000000..b5f18751 --- /dev/null +++ b/resource/certs/c01cdfa2.0 @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- diff --git a/resource/certs/c01eb047.0 b/resource/certs/c01eb047.0 new file mode 100644 index 00000000..2aeab490 --- /dev/null +++ b/resource/certs/c01eb047.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- diff --git a/resource/certs/c28a8a30.0 b/resource/certs/c28a8a30.0 new file mode 100644 index 00000000..e084d98b --- /dev/null +++ b/resource/certs/c28a8a30.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- diff --git a/resource/certs/c47d9980.0 b/resource/certs/c47d9980.0 new file mode 100644 index 00000000..7d3a2491 --- /dev/null +++ b/resource/certs/c47d9980.0 @@ -0,0 +1,42 @@ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- diff --git a/resource/certs/ca-certificates.crt b/resource/certs/ca-certificates.crt new file mode 100644 index 00000000..24c8f8fa --- /dev/null +++ b/resource/certs/ca-certificates.crt @@ -0,0 +1,3273 @@ +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- diff --git a/resource/certs/ca6e4ad9.0 b/resource/certs/ca6e4ad9.0 new file mode 100644 index 00000000..4b542569 --- /dev/null +++ b/resource/certs/ca6e4ad9.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- diff --git a/resource/certs/cbf06781.0 b/resource/certs/cbf06781.0 new file mode 100644 index 00000000..c2b29078 --- /dev/null +++ b/resource/certs/cbf06781.0 @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- diff --git a/resource/certs/cc450945.0 b/resource/certs/cc450945.0 new file mode 100644 index 00000000..76383219 --- /dev/null +++ b/resource/certs/cc450945.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- diff --git a/resource/certs/cd58d51e.0 b/resource/certs/cd58d51e.0 new file mode 100644 index 00000000..078bd0e3 --- /dev/null +++ b/resource/certs/cd58d51e.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- diff --git a/resource/certs/cd8c0d63.0 b/resource/certs/cd8c0d63.0 new file mode 100644 index 00000000..666cf67c --- /dev/null +++ b/resource/certs/cd8c0d63.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- diff --git a/resource/certs/ce5e74ef.0 b/resource/certs/ce5e74ef.0 new file mode 100644 index 00000000..a6f3e92a --- /dev/null +++ b/resource/certs/ce5e74ef.0 @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- diff --git a/resource/certs/certSIGN_ROOT_CA.pem b/resource/certs/certSIGN_ROOT_CA.pem new file mode 100644 index 00000000..0a38740b --- /dev/null +++ b/resource/certs/certSIGN_ROOT_CA.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- diff --git a/resource/certs/certSIGN_Root_CA_G2.pem b/resource/certs/certSIGN_Root_CA_G2.pem new file mode 100644 index 00000000..573ec331 --- /dev/null +++ b/resource/certs/certSIGN_Root_CA_G2.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- diff --git a/resource/certs/d4dae3dd.0 b/resource/certs/d4dae3dd.0 new file mode 100644 index 00000000..0a1a2b2d --- /dev/null +++ b/resource/certs/d4dae3dd.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- diff --git a/resource/certs/d6325660.0 b/resource/certs/d6325660.0 new file mode 100644 index 00000000..6508d1e8 --- /dev/null +++ b/resource/certs/d6325660.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- diff --git a/resource/certs/d7e8dc79.0 b/resource/certs/d7e8dc79.0 new file mode 100644 index 00000000..35cc4eb5 --- /dev/null +++ b/resource/certs/d7e8dc79.0 @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- diff --git a/resource/certs/d853d49e.0 b/resource/certs/d853d49e.0 new file mode 100644 index 00000000..fb804c94 --- /dev/null +++ b/resource/certs/d853d49e.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- diff --git a/resource/certs/d887a5bb.0 b/resource/certs/d887a5bb.0 new file mode 100644 index 00000000..e1ddb42f --- /dev/null +++ b/resource/certs/d887a5bb.0 @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- diff --git a/resource/certs/dc4d6a89.0 b/resource/certs/dc4d6a89.0 new file mode 100644 index 00000000..f3d2024a --- /dev/null +++ b/resource/certs/dc4d6a89.0 @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- diff --git a/resource/certs/dd8e9d41.0 b/resource/certs/dd8e9d41.0 new file mode 100644 index 00000000..bc20c1e1 --- /dev/null +++ b/resource/certs/dd8e9d41.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- diff --git a/resource/certs/de6d66f3.0 b/resource/certs/de6d66f3.0 new file mode 100644 index 00000000..fcbdeccd --- /dev/null +++ b/resource/certs/de6d66f3.0 @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- diff --git a/resource/certs/e-Szigno_Root_CA_2017.pem b/resource/certs/e-Szigno_Root_CA_2017.pem new file mode 100644 index 00000000..b6f59c28 --- /dev/null +++ b/resource/certs/e-Szigno_Root_CA_2017.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- diff --git a/resource/certs/e113c810.0 b/resource/certs/e113c810.0 new file mode 100644 index 00000000..220d95f9 --- /dev/null +++ b/resource/certs/e113c810.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- diff --git a/resource/certs/e18bfb83.0 b/resource/certs/e18bfb83.0 new file mode 100644 index 00000000..7d6c5b49 --- /dev/null +++ b/resource/certs/e18bfb83.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- diff --git a/resource/certs/e36a6752.0 b/resource/certs/e36a6752.0 new file mode 100644 index 00000000..988cc68a --- /dev/null +++ b/resource/certs/e36a6752.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- diff --git a/resource/certs/e73d606e.0 b/resource/certs/e73d606e.0 new file mode 100644 index 00000000..7c1082b0 --- /dev/null +++ b/resource/certs/e73d606e.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- diff --git a/resource/certs/e868b802.0 b/resource/certs/e868b802.0 new file mode 100644 index 00000000..b6f59c28 --- /dev/null +++ b/resource/certs/e868b802.0 @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- diff --git a/resource/certs/e8de2f56.0 b/resource/certs/e8de2f56.0 new file mode 100644 index 00000000..23b53062 --- /dev/null +++ b/resource/certs/e8de2f56.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- diff --git a/resource/certs/ePKI_Root_Certification_Authority.pem b/resource/certs/ePKI_Root_Certification_Authority.pem new file mode 100644 index 00000000..4b542569 --- /dev/null +++ b/resource/certs/ePKI_Root_Certification_Authority.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- diff --git a/resource/certs/ee64a828.0 b/resource/certs/ee64a828.0 new file mode 100644 index 00000000..33c71ba9 --- /dev/null +++ b/resource/certs/ee64a828.0 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- diff --git a/resource/certs/eed8c118.0 b/resource/certs/eed8c118.0 new file mode 100644 index 00000000..546c95e3 --- /dev/null +++ b/resource/certs/eed8c118.0 @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- diff --git a/resource/certs/ef954a4e.0 b/resource/certs/ef954a4e.0 new file mode 100644 index 00000000..de6f07dc --- /dev/null +++ b/resource/certs/ef954a4e.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- diff --git a/resource/certs/emSign_ECC_Root_CA_-_C3.pem b/resource/certs/emSign_ECC_Root_CA_-_C3.pem new file mode 100644 index 00000000..517c0e1c --- /dev/null +++ b/resource/certs/emSign_ECC_Root_CA_-_C3.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- diff --git a/resource/certs/emSign_ECC_Root_CA_-_G3.pem b/resource/certs/emSign_ECC_Root_CA_-_G3.pem new file mode 100644 index 00000000..060e943b --- /dev/null +++ b/resource/certs/emSign_ECC_Root_CA_-_G3.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- diff --git a/resource/certs/emSign_Root_CA_-_C1.pem b/resource/certs/emSign_Root_CA_-_C1.pem new file mode 100644 index 00000000..02bd4a71 --- /dev/null +++ b/resource/certs/emSign_Root_CA_-_C1.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- diff --git a/resource/certs/emSign_Root_CA_-_G1.pem b/resource/certs/emSign_Root_CA_-_G1.pem new file mode 100644 index 00000000..c50d2e6d --- /dev/null +++ b/resource/certs/emSign_Root_CA_-_G1.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- diff --git a/resource/certs/f081611a.0 b/resource/certs/f081611a.0 new file mode 100644 index 00000000..42e8d1ee --- /dev/null +++ b/resource/certs/f081611a.0 @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- diff --git a/resource/certs/f0c70a8d.0 b/resource/certs/f0c70a8d.0 new file mode 100644 index 00000000..0bfa8982 --- /dev/null +++ b/resource/certs/f0c70a8d.0 @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- diff --git a/resource/certs/f249de83.0 b/resource/certs/f249de83.0 new file mode 100644 index 00000000..85da7659 --- /dev/null +++ b/resource/certs/f249de83.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- diff --git a/resource/certs/f30dd6ad.0 b/resource/certs/f30dd6ad.0 new file mode 100644 index 00000000..b1cf1fd3 --- /dev/null +++ b/resource/certs/f30dd6ad.0 @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- diff --git a/resource/certs/f3377b1b.0 b/resource/certs/f3377b1b.0 new file mode 100644 index 00000000..ad1424ac --- /dev/null +++ b/resource/certs/f3377b1b.0 @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- diff --git a/resource/certs/f387163d.0 b/resource/certs/f387163d.0 new file mode 100644 index 00000000..d552e65d --- /dev/null +++ b/resource/certs/f387163d.0 @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- diff --git a/resource/certs/f39fc864.0 b/resource/certs/f39fc864.0 new file mode 100644 index 00000000..37400921 --- /dev/null +++ b/resource/certs/f39fc864.0 @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- diff --git a/resource/certs/f51bb24c.0 b/resource/certs/f51bb24c.0 new file mode 100644 index 00000000..4b40f56d --- /dev/null +++ b/resource/certs/f51bb24c.0 @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- diff --git a/resource/certs/fc5a8f99.0 b/resource/certs/fc5a8f99.0 new file mode 100644 index 00000000..2795cf31 --- /dev/null +++ b/resource/certs/fc5a8f99.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- diff --git a/resource/certs/fe8a2cd8.0 b/resource/certs/fe8a2cd8.0 new file mode 100644 index 00000000..b2e3f203 --- /dev/null +++ b/resource/certs/fe8a2cd8.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- diff --git a/resource/certs/ff34af3f.0 b/resource/certs/ff34af3f.0 new file mode 100644 index 00000000..63b136f6 --- /dev/null +++ b/resource/certs/ff34af3f.0 @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- diff --git a/resource/certs/ssl-cert-snakeoil.pem b/resource/certs/ssl-cert-snakeoil.pem new file mode 100644 index 00000000..b92f351b --- /dev/null +++ b/resource/certs/ssl-cert-snakeoil.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbigAwIBAgIUSzh1ULkST6atWX943hjSit8Qf30wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGdWJ1bnR1MB4XDTIxMTEyMjAzMTgxNVoXDTMxMTEyMDAz +MTgxNVowETEPMA0GA1UEAwwGdWJ1bnR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxO7yD9njwu0flf4fNGhizU6s3vp/SyITjiMn/SXH5QQ90JorkNeI +/PflDWFZcZTiz4foCSgezb5LBiqk9z+DLfYxqgT75A3CEV2xiP7kbIUSr9bIw+KJ +pKVvV9Dio0XaKB9383zOY1YgCFJc27WZPukzP9w4cWlAeWYKO60ZPa10LQ8pzIHk +o0bCzLkjq6dzJB7CynQ8Fr+/TLiGKE8k2lTAkDfFDAua4HYr4XeWusRlEvR+wTVQ +8EbKUvCUrqFXO0XNb/I8Gst+88Fa/cMYhchc+Xf+PeSXLbEehtuphik4bVyVWlFO +NrgPuvl5a0Z5OMI3HfEf1Wt53sru1TbceQIDAQABoyAwHjAJBgNVHRMEAjAAMBEG +A1UdEQQKMAiCBnVidW50dTANBgkqhkiG9w0BAQsFAAOCAQEAeNJJEc6hp6/cWRV2 +5AQsVv5LY9BGBoCuoaZ1CqzLDxsnEyZwYGw/IzDiNXwCoFv7pAAwFgPd5yiES68L +7VY1BzwA03EgT4O7U9iTfkS/Q7J1lG9VodKVtpl5QmRDyQduz5EMQnQZX/a1whH1 +Pa5OvUwQdMACiygPfQDeC/6sPvbr6iC5YYwpLHAJSexQQ6b921WxtcQ8SXCA+IsL +MJ12qQnQZSS4KoTVnFAT4OtcMhxvEfUgSPOFQUSEyVKHW4DJii12TdBnm/T3XIHO +dDvegXT322H0A7UCaQkD0TzVQD3npZMyF4YDD8Nac1uETgxhtfYSaIsAswsEKni0 +M2Okyw== +-----END CERTIFICATE----- diff --git a/resource/icons/archive.png b/resource/icons/archive.png Binary files differnew file mode 100644 index 00000000..37a87950 --- /dev/null +++ b/resource/icons/archive.png diff --git a/resource/icons/drafts.png b/resource/icons/drafts.png Binary files differnew file mode 100644 index 00000000..bc44f88a --- /dev/null +++ b/resource/icons/drafts.png diff --git a/resource/icons/flag-fill.png b/resource/icons/flag-fill.png Binary files differnew file mode 100644 index 00000000..b8723616 --- /dev/null +++ b/resource/icons/flag-fill.png diff --git a/resource/icons/folder.png b/resource/icons/folder.png Binary files differnew file mode 100644 index 00000000..b0e7989c --- /dev/null +++ b/resource/icons/folder.png diff --git a/resource/icons/importance.png b/resource/icons/importance.png Binary files differnew file mode 100644 index 00000000..e59ff133 --- /dev/null +++ b/resource/icons/importance.png diff --git a/resource/icons/inbox.png b/resource/icons/inbox.png Binary files differnew file mode 100644 index 00000000..5d0fbf2f --- /dev/null +++ b/resource/icons/inbox.png diff --git a/resource/icons/junk.png b/resource/icons/junk.png Binary files differnew file mode 100644 index 00000000..3fa05c63 --- /dev/null +++ b/resource/icons/junk.png diff --git a/resource/icons/receive_email.png b/resource/icons/receive_email.png Binary files differnew file mode 100644 index 00000000..eaa060fb --- /dev/null +++ b/resource/icons/receive_email.png diff --git a/resource/icons/sent.png b/resource/icons/sent.png Binary files differnew file mode 100644 index 00000000..b11d0425 --- /dev/null +++ b/resource/icons/sent.png diff --git a/resource/icons/server.png b/resource/icons/server.png Binary files differnew file mode 100644 index 00000000..2efc30ef --- /dev/null +++ b/resource/icons/server.png diff --git a/resource/icons/trash.png b/resource/icons/trash.png Binary files differnew file mode 100644 index 00000000..9cf606b8 --- /dev/null +++ b/resource/icons/trash.png diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 25c1a8bc..0769f11a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,33 @@ +# +# Copyright (C) 2021 Saturneric +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric<[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + + if (GPG_CORE) message(STATUS "Build Gpg Core") - add_subdirectory(gpg) + add_subdirectory(core) endif () if (UI_CORE) @@ -8,12 +35,6 @@ if (UI_CORE) add_subdirectory(ui) endif () -if (SMTP_SUPPORT) - message(STATUS "Build SMTP Support") - add_compile_definitions(SMTP_SUPPORT) - add_subdirectory(smtp) -endif () - if (SERVER_SUPPORT) message(STATUS "Build Server Support") add_compile_definitions(SERVER_SUPPORT) @@ -114,6 +135,7 @@ if (APPLICATION_BUILD) # Copy Resource Files file(COPY ${CMAKE_SOURCE_DIR}/resource/css DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN) file(COPY ${CMAKE_SOURCE_DIR}/resource/icons DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN) + file(COPY ${CMAKE_SOURCE_DIR}/resource/certs DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN) file(COPY ${CMAKE_SOURCE_DIR}/TRANSLATORS DESTINATION ${RESOURCE_OUTPUT_DIRECTORY} FOLLOW_SYMLINK_CHAIN) if (GPG_STANDALONE_MODE) file(COPY ${CMAKE_SOURCE_DIR}/resource/gpg1.4 DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN) @@ -231,92 +253,62 @@ if (APPLICATION_BUILD) endif () +# link options for GpgFrontend if (APPLICATION_BUILD) - - if (ADVANCE_SUPPORT) - set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} advance) - endif () - if (ADVANCE_SUPPORT) - set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} server) - endif () - if (SMTP_SUPPORT) - set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} smtp) - endif () - - set(GPGFRONTEND_LIBS ${GPGFRONTEND_AFTER_UI_LIBS} gpgfrontend-ui gpg_core ${GPGFRONTEND_BEFORE_UI_LIBS} easy_logging_pp) - set(QT_DEPENDENCY_LIBS Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core) - + target_link_libraries(${AppName} gpgfrontend_ui) IF (MINGW) message(STATUS "Link Application Static Library For MINGW") - find_library(libconfig NAMES libconfig++.a) - find_library(libintl NAMES libintl.a) - find_library(libiconv NAMES libiconv.a) - - target_link_libraries(${AppName} - ${GPGFRONTEND_LIBS} - ${QT_DEPENDENCY_LIBS} - ${Boost_LIBRARIES} - ${libintl} ${libiconv} ${libconfig} crypto ssl) + target_link_libraries(${AppName} crypto) elseif (APPLE) message(STATUS "Link Application Static Library For macOS") - target_link_libraries(${AppName} - ${GPGFRONTEND_LIBS} - ${QT_DEPENDENCY_LIBS} - ${Boost_LIBRARIES} - crypto ssl intl) + target_link_libraries(${AppName} intl) else () - message(STATUS "Link Application Static Library For UNIX ") - if (APP_IMAGE_UPDATE) - target_link_libraries(${AppName} - libappimageupdate) - endif () - target_link_libraries(${AppName} - ${GPGFRONTEND_LIBS} - ${QT_DEPENDENCY_LIBS} - ${Boost_LIBRARIES} - crypto ssl pthread) + message(STATUS "Link Application Static Library For Linux") + target_link_libraries(${AppName} crypto pthread) endif () endif () -if (LINUX_INSTALL_SOFTWARE) - if (LINUX) - if (INSTALL_GPGFRONTEND_APP) - install(TARGETS ${AppName} - EXPORT GpgFrontendTargets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) - install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS - DESTINATION /usr/local/share/${AppName}/) - install(FILES ${CMAKE_SOURCE_DIR}/resource/meta/pub.gpgfrontend.gpgfrontend.appdata.xml - DESTINATION /usr/share/metainfo/) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/desktop/ - DESTINATION /usr/share/applications/) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/pixmaps/ - DESTINATION /usr/share/pixmaps/) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/hicolor/ - DESTINATION /usr/share/icons/hicolor/) - endif () - if (MULTI_LANG_SUPPORT) - install(DIRECTORY ${LOCALE_OUTPUT_PATH}/ - DESTINATION ${CMAKE_INSTALL_FULL_LOCALEDIR}) - endif () - if (APP_PACKAGE_DEB) - message(STATUS "Configure Deb Package") - SET(CPACK_GENERATOR "DEB") - set(CPACK_INSTALL_PREFIX "/usr/local/") - set(CPACK_PACKAGE_NAME "gpgfrontend") - set(CPACK_DEBIAN_PACKAGE_NAME "gpgfrontend") - set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") - set(CPACK_PACKAGE_CONTACT "[email protected]") - SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Saturneric") - set(CPACK_DEBIAN_PACKAGE_DEPENDS "gpg (>= 2.2), libqt5core5a (>= 5.9), libqt5gui5 (>= 5.9), libqt5widgets5 (>= 5.9), libqt5network5 (>= 5.9), libqt5printsupport5 (>= 5.9), libconfig++-dev (>=1.5)") - set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") - set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") - set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") - include(CPack) - endif () +# using c++ standard 17 +target_compile_features(${AppName} PUBLIC cxx_std_17) + +# if building linux package +if (LINUX AND LINUX_INSTALL_SOFTWARE) + if (INSTALL_GPGFRONTEND_APP) + install(TARGETS ${AppName} + EXPORT GpgFrontendTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS + DESTINATION /usr/local/share/${AppName}/) + install(FILES ${CMAKE_SOURCE_DIR}/resource/meta/pub.gpgfrontend.gpgfrontend.appdata.xml + DESTINATION /usr/share/metainfo/) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/desktop/ + DESTINATION /usr/share/applications/) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/pixmaps/ + DESTINATION /usr/share/pixmaps/) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/hicolor/ + DESTINATION /usr/share/icons/hicolor/) + endif () + if (MULTI_LANG_SUPPORT) + install(DIRECTORY ${LOCALE_OUTPUT_PATH}/ + DESTINATION ${CMAKE_INSTALL_FULL_LOCALEDIR}) + endif () + if (APP_PACKAGE_DEB) + message(STATUS "Configure Deb Package") + SET(CPACK_GENERATOR "DEB") + set(CPACK_INSTALL_PREFIX "/usr/local/") + set(CPACK_PACKAGE_NAME "gpgfrontend") + set(CPACK_DEBIAN_PACKAGE_NAME "gpgfrontend") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") + set(CPACK_PACKAGE_CONTACT "[email protected]") + SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Saturneric") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "gpg (>= 2.2), libqt5core5a (>= 5.9), libqt5gui5 (>= 5.9), libqt5widgets5 (>= 5.9), libqt5network5 (>= 5.9), libqt5printsupport5 (>= 5.9), libconfig++-dev (>=1.5)") + set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") + set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") + set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") + include(CPack) endif () endif () diff --git a/src/GpgFrontend.h.in b/src/GpgFrontend.h.in index 11934550..78ab6e6a 100644 --- a/src/GpgFrontend.h.in +++ b/src/GpgFrontend.h.in @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,36 +8,46 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_H_IN #define GPGFRONTEND_H_IN -// i18n +// standard headers +#include <cstdint> +#include <optional> +#include <filesystem> + #ifdef WINDOWS #include <winsock2.h> #include <windows.h> #endif + +// i18n support #include <libintl.h> #define _(String) gettext (String) #define gettext_noop(String) String #define N_(String) gettext_noop (String) + +// fix macro bugs in mingw #ifdef WINDOWS #include <clocale> #undef vsnprintf @@ -43,23 +55,28 @@ #undef snprintf #endif -// logging + +// logging system #define ELPP_DEFAULT_LOGGING_FLAGS 8192 -#include <easyloggingpp/easylogging++.h> +#include <easylogging++.h> + +// build info #define PROJECT_NAME "@CMAKE_PROJECT_NAME@" #define OS_PLATFORM @OS_PLATFORM@ #define LOCALE_DIR "@LOCALE_DIR@" -/** - * Resources File(s) Path Vars - */ -#if defined(MACOS) && defined(RELEASE) + +// macros to find resource files +#if defined(MACOS) && defined(RELEASE) #define RESOURCE_DIR(appDir) (appDir + "/../Resources/") +#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir / ".." / "Resources") #elif defined(LINUX) && defined(RELEASE) #define RESOURCE_DIR(appDir) (appDir + "/../share/") +#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir / ".." / "share") #else #define RESOURCE_DIR(appDir) (appDir) +#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir) #endif #endif // GPGFRONTEND_H_IN diff --git a/src/GpgFrontendBuildInfo.h.in b/src/GpgFrontendBuildInfo.h.in index 12bef1b8..eff6e966 100644 --- a/src/GpgFrontendBuildInfo.h.in +++ b/src/GpgFrontendBuildInfo.h.in @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/GpgFrontendBuildInstallInfo.h.in b/src/GpgFrontendBuildInstallInfo.h.in index 057f30fe..abc1af0f 100644 --- a/src/GpgFrontendBuildInstallInfo.h.in +++ b/src/GpgFrontendBuildInstallInfo.h.in @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/advance/CMakeLists.txt b/src/advance/CMakeLists.txt deleted file mode 100644 index 696fc8e5..00000000 --- a/src/advance/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -aux_source_directory(. ADVANCE_SOURCE) - -add_library(advance STATIC ${ADVANCE_SOURCE}) - -target_link_libraries(advance - Qt5::Network Qt5::Widgets Qt5::Core)
\ No newline at end of file diff --git a/src/advance/UnknownSignersChecker.cpp b/src/advance/UnknownSignersChecker.cpp deleted file mode 100644 index fc70ee20..00000000 --- a/src/advance/UnknownSignersChecker.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "advance/UnknownSignersChecker.h" - -UnknownSignersChecker::UnknownSignersChecker(GpgFrontend::GpgContext *ctx, - gpgme_verify_result_t result) - : appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini"), - mCtx(ctx), - mResult(result) {} - -void UnknownSignersChecker::start() { - auto sign = mResult->signatures; - bool canContinue = true; - - while (sign && canContinue) { - switch (gpg_err_code(sign->status)) { - case GPG_ERR_BAD_SIGNATURE: - break; - case GPG_ERR_NO_ERROR: - if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) check_signer(sign); - break; - case GPG_ERR_NO_PUBKEY: - - case GPG_ERR_CERT_REVOKED: - case GPG_ERR_SIG_EXPIRED: - case GPG_ERR_KEY_EXPIRED: - check_signer(sign); - break; - case GPG_ERR_GENERAL: - canContinue = false; - break; - default: - break; - } - sign = sign->next; - } - - if (!unknownFprs.isEmpty()) { - PubkeyGetter pubkeyGetter(mCtx, unknownFprs); - pubkeyGetter.start(); - if (!pubkeyGetter.result()) { - } - } -} - -void UnknownSignersChecker::check_signer(gpgme_signature_t sign) { - auto key = mCtx->getKeyRefByFpr(sign->fpr); - if (!key.good) { - qDebug() << "Find Unknown FingerPrint " << sign->fpr; - unknownFprs.append(sign->fpr); - } -} diff --git a/src/advance/UnknownSignersChecker.h b/src/advance/UnknownSignersChecker.h deleted file mode 100644 index de07eaf8..00000000 --- a/src/advance/UnknownSignersChecker.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_UNKNOWNSIGNERSCHECKER_H -#define GPGFRONTEND_ZH_CN_TS_UNKNOWNSIGNERSCHECKER_H - -#include "server/api/PubkeyGetter.h" - -class UnknownSignersChecker : public QObject { - Q_OBJECT - public: - UnknownSignersChecker(GpgFrontend::GpgContext *ctx, - gpgme_verify_result_t result); - - void start(); - - private: - QString appPath; - QSettings settings; - GpgFrontend::GpgContext *mCtx; - gpgme_verify_result_t mResult; - - QVector<QString> unknownFprs; - - void check_signer(gpgme_signature_t sign); -}; - -#endif // GPGFRONTEND_ZH_CN_TS_UNKNOWNSIGNERSCHECKER_H diff --git a/src/before_exit.cpp b/src/before_exit.cpp new file mode 100644 index 00000000..50604a54 --- /dev/null +++ b/src/before_exit.cpp @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "core/function/GlobalSettingStation.h" + +/** + * @brief Actions performed before exiting the application + * + */ +void before_exit() { + LOG(INFO) << "called"; + GpgFrontend::GlobalSettingStation::GetInstance().ResetRootCerts(); +} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 00000000..66fe357c --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,101 @@ +# +# Copyright (C) 2021 Saturneric +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric<[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +aux_source_directory(./function/result_analyse GPG_SOURCE) +aux_source_directory(./function/gpg GPG_SOURCE) +aux_source_directory(./function/aes GPG_SOURCE) +aux_source_directory(./function GPG_SOURCE) +aux_source_directory(./model GPG_SOURCE) +aux_source_directory(. GPG_SOURCE) + +# define libgpgfrontend_core +add_library(gpgfrontend_core STATIC ${GPG_SOURCE}) + +set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils) +set(GPGME_LIB_DIR ${UTILS_DIR}/gpgme/lib) + +# link third-party libraries +target_link_libraries(gpgfrontend_core easyloggingpp config++) +# link boost libraries +target_link_libraries(gpgfrontend_core Boost::date_time Boost::system) +# link gnupg libraries +target_link_libraries(gpgfrontend_core gpgme assuan gpg-error) +# link openssl +target_link_libraries(gpgfrontend_core OpenSSL::SSL OpenSSL::Crypto) +# link Qt AES +target_link_libraries(gpgfrontend_core QtAES) +# link vmime +if (NOT LINUX) + # macOS + target_link_libraries(gpgfrontend_core + gpgfrontend_vmime intl iconv) + if (MINGW) + target_link_libraries(gpgfrontend_core ws2_32) + endif () +else () + target_link_libraries(gpgfrontend_core + gpgfrontend_vmime anl ssl crypto) +endif () +# link libarchive +if (MINGW) + find_library(LIBARCHIVE_LIB libarchive.a) + target_link_libraries(gpgfrontend_core ${LIBARCHIVE_LIB} expat lz4 zstd bcrypt lzma bz2 z) +else () + target_link_libraries(gpgfrontend_core archive_static) +endif () +# link json +target_link_libraries(gpgfrontend_core + nlohmann_json::nlohmann_json) +# link Qt core +target_link_libraries(gpgfrontend_core Qt5::Core) + +# set up pch +target_precompile_headers(gpgfrontend_core + PUBLIC ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h + PUBLIC GpgFrontendCore.h) + +# using std c++ 17 +target_compile_features(gpgfrontend_core PUBLIC cxx_std_17) + +# link for different platforms +if (MINGW) + message(STATUS "Link GPG Static Library For MINGW") + target_link_libraries(gpgfrontend_core wsock32) +elseif (APPLE) + message(STATUS "Link GPG Static Library For macOS") + target_link_libraries(gpgfrontend_core dl) + if (XCODE_BUILD) + set_target_properties(gpgfrontend_core + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) + endif () +else () + # linux + message(STATUS "Link GPG Static Library For Unix") + target_link_libraries(gpgfrontend_core pthread dl) +endif () diff --git a/src/gpg/GpgConstants.cpp b/src/core/GpgConstants.cpp index 2c9403da..284022a8 100644 --- a/src/gpg/GpgConstants.cpp +++ b/src/core/GpgConstants.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,52 +8,50 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/GpgConstants.h" +#include "core/GpgConstants.h" #include <gpg-error.h> #include <boost/algorithm/string/predicate.hpp> -#include <boost/filesystem.hpp> #include <string> const char* GpgFrontend::GpgConstants::PGP_CRYPT_BEGIN = - "-----BEGIN PGP MESSAGE-----"; + "-----BEGIN PGP MESSAGE-----"; ///< const char* GpgFrontend::GpgConstants::PGP_CRYPT_END = - "-----END PGP MESSAGE-----"; + "-----END PGP MESSAGE-----"; ///< const char* GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN = - "-----BEGIN PGP SIGNED MESSAGE-----"; + "-----BEGIN PGP SIGNED MESSAGE-----"; ///< const char* GpgFrontend::GpgConstants::PGP_SIGNED_END = - "-----END PGP SIGNATURE-----"; + "-----END PGP SIGNATURE-----"; ///< const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN = - "-----BEGIN PGP SIGNATURE-----"; + "-----BEGIN PGP SIGNATURE-----"; ///< const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_END = - "-----END PGP SIGNATURE-----"; + "-----END PGP SIGNATURE-----"; ///< const char* GpgFrontend::GpgConstants::PGP_PUBLIC_KEY_BEGIN = - "------BEGIN PGP PUBLIC KEY BLOCK-----"; + "-----BEGIN PGP PUBLIC KEY BLOCK-----"; ///< const char* GpgFrontend::GpgConstants::PGP_PRIVATE_KEY_BEGIN = - "-----BEGIN PGP PRIVATE KEY BLOCK-----"; + "-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///< const char* GpgFrontend::GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD = - "GpgF_Scpt://"; + "GpgF_Scpt://"; ///< -/// -/// \param err gpg_error_t -/// \return gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err) { if (gpg_err_code(err) != GPG_ERR_NO_ERROR) { LOG(ERROR) << "[" << _("Error") << " " << gpg_err_code(err) << "] " @@ -61,10 +61,6 @@ gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err) { return err; } -/// -/// \param err -/// \param predict -/// \return gpg_err_code_t GpgFrontend::check_gpg_error_2_err_code(gpgme_error_t err, gpgme_error_t predict) { auto err_code = gpg_err_code(err); @@ -76,10 +72,6 @@ gpg_err_code_t GpgFrontend::check_gpg_error_2_err_code(gpgme_error_t err, return err_code; } -/// -/// \param err -/// \param comment -/// \return gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err, const std::string& comment) { if (gpg_err_code(err) != GPG_ERR_NO_ERROR) { @@ -90,9 +82,6 @@ gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err, return err; } -/// -/// \param fingerprint -/// \return std::string GpgFrontend::beautify_fingerprint( GpgFrontend::BypeArrayConstRef fingerprint) { auto len = fingerprint.size(); @@ -106,16 +95,12 @@ std::string GpgFrontend::beautify_fingerprint( return out.str(); } -/// -/// \param s static inline void ltrim(std::string& s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })); } -/// -/// \param s static inline void rtrim(std::string& s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }) @@ -123,25 +108,19 @@ static inline void rtrim(std::string& s) { s.end()); } -/// -/// \param s -/// \return static inline std::string trim(std::string& s) { ltrim(s); rtrim(s); return s; } -/// -/// \param utf8_path -/// \return std::string GpgFrontend::read_all_data_in_file(const std::string& utf8_path) { - using namespace boost::filesystem; + using namespace std::filesystem; class path file_info(utf8_path.c_str()); if (!exists(file_info) || !is_regular_file(file_info)) return {}; std::ifstream in_file; #ifndef WINDOWS - in_file.open(file_info.string(), std::ios::in); + in_file.open(file_info.u8string(), std::ios::in); #else in_file.open(file_info.wstring().c_str(), std::ios::in); #endif @@ -153,16 +132,12 @@ std::string GpgFrontend::read_all_data_in_file(const std::string& utf8_path) { return in_buffer; } -/// -/// \param utf8_path -/// \param out_buffer -/// \return bool GpgFrontend::write_buffer_to_file(const std::string& utf8_path, const std::string& out_buffer) { - using namespace boost::filesystem; + using namespace std::filesystem; class path file_info(utf8_path.c_str()); #ifndef WINDOWS - std::ofstream out_file(file_info.string(), std::ios::out | std::ios::trunc); + std::ofstream out_file(file_info.u8string(), std::ios::out | std::ios::trunc); #else std::ofstream out_file(file_info.wstring().c_str(), std::ios::out | std::ios::trunc); @@ -173,40 +148,31 @@ bool GpgFrontend::write_buffer_to_file(const std::string& utf8_path, return true; } -/// -/// \param path -/// \return std::string GpgFrontend::get_file_extension(const std::string& path) { // Create a path object from given string - boost::filesystem::path path_obj(path); + std::filesystem::path path_obj(path); // Check if file name in the path object has extension if (path_obj.has_extension()) { // Fetch the extension from path object and return - return path_obj.extension().string(); + return path_obj.extension().u8string(); } // In case of no extension return empty string return {}; } -/// -/// \param path -/// \return std::string GpgFrontend::get_only_file_name_with_path(const std::string& path) { // Create a path object from given string - boost::filesystem::path path_obj(path); + std::filesystem::path path_obj(path); // Check if file name in the path object has extension if (path_obj.has_filename()) { // Fetch the extension from path object and return - return (path_obj.parent_path() / path_obj.stem()).string(); + return (path_obj.parent_path() / path_obj.stem()).u8string(); } // In case of no extension return empty string return {}; } -/// -/// \param text -/// \return int GpgFrontend::text_is_signed(GpgFrontend::BypeArrayRef text) { using boost::algorithm::ends_with; using boost::algorithm::starts_with; @@ -222,53 +188,36 @@ int GpgFrontend::text_is_signed(GpgFrontend::BypeArrayRef text) { return 0; } -/// -/// \param result -/// \return GpgFrontend::GpgEncrResult GpgFrontend::_new_result( gpgme_encrypt_result_t&& result) { gpgme_result_ref(result); return {result, _result_ref_deletor()}; } -/// -/// \param result -/// \return GpgFrontend::GpgDecrResult GpgFrontend::_new_result( gpgme_decrypt_result_t&& result) { gpgme_result_ref(result); return {result, _result_ref_deletor()}; } -/// -/// \param result -/// \return GpgFrontend::GpgSignResult GpgFrontend::_new_result( gpgme_sign_result_t&& result) { gpgme_result_ref(result); return {result, _result_ref_deletor()}; } -/// -/// \param result -/// \return GpgFrontend::GpgVerifyResult GpgFrontend::_new_result( gpgme_verify_result_t&& result) { gpgme_result_ref(result); return {result, _result_ref_deletor()}; } -/// -/// \param result -/// \return GpgFrontend::GpgGenKeyResult GpgFrontend::_new_result( gpgme_genkey_result_t&& result) { gpgme_result_ref(result); return {result, _result_ref_deletor()}; } -/// -/// \param _result void GpgFrontend::_result_ref_deletor::operator()(void* _result) { DLOG(INFO) << _("Called") << _result; if (_result != nullptr) gpgme_result_unref(_result); diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h new file mode 100644 index 00000000..8c6977ac --- /dev/null +++ b/src/core/GpgConstants.h @@ -0,0 +1,220 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPG_CONSTANTS_H +#define GPG_CONSTANTS_H + +#include <gpgme.h> + +#include <cassert> +#include <functional> +#include <memory> +#include <string> + +#include "GpgFrontend.h" + +const int RESTART_CODE = 1000; ///< + +namespace GpgFrontend { + +using ByteArray = std::string; ///< +using ByteArrayPtr = std::unique_ptr<ByteArray>; ///< +using StdBypeArrayPtr = std::unique_ptr<ByteArray>; ///< +using BypeArrayRef = ByteArray&; ///< +using BypeArrayConstRef = const ByteArray&; ///< +using StringArgsPtr = std::unique_ptr<std::vector<std::string>>; ///< +using StringArgsRef = std::vector<std::string>&; ///< + +using GpgError = gpgme_error_t; + +/** + * @brief Result Deleter + * + */ +struct _result_ref_deletor { + void operator()(void* _result); +}; + +using GpgEncrResult = std::shared_ptr<struct _gpgme_op_encrypt_result>; ///< +using GpgDecrResult = std::shared_ptr<struct _gpgme_op_decrypt_result>; ///< +using GpgSignResult = std::shared_ptr<struct _gpgme_op_sign_result>; ///< +using GpgVerifyResult = std::shared_ptr<struct _gpgme_op_verify_result>; ///< +using GpgGenKeyResult = std::shared_ptr<struct _gpgme_op_genkey_result>; ///< + +// Convert from gpgme_xxx_result to GpgXXXResult + +/** + * @brief + * + * @param result + * @return GpgEncrResult + */ +GpgEncrResult _new_result(gpgme_encrypt_result_t&& result); + +/** + * @brief + * + * @param result + * @return GpgDecrResult + */ +GpgDecrResult _new_result(gpgme_decrypt_result_t&& result); + +/** + * @brief + * + * @param result + * @return GpgSignResult + */ +GpgSignResult _new_result(gpgme_sign_result_t&& result); + +/** + * @brief + * + * @param result + * @return GpgVerifyResult + */ +GpgVerifyResult _new_result(gpgme_verify_result_t&& result); + +/** + * @brief + * + * @param result + * @return GpgGenKeyResult + */ +GpgGenKeyResult _new_result(gpgme_genkey_result_t&& result); + +// Error Info Printer + +/** + * @brief + * + * @param err + * @return GpgError + */ +GpgError check_gpg_error(GpgError err); + +/** + * @brief + * + * @param gpgmeError + * @param comment + * @return GpgError + */ +GpgError check_gpg_error(GpgError gpgmeError, const std::string& comment); + +/** + * @brief + * + * @param err + * @param predict + * @return gpg_err_code_t + */ +gpg_err_code_t check_gpg_error_2_err_code( + gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR); + +// Fingerprint + +/** + * @brief + * + * @param fingerprint + * @return std::string + */ +std::string beautify_fingerprint(BypeArrayConstRef fingerprint); + +// File Operation + +/** + * @brief + * + * @param path + * @return std::string + */ +std::string read_all_data_in_file(const std::string& path); + +/** + * @brief + * + * @param path + * @param out_buffer + * @return true + * @return false + */ +bool write_buffer_to_file(const std::string& path, + const std::string& out_buffer); + +/** + * @brief Get the file extension object + * + * @param path + * @return std::string + */ +std::string get_file_extension(const std::string& path); + +/** + * @brief Get the only file name with path object + * + * @param path + * @return std::string + */ +std::string get_only_file_name_with_path(const std::string& path); + +// Check + +/** + * @brief + * + * @param text + * @return int + */ +int text_is_signed(BypeArrayRef text); + +// Channels +const int GPGFRONTEND_DEFAULT_CHANNEL = 0; ///< +const int GPGFRONTEND_NON_ASCII_CHANNEL = 2; ///< + +/** + * @brief + * + */ +class GpgConstants { + public: + static const char* PGP_CRYPT_BEGIN; ///< + static const char* PGP_CRYPT_END; ///< + static const char* PGP_SIGNED_BEGIN; ///< + static const char* PGP_SIGNED_END; ///< + static const char* PGP_SIGNATURE_BEGIN; ///< + static const char* PGP_SIGNATURE_END; ///< + static const char* PGP_PUBLIC_KEY_BEGIN; ///< + static const char* PGP_PRIVATE_KEY_BEGIN; ///< + static const char* GPG_FRONTEND_SHORT_CRYPTO_HEAD; ///< +}; + +} // namespace GpgFrontend + +#endif // GPG_CONSTANTS_H diff --git a/src/gpg/GpgContext.cpp b/src/core/GpgContext.cpp index e3f10056..1897202f 100644 --- a/src/gpg/GpgContext.cpp +++ b/src/core/GpgContext.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include <gpg-error.h> #include <gpgme.h> diff --git a/src/gpg/GpgContext.h b/src/core/GpgContext.h index 146f0794..7de6bcad 100644 --- a/src/gpg/GpgContext.h +++ b/src/core/GpgContext.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -32,9 +36,13 @@ namespace GpgFrontend { +/** + * @brief + * + */ struct GpgContextInitArgs { // make no sense for gpg2 - bool independent_database = false; + bool independent_database = false; ///< std::string db_path = {}; bool gpg_alone = false; std::string gpg_path = {}; @@ -45,48 +53,110 @@ struct GpgContextInitArgs { }; /** - * Custom Encapsulation of GpgME APIs + * @brief + * */ class GpgContext : public SingletonFunctionObject<GpgContext> { public: + /** + * @brief Construct a new Gpg Context object + * + * @param args + */ explicit GpgContext(const GpgContextInitArgs& args = {}); + /** + * @brief Construct a new Gpg Context object + * + * @param channel + */ explicit GpgContext(int channel) : SingletonFunctionObject<GpgContext>(channel) {} + /** + * @brief Destroy the Gpg Context object + * + */ ~GpgContext() override = default; + /** + * @brief + * + * @return true + * @return false + */ [[nodiscard]] bool good() const; + /** + * @brief Get the Info object + * + * @return const GpgInfo& + */ [[nodiscard]] const GpgInfo& GetInfo() const { return info_; } + /** + * @brief + * + * @return gpgme_ctx_t + */ operator gpgme_ctx_t() const { return _ctx_ref.get(); } private: - GpgInfo info_; - GpgContextInitArgs args_; + GpgInfo info_; ///< + GpgContextInitArgs args_; ///< + /** + * @brief + * + */ void init_ctx(); + /** + * @brief + * + */ struct _ctx_ref_deleter { void operator()(gpgme_ctx_t _ctx) { if (_ctx != nullptr) gpgme_release(_ctx); } }; - using CtxRefHandler = std::unique_ptr<struct gpgme_context, _ctx_ref_deleter>; - CtxRefHandler _ctx_ref = nullptr; - - bool good_ = true; + using CtxRefHandler = + std::unique_ptr<struct gpgme_context, _ctx_ref_deleter>; ///< + CtxRefHandler _ctx_ref = nullptr; ///< + bool good_ = true; ///< public: + /** + * @brief + * + * @param opaque + * @param uid_hint + * @param passphrase_info + * @param last_was_bad + * @param fd + * @return gpgme_error_t + */ static gpgme_error_t test_passphrase_cb(void* opaque, const char* uid_hint, const char* passphrase_info, int last_was_bad, int fd); + /** + * @brief + * + * @param hook + * @param keyword + * @param args + * @return gpgme_error_t + */ static gpgme_error_t test_status_cb(void* hook, const char* keyword, const char* args); + /** + * @brief Set the Passphrase Cb object + * + * @param func + */ void SetPassphraseCb(gpgme_passphrase_cb_t func) const; }; } // namespace GpgFrontend diff --git a/src/gpg/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index 3f07d2b1..6d9963d6 100644 --- a/src/gpg/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/gpg/GpgCoreInit.h b/src/core/GpgCoreInit.h index 577f46a3..5ac804da 100644 --- a/src/gpg/GpgCoreInit.h +++ b/src/core/GpgCoreInit.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,9 +33,17 @@ namespace GpgFrontend { -// Init +/** + * @brief + * + */ void init_gpgfrontend_core(); +/** + * @brief + * + * @param channel + */ void new_default_settings_channel( int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL); diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h new file mode 100644 index 00000000..5931695d --- /dev/null +++ b/src/core/GpgFrontendCore.h @@ -0,0 +1,61 @@ +/** +* Copyright (C) 2021 Saturneric +* +* This file is part of GpgFrontend. +* +* GpgFrontend is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GpgFrontend is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +* +* The initial version of the source code is inherited from +* the gpg4usb project, which is under GPL-3.0-or-later. +* +* All the source code of GpgFrontend was modified and released by +* Saturneric<[email protected]> starting on May 12, 2021. +* +* SPDX-License-Identifier: GPL-3.0-or-later +* + */ + +#ifndef GPGFRONTEND_GPGFRONTENDCORE_H +#define GPGFRONTEND_GPGFRONTENDCORE_H + +#include "GpgFrontend.h" + +// std includes +#include <filesystem> + +// boost includes +#include <boost/format.hpp> + +// Qt includes +#include <QtCore> + +// vmime includes +#define VMIME_STATIC +#undef VMIME_HAVE_MLANG +#include <vmime/vmime.hpp> + +// libconfig includes +#undef LIBCONFIGXX_STATIC +#define LIBCONFIGXX_STATIC +#include <libconfig.h++> + + +// libarchive includes +#include <libarchive/libarchive/archive.h> +#include <libarchive/libarchive/archive_entry.h> + +#include "core/GpgModel.h" + + +#endif // GPGFRONTEND_GPGFRONTENDCORE_H diff --git a/src/gpg/GpgFunctionObject.h b/src/core/GpgFunctionObject.h index 404b2f84..391b1585 100644 --- a/src/gpg/GpgFunctionObject.h +++ b/src/core/GpgFunctionObject.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,27 +8,27 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H #define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H -#include <easyloggingpp/easylogging++.h> - #include <map> #include <memory> #include <mutex> @@ -38,9 +40,20 @@ namespace GpgFrontend { +/** + * @brief + * + * @tparam T + */ template <typename T> class SingletonFunctionObject { public: + /** + * @brief Get the Instance object + * + * @param channel + * @return T& + */ static T& GetInstance( int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) { static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, @@ -53,6 +66,13 @@ class SingletonFunctionObject { return *_p_pbj; } + /** + * @brief Create a Instance object + * + * @param channel + * @param factory + * @return T& + */ static T& CreateInstance(int channel, std::function<std::unique_ptr<T>(void)> factory) { static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, @@ -65,6 +85,13 @@ class SingletonFunctionObject { return *_p_pbj; } + /** + * @brief Create a Instance object + * + * @param channel + * @param p_obj + * @return T& + */ static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) { static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, "T not derived from SingletonFunctionObject<T>"); @@ -76,6 +103,12 @@ class SingletonFunctionObject { return *_p_pbj; } + /** + * @brief + * + * @param channel + * @return T& + */ static T& ReleaseChannel(int channel) { decltype(_instances_map.end()) _it; { @@ -86,33 +119,79 @@ class SingletonFunctionObject { DLOG(INFO) << "channel" << channel << "released"; } + /** + * @brief Get the Default Channel object + * + * @return int + */ static int GetDefaultChannel() { return _default_channel; } + /** + * @brief Get the Channel object + * + * @return int + */ [[nodiscard]] int GetChannel() const { return channel_; } + /** + * @brief Construct a new Singleton Function Object object + * + */ SingletonFunctionObject(T&&) = delete; + /** + * @brief Construct a new Singleton Function Object object + * + */ SingletonFunctionObject(const T&) = delete; + /** + * @brief + * + */ void operator=(const T&) = delete; protected: + /** + * @brief Construct a new Singleton Function Object object + * + */ SingletonFunctionObject() = default; + /** + * @brief Construct a new Singleton Function Object object + * + * @param channel + */ explicit SingletonFunctionObject(int channel) : channel_(channel) {} + /** + * @brief Destroy the Singleton Function Object object + * + */ virtual ~SingletonFunctionObject() = default; + /** + * @brief Set the Channel object + * + * @param channel + */ void SetChannel(int channel) { this->channel_ = channel; } private: - int channel_ = _default_channel; - static int _default_channel; - static std::mutex _instance_mutex; - static std::shared_mutex _instances_mutex; - static std::unique_ptr<T> _instance; - static std::map<int, std::unique_ptr<T>> _instances_map; - + int channel_ = _default_channel; ///< + static int _default_channel; ///< + static std::mutex _instance_mutex; ///< + static std::shared_mutex _instances_mutex; ///< + static std::unique_ptr<T> _instance; ///< + static std::map<int, std::unique_ptr<T>> _instances_map; ///< + + /** + * @brief + * + * @param channel + * @return T* + */ static T* find_object_in_channel(int channel) { // read _instances_map decltype(_instances_map.end()) _it; @@ -126,6 +205,13 @@ class SingletonFunctionObject { } } + /** + * @brief Set the object in channel object + * + * @param channel + * @param p_obj + * @return T* + */ static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) { { if (p_obj == nullptr) p_obj = std::make_unique<T>(); diff --git a/src/gpg/GpgGenKeyInfo.cpp b/src/core/GpgGenKeyInfo.cpp index f67aaa1f..6ca83c96 100644 --- a/src/gpg/GpgGenKeyInfo.cpp +++ b/src/core/GpgGenKeyInfo.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,25 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/GpgGenKeyInfo.h" - -#include <easyloggingpp/easylogging++.h> +#include "core/GpgGenKeyInfo.h" #include <boost/date_time/gregorian/greg_date.hpp> #include <boost/date_time/gregorian/greg_duration.hpp> @@ -32,31 +34,31 @@ #include <string> #include <vector> -void GpgFrontend::GenKeyInfo::setAlgo(const std::string &m_algo) { +void GpgFrontend::GenKeyInfo::SetAlgo(const std::string &m_algo) { LOG(INFO) << "set algo" << m_algo; // Check algo if supported std::string algo_args = std::string(m_algo); boost::algorithm::to_upper(algo_args); if (standalone_) { if (!subkey_) { - auto support_algo = getSupportedKeyAlgoStandalone(); + auto support_algo = GetSupportedKeyAlgoStandalone(); auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); // Algo Not Supported if (it == support_algo.end()) return; } else { - auto support_algo = getSupportedSubkeyAlgoStandalone(); + auto support_algo = GetSupportedSubkeyAlgoStandalone(); auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); // Algo Not Supported if (it == support_algo.end()) return; } } else { if (!subkey_) { - auto support_algo = getSupportedKeyAlgo(); + auto support_algo = GetSupportedKeyAlgo(); auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); // Algo Not Supported if (it == support_algo.end()) return; } else { - auto support_algo = getSupportedSubkeyAlgo(); + auto support_algo = GetSupportedSubkeyAlgo(); auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); // Algo Not Supported if (it == support_algo.end()) return; @@ -67,12 +69,12 @@ void GpgFrontend::GenKeyInfo::setAlgo(const std::string &m_algo) { reset_options(); if (!this->subkey_) { - this->setAllowCertification(true); + this->SetAllowCertification(true); } else { - this->setAllowCertification(false); + this->SetAllowCertification(false); } - this->allowChangeCertification = false; + this->allow_change_certification_ = false; if (!standalone_) boost::algorithm::to_lower(algo_args); @@ -85,7 +87,7 @@ void GpgFrontend::GenKeyInfo::setAlgo(const std::string &m_algo) { suggest_min_key_size_ = 1024; suggest_max_key_size_ = 4096; suggest_size_addition_step_ = 1024; - setKeySize(2048); + SetKeyLength(2048); } else if (algo_args == "dsa") { /** @@ -94,62 +96,62 @@ void GpgFrontend::GenKeyInfo::setAlgo(const std::string &m_algo) { * Recently, NIST has declared 512-bit keys obsolete: * now, DSA is available in 1024, 2048 and 3072-bit lengths. */ - setAllowEncryption(false); - allowChangeEncryption = false; + SetAllowEncryption(false); + allow_change_encryption_ = false; suggest_min_key_size_ = 1024; suggest_max_key_size_ = 3072; suggest_size_addition_step_ = 1024; - setKeySize(2048); + SetKeyLength(2048); } else if (algo_args == "ed25519") { /** * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths * ranging from 1024 to 4096 bits. */ - setAllowEncryption(false); - allowChangeEncryption = false; + SetAllowEncryption(false); + allow_change_encryption_ = false; suggest_min_key_size_ = -1; suggest_max_key_size_ = -1; suggest_size_addition_step_ = -1; - setKeySize(-1); + SetKeyLength(-1); } else if (algo_args == "elg") { /** * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths * ranging from 1024 to 4096 bits. */ - setAllowAuthentication(false); - allowChangeAuthentication = false; + SetAllowAuthentication(false); + allow_change_authentication_ = false; - setAllowSigning(false); - allowChangeSigning = false; + SetAllowSigning(false); + allow_change_signing_ = false; suggest_min_key_size_ = 1024; suggest_max_key_size_ = 4096; suggest_size_addition_step_ = 1024; - setKeySize(2048); + SetKeyLength(2048); } this->algo_ = algo_args; } void GpgFrontend::GenKeyInfo::reset_options() { - allowChangeEncryption = true; - setAllowEncryption(true); + allow_change_encryption_ = true; + SetAllowEncryption(true); - allowChangeCertification = true; - setAllowCertification(true); + allow_change_certification_ = true; + SetAllowCertification(true); - allowChangeSigning = true; - setAllowSigning(true); + allow_change_signing_ = true; + SetAllowSigning(true); - allowChangeAuthentication = true; - setAllowAuthentication(true); + allow_change_authentication_ = true; + SetAllowAuthentication(true); passphrase_.clear(); } -std::string GpgFrontend::GenKeyInfo::getKeySizeStr() const { +std::string GpgFrontend::GenKeyInfo::GetKeySizeStr() const { if (key_size_ > 0) { return std::to_string(key_size_); } else { @@ -157,7 +159,7 @@ std::string GpgFrontend::GenKeyInfo::getKeySizeStr() const { } } -void GpgFrontend::GenKeyInfo::setKeySize(int m_key_size) { +void GpgFrontend::GenKeyInfo::SetKeyLength(int m_key_size) { if (m_key_size < suggest_min_key_size_ || m_key_size > suggest_max_key_size_) { return; @@ -165,57 +167,58 @@ void GpgFrontend::GenKeyInfo::setKeySize(int m_key_size) { GenKeyInfo::key_size_ = m_key_size; } -void GpgFrontend::GenKeyInfo::setExpired( +void GpgFrontend::GenKeyInfo::SetExpireTime( const boost::posix_time::ptime &m_expired) { using namespace boost::gregorian; - if (!isNonExpired()) { + if (!IsNonExpired()) { GenKeyInfo::expired_ = m_expired; } } -void GpgFrontend::GenKeyInfo::setNonExpired(bool m_non_expired) { +void GpgFrontend::GenKeyInfo::SetNonExpired(bool m_non_expired) { using namespace boost::posix_time; if (!m_non_expired) this->expired_ = from_time_t(0); GenKeyInfo::non_expired_ = m_non_expired; } -void GpgFrontend::GenKeyInfo::setAllowEncryption(bool m_allow_encryption) { - if (allowChangeEncryption) GenKeyInfo::allowEncryption = m_allow_encryption; +void GpgFrontend::GenKeyInfo::SetAllowEncryption(bool m_allow_encryption) { + if (allow_change_encryption_) + GenKeyInfo::allow_encryption_ = m_allow_encryption; } -void GpgFrontend::GenKeyInfo::setAllowCertification( +void GpgFrontend::GenKeyInfo::SetAllowCertification( bool m_allow_certification) { - if (allowChangeCertification) - GenKeyInfo::allowCertification = m_allow_certification; + if (allow_change_certification_) + GenKeyInfo::allow_certification_ = m_allow_certification; } GpgFrontend::GenKeyInfo::GenKeyInfo(bool m_is_sub_key, bool m_standalone) : standalone_(m_standalone), subkey_(m_is_sub_key) { - setAlgo("rsa"); + SetAlgo("rsa"); } -const std::vector<std::string> &GpgFrontend::GenKeyInfo::getSupportedKeyAlgo() { +const std::vector<std::string> &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgo() { static const std::vector<std::string> support_key_algo = {"RSA", "DSA", "ED25519"}; return support_key_algo; } const std::vector<std::string> - &GpgFrontend::GenKeyInfo::getSupportedSubkeyAlgo() { + &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgo() { static const std::vector<std::string> support_subkey_algo = {"RSA", "DSA", "ED25519"}; return support_subkey_algo; } const std::vector<std::string> - &GpgFrontend::GenKeyInfo::getSupportedKeyAlgoStandalone() { + &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgoStandalone() { static const std::vector<std::string> support_subkey_algo_standalone = { "RSA", "DSA"}; return support_subkey_algo_standalone; } const std::vector<std::string> - &GpgFrontend::GenKeyInfo::getSupportedSubkeyAlgoStandalone() { + &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgoStandalone() { static const std::vector<std::string> support_subkey_algo_standalone = { "RSA", "DSA", "ELG-E"}; return support_subkey_algo_standalone; diff --git a/src/core/GpgGenKeyInfo.h b/src/core/GpgGenKeyInfo.h new file mode 100644 index 00000000..59ced710 --- /dev/null +++ b/src/core/GpgGenKeyInfo.h @@ -0,0 +1,435 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGGENKEYINFO_H +#define GPGFRONTEND_GPGGENKEYINFO_H + +#include <boost/date_time.hpp> +#include <boost/date_time/gregorian/greg_duration_types.hpp> +#include <boost/format.hpp> +#include <string> +#include <vector> + +#include "GpgFrontend.h" + +namespace GpgFrontend { + +class GenKeyInfo { + bool standalone_ = false; ///< + bool subkey_ = false; ///< + std::string name_; ///< + std::string email_; ///< + std::string comment_; ///< + + std::string algo_; ///< + int key_size_ = 2048; + boost::posix_time::ptime expired_ = + boost::posix_time::second_clock::local_time() + + boost::gregorian::years(2); ///< + bool non_expired_ = false; ///< + + bool no_passphrase_ = false; ///< + bool allow_no_pass_phrase_ = true; ///< + + int suggest_max_key_size_ = 4096; ///< + int suggest_size_addition_step_ = 1024; ///< + int suggest_min_key_size_ = 1024; ///< + + std::string passphrase_; ///< + + public: + /** + * @brief Get the Supported Key Algo object + * + * @return const std::vector<std::string>& + */ + static const std::vector<std::string> &GetSupportedKeyAlgo(); + + /** + * @brief Get the Supported Subkey Algo object + * + * @return const std::vector<std::string>& + */ + static const std::vector<std::string> &GetSupportedSubkeyAlgo(); + + /** + * @brief Get the Supported Key Algo Standalone object + * + * @return const std::vector<std::string>& + */ + static const std::vector<std::string> &GetSupportedKeyAlgoStandalone(); + + /** + * @brief Get the Supported Subkey Algo Standalone object + * + * @return const std::vector<std::string>& + */ + static const std::vector<std::string> &GetSupportedSubkeyAlgoStandalone(); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsSubKey() const { return subkey_; } + + /** + * @brief Set the Is Sub Key object + * + * @param m_sub_key + */ + void SetIsSubKey(bool m_sub_key) { GenKeyInfo::subkey_ = m_sub_key; } + + /** + * @brief Get the Userid object + * + * @return std::string + */ + [[nodiscard]] std::string GetUserid() const { + auto uid_format = boost::format("%1%(%2%)<%3%>") % this->name_ % + this->comment_ % this->email_; + return uid_format.str(); + } + + /** + * @brief Set the Name object + * + * @param m_name + */ + void SetName(const std::string &m_name) { this->name_ = m_name; } + + /** + * @brief Set the Email object + * + * @param m_email + */ + void SetEmail(const std::string &m_email) { this->email_ = m_email; } + + /** + * @brief Set the Comment object + * + * @param m_comment + */ + void SetComment(const std::string &m_comment) { this->comment_ = m_comment; } + + /** + * @brief Get the Name object + * + * @return std::string + */ + [[nodiscard]] std::string GetName() const { return name_; } + + /** + * @brief Get the Email object + * + * @return std::string + */ + [[nodiscard]] std::string GetEmail() const { return email_; } + + /** + * @brief Get the Comment object + * + * @return std::string + */ + [[nodiscard]] std::string GetComment() const { return comment_; } + + /** + * @brief Get the Algo object + * + * @return const std::string& + */ + [[nodiscard]] const std::string &GetAlgo() const { return algo_; } + + /** + * @brief Set the Algo object + * + * @param m_algo + */ + void SetAlgo(const std::string &m_algo); + + /** + * @brief Get the Key Size Str object + * + * @return std::string + */ + [[nodiscard]] std::string GetKeySizeStr() const; + + /** + * @brief Get the Key Size object + * + * @return int + */ + [[nodiscard]] int GetKeyLength() const { return key_size_; } + + /** + * @brief Set the Key Size object + * + * @param m_key_size + */ + void SetKeyLength(int m_key_size); + + /** + * @brief Get the Expired object + * + * @return const boost::posix_time::ptime& + */ + [[nodiscard]] const boost::posix_time::ptime &GetExpireTime() const { + return expired_; + } + + /** + * @brief Set the Expired object + * + * @param m_expired + */ + void SetExpireTime(const boost::posix_time::ptime &m_expired); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsNonExpired() const { return non_expired_; } + + /** + * @brief Set the Non Expired object + * + * @param m_non_expired + */ + void SetNonExpired(bool m_non_expired); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsNoPassPhrase() const { return this->no_passphrase_; } + + /** + * @brief Set the Non Pass Phrase object + * + * @param m_non_pass_phrase + */ + void SetNonPassPhrase(bool m_non_pass_phrase) { + GenKeyInfo::no_passphrase_ = m_non_pass_phrase; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowSigning() const { return allow_signing_; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowNoPassPhrase() const { + return allow_no_pass_phrase_; + } + + /** + * @brief Set the Allow Signing object + * + * @param m_allow_signing + */ + void SetAllowSigning(bool m_allow_signing) { + if (allow_change_signing_) GenKeyInfo::allow_signing_ = m_allow_signing; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowEncryption() const { return allow_encryption_; } + + /** + * @brief Set the Allow Encryption object + * + * @param m_allow_encryption + */ + void SetAllowEncryption(bool m_allow_encryption); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowCertification() const { + return allow_certification_; + } + + /** + * @brief Set the Allow Certification object + * + * @param m_allow_certification + */ + void SetAllowCertification(bool m_allow_certification); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowAuthentication() const { + return allow_authentication_; + } + + /** + * @brief Set the Allow Authentication object + * + * @param m_allow_authentication + */ + void SetAllowAuthentication(bool m_allow_authentication) { + if (allow_change_authentication_) + GenKeyInfo::allow_authentication_ = m_allow_authentication; + } + + /** + * @brief Get the Pass Phrase object + * + * @return const std::string& + */ + [[nodiscard]] const std::string &GetPassPhrase() const { return passphrase_; } + + /** + * @brief Set the Pass Phrase object + * + * @param m_pass_phrase + */ + void SetPassPhrase(const std::string &m_pass_phrase) { + GenKeyInfo::passphrase_ = m_pass_phrase; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowChangeSigning() const { + return allow_change_signing_; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowChangeEncryption() const { + return allow_change_encryption_; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowChangeCertification() const { + return allow_change_certification_; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsAllowChangeAuthentication() const { + return allow_change_authentication_; + } + + /** + * @brief Get the Suggest Max Key Size object + * + * @return int + */ + [[nodiscard]] int GetSuggestMaxKeySize() const { + return suggest_max_key_size_; + } + + /** + * @brief Get the Suggest Min Key Size object + * + * @return int + */ + [[nodiscard]] int GetSuggestMinKeySize() const { + return suggest_min_key_size_; + } + + /** + * @brief Get the Size Change Step object + * + * @return int + */ + [[nodiscard]] int GetSizeChangeStep() const { + return suggest_size_addition_step_; + } + + private: + bool allow_encryption_ = true; ///< + bool allow_change_encryption_ = true; ///< + bool allow_certification_ = true; ///< + bool allow_change_certification_ = true; ///< + bool allow_authentication_ = true; ///< + bool allow_change_authentication_ = true; ///< + bool allow_signing_ = true; ///< + bool allow_change_signing_ = true; ///< + + /** + * @brief + * + */ + void reset_options(); + + public: + /** + * @brief Construct a new Gen Key Info object + * + * @param m_is_sub_key + * @param m_standalone + */ + explicit GenKeyInfo(bool m_is_sub_key = false, bool m_standalone = false); +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGGENKEYINFO_H diff --git a/src/gpg/GpgInfo.cpp b/src/core/GpgInfo.cpp index 392dcf08..a77f0ed4 100644 --- a/src/gpg/GpgInfo.cpp +++ b/src/core/GpgInfo.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,20 +8,22 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/GpgInfo.h" +#include "core/GpgInfo.h" diff --git a/src/core/GpgInfo.h b/src/core/GpgInfo.h new file mode 100644 index 00000000..71c5f9a9 --- /dev/null +++ b/src/core/GpgInfo.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H +#define GPGFRONTEND_ZH_CN_TS_GPGINFO_H + +#include <string> + +namespace GpgFrontend { +/** + * @brief Use to record some info about gnupg + * + */ +class GpgInfo { + public: + std::string AppPath; ///< executable binary path of gnupg + std::string DatabasePath; ///< + std::string GnupgVersion; ///< + std::string GpgConfPath; ///< + std::string CMSPath; ///< + std::string GpgMEVersion; ///< +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H diff --git a/src/core/GpgModel.h b/src/core/GpgModel.h new file mode 100644 index 00000000..e3d43332 --- /dev/null +++ b/src/core/GpgModel.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H +#define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H + +#include <list> +#include <utility> + +#include "GpgConstants.h" +#include "core/model/GpgData.h" +#include "core/model/GpgKey.h" +#include "core/model/GpgSignature.h" + +namespace GpgFrontend { + +using KeyId = std::string; ///< +using SubkeyId = std::string; ///< +using KeyIdArgsList = std::vector<KeyId>; ///< +using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>; ///< +using UIDArgsList = std::vector<std::string>; ///< +using UIDArgsListPtr = std::unique_ptr<UIDArgsList>; ///< +using SignIdArgsList = std::vector<std::pair<std::string, std::string>>; ///< +using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; ///< +using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>; ///< +using KeyArgsList = std::vector<GpgKey>; ///< +using KeyListPtr = std::unique_ptr<KeyArgsList>; ///< +using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>; ///< +using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///< +using KeyPtr = std::unique_ptr<GpgKey>; ///< +using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///< + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_ZH_CN_TS_GPGMODEL_H diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp new file mode 100644 index 00000000..1a1ffaec --- /dev/null +++ b/src/core/function/ArchiveFileOperator.cpp @@ -0,0 +1,294 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "ArchiveFileOperator.h" + +int copy_data(struct archive *ar, struct archive *aw) { + int r; + const void *buff; + size_t size; + int64_t offset; + + for (;;) { + r = archive_read_data_block(ar, &buff, &size, &offset); + if (r == ARCHIVE_EOF) return (ARCHIVE_OK); + if (r != ARCHIVE_OK) { + LOG(ERROR) << "archive_read_data_block() failed: " + << archive_error_string(ar); + return (r); + } + r = archive_write_data_block(aw, buff, size, offset); + if (r != ARCHIVE_OK) { + LOG(ERROR) << "archive_write_data_block() failed: " + << archive_error_string(aw); + return (r); + } + } +} + +void GpgFrontend::ArchiveFileOperator::CreateArchive( + const std::filesystem::path &base_path, + const std::filesystem::path &archive_path, int compress, + const std::vector<std::filesystem::path> &files) { + LOG(INFO) << "CreateArchive: " << archive_path.u8string(); + + auto current_base_path_backup = QDir::currentPath(); + QDir::setCurrent(base_path.u8string().c_str()); + + auto relative_archive_path = + std::filesystem::relative(archive_path, base_path); + + std::vector<std::filesystem::path> relative_files; + relative_files.reserve(files.size()); + for (const auto &file : files) { + relative_files.push_back(std::filesystem::relative(file, base_path)); + } + + struct archive *a; + struct archive_entry *entry; + ssize_t len; + int fd; + + LOG(INFO) << "compress: " << compress; + + a = archive_write_new(); + switch (compress) { +#ifndef NO_BZIP2_CREATE + case 'j': + case 'y': + archive_write_add_filter_bzip2(a); + break; +#endif +#ifndef NO_COMPRESS_CREATE + case 'Z': + archive_write_add_filter_compress(a); + break; +#endif +#ifndef NO_GZIP_CREATE + case 'z': + archive_write_add_filter_gzip(a); + break; +#endif + default: + archive_write_add_filter_none(a); + break; + } + archive_write_set_format_ustar(a); + archive_write_set_format_pax_restricted(a); + + auto u8_filename = relative_archive_path.u8string(); + + if (!u8_filename.empty() && u8_filename == u8"-") + throw std::runtime_error("cannot write to stdout"); + +#ifdef WINDOWS + archive_write_open_filename_w(a, relative_archive_path.wstring().c_str()); +#else + archive_write_open_filename(a, u8_filename.c_str()); +#endif + + for (const auto &file : relative_files) { + struct archive *disk = archive_read_disk_new(); +#ifndef NO_LOOKUP + archive_read_disk_set_standard_lookup(disk); +#endif + int r; + + LOG(INFO) << "reading file: " << file.u8string(); + +#ifdef WINDOWS + r = archive_read_disk_open_w(disk, file.wstring().c_str()); +#else + r = archive_read_disk_open(disk, file.u8string().c_str()); +#endif + + LOG(INFO) << "read file done: " << file.u8string(); + + if (r != ARCHIVE_OK) { + LOG(ERROR) << "archive_read_disk_open() failed: " + << archive_error_string(disk); + throw std::runtime_error("archive_read_disk_open() failed"); + } + + for (;;) { + bool needcr = false; + + entry = archive_entry_new(); + r = archive_read_next_header2(disk, entry); + + if (r == ARCHIVE_EOF) break; + if (r != ARCHIVE_OK) { + LOG(ERROR) << "archive_read_next_header2() failed: " + << archive_error_string(disk); + throw std::runtime_error("archive_read_next_header2() failed"); + } + archive_read_disk_descend(disk); + +#ifdef WINDOWS + auto entry_path = + QString::fromStdWString(std::wstring(archive_entry_pathname_w(entry))).toUtf8() + .toStdString(); +#else + auto entry_path = std::string(archive_entry_pathname_utf8(entry)); +#endif + + LOG(INFO) << "Adding: " << archive_entry_pathname_utf8(entry) << "size" + << archive_entry_size(entry) << " bytes" + << "file type" << archive_entry_filetype(entry); + + + r = archive_write_header(a, entry); + if (r < ARCHIVE_OK) { + LOG(ERROR) << "archive_write_header() failed: " + << archive_error_string(a); + throw std::runtime_error("archive_write_header() failed"); + } + if (r == ARCHIVE_FATAL) throw std::runtime_error("archive fatal"); + if (r > ARCHIVE_FAILED) { + QByteArray buff; +#ifdef WINDOWS + FileOperator::ReadFile( + QString::fromStdWString(archive_entry_sourcepath_w(entry)), buff); +#else + FileOperator::ReadFile(archive_entry_sourcepath(entry), buff); +#endif + archive_write_data(a, buff.data(), buff.size()); + } + archive_entry_free(entry); + } + archive_read_close(disk); + archive_read_free(disk); + } + archive_write_close(a); + archive_write_free(a); + + QDir::setCurrent(current_base_path_backup); +} + +void GpgFrontend::ArchiveFileOperator::ExtractArchive( + const std::filesystem::path &archive_path, + const std::filesystem::path &base_path) { + LOG(INFO) << "ExtractArchive: " << archive_path.u8string(); + + auto current_base_path_backup = QDir::currentPath(); + QDir::setCurrent(base_path.u8string().c_str()); + + struct archive *a; + struct archive *ext; + struct archive_entry *entry; + int r; + + a = archive_read_new(); + ext = archive_write_disk_new(); + archive_write_disk_set_options(ext, 0); +#ifndef NO_BZIP2_EXTRACT + archive_read_support_filter_bzip2(a); +#endif +#ifndef NO_GZIP_EXTRACT + archive_read_support_filter_gzip(a); +#endif +#ifndef NO_COMPRESS_EXTRACT + archive_read_support_filter_compress(a); +#endif +#ifndef NO_TAR_EXTRACT + archive_read_support_format_tar(a); +#endif +#ifndef NO_CPIO_EXTRACT + archive_read_support_format_cpio(a); +#endif +#ifndef NO_LOOKUP + archive_write_disk_set_standard_lookup(ext); +#endif + + auto filename = archive_path.u8string(); + + if (!filename.empty() && filename == u8"-") { + LOG(ERROR) << "cannot read from stdin"; + } +#ifdef WINDOWS + if ((r = archive_read_open_filename_w(a, archive_path.wstring().c_str(), + 10240))) { +#else + if ((r = archive_read_open_filename(a, archive_path.u8string().c_str(), + 10240))) { +#endif + LOG(ERROR) << "archive_read_open_filename() failed: " + << archive_error_string(a); + throw std::runtime_error("archive_read_open_filename() failed"); + } + for (;;) { + r = archive_read_next_header(a, &entry); + if (r == ARCHIVE_EOF) break; + if (r != ARCHIVE_OK) { + LOG(ERROR) << "archive_read_next_header() failed: " + << archive_error_string(a); + throw std::runtime_error("archive_read_next_header() failed"); + } + LOG(INFO) << "Extracting: " << archive_entry_pathname(entry) << "size" + << archive_entry_size(entry) << " bytes" + << "file type" << archive_entry_filetype(entry); + r = archive_write_header(ext, entry); + if (r != ARCHIVE_OK) { + LOG(ERROR) << "archive_write_header() failed: " + << archive_error_string(ext); + } else { + r = copy_data(a, ext); + if (r != ARCHIVE_OK) { + LOG(ERROR) << "copy_data() failed: " << archive_error_string(ext); + } + } + } + archive_read_close(a); + archive_read_free(a); + + archive_write_close(ext); + archive_write_free(ext); + + QDir::setCurrent(current_base_path_backup); +} + +void GpgFrontend::ArchiveFileOperator::ListArchive( + const std::filesystem::path &archive_path) { + struct archive *a; + struct archive_entry *entry; + int r; + + a = archive_read_new(); + archive_read_support_filter_all(a); + archive_read_support_format_all(a); + r = archive_read_open_filename(a, archive_path.u8string().c_str(), + 10240); // Note 1 + if (r != ARCHIVE_OK) return; + while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { + LOG(INFO) << "File: " << archive_entry_pathname(entry); + LOG(INFO) << "File Path: " << archive_entry_pathname(entry); + archive_read_data_skip(a); // Note 2 + } + r = archive_read_free(a); // Note 3 + if (r != ARCHIVE_OK) return; +} diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h new file mode 100644 index 00000000..324d9d53 --- /dev/null +++ b/src/core/function/ArchiveFileOperator.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_ARCHIVEFILEOPERATOR_H +#define GPGFRONTEND_ARCHIVEFILEOPERATOR_H + +#include "core/GpgFrontendCore.h" +#include "core/function/FileOperator.h" + +namespace GpgFrontend { + +struct ArchiveStruct { + struct archive *archive; + struct archive_entry *entry; + int fd; + bool is_open; + std::string name; +}; + +class ArchiveFileOperator { + public: + static void ListArchive(const std::filesystem::path &archive_path); + + static void CreateArchive( + const std::filesystem::path &base_path, + const std::filesystem::path &archive_path, + int compress, + const std::vector<std::filesystem::path> &files); + + static void ExtractArchive( + const std::filesystem::path &archive_path, + const std::filesystem::path &base_path); +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_ARCHIVEFILEOPERATOR_H diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp new file mode 100644 index 00000000..1e216dd6 --- /dev/null +++ b/src/core/function/DataObjectOperator.cpp @@ -0,0 +1,169 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "DataObjectOperator.h" + +#include <qt-aes/qaesencryption.h> + +#include "core/function/FileOperator.h" +#include "core/function/PassphraseGenerator.h" + +void GpgFrontend::DataObjectOperator::init_app_secure_key() { + LOG(INFO) << "Initializing application secure key"; + FileOperator::WriteFileStd(app_secure_key_path_, + PassphraseGenerator::GetInstance().Generate(256)); + std::filesystem::permissions( + app_secure_key_path_, + std::filesystem::perms::owner_read | std::filesystem::perms::owner_write); +} + +GpgFrontend::DataObjectOperator::DataObjectOperator(int channel) + : SingletonFunctionObject<DataObjectOperator>(channel) { + if (!is_directory(app_secure_path_)) create_directory(app_secure_path_); + + if (!exists(app_secure_key_path_)) { + init_app_secure_key(); + } + + std::string key; + if (!FileOperator::ReadFileStd(app_secure_key_path_.u8string(), key)) { + LOG(FATAL) << _("Failed to read app secure key file") + << app_secure_key_path_; + throw std::runtime_error(_("Failed to read app secure key file")); + } + hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key), + QCryptographicHash::Sha256); + LOG(INFO) << "App secure key loaded" << hash_key_.size() << "bytes"; + + if (!exists(app_data_objs_path_)) create_directory(app_data_objs_path_); +} + +std::string GpgFrontend::DataObjectOperator::SaveDataObj( + const std::string& _key, const nlohmann::json& value) { + + std::string _hash_obj_key = {}; + if (_key.empty()) { + _hash_obj_key = + QCryptographicHash::hash( + hash_key_ + QByteArray::fromStdString( + PassphraseGenerator::GetInstance().Generate(32) + + to_iso_extended_string( + boost::posix_time::second_clock::local_time())), + QCryptographicHash::Sha256) + .toHex() + .toStdString(); + } else { + _hash_obj_key = + QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key), + QCryptographicHash::Sha256) + .toHex() + .toStdString(); + } + + const auto obj_path = app_data_objs_path_ / _hash_obj_key; + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + auto encoded = + encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_); + + LOG(INFO) << _("Saving data object") << _hash_obj_key << "to" << obj_path << encoded.size() << "bytes"; + + FileOperator::WriteFileStd(obj_path.u8string(), encoded.toStdString()); + + return _key.empty() ? _hash_obj_key : std::string(); +} + +std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject( + const std::string& _key) { + try { + LOG(INFO) << _("Get data object") << _key; + auto _hash_obj_key = + QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key), + QCryptographicHash::Sha256) + .toHex() + .toStdString(); + + const auto obj_path = app_data_objs_path_ / _hash_obj_key; + + if (!std::filesystem::exists(obj_path)) { + LOG(ERROR) << _("Data object not found") << _key; + return {}; + } + + std::string buffer; + if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) { + LOG(ERROR) << _("Failed to read data object") << _key; + return {}; + } + + LOG(INFO) << _("Data object found") << _key; + + auto encoded = QByteArray::fromStdString(buffer); + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + + LOG(INFO) << _("Decrypting data object") << encoded.size() << hash_key_.size(); + + auto decoded = + encryption.removePadding(encryption.decode(encoded, hash_key_)); + + LOG(INFO) << _("Data object decoded") << _key; + + return nlohmann::json::parse(decoded.toStdString()); + } catch (...) { + LOG(ERROR) << _("Failed to get data object") << _key; + return {}; + } +} + +std::optional<nlohmann::json> +GpgFrontend::DataObjectOperator::GetDataObjectByRef(const std::string& _ref) { + if (_ref.size() != 64) return {}; + + try { + const auto& _hash_obj_key = _ref; + const auto obj_path = app_data_objs_path_ / _hash_obj_key; + + if (!std::filesystem::exists(obj_path)) return {}; + + std::string buffer; + if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) return {}; + auto encoded = QByteArray::fromStdString(buffer); + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + + auto decoded = + encryption.removePadding(encryption.decode(encoded, hash_key_)); + + return nlohmann::json::parse(decoded.toStdString()); + } catch (...) { + return {}; + } +} diff --git a/src/core/function/DataObjectOperator.h b/src/core/function/DataObjectOperator.h new file mode 100644 index 00000000..0ce4e313 --- /dev/null +++ b/src/core/function/DataObjectOperator.h @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_DATAOBJECTOPERATOR_H +#define GPGFRONTEND_DATAOBJECTOPERATOR_H + +#include <json/single_include/nlohmann/json.hpp> + +#include "core/GpgFrontendCore.h" +#include "core/GpgFunctionObject.h" +#include "core/function/GlobalSettingStation.h" + +namespace GpgFrontend { + +class DataObjectOperator : public SingletonFunctionObject<DataObjectOperator> { + public: + /** + * @brief DataObjectOperator constructor + * + * @param channel channel + */ + explicit DataObjectOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()); + + std::string SaveDataObj(const std::string &_key, const nlohmann::json &value); + + std::optional<nlohmann::json> GetDataObject(const std::string &_key); + + std::optional<nlohmann::json> GetDataObjectByRef(const std::string &_ref); + + private: + /** + * @brief init the secure key of application data object + * + */ + void init_app_secure_key(); + + GlobalSettingStation &global_setting_station_ = + GlobalSettingStation::GetInstance(); ///< GlobalSettingStation + std::filesystem::path app_secure_path_ = + global_setting_station_.GetAppConfigPath() / + "secure"; ///< Where sensitive information is stored + std::filesystem::path app_secure_key_path_ = + app_secure_path_ / "app.key"; ///< Where the key of data object is stored + std::filesystem::path app_data_objs_path_ = + global_setting_station_.GetAppDataPath() / "data_objs"; ///< Where data + ///< object is + ///< stored + + std::random_device rd_; ///< Random device + std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister + QByteArray hash_key_; ///< Hash key +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_DATAOBJECTOPERATOR_H diff --git a/src/core/function/FileOperator.cpp b/src/core/function/FileOperator.cpp new file mode 100644 index 00000000..4977b3a9 --- /dev/null +++ b/src/core/function/FileOperator.cpp @@ -0,0 +1,122 @@ +/** +* Copyright (C) 2021 Saturneric +* +* This file is part of GpgFrontend. +* +* GpgFrontend is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GpgFrontend is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +* +* The initial version of the source code is inherited from +* the gpg4usb project, which is under GPL-3.0-or-later. +* +* All the source code of GpgFrontend was modified and released by +* Saturneric<[email protected]> starting on May 12, 2021. +* +* SPDX-License-Identifier: GPL-3.0-or-later +* +*/ + +#include "FileOperator.h" + +bool GpgFrontend::FileOperator::ReadFile(const QString& file_name, + QByteArray& data) { + QFile file(file_name); + if (!file.open(QIODevice::ReadOnly)) { + LOG(ERROR) << "failed to open file" << file_name.toStdString(); + return false; + } + data = file.readAll(); + file.close(); + return true; +} + +bool GpgFrontend::FileOperator::WriteFile(const QString& file_name, + const QByteArray& data) { + QFile file(file_name); + if (!file.open(QIODevice::WriteOnly)) { + LOG(ERROR) << "failed to open file" << file_name.toStdString(); + return false; + } + file.write(data); + file.close(); + return true; +} + +bool GpgFrontend::FileOperator::ReadFileStd( + const std::filesystem::path& file_name, std::string& data) { + QByteArray byte_data; +#ifdef WINDOWS + bool res = ReadFile(QString::fromStdU16String(file_name.u16string()).toUtf8(), byte_data); +#else + bool res = ReadFile(QString::fromStdString(file_name.u8string()).toUtf8(), byte_data); +#endif + data = byte_data.toStdString(); + return res; +} + +bool GpgFrontend::FileOperator::WriteFileStd( + const std::filesystem::path& file_name, const std::string& data) { + return WriteFile(QString::fromStdString(file_name.u8string()).toUtf8(), QByteArray::fromStdString(data)); +} + +std::string GpgFrontend::FileOperator::CalculateHash( + const std::filesystem::path& file_path) { + // Returns empty QByteArray() on failure. + QFileInfo info(QString::fromStdString(file_path.string())); + std::stringstream ss; + + if (info.isFile() && info.isReadable()) { + ss << "[#] " << _("File Hash Information") << std::endl; + ss << " " << _("filename") << _(": ") + << file_path.filename().u8string().c_str() << std::endl; + + + QFile f(info.filePath()); + f.open(QFile::ReadOnly); + auto buffer = f.readAll(); + ss << " " << _("file size(bytes)") << _(": ") + << buffer.size() << std::endl; + f.close(); + if (f.open(QFile::ReadOnly)) { + auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5); + // md5 + hash_md5.addData(buffer); + auto md5 = hash_md5.result().toHex().toStdString(); + LOG(INFO) << "md5" << md5; + ss << " " + << "md5" << _(": ") << md5 << std::endl; + + auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1); + // sha1 + hash_sha1.addData(buffer); + auto sha1 = hash_sha1.result().toHex().toStdString(); + LOG(INFO) << "sha1" << sha1; + ss << " " + << "sha1" << _(": ") << sha1 << std::endl; + + auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256); + // sha1 + hash_sha256.addData(buffer); + auto sha256 = hash_sha256.result().toHex().toStdString(); + LOG(INFO) << "sha256" << sha256; + ss << " " + << "sha256" << _(": ") << sha256 << std::endl; + + ss << std::endl; + } + } else { + ss << "[#] " << _("Error in Calculating File Hash ") << std::endl; + } + + return ss.str(); +} diff --git a/src/core/function/FileOperator.h b/src/core/function/FileOperator.h new file mode 100644 index 00000000..aa2c3b73 --- /dev/null +++ b/src/core/function/FileOperator.h @@ -0,0 +1,92 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_FILEOPERATOR_H +#define GPGFRONTEND_FILEOPERATOR_H + +#include "core/GpgFrontendCore.h" + +namespace GpgFrontend { + +/** + * @brief provides file operations + * + */ +class FileOperator { + public: + /** + * @brief read file content using std struct + * + * + * @param file_name file name + * @param data data read from file + * @return + */ + static bool ReadFileStd(const std::filesystem::path &file_name, + std::string &data); + + /** + * @brief write file content using std struct + * + * @param file_name file name + * @param data data to write to file + * @return + */ + static bool WriteFileStd(const std::filesystem::path &file_name, + const std::string &data); + + /** + * @brief read file content + * + * @param file_name file name + * @param data data read from file + * @return true if success + * @return false if failed + */ + static bool ReadFile(const QString &file_name, QByteArray &data); + + /** + * @brief write file content + * + * @param file_name file name + * @param data data to write to file + * @return true if success + * @return false if failed + */ + static bool WriteFile(const QString &file_name, const QByteArray &data); + + /** + * calculate the hash of a file + * @param file_path + * @return + */ + static std::string CalculateHash(const std::filesystem::path &file_path); +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_FILEOPERATOR_H diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp new file mode 100644 index 00000000..8850cbe4 --- /dev/null +++ b/src/core/function/GlobalSettingStation.cpp @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GlobalSettingStation.h" + +#include <openssl/bio.h> +#include <openssl/pem.h> + +#include <vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp> +#include <vmime/vmime.hpp> + +#include "core/function/FileOperator.h" + +void GpgFrontend::GlobalSettingStation::SyncSettings() noexcept { + using namespace libconfig; + try { + ui_cfg_.writeFile(ui_config_path_.u8string().c_str()); + LOG(INFO) << _("Updated ui configuration successfully written to") + << ui_config_path_; + + } catch (const FileIOException &fioex) { + LOG(ERROR) << _("I/O error while writing ui configuration file") + << ui_config_path_; + } +} + +GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept + : SingletonFunctionObject<GlobalSettingStation>(channel) { + using namespace std::filesystem; + using namespace libconfig; + + el::Loggers::addFlag(el::LoggingFlag::AutoSpacing); + + LOG(INFO) << _("App Path") << app_path_; + LOG(INFO) << _("App Configure Path") << app_configure_path_; + LOG(INFO) << _("App Data Path") << app_data_path_; + LOG(INFO) << _("App Log Path") << app_log_path_; + LOG(INFO) << _("App Locale Path") << app_locale_path_; + + if (!is_directory(app_configure_path_)) create_directory(app_configure_path_); + + if (!is_directory(app_data_path_)) create_directory(app_data_path_); + + if (!is_directory(app_log_path_)) create_directory(app_log_path_); + + if (!is_directory(ui_config_dir_path_)) create_directory(ui_config_dir_path_); + + if (!exists(ui_config_path_)) { + try { + this->ui_cfg_.writeFile(ui_config_path_.u8string().c_str()); + LOG(INFO) << _("UserInterface configuration successfully written to") + << ui_config_path_; + + } catch (const FileIOException &fioex) { + LOG(ERROR) + << _("I/O error while writing UserInterface configuration file") + << ui_config_path_; + } + } else { + try { + this->ui_cfg_.readFile(ui_config_path_.u8string().c_str()); + LOG(INFO) << _("UserInterface configuration successfully read from") + << ui_config_path_; + } catch (const FileIOException &fioex) { + LOG(ERROR) << _("I/O error while reading UserInterface configure file"); + } catch (const ParseException &pex) { + LOG(ERROR) << _("Parse error at ") << pex.getFile() << ":" + << pex.getLine() << " - " << pex.getError(); + } + } +} + +void GpgFrontend::GlobalSettingStation::AddRootCert( + const std::filesystem::path &path) { + std::string out_buffer; + if (!FileOperator::ReadFileStd(path, out_buffer)) { + LOG(ERROR) << _("Failed to read root certificate file") << path; + return; + } + + auto mem_bio = std::shared_ptr<BIO>( + BIO_new_mem_buf(out_buffer.data(), static_cast<int>(out_buffer.size())), + [](BIO *_p) { BIO_free(_p); }); + + auto x509 = std::shared_ptr<X509>( + PEM_read_bio_X509(mem_bio.get(), nullptr, nullptr, nullptr), + [](X509 *_p) { X509_free(_p); }); + + if (!x509) return; + + root_certs_.push_back(x509); +} + +vmime::shared_ptr<vmime::security::cert::defaultCertificateVerifier> +GpgFrontend::GlobalSettingStation::GetCertVerifier() const { + auto p_cv = + vmime::make_shared<vmime::security::cert::defaultCertificateVerifier>(); + + std::vector<vmime::shared_ptr<vmime::security::cert::X509Certificate>> + _root_certs; + for (const auto &cert : root_certs_) { + _root_certs.push_back( + std::make_shared<vmime::security::cert::X509Certificate_OpenSSL>( + cert.get())); + } + return p_cv; +} + +const std::vector<std::shared_ptr<X509>> + &GpgFrontend::GlobalSettingStation::GetRootCerts() { + return root_certs_; +} + +void GpgFrontend::GlobalSettingStation::init_app_secure_key() {} + +GpgFrontend::GlobalSettingStation::~GlobalSettingStation() noexcept = default; diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h new file mode 100644 index 00000000..d6521c8a --- /dev/null +++ b/src/core/function/GlobalSettingStation.h @@ -0,0 +1,232 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H +#define GPGFRONTEND_GLOBALSETTINGSTATION_H + +#include <openssl/x509.h> + +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> + +#include "GpgFrontendBuildInstallInfo.h" +#include "core/GpgFrontendCore.h" +#include "core/GpgFunctionObject.h" + +namespace vmime::security::cert { +class defaultCertificateVerifier; +class X509Certificate; +} // namespace vmime::security::cert + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GlobalSettingStation + : public SingletonFunctionObject<GlobalSettingStation> { + public: + /** + * @brief Construct a new Global Setting Station object + * + */ + explicit GlobalSettingStation( + int channel = SingletonFunctionObject::GetDefaultChannel()) noexcept; + + /** + * @brief Destroy the Global Setting Station object + * + */ + ~GlobalSettingStation() noexcept override; + + /** + * @brief + * + * @return libconfig::Setting& + */ + libconfig::Setting &GetUISettings() noexcept { return ui_cfg_.getRoot(); } + + /** + * @brief Get the App Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetAppDir() const { return app_path_; } + + [[nodiscard]] std::filesystem::path GetAppDataPath() const { + return app_data_path_; + } + + /** + * @brief Get the Log Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetLogDir() const { + return app_log_path_; + } + + /** + * @brief Get the Standalone Database Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetStandaloneDatabaseDir() const { + auto db_path = app_configure_path_ / "db"; + if (!std::filesystem::exists(db_path)) { + std::filesystem::create_directory(db_path); + } + return db_path; + } + + [[nodiscard]] std::filesystem::path GetAppConfigPath() const { + return app_configure_path_; + } + + /** + * @brief Get the Standalone Gpg Bin Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetStandaloneGpgBinDir() const { + return app_resource_path_ / "gpg1.4" / "gpg"; + } + + /** + * @brief Get the Locale Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetLocaleDir() const { + return app_locale_path_; + } + + /** + * @brief Get the Resource Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetResourceDir() const { + return app_resource_path_; + } + + /** + * @brief Get the Certs Dir object + * + * @return std::filesystem::path + */ + [[nodiscard]] std::filesystem::path GetCertsDir() const { + return app_resource_path_ / "certs"; + } + + /** + * @brief Get the Cert Verifier object + * + * @return std::shared_ptr< + * vmime::security::cert::defaultCertificateVerifier> + */ + [[nodiscard]] std::shared_ptr< + vmime::security::cert::defaultCertificateVerifier> + GetCertVerifier() const; + + /** + * @brief + * + * @param path + */ + void AddRootCert(const std::filesystem::path &path); + + /** + * @brief Get the Root Certs object + * + * @return const std::vector<std::shared_ptr<X509>>& + */ + const std::vector<std::shared_ptr<X509>> &GetRootCerts(); + + /** + * @brief + * + */ + void ResetRootCerts() { root_certs_.clear(); } + + /** + * @brief sync the settings to the file + * + */ + void SyncSettings() noexcept; + + private: + std::filesystem::path app_path_ = + qApp->applicationDirPath().toStdString(); ///< Program Location + std::filesystem::path app_data_path_ = + QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + .toStdString(); ///< Program Data Location + std::filesystem::path app_log_path_ = + app_data_path_ / "logs"; ///< Program Data Location + std::filesystem::path app_data_objs_path_ = + app_data_path_ / "objs"; ///< Object storage path + +#ifdef LINUX_INSTALL_BUILD + std::filesystem::path app_resource_path_ = + std::filesystem::path(APP_LOCALSTATE_PATH) / + "gpgfrontend"; ///< Program Data Location +#else + std::filesystem::path app_resource_path_ = + RESOURCE_DIR_BOOST_PATH(app_path_); ///< Program Data Location +#endif + +#ifdef LINUX_INSTALL_BUILD + std::filesystem::path app_locale_path_ = + std::string(APP_LOCALE_PATH); ///< Program Data Location +#else + std::filesystem::path app_locale_path_ = + app_resource_path_ / "locales"; ///< Program Data Location +#endif + + std::filesystem::path app_configure_path_ = + QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + .toStdString(); ///< Program Configure Location + std::filesystem::path ui_config_dir_path_ = + app_configure_path_ / + "UserInterface"; ///< Configure File Directory Location + std::filesystem::path ui_config_path_ = + ui_config_dir_path_ / "ui.cfg"; ///< UI Configure File Location + + libconfig::Config ui_cfg_; ///< + std::vector<std::shared_ptr<X509>> root_certs_; ///< + + /** + * @brief + * + */ + void init_app_secure_key(); +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp new file mode 100644 index 00000000..67fa3fac --- /dev/null +++ b/src/core/function/KeyPackageOperator.cpp @@ -0,0 +1,120 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "KeyPackageOperator.h" + +#include "FileOperator.h" +#include "function/PassphraseGenerator.h" +#include "function/gpg/GpgKeyGetter.h" +#include "function/gpg/GpgKeyImportExporter.h" +#include "qt-aes/qaesencryption.h" + +namespace GpgFrontend { + +bool KeyPackageOperator::GeneratePassphrase( + const std::filesystem::path& phrase_path, std::string& phrase) { + phrase = PassphraseGenerator::GetInstance().Generate(256); + LOG(INFO) << "Generated passphrase: " << phrase.size() << " bytes"; + return FileOperator::WriteFileStd(phrase_path, phrase); +} + +bool KeyPackageOperator::GenerateKeyPackage( + const std::filesystem::path& key_package_path, + const std::string& key_package_name, KeyIdArgsListPtr& key_ids, + std::string& phrase, bool secret) { + LOG(INFO) << "Generating key package: " << key_package_name; + + ByteArrayPtr key_export_data = nullptr; + if (!GpgKeyImportExporter::GetInstance().ExportKeys(key_ids, key_export_data, + secret)) { + LOG(ERROR) << "Failed to export keys"; + return false; + } + + auto key = QByteArray::fromStdString(phrase); + auto data = QString::fromStdString(*key_export_data).toLocal8Bit().toBase64(); + + auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256); + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + auto encoded = encryption.encode(data, hash_key); + + LOG(INFO) << "Writing key package: " << key_package_name; + return FileOperator::WriteFileStd(key_package_path, encoded.toStdString()); +} + +bool KeyPackageOperator::ImportKeyPackage( + const std::filesystem::path& key_package_path, + const std::filesystem::path& phrase_path, + GpgFrontend::GpgImportInformation& import_info) { + + LOG(INFO) << "Importing key package: " << key_package_path.u8string(); + + std::string encrypted_data; + FileOperator::ReadFileStd(key_package_path, encrypted_data); + + if (encrypted_data.empty()) { + LOG(ERROR) << "Failed to read key package: " << key_package_path.u8string(); + return false; + }; + + std::string passphrase; + FileOperator::ReadFileStd(phrase_path, passphrase); + LOG(INFO) << "Passphrase: " << passphrase.size() << " bytes"; + if (passphrase.size() != 256) { + LOG(ERROR) << "Failed to read passphrase: " << phrase_path.u8string(); + return false; + } + + auto hash_key = QCryptographicHash::hash( + QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256); + auto encoded = QByteArray::fromStdString(encrypted_data); + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + + auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key)); + auto key_data = QByteArray::fromBase64(decoded); + + LOG(INFO) << "key data" << key_data.size(); + if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) && + !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) { + return false; + } + + auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString()); + import_info = + GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr)); + return true; +} + +std::string KeyPackageOperator::GenerateKeyPackageName() { + return generate_key_package_name(); +} + +} // namespace GpgFrontend diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h new file mode 100644 index 00000000..cd344688 --- /dev/null +++ b/src/core/function/KeyPackageOperator.h @@ -0,0 +1,107 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_KEYPACKAGEOPERATOR_H +#define GPGFRONTEND_KEYPACKAGEOPERATOR_H + +#include "core/GpgFrontendCore.h" +#include "core/function/gpg/GpgKeyImportExporter.h" + +namespace GpgFrontend { + +/** + * @brief give the possibility to import or export a key package + * + */ +class KeyPackageOperator { + public: + /** + * @brief generate passphrase for key package and save it to file + * + * @param phrase_path path to passphrase file + * @param phrase passphrase generated + * @return true if passphrase was generated and saved + * @return false if passphrase was not generated and saved + */ + static bool GeneratePassphrase(const std::filesystem::path &phrase_path, + std::string &phrase); + + /** + * @brief generate the name of the key package + * + * @return std::string name of the key package + */ + static std::string GenerateKeyPackageName(); + + /** + * @brief generate key package + * + * @param key_package_path path to key package + * @param key_package_name name of the key package + * @param key_ids key ids to export + * @param phrase passphrase to encrypt key package + * @param secret true if secret key should be exported + * @return true if key package was generated + * @return false if key package was not generated + */ + static bool GenerateKeyPackage(const std::filesystem::path &key_package_path, + const std::string &key_package_name, + KeyIdArgsListPtr &key_ids, std::string &phrase, + bool secret); + + /** + * @brief import key package + * + * @param key_package_path path to key package + * @param phrase_path path to passphrase file + * @param import_info import info + * @return true if key package was imported + * @return false if key package was not imported + */ + static bool ImportKeyPackage(const std::filesystem::path &key_package_path, + const std::filesystem::path &phrase_path, + GpgFrontend::GpgImportInformation &import_info); + + private: + /** + * @brief generate key package name + * + * @return std::string key package name + */ + static std::string generate_key_package_name() { + std::random_device rd_; ///< Random device + auto mt_ = std::mt19937(rd_()); ///< Mersenne twister + + std::uniform_int_distribution<int> dist(999, 99999); + auto file_string = boost::format("KeyPackage_%1%") % dist(mt_); + return file_string.str(); + } +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_KEYPACKAGEOPERATOR_H diff --git a/src/core/function/PassphraseGenerator.cpp b/src/core/function/PassphraseGenerator.cpp new file mode 100644 index 00000000..0267edda --- /dev/null +++ b/src/core/function/PassphraseGenerator.cpp @@ -0,0 +1,29 @@ +/** +* Copyright (C) 2021 Saturneric +* +* This file is part of GpgFrontend. +* +* GpgFrontend is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GpgFrontend is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +* +* The initial version of the source code is inherited from +* the gpg4usb project, which is under GPL-3.0-or-later. +* +* All the source code of GpgFrontend was modified and released by +* Saturneric<[email protected]> starting on May 12, 2021. +* +* SPDX-License-Identifier: GPL-3.0-or-later +* + */ + +#include "PassphraseGenerator.h" diff --git a/src/core/function/PassphraseGenerator.h b/src/core/function/PassphraseGenerator.h new file mode 100644 index 00000000..d1cc7607 --- /dev/null +++ b/src/core/function/PassphraseGenerator.h @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_PASSPHRASEGENERATOR_H +#define GPGFRONTEND_PASSPHRASEGENERATOR_H + +#include "core/GpgFrontendCore.h" +#include "core/GpgFunctionObject.h" + +namespace GpgFrontend { + +/** + * @brief The PassphraseGenerator class + * + * This class is used to generate a passphrase. + */ +class PassphraseGenerator + : public SingletonFunctionObject<PassphraseGenerator> { + public: + /** + * @brief PassphraseGenerator constructor + * + * @param channel The channel to use + */ + explicit PassphraseGenerator( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<PassphraseGenerator>(channel) {} + + /** + * @brief generate passphrase + * + * @param len length of the passphrase + * @return std::string passphrase + */ + std::string Generate(int len) { + std::uniform_int_distribution<int> dist(999, 99999); + + auto file_string = boost::format("KeyPackage_%1%") % dist(mt_); + static const char alphanum[] = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + std::string tmp_str; + tmp_str.reserve(len); + + for (int i = 0; i < len; ++i) { + tmp_str += alphanum[dist(mt_) % (sizeof(alphanum) - 1)]; + } + return tmp_str; + } + + std::random_device rd_; ///< Random device + std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_PASSPHRASEGENERATOR_H diff --git a/src/core/function/aes/aes_ssl.h b/src/core/function/aes/aes_ssl.h new file mode 100644 index 00000000..b5f0820f --- /dev/null +++ b/src/core/function/aes/aes_ssl.h @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_AES_SSL_H +#define GPGFRONTEND_AES_SSL_H + +#include "GpgFrontend.h" + +#include <openssl/aes.h> +#include <openssl/evp.h> + +namespace GpgFrontend::RawAPI { + +/** + * @brief + * + * @param key_data + * @param key_data_len + * @param salt + * @param e_ctx + * @param d_ctx + * @return int + */ +int aes_256_cbc_init(uint8_t *key_data, int key_data_len, uint8_t *salt, + EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx); + +/** + * @brief + * + * @param e + * @param plaintext + * @param len + * @return uint8_t* + */ +uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len); + +/** + * @brief + * + * @param e + * @param ciphertext + * @param len + * @return uint8_t* + */ +uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len); + +} // namespace GpgFrontend::RawAPI + +#endif // GPGFRONTEND_AES_SSL_H diff --git a/src/core/function/aes/aes_ssl_cbc.cpp b/src/core/function/aes/aes_ssl_cbc.cpp new file mode 100644 index 00000000..95ae0ce2 --- /dev/null +++ b/src/core/function/aes/aes_ssl_cbc.cpp @@ -0,0 +1,99 @@ +/** + * AES encryption/decryption demo program using OpenSSL EVP apis + * gcc -Wall openssl_aes.c -lcrypto + * this is public domain code. + * Saju Pillai ([email protected]) + **/ + +#include "aes_ssl.h" + +namespace GpgFrontend::RawAPI { + +/** + * @brief Create a 256 bit key and IV using the supplied key_data. salt can be + * added for taste. Fills in the encryption and decryption ctx objects and + * returns 0 on success + * + * @param key_data + * @param key_data_len + * @param salt + * @param e_ctx + * @param d_ctx + * @return int + */ +int aes_256_cbc_init(uint8_t *key_data, int key_data_len, uint8_t *salt, + EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx) { + int i, nrounds = 5; + uint8_t key[32], iv[32]; + + /* + * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the + * supplied key material. nrounds is the number of times the we hash the + * material. More rounds are more secure but slower. + */ + i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, + key_data_len, nrounds, key, iv); + if (i != 32) { + printf("Key size is %d bits - should be 256 bits\n", i); + return -1; + } + + EVP_CIPHER_CTX_init(e_ctx); + EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv); + EVP_CIPHER_CTX_init(d_ctx); + EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv); + + return 0; +} + +/** + * @brief Encrypt *len bytes of data All data going in & out is considered + * binary (uint8_t[]) + * + * @param e + * @param plaintext + * @param len + * @return uint8_t* + */ +uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len) { + /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 + * bytes */ + int c_len = *len + AES_BLOCK_SIZE, f_len = 0; + auto *ciphertext = (uint8_t *)malloc(c_len); + + /* allows reusing of 'e' for multiple encryption cycles */ + EVP_EncryptInit_ex(e, nullptr, nullptr, nullptr, nullptr); + + /* update ciphertext, c_len is filled with the length of ciphertext generated, + *len is the size of plaintext in bytes */ + EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len); + + /* update ciphertext with the final remaining bytes */ + EVP_EncryptFinal_ex(e, ciphertext + c_len, &f_len); + + *len = c_len + f_len; + return ciphertext; +} + +/** + * @brief Decrypt *len bytes of ciphertext + * + * @param e + * @param ciphertext + * @param len + * @return uint8_t* + */ +uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len) { + /* plaintext will always be equal to or lesser than length of ciphertext*/ + int p_len = *len, f_len = 0; + auto *plaintext = (uint8_t *)malloc(p_len); + + EVP_DecryptInit_ex(e, nullptr, nullptr, nullptr, nullptr); + EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len); + EVP_DecryptFinal_ex(e, plaintext + p_len, &f_len); + + *len = p_len + f_len; + return plaintext; +} + +} // namespace GpgFrontend::RawAPI
\ No newline at end of file diff --git a/src/gpg/function/BasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp index 0383f8ab..b92404a9 100644 --- a/src/gpg/function/BasicOperator.cpp +++ b/src/core/function/gpg/GpgBasicOperator.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,29 +8,31 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/BasicOperator.h" +#include "GpgBasicOperator.h" #include <vector> -#include "gpg/function/GpgKeyGetter.h" +#include "GpgKeyGetter.h" -GpgFrontend::GpgError GpgFrontend::BasicOperator::Encrypt( +GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Encrypt( KeyListPtr keys, GpgFrontend::BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) { // gpgme_encrypt_result_t e_result; @@ -43,55 +47,55 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Encrypt( GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; gpgme_error_t err = check_gpg_error(gpgme_op_encrypt( - ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); + ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); auto temp_data_out = data_out.Read2Buffer(); std::swap(temp_data_out, out_buffer); - auto temp_result = _new_result(gpgme_op_encrypt_result(ctx)); + auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_)); std::swap(result, temp_result); return err; } -GpgFrontend::GpgError GpgFrontend::BasicOperator::Decrypt( +GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Decrypt( BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgDecrResult& result) { gpgme_error_t err; GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - err = check_gpg_error(gpgme_op_decrypt(ctx, data_in, data_out)); + err = check_gpg_error(gpgme_op_decrypt(ctx_, data_in, data_out)); auto temp_data_out = data_out.Read2Buffer(); std::swap(temp_data_out, out_buffer); - auto temp_result = _new_result(gpgme_op_decrypt_result(ctx)); + auto temp_result = _new_result(gpgme_op_decrypt_result(ctx_)); std::swap(result, temp_result); return err; } -GpgFrontend::GpgError GpgFrontend::BasicOperator::Verify( +GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Verify( BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer, GpgVerifyResult& result) const { gpgme_error_t err; - + GpgData data_in(in_buffer.data(), in_buffer.size()); GpgData data_out; if (sig_buffer != nullptr) { GpgData sig_data(sig_buffer->data(), sig_buffer->size()); - err = check_gpg_error(gpgme_op_verify(ctx, sig_data, data_in, nullptr)); + err = check_gpg_error(gpgme_op_verify(ctx_, sig_data, data_in, nullptr)); } else - err = check_gpg_error(gpgme_op_verify(ctx, data_in, nullptr, data_out)); + err = check_gpg_error(gpgme_op_verify(ctx_, data_in, nullptr, data_out)); - auto temp_result = _new_result(gpgme_op_verify_result(ctx)); + auto temp_result = _new_result(gpgme_op_verify_result(ctx_)); std::swap(result, temp_result); return err; } -GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyListPtr keys, +GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Sign(KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode, @@ -99,57 +103,44 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyListPtr keys, gpgme_error_t err; // Set Singers of this opera - SetSigners(*keys); + SetSigners(*signers); GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - /** - `GPGME_SIG_MODE_NORMAL' - A normal signature is made, the output includes the plaintext - and the signature. - - `GPGME_SIG_MODE_DETACH' - A detached signature is made. - - `GPGME_SIG_MODE_CLEAR' - A clear text signature is made. The ASCII armor and text - mode settings of the context are ignored. - */ - - err = check_gpg_error(gpgme_op_sign(ctx, data_in, data_out, mode)); + err = check_gpg_error(gpgme_op_sign(ctx_, data_in, data_out, mode)); auto temp_data_out = data_out.Read2Buffer(); std::swap(temp_data_out, out_buffer); - auto temp_result = _new_result(gpgme_op_sign_result(ctx)); + auto temp_result = _new_result(gpgme_op_sign_result(ctx_)); std::swap(result, temp_result); return err; } -gpgme_error_t GpgFrontend::BasicOperator::DecryptVerify( +gpgme_error_t GpgFrontend::GpgBasicOperator::DecryptVerify( BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) { gpgme_error_t err; GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; - err = check_gpg_error(gpgme_op_decrypt_verify(ctx, data_in, data_out)); + err = check_gpg_error(gpgme_op_decrypt_verify(ctx_, data_in, data_out)); auto temp_data_out = data_out.Read2Buffer(); std::swap(temp_data_out, out_buffer); - auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx)); + auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx_)); std::swap(decrypt_result, temp_decr_result); - auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx)); + auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx_)); std::swap(verify_result, temp_verify_result); return err; } -gpgme_error_t GpgFrontend::BasicOperator::EncryptSign( +gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign( KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, GpgEncrResult& encr_result, GpgSignResult& sign_result) { @@ -170,57 +161,58 @@ gpgme_error_t GpgFrontend::BasicOperator::EncryptSign( // If the last parameter isnt 0, a private copy of data is made err = check_gpg_error(gpgme_op_encrypt_sign( - ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); + ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); auto temp_data_out = data_out.Read2Buffer(); std::swap(temp_data_out, out_buffer); - auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx)); + auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx_)); swap(encr_result, temp_encr_result); - auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx)); + auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx_)); swap(sign_result, temp_sign_result); return err; } -void GpgFrontend::BasicOperator::SetSigners(KeyArgsList& keys) { - gpgme_signers_clear(ctx); - for (const GpgKey& key : keys) { - DLOG(INFO) << "key" << key.fpr(); - if (key.CanSignActual()) { +void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) { + gpgme_signers_clear(ctx_); + for (const GpgKey& key : signers) { + DLOG(INFO) << "key" << key.GetFingerprint(); + if (key.IsHasActualSigningCapability()) { DLOG(INFO) << "signer"; - auto error = gpgme_signers_add(ctx, gpgme_key_t(key)); + auto error = gpgme_signers_add(ctx_, gpgme_key_t(key)); check_gpg_error(error); } } - if (keys.size() != gpgme_signers_count(ctx)) + if (signers.size() != gpgme_signers_count(ctx_)) DLOG(INFO) << "No All Signers Added"; } std::unique_ptr<GpgFrontend::KeyArgsList> -GpgFrontend::BasicOperator::GetSigners() { - auto count = gpgme_signers_count(ctx); +GpgFrontend::GpgBasicOperator::GetSigners() { + auto count = gpgme_signers_count(ctx_); auto signers = std::make_unique<std::vector<GpgKey>>(); for (auto i = 0u; i < count; i++) { - auto key = GpgKey(gpgme_signers_enum(ctx, i)); + auto key = GpgKey(gpgme_signers_enum(ctx_, i)); signers->push_back(GpgKey(std::move(key))); } return signers; } -gpg_error_t GpgFrontend::BasicOperator::EncryptSymmetric( + +gpg_error_t GpgFrontend::GpgBasicOperator::EncryptSymmetric( GpgFrontend::ByteArray& in_buffer, GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) { GpgData data_in(in_buffer.data(), in_buffer.size()), data_out; gpgme_error_t err = check_gpg_error(gpgme_op_encrypt( - ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); + ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); auto temp_data_out = data_out.Read2Buffer(); std::swap(temp_data_out, out_buffer); // TODO(Saturneric): maybe a bug of gpgme if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { - auto temp_result = _new_result(gpgme_op_encrypt_result(ctx)); + auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_)); std::swap(result, temp_result); } diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h new file mode 100644 index 00000000..9b9d9f63 --- /dev/null +++ b/src/core/function/gpg/GpgBasicOperator.h @@ -0,0 +1,179 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H +#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H + +#include "core/GpgConstants.h" +#include "core/GpgContext.h" +#include "core/GpgFunctionObject.h" +#include "core/GpgModel.h" + +namespace GpgFrontend { + +/** + * @brief Basic operation collection + * + */ +class GpgBasicOperator : public SingletonFunctionObject<GpgBasicOperator> { + public: + /** + * @brief Construct a new Basic Operator object + * + * @param channel Channel corresponding to the context + */ + explicit GpgBasicOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgBasicOperator>(channel) {} + + /** + * @brief Call the interface provided by gpgme for encryption operation + * + * All incoming data pointers out_buffer will be replaced with new valid + * values + * + * @param keys list of public keys + * @param in_buffer data that needs to be encrypted + * @param out_buffer encrypted data + * @param result the result of the operation + * @return error code + */ + gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer, + ByteArrayPtr& out_buffer, GpgEncrResult& result); + + /** + * @brief Call the interface provided by GPGME to symmetrical encryption + * + * @param in_buffer Data for encryption + * @param out_buffer Encrypted data + * @param result Encrypted results + * @return gpg_error_t + */ + gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, + GpgEncrResult& result); + + /** + * + * @brief Call the interface provided by gpgme to perform encryption and + * signature operations at the same time. + * + * @param keys List of public keys + * @param signers Private key for signatures + * @param in_buffer Data for operation + * @param out_buffer Encrypted data + * @param encr_result Encrypted results + * @param sign_result Signature result + * @return + */ + gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers, + BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, + GpgEncrResult& encr_result, + GpgSignResult& sign_result); + + /** + * @brief Call the interface provided by gpgme for decryption operation + * + * @param in_buffer data that needs to be decrypted + * @param out_buffer decrypted data + * @param result the result of the operation + * @return error code + */ + gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, + GpgDecrResult& result); + + /** + * @brief Call the interface provided by gpgme to perform decryption and + * verification operations at the same time. + * + * @param in_buffer data to be manipulated + * @param out_buffer data resulting from decryption operation + * @param decrypt_result the result of the decrypting operation + * @param verify_result the result of the verifying operation + * @return error code + */ + gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, + GpgDecrResult& decrypt_result, + GpgVerifyResult& verify_result); + + /** + * @brief Call the interface provided by gpgme for verification operation + * + * @param in_buffer data that needs to be verified + * @param out_buffer verified data + * @param result the result of the operation + * @return error code + */ + gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer, + GpgVerifyResult& result) const; + + /** + * @brief Call the interface provided by gpgme for signing operation + * + * The signing modes are as follows: + * `GPGME_SIG_MODE_NORMAL' + * A normal signature is made, the output includes the plaintext and the + * signature. + * `GPGME_SIG_MODE_DETACH' + * A detached signature is made. + * `GPGME_SIG_MODE_CLEAR' + * A clear text signature is made. The ASCII armor and text mode settings + * of the context are ignored. + * + * @param signers private keys for signing operations + * @param in_buffer data that needs to be signed + * @param out_buffer verified data + * @param mode signing mode + * @param result the result of the operation + * @return error code + */ + gpg_error_t Sign(KeyListPtr signers, BypeArrayRef in_buffer, + ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode, + GpgSignResult& result); + + /** + * @brief Set the private key for signatures, this operation is a global + * operation. + * + * @param keys + */ + void SetSigners(KeyArgsList& signers); + + /** + * @brief Get a global signature private keys that has been set. + * + * @return Intelligent pointer pointing to the private key list + */ + std::unique_ptr<KeyArgsList> GetSigners(); + + private: + GpgContext& ctx_ = GpgContext::GetInstance( + SingletonFunctionObject::GetChannel()); ///< Corresponding context +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H diff --git a/src/gpg/function/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp index 9b99b400..a6a67d08 100644 --- a/src/gpg/function/GpgCommandExecutor.cpp +++ b/src/core/function/gpg/GpgCommandExecutor.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,22 +8,24 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/GpgCommandExecutor.h" +#include "GpgCommandExecutor.h" #ifndef WINDOWS #include <boost/asio.hpp> #endif @@ -42,7 +46,7 @@ void GpgFrontend::GpgCommandExecutor::Execute( async_pipe in_pipe_stream(ios); async_pipe out_pipe_stream(ios); - child child_process(ctx.GetInfo().AppPath.c_str(), arguments, + child child_process(ctx_.GetInfo().AppPath.c_str(), arguments, std_out > in_pipe_stream, std_in < out_pipe_stream); boost::asio::async_read( diff --git a/src/gpg/function/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h index dcdd318d..49baf406 100644 --- a/src/gpg/function/GpgCommandExecutor.h +++ b/src/core/function/gpg/GpgCommandExecutor.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,17 +33,34 @@ #include <boost/process.hpp> #endif -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" +#include "core/GpgContext.h" +#include "core/GpgFunctionObject.h" namespace GpgFrontend { + +/** + * @brief Extra commands related to GPG + * + */ class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> { public: + /** + * @brief Construct a new Gpg Command Executor object + * + * @param channel Corresponding context + */ explicit GpgCommandExecutor( int channel = SingletonFunctionObject::GetDefaultChannel()) : SingletonFunctionObject<GpgCommandExecutor>(channel) {} #ifndef WINDOWS + + /** + * @brief Excuting an order + * + * @param arguments Command parameters + * @param interact_func Command answering function + */ void Execute(StringArgsRef arguments, const std::function<void(boost::process::async_pipe &in, boost::process::async_pipe &out)> @@ -47,8 +68,8 @@ class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> { #endif private: - GpgContext &ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + GpgContext &ctx_ = GpgContext::GetInstance( + SingletonFunctionObject::GetChannel()); ///< Corresponding context }; } // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp new file mode 100644 index 00000000..25357288 --- /dev/null +++ b/src/core/function/gpg/GpgFileOpera.cpp @@ -0,0 +1,245 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "GpgFileOpera.h" + +#include <memory> +#include <string> + +#include "GpgConstants.h" +#include "GpgBasicOperator.h" +#include "function/FileOperator.h" + +GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile( + KeyListPtr keys, const std::string& in_path, const std::string& out_path, + GpgEncrResult& result, int _channel) { + +#ifdef WINDOWS + auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); + auto out_path_std = std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(in_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + + std::unique_ptr<std::string> out_buffer = nullptr; + + auto err = GpgBasicOperator::GetInstance(_channel).Encrypt( + std::move(keys), in_buffer, out_buffer, result); + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) + if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) { + throw std::runtime_error("write_buffer_to_file error"); + }; + + return err; +} + +GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile( + const std::string& in_path, const std::string& out_path, + GpgDecrResult& result) { + +#ifdef WINDOWS + auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); + auto out_path_std = std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(in_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + std::unique_ptr<std::string> out_buffer; + + auto err = + GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result); + + assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR); + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) + if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) { + throw std::runtime_error("write_buffer_to_file error"); + }; + + return err; +} + +gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys, + const std::string& in_path, + const std::string& out_path, + GpgSignResult& result, + int _channel) { + +#ifdef WINDOWS + auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); + auto out_path_std = std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(in_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + std::unique_ptr<std::string> out_buffer; + + auto err = GpgBasicOperator::GetInstance(_channel).Sign( + std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result); + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) + if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) { + throw std::runtime_error("write_buffer_to_file error"); + }; + + return err; +} + +gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile( + const std::string& data_path, const std::string& sign_path, + GpgVerifyResult& result, int _channel) { + +#ifdef WINDOWS + auto data_path_std = std::filesystem::path(QString::fromStdString(data_path).toStdU16String()); + auto sign_path_std = std::filesystem::path(QString::fromStdString(sign_path).toStdU16String()); +#else + auto data_path_std = std::filesystem::path(data_path); + auto sign_path_std = std::filesystem::path(sign_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(data_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + std::unique_ptr<std::string> sign_buffer = nullptr; + if (!sign_path.empty()) { + std::string sign_buffer_str; + if (!FileOperator::ReadFileStd(sign_path_std, sign_buffer_str)) { + throw std::runtime_error("read file error"); + } + sign_buffer = + std::make_unique<std::string>(sign_buffer_str); + } + auto err = GpgBasicOperator::GetInstance(_channel).Verify(in_buffer, sign_buffer, + result); + return err; +} + +gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile( + KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path, + const std::string& out_path, GpgEncrResult& encr_res, + GpgSignResult& sign_res, int _channel) { + +#ifdef WINDOWS + auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); + auto out_path_std = std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(in_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + std::unique_ptr<std::string> out_buffer = nullptr; + + auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign( + std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res, + sign_res); + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) + if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) { + throw std::runtime_error("write_buffer_to_file error"); + }; + + return err; +} + +gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile( + const std::string& in_path, const std::string& out_path, + GpgDecrResult& decr_res, GpgVerifyResult& verify_res) { + +#ifdef WINDOWS + auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); + auto out_path_std = std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(in_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + + std::unique_ptr<std::string> out_buffer = nullptr; + auto err = GpgBasicOperator::GetInstance().DecryptVerify(in_buffer, out_buffer, + decr_res, verify_res); + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) + if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) { + throw std::runtime_error("write file error"); + }; + + return err; +} +unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric( + const std::string& in_path, const std::string& out_path, + GpgFrontend::GpgEncrResult& result, int _channel) { + +#ifdef WINDOWS + auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); + auto out_path_std = std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif + + std::string in_buffer; + if(!FileOperator::ReadFileStd(in_path_std, in_buffer)) { + throw std::runtime_error("read file error"); + } + + std::unique_ptr<std::string> out_buffer; + auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric( + in_buffer, out_buffer, result); + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) + if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) { + throw std::runtime_error("write_buffer_to_file error"); + }; + + return err; +} diff --git a/src/gpg/function/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h index f4508f42..f21bf04c 100644 --- a/src/gpg/function/GpgFileOpera.h +++ b/src/core/function/gpg/GpgFileOpera.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,59 +8,124 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_GPGFILEOPERA_H #define GPGFRONTEND_GPGFILEOPERA_H -#include "gpg/GpgConstants.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgModel.h" +#include "core/GpgConstants.h" +#include "core/GpgContext.h" +#include "core/GpgModel.h" namespace GpgFrontend { +/** + * @brief Executive files related to the basic operations that are provided by + * GpgBasicOperator + * @class class: GpgBasicOperator + */ class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> { public: explicit GpgFileOpera( int channel = SingletonFunctionObject::GetDefaultChannel()) : SingletonFunctionObject<GpgFileOpera>(channel) {} + /** + * @brief Encrypted file + * + * @param keys Used public key + * @param in_path The path where the enter file is located + * @param out_path The path where the output file is located + * @param result Encrypted results + * @param _channel Channel in context + * @return unsigned int error code + */ static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path, const std::string& out_path, GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL); + /** + * @brief 运用对称加密算法加密文件 + * + * @param in_path + * @param out_path + * @param result + * @param _channel + * @return unsigned int + */ static unsigned int EncryptFileSymmetric( const std::string& in_path, const std::string& out_path, GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL); + /** + * @brief + * + * @param in_path + * @param out_path + * @param result + * @return GpgError + */ static GpgError DecryptFile(const std::string& in_path, const std::string& out_path, GpgDecrResult& result); + /** + * @brief + * + * @param keys + * @param in_path + * @param out_path + * @param result + * @param _channel + * @return GpgError + */ static GpgError SignFile(KeyListPtr keys, const std::string& in_path, const std::string& out_path, GpgSignResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL); + /** + * @brief + * + * @param data_path + * @param sign_path + * @param result + * @param _channel + * @return GpgError + */ static GpgError VerifyFile(const std::string& data_path, const std::string& sign_path, GpgVerifyResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL); + /** + * @brief + * + * @param keys + * @param signer_keys + * @param in_path + * @param out_path + * @param encr_res + * @param sign_res + * @param _channel + * @return GpgError + */ static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path, const std::string& out_path, @@ -66,6 +133,15 @@ class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> { GpgSignResult& sign_res, int _channel = GPGFRONTEND_DEFAULT_CHANNEL); + /** + * @brief + * + * @param in_path + * @param out_path + * @param decr_res + * @param verify_res + * @return GpgError + */ static GpgError DecryptVerifyFile(const std::string& in_path, const std::string& out_path, GpgDecrResult& decr_res, diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp index 8a26dcd9..1a4715e7 100644 --- a/src/gpg/function/GpgKeyGetter.cpp +++ b/src/core/function/gpg/GpgKeyGetter.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/GpgKeyGetter.h" +#include "GpgKeyGetter.h" #include <gpg-error.h> @@ -30,7 +34,7 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) { gpgme_key_t _p_key = nullptr; - gpgme_get_key(ctx, fpr.c_str(), &_p_key, 1); + gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1); if (_p_key == nullptr) { DLOG(WARNING) << "GpgKeyGetter GetKey Private _p_key Null fpr" << fpr; return GetPubkey(fpr); @@ -42,7 +46,7 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) { GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey( const std::string& fpr) { gpgme_key_t _p_key = nullptr; - gpgme_get_key(ctx, fpr.c_str(), &_p_key, 0); + gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0); if (_p_key == nullptr) DLOG(WARNING) << "GpgKeyGetter GetKey _p_key Null" << fpr; return GpgKey(std::move(_p_key)); @@ -53,17 +57,17 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { auto keys_list = std::make_unique<GpgKeyLinkList>(); - err = gpgme_op_keylist_start(ctx, nullptr, 0); + err = gpgme_op_keylist_start(ctx_, nullptr, 0); assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR); gpgme_key_t key; - while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { + while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) { keys_list->push_back(GetKey(key->fpr)); } assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF); - err = gpgme_op_keylist_end(ctx); + err = gpgme_op_keylist_end(ctx_); assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR); @@ -80,13 +84,13 @@ GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys( GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy( const GpgFrontend::KeyLinkListPtr& keys) { auto keys_copy = std::make_unique<GpgKeyLinkList>(); - for (const auto& key : *keys) keys_copy->push_back(key.copy()); + for (const auto& key : *keys) keys_copy->push_back(key.Copy()); return keys_copy; } GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy( const GpgFrontend::KeyListPtr& keys) { auto keys_copy = std::make_unique<KeyArgsList>(); - for (const auto& key : *keys) keys_copy->push_back(key.copy()); + for (const auto& key : *keys) keys_copy->push_back(key.Copy()); return keys_copy; } diff --git a/src/gpg/function/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h index fcd518d3..cde027a0 100644 --- a/src/gpg/function/GpgKeyGetter.h +++ b/src/core/function/gpg/GpgKeyGetter.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,51 +8,101 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H #define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" -#include "gpg/GpgModel.h" +#include "core/GpgContext.h" +#include "core/GpgFunctionObject.h" +#include "core/GpgModel.h" namespace GpgFrontend { +/** + * @brief + * + */ class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { public: + /** + * @brief Construct a new Gpg Key Getter object + * + * @param channel + */ explicit GpgKeyGetter( int channel = SingletonFunctionObject::GetDefaultChannel()) : SingletonFunctionObject<GpgKeyGetter>(channel) {} + /** + * @brief Get the Key object + * + * @param fpr + * @return GpgKey + */ GpgKey GetKey(const std::string& fpr); + /** + * @brief Get the Keys object + * + * @param ids + * @return KeyListPtr + */ KeyListPtr GetKeys(const KeyIdArgsListPtr& ids); + /** + * @brief Get the Pubkey object + * + * @param fpr + * @return GpgKey + */ GpgKey GetPubkey(const std::string& fpr); + /** + * @brief + * + * @return KeyLinkListPtr + */ KeyLinkListPtr FetchKey(); + /** + * @brief Get the Keys Copy object + * + * @param keys + * @return KeyListPtr + */ static KeyListPtr GetKeysCopy(const KeyListPtr& keys); + /** + * @brief Get the Keys Copy object + * + * @param keys + * @return KeyLinkListPtr + */ static KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys); private: - GpgContext& ctx = + /** + * @brief + * + */ + GpgContext& ctx_ = GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp index dd027eab..0f1ebfa2 100644 --- a/src/gpg/function/GpgKeyImportExporter.cpp +++ b/src/core/function/gpg/GpgKeyImportExporter.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,26 +8,28 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/GpgKeyImportExporter.h" +#include "GpgKeyImportExporter.h" #include "GpgConstants.h" -#include "gpg/function/GpgKeyGetter.h" +#include "GpgKeyGetter.h" /** * Import key pair @@ -37,11 +41,11 @@ GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey( if (in_buffer->empty()) return {}; GpgData data_in(in_buffer->data(), in_buffer->size()); - auto err = check_gpg_error(gpgme_op_import(ctx, data_in)); + auto err = check_gpg_error(gpgme_op_import(ctx_, data_in)); if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {}; gpgme_import_result_t result; - result = gpgme_op_import_result(ctx); + result = gpgme_op_import_result(ctx_); gpgme_import_status_t status = result->imports; auto import_info = std::make_unique<GpgImportInformation>(result); while (status != nullptr) { @@ -79,7 +83,7 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list, keys_array[index] = nullptr; GpgData data_out; - auto err = gpgme_op_export_keys(ctx, keys_array, _mode, data_out); + auto err = gpgme_op_export_keys(ctx_, keys_array, _mode, data_out); if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false; delete[] keys_array; @@ -104,7 +108,7 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, ByteArrayPtr& out_buffer, bool secret) const { KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>(); - for (const auto& key : keys) key_ids->push_back(key.id()); + for (const auto& key : keys) key_ids->push_back(key.GetId()); return ExportKeys(key_ids, out_buffer, secret); } @@ -116,14 +120,14 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, */ bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey( const GpgKey& key, ByteArrayPtr& out_buffer) const { - DLOG(INFO) << "Export Secret Key" << key.id().c_str(); + DLOG(INFO) << "Export Secret Key" << key.GetId().c_str(); gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr}; GpgData data_out; // export private key to outBuffer - gpgme_error_t err = - gpgme_op_export_keys(ctx, target_key, GPGME_EXPORT_MODE_SECRET, data_out); + gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key, + GPGME_EXPORT_MODE_SECRET, data_out); auto temp_out_buffer = data_out.Read2Buffer(); std::swap(out_buffer, temp_out_buffer); @@ -135,7 +139,7 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKey( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; - auto err = gpgme_op_export(ctx, key.id().c_str(), 0, data_out); + auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out); DLOG(INFO) << "exportKeys read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END); @@ -149,8 +153,8 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; - auto err = - gpgme_op_export(ctx, key.id().c_str(), GPGME_EXPORT_MODE_SSH, data_out); + auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH, + data_out); DLOG(INFO) << "read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END); @@ -163,8 +167,8 @@ bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; - auto err = gpgme_op_export(ctx, key.id().c_str(), GPGME_EXPORT_MODE_MINIMAL, - data_out); + auto err = gpgme_op_export(ctx_, key.GetId().c_str(), + GPGME_EXPORT_MODE_MINIMAL, data_out); DLOG(INFO) << "read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END); diff --git a/src/gpg/function/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h index 64b3b8a9..d7e6deae 100644 --- a/src/gpg/function/GpgKeyImportExporter.h +++ b/src/core/function/gpg/GpgKeyImportExporter.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -27,25 +31,38 @@ #include <string> -#include "gpg/GpgConstants.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" -#include "gpg/GpgModel.h" +#include "core/GpgConstants.h" +#include "core/GpgContext.h" +#include "core/GpgFunctionObject.h" +#include "core/GpgModel.h" namespace GpgFrontend { +/** + * @brief + * + */ class GpgImportedKey { public: - std::string fpr; - int import_status; + std::string fpr; ///< + int import_status; ///< }; -typedef std::list<GpgImportedKey> GpgImportedKeyList; +typedef std::list<GpgImportedKey> GpgImportedKeyList; ///< +/** + * @brief + * + */ class GpgImportInformation { public: GpgImportInformation() = default; + /** + * @brief Construct a new Gpg Import Information object + * + * @param result + */ explicit GpgImportInformation(gpgme_import_result_t result) { if (result->unchanged) unchanged = result->unchanged; if (result->considered) considered = result->considered; @@ -63,49 +80,114 @@ class GpgImportInformation { if (result->not_imported) not_imported = result->not_imported; } - int considered = 0; - int no_user_id = 0; - int imported = 0; - int imported_rsa = 0; - int unchanged = 0; - int new_user_ids = 0; - int new_sub_keys = 0; - int new_signatures = 0; - int new_revocations = 0; - int secret_read = 0; - int secret_imported = 0; - int secret_unchanged = 0; - int not_imported = 0; - GpgImportedKeyList importedKeys; + int considered = 0; ///< + int no_user_id = 0; ///< + int imported = 0; ///< + int imported_rsa = 0; ///< + int unchanged = 0; ///< + int new_user_ids = 0; ///< + int new_sub_keys = 0; ///< + int new_signatures = 0; ///< + int new_revocations = 0; ///< + int secret_read = 0; ///< + int secret_imported = 0; ///< + int secret_unchanged = 0; ///< + int not_imported = 0; ///< + GpgImportedKeyList importedKeys; ///< }; +/** + * @brief + * + */ class GpgKeyImportExporter : public SingletonFunctionObject<GpgKeyImportExporter> { public: + /** + * @brief Construct a new Gpg Key Import Exporter object + * + * @param channel + */ explicit GpgKeyImportExporter( int channel = SingletonFunctionObject::GetDefaultChannel()) : SingletonFunctionObject<GpgKeyImportExporter>(channel) {} + /** + * @brief + * + * @param inBuffer + * @return GpgImportInformation + */ GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer); + /** + * @brief + * + * @param uid_list + * @param out_buffer + * @param secret + * @return true + * @return false + */ bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, bool secret = false) const; + /** + * @brief + * + * @param keys + * @param outBuffer + * @param secret + * @return true + * @return false + */ bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer, bool secret = false) const; + /** + * @brief + * + * @param key + * @param out_buffer + * @return true + * @return false + */ bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const; + /** + * @brief + * + * @param key + * @param out_buffer + * @return true + * @return false + */ bool ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const; + /** + * @brief + * + * @param key + * @param outBuffer + * @return true + * @return false + */ bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const; + /** + * @brief + * + * @param key + * @param outBuffer + * @return true + * @return false + */ bool ExportSecretKeyShortest(const GpgKey& key, ByteArrayPtr& outBuffer) const; private: - GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + GpgContext& ctx_ = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp index 998c27a7..c17df49e 100644 --- a/src/gpg/function/GpgKeyManager.cpp +++ b/src/core/function/gpg/GpgKeyManager.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,37 +8,39 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/GpgKeyManager.h" +#include "GpgKeyManager.h" #include <boost/date_time/posix_time/conversion.hpp> #include <string> -#include "gpg/function/BasicOperator.h" -#include "gpg/function/GpgKeyGetter.h" +#include "GpgBasicOperator.h" +#include "GpgKeyGetter.h" -bool GpgFrontend::GpgKeyManager::signKey( +bool GpgFrontend::GpgKeyManager::SignKey( const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys, const std::string& uid, const std::unique_ptr<boost::posix_time::ptime>& expires) { using namespace boost::posix_time; - BasicOperator::GetInstance().SetSigners(keys); + GpgBasicOperator::GetInstance().SetSigners(keys); unsigned int flags = 0; unsigned int expires_time_t = 0; @@ -47,20 +51,20 @@ bool GpgFrontend::GpgKeyManager::signKey( expires_time_t = to_time_t(*expires); auto err = check_gpg_error(gpgme_op_keysign( - ctx, gpgme_key_t(target), uid.c_str(), expires_time_t, flags)); + ctx_, gpgme_key_t(target), uid.c_str(), expires_time_t, flags)); return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyManager::revSign( +bool GpgFrontend::GpgKeyManager::RevSign( const GpgFrontend::GpgKey& key, const GpgFrontend::SignIdArgsListPtr& signature_id) { auto& key_getter = GpgKeyGetter::GetInstance(); for (const auto& sign_id : *signature_id) { auto signing_key = key_getter.GetKey(sign_id.first); - assert(signing_key.good()); - auto err = check_gpg_error(gpgme_op_revsig(ctx, gpgme_key_t(key), + assert(signing_key.IsGood()); + auto err = check_gpg_error(gpgme_op_revsig(ctx_, gpgme_key_t(key), gpgme_key_t(signing_key), sign_id.second.c_str(), 0)); if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return false; @@ -68,7 +72,7 @@ bool GpgFrontend::GpgKeyManager::revSign( return true; } -bool GpgFrontend::GpgKeyManager::setExpire( +bool GpgFrontend::GpgKeyManager::SetExpire( const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey, std::unique_ptr<boost::posix_time::ptime>& expires) { using namespace boost::posix_time; @@ -79,10 +83,10 @@ bool GpgFrontend::GpgKeyManager::setExpire( const char* sub_fprs = nullptr; - if (subkey != nullptr) sub_fprs = subkey->fpr().c_str(); + if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str(); auto err = check_gpg_error( - gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, sub_fprs, 0)); + gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, sub_fprs, 0)); return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } diff --git a/src/gpg/function/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h index b2444e8d..5bcac545 100644 --- a/src/gpg/function/GpgKeyManager.h +++ b/src/core/function/gpg/GpgKeyManager.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,56 +8,84 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H #define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" -#include "gpg/GpgModel.h" +#include "core/GpgContext.h" +#include "core/GpgFunctionObject.h" +#include "core/GpgModel.h" namespace GpgFrontend { +/** + * @brief + * + */ class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { public: + /** + * @brief Construct a new Gpg Key Manager object + * + * @param channel + */ explicit GpgKeyManager( int channel = SingletonFunctionObject::GetDefaultChannel()) : SingletonFunctionObject<GpgKeyManager>(channel) {} /** - * Sign a key pair(actually a certain uid) + * @brief Sign a key pair(actually a certain uid) * @param target target key pair * @param uid target * @param expires expire date and time of the signature * @return if successful */ - bool signKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid, + bool SignKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid, const std::unique_ptr<boost::posix_time::ptime>& expires); - bool revSign(const GpgFrontend::GpgKey& key, + /** + * @brief + * + * @param key + * @param signature_id + * @return true + * @return false + */ + bool RevSign(const GpgFrontend::GpgKey& key, const GpgFrontend::SignIdArgsListPtr& signature_id); - bool setExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey, + /** + * @brief Set the Expire object + * + * @param key + * @param subkey + * @param expires + * @return true + * @return false + */ + bool SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey, std::unique_ptr<boost::posix_time::ptime>& expires); private: - GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + GpgContext& ctx_ = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index e9fcbc1d..23dcae9f 100644 --- a/src/gpg/function/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/GpgKeyOpera.h" +#include "GpgKeyOpera.h" #include <boost/asio.hpp> #include <boost/date_time/posix_time/conversion.hpp> @@ -32,10 +36,10 @@ #include <string> #include <vector> -#include "gpg/GpgConstants.h" -#include "gpg/GpgGenKeyInfo.h" -#include "gpg/function/GpgCommandExecutor.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/GpgConstants.h" +#include "core/GpgGenKeyInfo.h" +#include "GpgCommandExecutor.h" +#include "GpgKeyGetter.h" /** * Delete keys @@ -46,9 +50,9 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys( GpgError err; for (const auto& tmp : *key_ids) { auto key = GpgKeyGetter::GetInstance().GetKey(tmp); - if (key.good()) { + if (key.IsGood()) { err = check_gpg_error( - gpgme_op_delete_ext(ctx, gpgme_key_t(key), + gpgme_op_delete_ext(ctx_, gpgme_key_t(key), GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE)); assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); } else { @@ -77,13 +81,13 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire( to_time_t(*expires) - system_clock::to_time_t(system_clock::now()); } - LOG(INFO) << key.id() << subkey_fpr << expires_time; + LOG(INFO) << key.GetId() << subkey_fpr << expires_time; GpgError err; - if (key.fpr() == subkey_fpr || subkey_fpr.empty()) - err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, nullptr, 0); + if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty()) + err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, nullptr, 0); else - err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, + err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, subkey_fpr.c_str(), 0); return err; @@ -97,9 +101,15 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire( */ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( const GpgKey& key, const std::string& output_file_name) { - auto args = std::vector<std::string>{ - "--no-tty", "--command-fd", "0", "--status-fd", "1", "-o", - output_file_name, "--gen-revoke", key.fpr()}; + auto args = std::vector<std::string>{"--no-tty", + "--command-fd", + "0", + "--status-fd", + "1", + "-o", + output_file_name, + "--gen-revoke", + key.GetFingerprint()}; using boost::asio::async_write; using boost::process::async_pipe; @@ -151,36 +161,36 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( */ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) { - auto userid_utf8 = params->getUserid(); + auto userid_utf8 = params->GetUserid(); const char* userid = userid_utf8.c_str(); - auto algo_utf8 = params->getAlgo() + params->getKeySizeStr(); + auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr(); - LOG(INFO) << "params" << params->getAlgo() << params->getKeySizeStr(); + LOG(INFO) << "params" << params->GetAlgo() << params->GetKeySizeStr(); const char* algo = algo_utf8.c_str(); unsigned long expires = 0; { using namespace boost::posix_time; using namespace std::chrono; - expires = to_time_t(ptime(params->getExpired())) - + expires = to_time_t(ptime(params->GetExpireTime())) - system_clock::to_time_t(system_clock::now()); } GpgError err; - if (ctx.GetInfo().GnupgVersion >= "2.1.0") { + if (ctx_.GetInfo().GnupgVersion >= "2.1.0") { unsigned int flags = 0; - if (!params->isSubKey()) flags |= GPGME_CREATE_CERT; - if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR; - if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN; - if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH; - if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; - if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; + if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT; + if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR; + if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN; + if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH; + if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; + if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; LOG(INFO) << "args: " << userid << algo << expires << flags; - err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); + err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags); } else { std::stringstream ss; @@ -193,27 +203,27 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( "Name-Real: %3%\n" "Name-Comment: %4%\n" "Name-Email: %5%\n"} % - params->getAlgo() % params->getKeySize() % params->getName() % - params->getComment() % params->getEmail(); + params->GetAlgo() % params->GetKeyLength() % params->GetName() % + params->GetComment() % params->GetEmail(); ss << param_format; - if (!params->isNonExpired()) { - auto date = params->getExpired().date(); + if (!params->IsNonExpired()) { + auto date = params->GetExpireTime().date(); ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date); } else ss << boost::format{"Expire-Date: 0\n"}; - if (!params->isNoPassPhrase()) - ss << boost::format{"Passphrase: %1%\n"} % params->getPassPhrase(); + if (!params->IsNoPassPhrase()) + ss << boost::format{"Passphrase: %1%\n"} % params->GetPassPhrase(); ss << "</GnupgKeyParms>"; DLOG(INFO) << "params" << std::endl << ss.str(); - err = gpgme_op_genkey(ctx, ss.str().c_str(), nullptr, nullptr); + err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr); } if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) { - auto temp_result = _new_result(gpgme_op_genkey_result(ctx)); + auto temp_result = _new_result(gpgme_op_genkey_result(ctx_)); std::swap(temp_result, result); } @@ -228,51 +238,51 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( */ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey( const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) { - if (!params->isSubKey()) return GPG_ERR_CANCELED; + if (!params->IsSubKey()) return GPG_ERR_CANCELED; - auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()); + auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr()); const char* algo = algo_utf8.c_str(); unsigned long expires = 0; { using namespace boost::posix_time; using namespace std::chrono; - expires = to_time_t(ptime(params->getExpired())) - + expires = to_time_t(ptime(params->GetExpireTime())) - system_clock::to_time_t(system_clock::now()); } unsigned int flags = 0; - if (!params->isSubKey()) flags |= GPGME_CREATE_CERT; - if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR; - if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN; - if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH; - if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; + if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT; + if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR; + if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN; + if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH; + if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; flags |= GPGME_CREATE_NOPASSWD; - LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateSubkey Args: " << key.id() + LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateSubkey Args: " << key.GetId() << algo << expires << flags; auto err = - gpgme_op_createsubkey(ctx, gpgme_key_t(key), algo, 0, expires, flags); + gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags); return check_gpg_error(err); } GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword( const GpgFrontend::GpgKey& key) { - if (ctx.GetInfo().GnupgVersion < "2.0.15") { + if (ctx_.GetInfo().GnupgVersion < "2.0.15") { LOG(ERROR) << _("operator not support"); return GPG_ERR_NOT_SUPPORTED; } - auto err = gpgme_op_passwd(ctx, gpgme_key_t(key), 0); + auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0); return check_gpg_error(err); } GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy( const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) { - if (ctx.GetInfo().GnupgVersion < "2.1.10") { + if (ctx_.GetInfo().GnupgVersion < "2.1.10") { LOG(ERROR) << _("operator not support"); return GPG_ERR_NOT_SUPPORTED; } - auto err = gpgme_op_tofu_policy(ctx, gpgme_key_t(key), tofu_policy); + auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy); return check_gpg_error(err); } diff --git a/src/gpg/function/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h index 73b8bdb5..04571c10 100644 --- a/src/gpg/function/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,61 +8,127 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef _GPGKEYOPERA_H #define _GPGKEYOPERA_H -#include "gpg/GpgConstants.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgModel.h" +#include "core/GpgConstants.h" +#include "core/GpgContext.h" +#include "core/GpgModel.h" namespace GpgFrontend { +/** + * @brief + * + */ class GenKeyInfo; + +/** + * @brief + * + */ class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { public: + /** + * @brief Construct a new Gpg Key Opera object + * + * @param channel + */ explicit GpgKeyOpera( int channel = SingletonFunctionObject::GetDefaultChannel()) : SingletonFunctionObject<GpgKeyOpera>(channel) {} + /** + * @brief + * + * @param key_ids + */ void DeleteKeys(KeyIdArgsListPtr key_ids); + /** + * @brief + * + * @param key_id + */ void DeleteKey(const KeyId& key_id); + /** + * @brief Set the Expire object + * + * @param key + * @param subkey_fpr + * @param expires + * @return GpgError + */ GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, std::unique_ptr<boost::posix_time::ptime>& expires); + /** + * @brief + * + * @param key + * @param output_file_name + */ static void GenerateRevokeCert(const GpgKey& key, const std::string& output_file_name); + /** + * @brief + * + * @param key + * @return GpgFrontend::GpgError + */ GpgFrontend::GpgError ModifyPassword(const GpgKey& key); + /** + * @brief + * + * @param key + * @param tofu_policy + * @return GpgFrontend::GpgError + */ GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy); - + /** + * @brief + * + * @param params + * @param result + * @return GpgFrontend::GpgError + */ GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result); + /** + * @brief + * + * @param key + * @param params + * @return GpgFrontend::GpgError + */ GpgFrontend::GpgError GenerateSubkey( const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params); private: - GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + GpgContext& ctx_ = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< }; } // namespace GpgFrontend diff --git a/src/gpg/function/UidOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp index d7acc3b1..dd0c43f6 100644 --- a/src/gpg/function/UidOperator.cpp +++ b/src/core/function/gpg/GpgUIDOperator.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,59 +8,61 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/function/UidOperator.h" +#include "GpgUIDOperator.h" #include "boost/format.hpp" -bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey& key, +bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key, const std::string& uid) { - auto err = gpgme_op_adduid(ctx, gpgme_key_t(key), uid.c_str(), 0); + auto err = gpgme_op_adduid(ctx_, gpgme_key_t(key), uid.c_str(), 0); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) return true; else return false; } -bool GpgFrontend::UidOperator::revUID(const GpgFrontend::GpgKey& key, +bool GpgFrontend::GpgUIDOperator::RevUID(const GpgFrontend::GpgKey& key, const std::string& uid) { auto err = - check_gpg_error(gpgme_op_revuid(ctx, gpgme_key_t(key), uid.c_str(), 0)); + check_gpg_error(gpgme_op_revuid(ctx_, gpgme_key_t(key), uid.c_str(), 0)); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) return true; else return false; } -bool GpgFrontend::UidOperator::setPrimaryUID(const GpgFrontend::GpgKey& key, +bool GpgFrontend::GpgUIDOperator::SetPrimaryUID(const GpgFrontend::GpgKey& key, const std::string& uid) { auto err = check_gpg_error(gpgme_op_set_uid_flag( - ctx, gpgme_key_t(key), uid.c_str(), "primary", nullptr)); + ctx_, gpgme_key_t(key), uid.c_str(), "primary", nullptr)); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) return true; else return false; } -bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey& key, +bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key, const std::string& name, const std::string& comment, const std::string& email) { - LOG(INFO) << "GpgFrontend::UidOperator::addUID" << name << comment << email; + LOG(INFO) << "GpgFrontend::UidOperator::AddUID" << name << comment << email; auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email; - return addUID(key, uid.str()); + return AddUID(key, uid.str()); } diff --git a/src/gpg/function/UidOperator.h b/src/core/function/gpg/GpgUIDOperator.h index d1a92b38..479505e5 100644 --- a/src/gpg/function/UidOperator.h +++ b/src/core/function/gpg/GpgUIDOperator.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,35 +8,40 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H #define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H -#include "gpg/GpgContext.h" -#include "gpg/GpgModel.h" +#include "core/GpgContext.h" +#include "core/GpgModel.h" namespace GpgFrontend { - -class UidOperator : public SingletonFunctionObject<UidOperator> { +/** + * @brief + * + */ +class GpgUIDOperator : public SingletonFunctionObject<GpgUIDOperator> { public: - explicit UidOperator( + explicit GpgUIDOperator( int channel = SingletonFunctionObject::GetDefaultChannel()) - : SingletonFunctionObject<UidOperator>(channel) {} + : SingletonFunctionObject<GpgUIDOperator>(channel) {} /** * create a new uid in certain key pair @@ -42,7 +49,7 @@ class UidOperator : public SingletonFunctionObject<UidOperator> { * @param uid uid args(combine name&comment&email) * @return if successful */ - bool addUID(const GpgKey& key, const std::string& uid); + bool AddUID(const GpgKey& key, const std::string& uid); /** * create a new uid in certain key pair @@ -52,7 +59,7 @@ class UidOperator : public SingletonFunctionObject<UidOperator> { * @param email * @return */ - bool addUID(const GpgKey& key, const std::string& name, + bool AddUID(const GpgKey& key, const std::string& name, const std::string& comment, const std::string& email); /** @@ -61,7 +68,7 @@ class UidOperator : public SingletonFunctionObject<UidOperator> { * @param uid target uid * @return if successful */ - bool revUID(const GpgKey& key, const std::string& uid); + bool RevUID(const GpgKey& key, const std::string& uid); /** * Set one of a uid of a key pair as primary @@ -69,11 +76,11 @@ class UidOperator : public SingletonFunctionObject<UidOperator> { * @param uid target uid * @return if successful */ - bool setPrimaryUID(const GpgKey& key, const std::string& uid); + bool SetPrimaryUID(const GpgKey& key, const std::string& uid); private: - GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + GpgContext& ctx_ = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< }; } // namespace GpgFrontend diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp new file mode 100644 index 00000000..ff3d2e27 --- /dev/null +++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp @@ -0,0 +1,97 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgDecryptResultAnalyse.h" + +#include "function/gpg/GpgKeyGetter.h" + +GpgFrontend::GpgDecryptResultAnalyse::GpgDecryptResultAnalyse(GpgError m_error, + GpgDecrResult m_result) + : error_(m_error), result_(std::move(m_result)) {} + +void GpgFrontend::GpgDecryptResultAnalyse::do_analyse() { + stream_ << "[#] " << _("Decrypt Operation"); + + if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) { + stream_ << "[" << _("Success") << "]" << std::endl; + } else { + stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_) + << std::endl; + set_status(-1); + if (result_ != nullptr && result_->unsupported_algorithm != nullptr) { + stream_ << "------------>" << std::endl; + stream_ << _("Unsupported Algo") << ": " << result_->unsupported_algorithm + << std::endl; + } + } + + if (result_ != nullptr && result_->recipients != nullptr) { + stream_ << "------------>" << std::endl; + if (result_->file_name != nullptr) { + stream_ << _("File Name") << ": " << result_->file_name << std::endl; + stream_ << std::endl; + } + if (result_->is_mime) { + stream_ << _("MIME") << ": " << _("true") << std::endl; + } + + auto recipient = result_->recipients; + if (recipient != nullptr) stream_ << _("Recipient(s)") << ": " << std::endl; + while (recipient != nullptr) { + print_recipient(stream_, recipient); + recipient = recipient->next; + } + stream_ << "<------------" << std::endl; + } + + stream_ << std::endl; +} + +void GpgFrontend::GpgDecryptResultAnalyse::print_recipient( + std::stringstream &stream, gpgme_recipient_t recipient) { + // check + if (recipient->keyid == nullptr) return; + + stream << " {>} " << _("Recipient") << ": "; + auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(recipient->keyid); + if (key.IsGood()) { + stream << key.GetName().c_str(); + if (!key.GetEmail().empty()) { + stream << "<" << key.GetEmail().c_str() << ">"; + } + } else { + stream << "<" << _("Unknown") << ">"; + set_status(0); + } + + stream << std::endl; + + stream << " " << _("Key ID") << ": " << recipient->keyid << std::endl; + stream << " " << _("Public Key Algo") << ": " + << gpgme_pubkey_algo_name(recipient->pubkey_algo) << std::endl; +} diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h new file mode 100644 index 00000000..af42f995 --- /dev/null +++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H +#define GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H + +#include "GpgResultAnalyse.h" +#include "core/GpgConstants.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GpgDecryptResultAnalyse : public GpgResultAnalyse { + public: + /** + * @brief Construct a new Decrypt Result Analyse object + * + * @param m_error + * @param m_result + */ + explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result); + + protected: + /** + * @brief + * + */ + void do_analyse() final; + + private: + /** + * @brief + * + * @param stream + * @param recipient + */ + void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient); + + GpgError error_; ///< + GpgDecrResult result_; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp new file mode 100644 index 00000000..053a15a5 --- /dev/null +++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgEncryptResultAnalyse.h" + +GpgFrontend::GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(GpgError error, + GpgEncrResult result) + : error_(error), result_(std::move(result)) {} + +void GpgFrontend::GpgEncryptResultAnalyse::do_analyse() { + LOG(INFO) << _("Start Encrypt Result Analyse"); + + stream_ << "[#] " << _("Encrypt Operation") << " "; + + if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) + stream_ << "[" << _("Success") << "]" << std::endl; + else { + stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_) + << std::endl; + set_status(-1); + } + + if (!~status_) { + stream_ << "------------>" << std::endl; + if (result_ != nullptr) { + stream_ << _("Invalid Recipients") << ": " << std::endl; + auto inv_reci = result_->invalid_recipients; + while (inv_reci != nullptr) { + stream_ << _("Fingerprint") << ": " << inv_reci->fpr << std::endl; + stream_ << _("Reason") << ": " << gpgme_strerror(inv_reci->reason) + << std::endl; + stream_ << std::endl; + + inv_reci = inv_reci->next; + } + } + stream_ << "<------------" << std::endl; + } + + stream_ << std::endl; +} diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h new file mode 100644 index 00000000..c5125fdc --- /dev/null +++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H +#define GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H + +#include "GpgResultAnalyse.h" +#include "core/GpgConstants.h" + +namespace GpgFrontend { +/** + * @brief + * + */ +class GpgEncryptResultAnalyse : public GpgResultAnalyse { + public: + /** + * @brief Construct a new Encrypt Result Analyse object + * + * @param error + * @param result + */ + explicit GpgEncryptResultAnalyse(GpgError error, GpgEncrResult result); + + protected: + /** + * @brief + * + */ + void do_analyse() final; + + private: + GpgError error_; ///< + GpgEncrResult result_; ///< +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H diff --git a/src/core/function/result_analyse/GpgResultAnalyse.cpp b/src/core/function/result_analyse/GpgResultAnalyse.cpp new file mode 100644 index 00000000..40ba4c3e --- /dev/null +++ b/src/core/function/result_analyse/GpgResultAnalyse.cpp @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgResultAnalyse.h" + +const std::string GpgFrontend::GpgResultAnalyse::GetResultReport() const { + return stream_.str(); +} + +int GpgFrontend::GpgResultAnalyse::GetStatus() const { return status_; } + +void GpgFrontend::GpgResultAnalyse::set_status(int m_status) { + if (m_status < status_) status_ = m_status; +} + +void GpgFrontend::GpgResultAnalyse::Analyse() { + if (!analysed_) { + do_analyse(); + analysed_ = true; + } +} diff --git a/src/core/function/result_analyse/GpgResultAnalyse.h b/src/core/function/result_analyse/GpgResultAnalyse.h new file mode 100644 index 00000000..888c6449 --- /dev/null +++ b/src/core/function/result_analyse/GpgResultAnalyse.h @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef GPGFRONTEND_GPGRESULTANALYSE_H +#define GPGFRONTEND_GPGRESULTANALYSE_H + +#include <sstream> +#include <string> + +#include "core/GpgConstants.h" +namespace GpgFrontend { + +class GpgResultAnalyse { + public: + /** + * @brief Construct a new Result Analyse object + * + */ + GpgResultAnalyse() = default; + + /** + * @brief Get the Result Report object + * + * @return const std::string + */ + [[nodiscard]] const std::string GetResultReport() const; + + /** + * @brief Get the Status object + * + * @return int + */ + [[nodiscard]] int GetStatus() const; + + /** + * @brief + * + */ + void Analyse(); + + protected: + /** + * @brief + * + */ + virtual void do_analyse() = 0; + + /** + * @brief Set the status object + * + * @param m_status + */ + void set_status(int m_status); + + std::stringstream stream_; ///< + int status_ = 1; ///< + bool analysed_ = false; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGRESULTANALYSE_H diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp new file mode 100644 index 00000000..e389523c --- /dev/null +++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgSignResultAnalyse.h" + +#include "function/gpg/GpgKeyGetter.h" + +GpgFrontend::GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error, + GpgSignResult result) + : error_(error), result_(std::move(result)) {} + +void GpgFrontend::GpgSignResultAnalyse::do_analyse() { + LOG(INFO) << _("Start Sign Result Analyse"); + + stream_ << "[#] " << _("Sign Operation") << " "; + + if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) + stream_ << "[" << _("Success") << "]" << std::endl; + else { + stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_) + << std::endl; + set_status(-1); + } + + if (result_ != nullptr && + (result_->signatures != nullptr || result_->invalid_signers != nullptr)) { + LOG(INFO) << _("Sign Result Analyse Getting Result"); + stream_ << "------------>" << std::endl; + auto new_sign = result_->signatures; + + while (new_sign != nullptr) { + stream_ << "[>]" << _("New Signature") << ": " << std::endl; + + LOG(INFO) << _("Signers Fingerprint") << ": " << new_sign->fpr; + + stream_ << " " << _("Sign Mode") << ": "; + if (new_sign->type == GPGME_SIG_MODE_NORMAL) + stream_ << _("Normal"); + else if (new_sign->type == GPGME_SIG_MODE_CLEAR) + stream_ << _("Clear"); + else if (new_sign->type == GPGME_SIG_MODE_DETACH) + stream_ << _("Detach"); + + stream_ << std::endl; + + auto singerKey = + GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr); + if (singerKey.IsGood()) { + stream_ << " " << _("Signer") << ": " + << singerKey.GetUIDs()->front().GetUID() << std::endl; + } else { + stream_ << " " << _("Signer") << ": " + << "<unknown>" << std::endl; + } + stream_ << " " << _("Public Key Algo") << ": " + << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl; + stream_ << " " << _("Hash Algo") << ": " + << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl; + stream_ << " " << _("Date") << "(" << _("UTC") << ")" + << ": " + << boost::posix_time::to_iso_extended_string( + boost::posix_time::from_time_t(new_sign->timestamp)) + << std::endl; + + stream_ << std::endl; + + new_sign = new_sign->next; + } + + LOG(INFO) << _("Sign Result Analyse Getting Invalid Signer"); + + auto invalid_signer = result_->invalid_signers; + + if (invalid_signer != nullptr) + stream_ << _("Invalid Signers") << ": " << std::endl; + + while (invalid_signer != nullptr) { + set_status(0); + stream_ << "[>] " << _("Signer") << ": " << std::endl; + stream_ << " " << _("Fingerprint") << ": " << invalid_signer->fpr + << std::endl; + stream_ << " " << _("Reason") << ": " + << gpgme_strerror(invalid_signer->reason) << std::endl; + stream_ << std::endl; + + invalid_signer = invalid_signer->next; + } + stream_ << "<------------" << std::endl; + } +}
\ No newline at end of file diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.h b/src/core/function/result_analyse/GpgSignResultAnalyse.h new file mode 100644 index 00000000..d593b33d --- /dev/null +++ b/src/core/function/result_analyse/GpgSignResultAnalyse.h @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGSIGNRESULTANALYSE_H +#define GPGFRONTEND_GPGSIGNRESULTANALYSE_H + +#include "GpgResultAnalyse.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GpgSignResultAnalyse : public GpgResultAnalyse { + public: + /** + * @brief Construct a new Sign Result Analyse object + * + * @param error + * @param result + */ + explicit GpgSignResultAnalyse(GpgError error, GpgSignResult result); + + protected: + /** + * @brief + * + */ + void do_analyse(); + + private: + GpgError error_; ///< + + GpgSignResult result_; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGSIGNRESULTANALYSE_H diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp new file mode 100644 index 00000000..44031e67 --- /dev/null +++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp @@ -0,0 +1,214 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgVerifyResultAnalyse.h" + +#include <boost/format.hpp> + +#include "GpgFrontend.h" +#include "core/GpgConstants.h" +#include "function/gpg/GpgKeyGetter.h" + +GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse(GpgError error, + GpgVerifyResult result) + : error_(error), result_(std::move(result)) {} + +void GpgFrontend::GpgVerifyResultAnalyse::do_analyse() { + LOG(INFO) << _("started"); + + stream_ << "[#] " << _("Verify Operation") << " "; + + if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) + stream_ << "[" << _("Success") << "]" << std::endl; + else { + stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_) + << std::endl; + set_status(-1); + } + + if (result_ != nullptr && result_->signatures != nullptr) { + stream_ << "------------>" << std::endl; + auto sign = result_->signatures; + + stream_ << "[>] " << _("Signed On") << "(" << _("UTC") << ")" + << " " + << boost::posix_time::to_iso_extended_string( + boost::posix_time::from_time_t(sign->timestamp)) + << std::endl; + + stream_ << std::endl << "[>] " << _("Signatures List") << ":" << std::endl; + + bool canContinue = true; + + int count = 1; + while (sign && canContinue) { + stream_ << boost::format(_("Signature [%1%]:")) % count++ << std::endl; + switch (gpg_err_code(sign->status)) { + case GPG_ERR_BAD_SIGNATURE: + stream_ << _("A Bad Signature.") << std::endl; + print_signer(stream_, sign); + stream_ << _("This Signature is invalid.") << std::endl; + canContinue = false; + set_status(-1); + break; + case GPG_ERR_NO_ERROR: + stream_ << _("A") << " "; + if (sign->summary & GPGME_SIGSUM_GREEN) { + stream_ << _("Good") << " "; + } + if (sign->summary & GPGME_SIGSUM_RED) { + stream_ << _("Bad") << " "; + } + if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) { + stream_ << _("Expired") << " "; + } + if (sign->summary & GPGME_SIGSUM_KEY_MISSING) { + stream_ << _("Missing Key's") << " "; + } + if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) { + stream_ << _("Revoked Key's") << " "; + } + if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) { + stream_ << _("Expired Key's") << " "; + } + if (sign->summary & GPGME_SIGSUM_CRL_MISSING) { + stream_ << _("Missing CRL's") << " "; + } + + if (sign->summary & GPGME_SIGSUM_VALID) { + stream_ << _("Signature Fully Valid.") << std::endl; + } else { + stream_ << _("Signature Not Fully Valid.") << std::endl; + } + + if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) { + if (!print_signer(stream_, sign)) set_status(0); + } else { + stream_ << _("Key is NOT present with ID 0x") << sign->fpr + << std::endl; + } + + set_status(1); + + break; + case GPG_ERR_NO_PUBKEY: + stream_ << _("A signature could NOT be verified due to a Missing Key") + << std::endl; + set_status(-2); + break; + case GPG_ERR_CERT_REVOKED: + stream_ << _("A signature is valid but the key used to verify the " + "signature has been revoked") + << std::endl; + if (!print_signer(stream_, sign)) { + set_status(0); + } + set_status(-1); + break; + case GPG_ERR_SIG_EXPIRED: + stream_ << _("A signature is valid but expired") << std::endl; + if (!print_signer(stream_, sign)) { + set_status(0); + } + set_status(-1); + break; + case GPG_ERR_KEY_EXPIRED: + stream_ << _("A signature is valid but the key used to " + "verify the signature has expired.") + << std::endl; + if (!print_signer(stream_, sign)) { + set_status(0); + } + break; + case GPG_ERR_GENERAL: + stream_ << _("There was some other error which prevented " + "the signature verification.") + << std::endl; + status_ = -1; + canContinue = false; + break; + default: + auto fpr = std::string(sign->fpr); + stream_ << _("Error for key with fingerprint") << " " + << GpgFrontend::beautify_fingerprint(fpr); + set_status(-1); + } + stream_ << std::endl; + sign = sign->next; + } + stream_ << "<------------" << std::endl; + } else { + stream_ + << "[>] " + << _("Could not find information that can be used for verification.") + << std::endl; + set_status(0); + return; + } +} + +bool GpgFrontend::GpgVerifyResultAnalyse::print_signer(std::stringstream &stream, + gpgme_signature_t sign) { + bool keyFound = true; + auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr); + + if (!key.IsGood()) { + stream << " " << _("Signed By") << ": " + << "<" << _("Unknown") << ">" << std::endl; + set_status(0); + keyFound = false; + } else { + stream << " " << _("Signed By") << ": " + << key.GetUIDs()->front().GetUID() << std::endl; + } + if (sign->pubkey_algo) + stream << " " << _("Public Key Algo") << ": " + << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl; + if (sign->hash_algo) + stream << " " << _("Hash Algo") << ": " + << gpgme_hash_algo_name(sign->hash_algo) << std::endl; + if (sign->timestamp) + stream << " " << _("Date") << "(" << _("UTC") << ")" + << ": " + << boost::posix_time::to_iso_extended_string( + boost::posix_time::from_time_t(sign->timestamp)) + << std::endl; + stream << std::endl; + return keyFound; +} + +gpgme_signature_t GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const { + if (result_) + return result_->signatures; + else + return nullptr; +} +GpgFrontend::GpgVerifyResult +GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult() { + return std::move(result_); +} diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h new file mode 100644 index 00000000..12e4b7ff --- /dev/null +++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGVERIFYRESULTANALYSE_H +#define GPGFRONTEND_GPGVERIFYRESULTANALYSE_H + +#include "GpgResultAnalyse.h" +#include "core/model/GpgKeySignature.h" + +namespace GpgFrontend { +/** + * @brief + * + */ +class GpgVerifyResultAnalyse : public GpgResultAnalyse { + public: + /** + * @brief Construct a new Verify Result Analyse object + * + * @param error + * @param result + */ + explicit GpgVerifyResultAnalyse(GpgError error, GpgVerifyResult result); + + /** + * @brief Get the Signatures object + * + * @return gpgme_signature_t + */ + gpgme_signature_t GetSignatures() const; + + /** + * @brief + * + * @return GpgVerifyResult + */ + GpgVerifyResult TakeChargeOfResult(); + + private: + /** + * @brief + * + */ + void do_analyse(); + + private: + /** + * @brief + * + * @param stream + * @param sign + * @return true + * @return false + */ + bool print_signer(std::stringstream &stream, gpgme_signature_t sign); + + GpgError error_; ///< + GpgVerifyResult result_; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGVERIFYRESULTANALYSE_H diff --git a/src/gpg/model/GpgData.cpp b/src/core/model/GpgData.cpp index c6e9b2ce..7fda4416 100644 --- a/src/gpg/model/GpgData.cpp +++ b/src/core/model/GpgData.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/model/GpgData.h" +#include "core/model/GpgData.h" GpgFrontend::GpgData::GpgData() { gpgme_data_t data; @@ -30,8 +34,7 @@ GpgFrontend::GpgData::GpgData() { auto err = gpgme_data_new(&data); assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); - data_ = - std::unique_ptr<struct gpgme_data, __data_ref_deletor>(std::move(data)); + data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data); } GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) { @@ -40,8 +43,7 @@ GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) { auto err = gpgme_data_new_from_mem(&data, (const char*)buffer, size, copy); assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); - data_ = - std::unique_ptr<struct gpgme_data, __data_ref_deletor>(std::move(data)); + data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data); } /** diff --git a/src/core/model/GpgData.h b/src/core/model/GpgData.h new file mode 100644 index 00000000..c06f78d6 --- /dev/null +++ b/src/core/model/GpgData.h @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef _GPGDATA_H +#define _GPGDATA_H + +#include "core/GpgConstants.h" + +namespace GpgFrontend { +/** + * @brief + * + */ +class GpgData { + public: + /** + * @brief Construct a new Gpg Data object + * + */ + GpgData(); + + /** + * @brief Construct a new Gpg Data object + * + * @param buffer + * @param size + * @param copy + */ + GpgData(void* buffer, size_t size, bool copy = true); + + /** + * @brief + * + * @return gpgme_data_t + */ + operator gpgme_data_t() { return data_ref_.get(); } + + /** + * @brief + * + * @return ByteArrayPtr + */ + ByteArrayPtr Read2Buffer(); + + private: + /** + * @brief + * + */ + struct _data_ref_deleter { + void operator()(gpgme_data_t _data) { + if (_data != nullptr) gpgme_data_release(_data); + } + }; + + std::unique_ptr<struct gpgme_data, _data_ref_deleter> data_ref_ = + nullptr; ///< +}; + +} // namespace GpgFrontend + +#endif // _GPGDATA_H
\ No newline at end of file diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp new file mode 100644 index 00000000..b0952cfa --- /dev/null +++ b/src/core/model/GpgKey.cpp @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "core/model/GpgKey.h" + +GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : key_ref_(std::move(key)) {} + +GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(key_ref_, k.key_ref_); } + +GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept { + swap(key_ref_, k.key_ref_); + return *this; +} + +std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>> +GpgFrontend::GpgKey::GetSubKeys() const { + auto p_keys = std::make_unique<std::vector<GpgSubKey>>(); + auto next = key_ref_->subkeys; + while (next != nullptr) { + p_keys->push_back(GpgSubKey(next)); + next = next->next; + } + return p_keys; +} + +std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::GetUIDs() + const { + auto p_uids = std::make_unique<std::vector<GpgUID>>(); + auto uid_next = key_ref_->uids; + while (uid_next != nullptr) { + p_uids->push_back(GpgUID(uid_next)); + uid_next = uid_next->next; + } + return p_uids; +} + +bool GpgFrontend::GpgKey::IsHasActualSigningCapability() const { + auto subkeys = GetSubKeys(); + if (std::any_of(subkeys->begin(), subkeys->end(), + [](const GpgSubKey &subkey) -> bool { + return subkey.IsSecretKey() && + subkey.IsHasSigningCapability() && + !subkey.IsDisabled() && !subkey.IsRevoked() && + !subkey.IsExpired(); + })) + return true; + else + return false; +} + +bool GpgFrontend::GpgKey::IsHasActualAuthenticationCapability() const { + auto subkeys = GetSubKeys(); + if (std::any_of(subkeys->begin(), subkeys->end(), + [](const GpgSubKey &subkey) -> bool { + return subkey.IsSecretKey() && + subkey.IsHasAuthenticationCapability() && + !subkey.IsDisabled() && !subkey.IsRevoked() && + !subkey.IsExpired(); + })) + return true; + else + return false; +} + +/** + * check if key can certify(actually) + * @param key target key + * @return if key certify + */ +bool GpgFrontend::GpgKey::IsHasActualCertificationCapability() const { + return IsHasMasterKey() && !IsExpired() && !IsRevoked() && !IsDisabled(); +} + +/** + * check if key can encrypt(actually) + * @param key target key + * @return if key encrypt + */ +bool GpgFrontend::GpgKey::IsHasActualEncryptionCapability() const { + auto subkeys = GetSubKeys(); + if (std::any_of(subkeys->begin(), subkeys->end(), + [](const GpgSubKey &subkey) -> bool { + return subkey.IsHasEncryptionCapability() && + !subkey.IsDisabled() && !subkey.IsRevoked() && + !subkey.IsExpired(); + })) + return true; + else + return false; +} diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h new file mode 100644 index 00000000..14315d4c --- /dev/null +++ b/src/core/model/GpgKey.h @@ -0,0 +1,415 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGKEY_H +#define GPGFRONTEND_GPGKEY_H + +#include <boost/date_time.hpp> +#include <boost/date_time/posix_time/conversion.hpp> + +#include "GpgSubKey.h" +#include "GpgUID.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GpgKey { + public: + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsGood() const { return key_ref_ != nullptr; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetId() const { return key_ref_->subkeys->keyid; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetName() const { return key_ref_->uids->name; }; + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetEmail() const { return key_ref_->uids->email; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetComment() const { + return key_ref_->uids->comment; + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetFingerprint() const { return key_ref_->fpr; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetProtocol() const { + return gpgme_get_protocol_name(key_ref_->protocol); + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetOwnerTrust() const { + switch (key_ref_->owner_trust) { + case GPGME_VALIDITY_UNKNOWN: + return "Unknown"; + case GPGME_VALIDITY_UNDEFINED: + return "Undefined"; + case GPGME_VALIDITY_NEVER: + return "Never"; + case GPGME_VALIDITY_MARGINAL: + return "Marginal"; + case GPGME_VALIDITY_FULL: + return "FULL"; + case GPGME_VALIDITY_ULTIMATE: + return "Ultimate"; + } + return "Invalid"; + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetPublicKeyAlgo() const { + return gpgme_pubkey_algo_name(key_ref_->subkeys->pubkey_algo); + } + + /** + * @brief + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetLastUpdateTime() const { + return boost::posix_time::from_time_t( + static_cast<time_t>(key_ref_->last_update)); + } + + /** + * @brief + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetExpireTime() const { + return boost::posix_time::from_time_t(key_ref_->subkeys->expires); + }; + + /** + * @brief Create a time object + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetCreateTime() const { + return boost::posix_time::from_time_t(key_ref_->subkeys->timestamp); + }; + + /** + * @brief s + * + * @return unsigned int + */ + [[nodiscard]] unsigned int GetPrimaryKeyLength() const { + return key_ref_->subkeys->length; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasEncryptionCapability() const { + return key_ref_->can_encrypt; + } + + /** + * @brief + + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasActualEncryptionCapability() const; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasSigningCapability() const { + return key_ref_->can_sign; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasActualSigningCapability() const; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasCertificationCapability() const { + return key_ref_->can_certify; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasActualCertificationCapability() const; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasAuthenticationCapability() const { + return key_ref_->can_authenticate; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasActualAuthenticationCapability() const; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasCardKey() const { + auto subkeys = GetSubKeys(); + return std::any_of( + subkeys->begin(), subkeys->end(), + [](const GpgSubKey& subkey) -> bool { return subkey.IsCardKey(); }); + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsPrivateKey() const { return key_ref_->secret; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsExpired() const { return key_ref_->expired; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsRevoked() const { return key_ref_->revoked; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsDisabled() const { return key_ref_->disabled; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasMasterKey() const { + return key_ref_->subkeys->secret; + } + + /** + * @brief + * + * @return std::unique_ptr<std::vector<GpgSubKey>> + */ + [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> GetSubKeys() const; + + /** + * @brief + * + * @return std::unique_ptr<std::vector<GpgUID>> + */ + [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> GetUIDs() const; + + /** + * @brief Construct a new Gpg Key object + * + */ + GpgKey() = default; + + /** + * @brief Construct a new Gpg Key object + * + * @param key + */ + explicit GpgKey(gpgme_key_t&& key); + + /** + * @brief Destroy the Gpg Key objects + * + */ + ~GpgKey() = default; + + /** + * @brief Construct a new Gpg Key object + * + * @param key + */ + GpgKey(const gpgme_key_t& key) = delete; + + /** + * @brief Construct a new Gpg Key object + * + * @param k + */ + GpgKey(GpgKey&& k) noexcept; + + /** + * @brief + * + * @param k + * @return GpgKey& + */ + GpgKey& operator=(GpgKey&& k) noexcept; + + /** + * @brief + * + * @param key + * @return GpgKey& + */ + GpgKey& operator=(const gpgme_key_t& key) = delete; + + /** + * @brief + * + * @param o + * @return true + * @return false + */ + bool operator==(const GpgKey& o) const { return o.GetId() == this->GetId(); } + + /** + * @brief + * + * @param o + * @return true + * @return false + */ + bool operator<=(const GpgKey& o) const { return this->GetId() < o.GetId(); } + + /** + * @brief + * + * @return gpgme_key_t + */ + explicit operator gpgme_key_t() const { return key_ref_.get(); } + + /** + * @brief + * + * @return GpgKey + */ + [[nodiscard]] GpgKey Copy() const { + gpgme_key_ref(key_ref_.get()); + auto* _new_key_ref = key_ref_.get(); + return GpgKey(std::move(_new_key_ref)); + } + + private: + /** + * @brief + * + */ + struct _key_ref_deleter { + void operator()(gpgme_key_t _key) { + if (_key != nullptr) gpgme_key_unref(_key); + } + }; + + using KeyRefHandler = + std::unique_ptr<struct _gpgme_key, _key_ref_deleter>; ///< + + KeyRefHandler key_ref_ = nullptr; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGKEY_H diff --git a/src/gpg/model/GpgKeySignature.cpp b/src/core/model/GpgKeySignature.cpp index 8f937198..0c11a93b 100644 --- a/src/gpg/model/GpgKeySignature.cpp +++ b/src/core/model/GpgKeySignature.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/model/GpgKeySignature.h" +#include "core/model/GpgKeySignature.h" GpgFrontend::GpgKeySignature::GpgKeySignature(gpgme_key_sig_t sig) - : _signature_ref(sig, [&](gpgme_key_sig_t signature) {}) {} + : signature_ref_(sig, [&](gpgme_key_sig_t signature) {}) {} diff --git a/src/core/model/GpgKeySignature.h b/src/core/model/GpgKeySignature.h new file mode 100644 index 00000000..33b84904 --- /dev/null +++ b/src/core/model/GpgKeySignature.h @@ -0,0 +1,209 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H +#define GPGFRONTEND_GPGKEYSIGNATURE_H + +#include <boost/date_time.hpp> +#include <string> + +#include "core/GpgConstants.h" + +/** + * @brief + * + */ +namespace GpgFrontend { + +/** + * @brief + * + */ +class GpgKeySignature { + public: + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsRevoked() const { return signature_ref_->revoked; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsExpired() const { return signature_ref_->expired; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsInvalid() const { return signature_ref_->invalid; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsExportable() const { return signature_ref_->exportable; } + + /** + * @brief + * + * @return gpgme_error_t + */ + [[nodiscard]] gpgme_error_t GetStatus() const { + return signature_ref_->status; + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetKeyID() const { return signature_ref_->keyid; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetPubkeyAlgo() const { + return gpgme_pubkey_algo_name(signature_ref_->pubkey_algo); + } + + /** + * @brief Create a time object + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetCreateTime() const { + return boost::posix_time::from_time_t(signature_ref_->timestamp); + } + + /** + * @brief + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetExpireTime() const { + return boost::posix_time::from_time_t(signature_ref_->expires); + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetUID() const { return signature_ref_->uid; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetName() const { return signature_ref_->name; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetEmail() const { return signature_ref_->email; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetComment() const { + return signature_ref_->comment; + } + + /** + * @brief Construct a new Gpg Key Signature object + * + */ + GpgKeySignature() = default; + + /** + * @brief Destroy the Gpg Key Signature object + * + */ + ~GpgKeySignature() = default; + + /** + * @brief Construct a new Gpg Key Signature object + * + * @param sig + */ + explicit GpgKeySignature(gpgme_key_sig_t sig); + + /** + * @brief Construct a new Gpg Key Signature object + * + */ + GpgKeySignature(GpgKeySignature &&) noexcept = default; + + /** + * @brief Construct a new Gpg Key Signature object + * + */ + GpgKeySignature(const GpgKeySignature &) = delete; + + /** + * @brief + * + * @return GpgKeySignature& + */ + GpgKeySignature &operator=(GpgKeySignature &&) noexcept = default; + + /** + * @brief + * + * @return GpgKeySignature& + */ + GpgKeySignature &operator=(const GpgKeySignature &) = delete; + + private: + using KeySignatrueRefHandler = + std::unique_ptr<struct _gpgme_key_sig, + std::function<void(gpgme_key_sig_t)>>; ///< + + KeySignatrueRefHandler signature_ref_ = nullptr; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGKEYSIGNATURE_H diff --git a/src/gpg/model/GpgSignature.cpp b/src/core/model/GpgSignature.cpp index c8509edf..f8084442 100644 --- a/src/gpg/model/GpgSignature.cpp +++ b/src/core/model/GpgSignature.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "GpgSignature.h" GpgFrontend::GpgSignature::GpgSignature(gpgme_signature_t sig) - : _signature_ref(sig, [&](gpgme_signature_t signature) {}) {} + : signature_ref_(sig, [&](gpgme_signature_t signature) {}) {} diff --git a/src/core/model/GpgSignature.h b/src/core/model/GpgSignature.h new file mode 100644 index 00000000..942f0097 --- /dev/null +++ b/src/core/model/GpgSignature.h @@ -0,0 +1,171 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGSIGNATURE_H +#define GPGFRONTEND_GPGSIGNATURE_H + +#include <boost/date_time/gregorian/greg_date.hpp> +#include <boost/date_time/posix_time/conversion.hpp> + +#include "core/GpgConstants.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GpgSignature { + public: + /** + * @brief + * + * @return gpgme_validity_t + */ + [[nodiscard]] gpgme_validity_t GetValidity() const { + return signature_ref_->validity; + } + + /** + * @brief + * + * @return gpgme_error_t + */ + [[nodiscard]] gpgme_error_t GetStatus() const { + return signature_ref_->status; + } + + /** + * @brief + * + * @return gpgme_error_t + */ + [[nodiscard]] gpgme_error_t GetSummary() const { + return signature_ref_->summary; + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetPubkeyAlgo() const { + return gpgme_pubkey_algo_name(signature_ref_->pubkey_algo); + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetHashAlgo() const { + return gpgme_hash_algo_name(signature_ref_->hash_algo); + } + + /** + * @brief Create a time object + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetCreateTime() const { + return boost::posix_time::from_time_t(signature_ref_->timestamp); + } + + /** + * @brief + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetExpireTime() const { + return boost::posix_time::from_time_t(signature_ref_->exp_timestamp); + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetFingerprint() const { + return signature_ref_->fpr; + } + + /** + * @brief Construct a new Gpg Signature object + * + */ + GpgSignature() = default; + + /** + * @brief Destroy the Gpg Signature object + * + */ + ~GpgSignature() = default; + + /** + * @brief Construct a new Gpg Signature object + * + * @param sig + */ + explicit GpgSignature(gpgme_signature_t sig); + + /** + * @brief Construct a new Gpg Signature object + * + */ + GpgSignature(GpgSignature &&) noexcept = default; + + /** + * @brief Construct a new Gpg Signature object + * + */ + GpgSignature(const GpgSignature &) = delete; + + /** + * @brief + * + * @return GpgSignature& + */ + GpgSignature &operator=(GpgSignature &&) noexcept = default; + + /** + * @brief + * + * @return GpgSignature& + */ + GpgSignature &operator=(const GpgSignature &) = delete; + + private: + using KeySignatrueRefHandler = + std::unique_ptr<struct _gpgme_signature, + std::function<void(gpgme_signature_t)>>; ///< + + KeySignatrueRefHandler signature_ref_ = nullptr; ///< +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGSIGNATURE_H diff --git a/src/gpg/model/GpgSubKey.cpp b/src/core/model/GpgSubKey.cpp index 83fbcaa2..767f9c5d 100644 --- a/src/gpg/model/GpgSubKey.cpp +++ b/src/core/model/GpgSubKey.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,22 +8,24 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/model/GpgSubKey.h" +#include "core/model/GpgSubKey.h" GpgFrontend::GpgSubKey::GpgSubKey(gpgme_subkey_t subkey) : _subkey_ref(subkey, [&](gpgme_subkey_t subkey) {}) {} diff --git a/src/core/model/GpgSubKey.h b/src/core/model/GpgSubKey.h new file mode 100644 index 00000000..1aadcdac --- /dev/null +++ b/src/core/model/GpgSubKey.h @@ -0,0 +1,248 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGSUBKEY_H +#define GPGFRONTEND_GPGSUBKEY_H + +#include <boost/date_time.hpp> +#include <string> + +#include "core/GpgConstants.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GpgSubKey { + public: + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetID() const { return _subkey_ref->keyid; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetFingerprint() const { return _subkey_ref->fpr; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetPubkeyAlgo() const { + return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo); + } + + /** + * @brief + * + * @return unsigned int + */ + [[nodiscard]] unsigned int GetKeyLength() const { + return _subkey_ref->length; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasEncryptionCapability() const { + return _subkey_ref->can_encrypt; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasSigningCapability() const { + return _subkey_ref->can_sign; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasCertificationCapability() const { + return _subkey_ref->can_certify; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsHasAuthenticationCapability() const { + return _subkey_ref->can_authenticate; + } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsPrivateKey() const { return _subkey_ref->secret; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsExpired() const { return _subkey_ref->expired; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsRevoked() const { return _subkey_ref->revoked; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsDisabled() const { return _subkey_ref->disabled; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsSecretKey() const { return _subkey_ref->secret; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsCardKey() const { return _subkey_ref->is_cardkey; } + + /** + * @brief + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetCreateTime() const { + return boost::posix_time::from_time_t(_subkey_ref->timestamp); + } + + /** + * @brief + * + * @return boost::posix_time::ptime + */ + [[nodiscard]] boost::posix_time::ptime GetExpireTime() const { + return boost::posix_time::from_time_t(_subkey_ref->expires); + } + + /** + * @brief Construct a new Gpg Sub Key object + * + */ + GpgSubKey() = default; + + /** + * @brief Construct a new Gpg Sub Key object + * + * @param subkey + */ + explicit GpgSubKey(gpgme_subkey_t subkey); + + /** + * @brief Construct a new Gpg Sub Key object + * + * @param o + */ + GpgSubKey(GpgSubKey&& o) noexcept { swap(_subkey_ref, o._subkey_ref); } + + /** + * @brief Construct a new Gpg Sub Key object + * + */ + GpgSubKey(const GpgSubKey&) = delete; + + /** + * @brief + * + * @param o + * @return GpgSubKey& + */ + GpgSubKey& operator=(GpgSubKey&& o) noexcept { + swap(_subkey_ref, o._subkey_ref); + return *this; + }; + + /** + * @brief + * + * @return GpgSubKey& + */ + GpgSubKey& operator=(const GpgSubKey&) = delete; + + /** + * @brief + * + * @param o + * @return true + * @return false + */ + bool operator==(const GpgSubKey& o) const { + return GetFingerprint() == o.GetFingerprint(); + } + + private: + using SubkeyRefHandler = + std::unique_ptr<struct _gpgme_subkey, + std::function<void(gpgme_subkey_t)>>; ///< + + SubkeyRefHandler _subkey_ref = nullptr; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGSUBKEY_H diff --git a/src/gpg/model/GpgTOFUInfo.cpp b/src/core/model/GpgTOFUInfo.cpp index 0f18a1c2..8c83b360 100644 --- a/src/gpg/model/GpgTOFUInfo.cpp +++ b/src/core/model/GpgTOFUInfo.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/core/model/GpgTOFUInfo.h b/src/core/model/GpgTOFUInfo.h new file mode 100644 index 00000000..b2fea4cf --- /dev/null +++ b/src/core/model/GpgTOFUInfo.h @@ -0,0 +1,167 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGTOFU_H +#define GPGFRONTEND_GPGTOFU_H + +#include "core/GpgConstants.h" + +namespace GpgFrontend { +/** + * @brief + * + */ +class GpgTOFUInfo { + public: + /** + * @brief + * + * @return unsigned + */ + [[nodiscard]] unsigned GetValidity() const { + return _tofu_info_ref->validity; + } + + /** + * @brief + * + * @return unsigned + */ + [[nodiscard]] unsigned GetPolicy() const { return _tofu_info_ref->policy; } + + /** + * @brief + * + * @return unsigned long + */ + [[nodiscard]] unsigned long GetSignCount() const { + return _tofu_info_ref->signcount; + } + + /** + * @brief + * + * @return unsigned long + */ + [[nodiscard]] unsigned long GetEncrCount() const { + return _tofu_info_ref->encrcount; + } + + /** + * @brief + * + * @return unsigned long + */ + [[nodiscard]] unsigned long GetSignFirst() const { + return _tofu_info_ref->signfirst; + } + + /** + * @brief + * + * @return unsigned long + */ + [[nodiscard]] unsigned long GetSignLast() const { + return _tofu_info_ref->signlast; + } + + /** + * @brief + * + * @return unsigned long + */ + [[nodiscard]] unsigned long GetEncrLast() const { + return _tofu_info_ref->encrlast; + } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetDescription() const { + return _tofu_info_ref->description; + } + + /** + * @brief Construct a new Gpg T O F U Info object + * + */ + GpgTOFUInfo() = default; + + /** + * @brief Construct a new Gpg T O F U Info object + * + * @param tofu_info + */ + explicit GpgTOFUInfo(gpgme_tofu_info_t tofu_info); + + /** + * @brief Construct a new Gpg T O F U Info object + * + * @param o + */ + GpgTOFUInfo(GpgTOFUInfo&& o) noexcept { + swap(_tofu_info_ref, o._tofu_info_ref); + } + + /** + * @brief Construct a new Gpg T O F U Info object + * + */ + GpgTOFUInfo(const GpgTOFUInfo&) = delete; + + /** + * @brief + * + * @param o + * @return GpgTOFUInfo& + */ + GpgTOFUInfo& operator=(GpgTOFUInfo&& o) noexcept { + swap(_tofu_info_ref, o._tofu_info_ref); + return *this; + }; + + /** + * @brief + * + * @return GpgTOFUInfo& + */ + GpgTOFUInfo& operator=(const GpgTOFUInfo&) = delete; + + private: + using SubkeyRefHandler = + std::unique_ptr<struct _gpgme_tofu_info, + std::function<void(gpgme_tofu_info_t)>>; ///< + + SubkeyRefHandler _tofu_info_ref = nullptr; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGTOFU_H diff --git a/src/gpg/model/GpgUID.cpp b/src/core/model/GpgUID.cpp index c0a63bab..6d98c882 100644 --- a/src/gpg/model/GpgUID.cpp +++ b/src/core/model/GpgUID.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "gpg/model/GpgUID.h" +#include "core/model/GpgUID.h" GpgFrontend::GpgUID::GpgUID(gpgme_user_id_t uid) - : _uid_ref(uid, [&](gpgme_user_id_t uid) {}) {}
\ No newline at end of file + : uid_ref_(uid, [&](gpgme_user_id_t uid) {}) {}
\ No newline at end of file diff --git a/src/core/model/GpgUID.h b/src/core/model/GpgUID.h new file mode 100644 index 00000000..7f8daf98 --- /dev/null +++ b/src/core/model/GpgUID.h @@ -0,0 +1,171 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_GPGUID_H +#define GPGFRONTEND_GPGUID_H + +#include "GpgKeySignature.h" +#include "GpgTOFUInfo.h" + +namespace GpgFrontend { +/** + * @brief + * + */ +class GpgUID { + public: + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetName() const { return uid_ref_->name; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetEmail() const { return uid_ref_->email; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetComment() const { return uid_ref_->comment; } + + /** + * @brief + * + * @return std::string + */ + [[nodiscard]] std::string GetUID() const { return uid_ref_->uid; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool GetRevoked() const { return uid_ref_->revoked; } + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool GetInvalid() const { return uid_ref_->invalid; } + + /** + * @brief + * + * @return std::unique_ptr<std::vector<GpgTOFUInfo>> + */ + [[nodiscard]] std::unique_ptr<std::vector<GpgTOFUInfo>> GetTofuInfos() const { + auto infos = std::make_unique<std::vector<GpgTOFUInfo>>(); + auto info_next = uid_ref_->tofu; + while (info_next != nullptr) { + infos->push_back(GpgTOFUInfo(info_next)); + info_next = info_next->next; + } + return infos; + } + + /** + * @brief + * + * @return std::unique_ptr<std::vector<GpgKeySignature>> + */ + [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> GetSignatures() + const { + auto sigs = std::make_unique<std::vector<GpgKeySignature>>(); + auto sig_next = uid_ref_->signatures; + while (sig_next != nullptr) { + sigs->push_back(GpgKeySignature(sig_next)); + sig_next = sig_next->next; + } + return sigs; + } + + /** + * @brief Construct a new Gpg U I D object + * + */ + GpgUID() = default; + + /** + * @brief Construct a new Gpg U I D object + * + * @param uid + */ + explicit GpgUID(gpgme_user_id_t uid); + + /** + * @brief Construct a new Gpg U I D object + * + * @param o + */ + GpgUID(GpgUID &&o) noexcept { swap(uid_ref_, o.uid_ref_); } + + /** + * @brief Construct a new Gpg U I D object + * + */ + GpgUID(const GpgUID &) = delete; + + /** + * @brief + * + * @param o + * @return GpgUID& + */ + GpgUID &operator=(GpgUID &&o) noexcept { + swap(uid_ref_, o.uid_ref_); + return *this; + } + + /** + * @brief + * + * @return GpgUID& + */ + GpgUID &operator=(const GpgUID &) = delete; + + private: + using UidRefHandler = + std::unique_ptr<struct _gpgme_user_id, + std::function<void(gpgme_user_id_t)>>; ///< + + UidRefHandler uid_ref_ = nullptr; ///< +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGUID_H
\ No newline at end of file diff --git a/src/gpg/CMakeLists.txt b/src/gpg/CMakeLists.txt deleted file mode 100644 index 87328504..00000000 --- a/src/gpg/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -aux_source_directory(./result_analyse GPG_SOURCE) -aux_source_directory(./function GPG_SOURCE) -aux_source_directory(./model GPG_SOURCE) -aux_source_directory(. GPG_SOURCE) - -add_library(gpg_core STATIC ${GPG_SOURCE}) - -set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils) - -set(GPGME_LIB_DIR ${UTILS_DIR}/gpgme/lib) - -if (EASY_LOGGING_PP) - set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} easy_logging_pp) -endif () -set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} config++) - -set(BOOST_LIBS Boost::date_time Boost::filesystem) - -if (MINGW) - message(STATUS "Link GPG Static Library For MINGW") - target_link_libraries(gpg_core ${THIRD_PARTY_LIBS} - ${BOOST_LIBS} - gpgme gpg-error assuan wsock32) - target_compile_features(gpg_core PUBLIC cxx_std_17) -elseif (APPLE) - find_library(libgpgme NAMES libgpgme.a) - find_library(libgpg-error NAMES libgpg-error.a) - find_library(libassuan NAMES libassuan.a) - message(STATUS "Link GPG Static Library For macOS") - target_link_libraries(gpg_core ${THIRD_PARTY_LIBS} - ${BOOST_LIBS} - ${libgpgme} ${libgpg-error} ${libassuan} - dl) - if (XCODE_BUILD) - set_target_properties(gpg_core - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) - endif () -else () - find_library(libgpgme NAMES libgpgme.a) - find_library(libgpg-error NAMES libgpg-error.a) - find_library(libassuan NAMES libassuan.a) - message(STATUS "Link GPG Static Library For Unix") - target_link_libraries(gpg_core ${THIRD_PARTY_LIBS} - ${libgpgme} ${libgpg-error} ${libassuan} - ${BOOST_LIBS} - pthread dl) -endif () diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h deleted file mode 100644 index d2f9b0b6..00000000 --- a/src/gpg/GpgConstants.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPG_CONSTANTS_H -#define GPG_CONSTANTS_H - -#include <gpg-error.h> -#include <gpgme.h> - -#include <cassert> -#include <functional> -#include <memory> -#include <string> - -#include "GpgFrontend.h" - -const int RESTART_CODE = 1000; - -namespace GpgFrontend { - -using ByteArray = std::string; -using ByteArrayPtr = std::unique_ptr<ByteArray>; -using StdBypeArrayPtr = std::unique_ptr<ByteArray>; -using BypeArrayRef = ByteArray&; -using BypeArrayConstRef = const ByteArray&; -using StringArgsPtr = std::unique_ptr<std::vector<std::string>>; -using StringArgsRef = std::vector<std::string>&; - -using GpgError = gpgme_error_t; - -// Result Deleter -struct _result_ref_deletor { - void operator()(void* _result); -}; - -using GpgEncrResult = std::shared_ptr<struct _gpgme_op_encrypt_result>; -using GpgDecrResult = std::shared_ptr<struct _gpgme_op_decrypt_result>; -using GpgSignResult = std::shared_ptr<struct _gpgme_op_sign_result>; -using GpgVerifyResult = std::shared_ptr<struct _gpgme_op_verify_result>; -using GpgGenKeyResult = std::shared_ptr<struct _gpgme_op_genkey_result>; - -// Convert from gpgme_xxx_result to GpgXXXResult -GpgEncrResult _new_result(gpgme_encrypt_result_t&& result); -GpgDecrResult _new_result(gpgme_decrypt_result_t&& result); -GpgSignResult _new_result(gpgme_sign_result_t&& result); -GpgVerifyResult _new_result(gpgme_verify_result_t&& result); -GpgGenKeyResult _new_result(gpgme_genkey_result_t&& result); - -// Error Info Printer -GpgError check_gpg_error(GpgError err); -GpgError check_gpg_error(GpgError gpgmeError, const std::string& comment); -gpg_err_code_t check_gpg_error_2_err_code( - gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR); - -// Fingerprint -std::string beautify_fingerprint(BypeArrayConstRef fingerprint); - -// File Operation -std::string read_all_data_in_file(const std::string& path); -bool write_buffer_to_file(const std::string& path, - const std::string& out_buffer); - -std::string get_file_extension(const std::string& path); -std::string get_only_file_name_with_path(const std::string& path); - -// Check -int text_is_signed(BypeArrayRef text); - -// Channels -const int GPGFRONTEND_DEFAULT_CHANNEL = 0; -const int GPGFRONTEND_NON_ASCII_CHANNEL = 2; - -class GpgConstants { - public: - static const char* PGP_CRYPT_BEGIN; - static const char* PGP_CRYPT_END; - static const char* PGP_SIGNED_BEGIN; - static const char* PGP_SIGNED_END; - static const char* PGP_SIGNATURE_BEGIN; - static const char* PGP_SIGNATURE_END; - static const char* PGP_PUBLIC_KEY_BEGIN; - static const char* PGP_PRIVATE_KEY_BEGIN; - static const char* GPG_FRONTEND_SHORT_CRYPTO_HEAD; -}; - -} // namespace GpgFrontend - -#endif // GPG_CONSTANTS_H diff --git a/src/gpg/GpgGenKeyInfo.h b/src/gpg/GpgGenKeyInfo.h deleted file mode 100644 index 8f7d19ea..00000000 --- a/src/gpg/GpgGenKeyInfo.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGGENKEYINFO_H -#define GPGFRONTEND_GPGGENKEYINFO_H - -#include <boost/date_time.hpp> -#include <boost/date_time/gregorian/greg_duration_types.hpp> -#include <boost/format.hpp> -#include <string> -#include <vector> - -namespace GpgFrontend { - -class GenKeyInfo { - bool standalone_ = false; - bool subkey_ = false; - std::string name_; - std::string email_; - std::string comment_; - - std::string algo_; - int key_size_ = 2048; - boost::posix_time::ptime expired_ = - boost::posix_time::second_clock::local_time() + - boost::gregorian::years(2); - bool non_expired_ = false; - - bool no_passphrase_ = false; - bool allow_no_pass_phrase_ = true; - - int suggest_max_key_size_ = 4096; - int suggest_size_addition_step_ = 1024; - int suggest_min_key_size_ = 1024; - - std::string passphrase_; - - public: - static const std::vector<std::string> &getSupportedKeyAlgo(); - - static const std::vector<std::string> &getSupportedSubkeyAlgo(); - - static const std::vector<std::string> &getSupportedKeyAlgoStandalone(); - - static const std::vector<std::string> &getSupportedSubkeyAlgoStandalone(); - - [[nodiscard]] bool isSubKey() const { return subkey_; } - - void setIsSubKey(bool m_sub_key) { GenKeyInfo::subkey_ = m_sub_key; } - - [[nodiscard]] std::string getUserid() const { - auto uid_format = boost::format("%1%(%2%)<%3%>") % this->name_ % - this->comment_ % this->email_; - return uid_format.str(); - } - - void setName(const std::string &m_name) { this->name_ = m_name; } - - void setEmail(const std::string &m_email) { this->email_ = m_email; } - - void setComment(const std::string &m_comment) { this->comment_ = m_comment; } - - [[nodiscard]] std::string getName() const { return name_; } - - [[nodiscard]] std::string getEmail() const { return email_; } - - [[nodiscard]] std::string getComment() const { return comment_; } - - [[nodiscard]] const std::string &getAlgo() const { return algo_; } - - void setAlgo(const std::string &m_algo); - - [[nodiscard]] std::string getKeySizeStr() const; - - [[nodiscard]] int getKeySize() const { return key_size_; } - - void setKeySize(int m_key_size); - - [[nodiscard]] const boost::posix_time::ptime &getExpired() const { - return expired_; - } - - void setExpired(const boost::posix_time::ptime &m_expired); - - [[nodiscard]] bool isNonExpired() const { return non_expired_; } - - void setNonExpired(bool m_non_expired); - - [[nodiscard]] bool isNoPassPhrase() const { return this->no_passphrase_; } - - void setNonPassPhrase(bool m_non_pass_phrase) { - GenKeyInfo::no_passphrase_ = m_non_pass_phrase; - } - - [[nodiscard]] bool isAllowSigning() const { return allowSigning; } - - [[nodiscard]] bool isAllowNoPassPhrase() const { - return allow_no_pass_phrase_; - } - - void setAllowSigning(bool m_allow_signing) { - if (allowChangeSigning) GenKeyInfo::allowSigning = m_allow_signing; - } - - [[nodiscard]] bool isAllowEncryption() const { return allowEncryption; } - - void setAllowEncryption(bool m_allow_encryption); - - [[nodiscard]] bool isAllowCertification() const { return allowCertification; } - - void setAllowCertification(bool m_allow_certification); - - [[nodiscard]] bool isAllowAuthentication() const { - return allowAuthentication; - } - - void setAllowAuthentication(bool m_allow_authentication) { - if (allowChangeAuthentication) - GenKeyInfo::allowAuthentication = m_allow_authentication; - } - - [[nodiscard]] const std::string &getPassPhrase() const { return passphrase_; } - - void setPassPhrase(const std::string &m_pass_phrase) { - GenKeyInfo::passphrase_ = m_pass_phrase; - } - - [[nodiscard]] bool isAllowChangeSigning() const { return allowChangeSigning; } - [[nodiscard]] bool isAllowChangeEncryption() const { - return allowChangeEncryption; - } - - [[nodiscard]] bool isAllowChangeCertification() const { - return allowChangeCertification; - } - - [[nodiscard]] bool isAllowChangeAuthentication() const { - return allowChangeAuthentication; - } - - [[nodiscard]] int getSuggestMaxKeySize() const { - return suggest_max_key_size_; - } - - [[nodiscard]] int getSuggestMinKeySize() const { - return suggest_min_key_size_; - } - - [[nodiscard]] int getSizeChangeStep() const { - return suggest_size_addition_step_; - } - - private: - bool allowEncryption = true; - bool allowChangeEncryption = true; - - bool allowCertification = true; - bool allowChangeCertification = true; - - bool allowAuthentication = true; - bool allowChangeAuthentication = true; - - bool allowSigning = true; - bool allowChangeSigning = true; - - void reset_options(); - - public: - explicit GenKeyInfo(bool m_is_sub_key = false, bool m_standalone = false); -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGGENKEYINFO_H diff --git a/src/gpg/GpgInfo.h b/src/gpg/GpgInfo.h deleted file mode 100644 index 67ac55d6..00000000 --- a/src/gpg/GpgInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H -#define GPGFRONTEND_ZH_CN_TS_GPGINFO_H - -#include <string> - -/** - * Use to record some info about gnupg - */ -class GpgInfo { - public: - /** - * executable binary path of gnupg - */ - std::string AppPath; - - std::string DatabasePath; - - std::string GnupgVersion; - - std::string GpgConfPath; - - std::string CMSPath; - - std::string GpgMEVersion; -}; - -#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H diff --git a/src/gpg/GpgModel.h b/src/gpg/GpgModel.h deleted file mode 100644 index af094bf5..00000000 --- a/src/gpg/GpgModel.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H -#define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H - -#include <list> -#include <utility> - -#include "GpgConstants.h" -#include "gpg/model/GpgData.h" -#include "gpg/model/GpgKey.h" -#include "gpg/model/GpgSignature.h" - -namespace GpgFrontend { - -using KeyId = std::string; - -using SubkeyId = std::string; - -using KeyIdArgsList = std::vector<KeyId>; - -using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>; - -using UIDArgsList = std::vector<std::string>; - -using UIDArgsListPtr = std::unique_ptr<UIDArgsList>; - -// KeyID/UID -using SignIdArgsList = std::vector<std::pair<std::string, std::string>>; - -using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; - -using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>; - -using KeyArgsList = std::vector<GpgKey>; - -using KeyListPtr = std::unique_ptr<KeyArgsList>; - -using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>; - -using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; - -using KeyPtr = std::unique_ptr<GpgKey>; - -using KeyPtrArgsList = const std::initializer_list<KeyPtr>; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_ZH_CN_TS_GPGMODEL_H diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h deleted file mode 100644 index 41bd9b7f..00000000 --- a/src/gpg/function/BasicOperator.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H -#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H - -#include "gpg/GpgConstants.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" -#include "gpg/GpgModel.h" - -namespace GpgFrontend { - -class BasicOperator : public SingletonFunctionObject<BasicOperator> { - public: - explicit BasicOperator( - int channel = SingletonFunctionObject::GetDefaultChannel()) - : SingletonFunctionObject<BasicOperator>(channel) {} - - gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer, - ByteArrayPtr& out_buffer, GpgEncrResult& result); - - gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - GpgEncrResult& result); - - gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers, - BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - GpgEncrResult& encr_result, - GpgSignResult& sign_result); - - gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - GpgDecrResult& result); - - gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - GpgDecrResult& decrypt_result, - GpgVerifyResult& verify_result); - - gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer, - GpgVerifyResult& result) const; - - gpg_error_t Sign(KeyListPtr keys, BypeArrayRef in_buffer, - ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode, - GpgSignResult& result); - - void SetSigners(KeyArgsList& keys); - - std::unique_ptr<KeyArgsList> GetSigners(); - - private: - GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); -}; -} // namespace GpgFrontend - -#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H diff --git a/src/gpg/function/GpgFileOpera.cpp b/src/gpg/function/GpgFileOpera.cpp deleted file mode 100644 index 8babfa6d..00000000 --- a/src/gpg/function/GpgFileOpera.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ -#include "gpg/function/GpgFileOpera.h" - -#include <memory> -#include <string> - -#include "GpgConstants.h" -#include "gpg/function/BasicOperator.h" - -GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile( - KeyListPtr keys, const std::string& in_path, const std::string& out_path, - GpgEncrResult& result, int _channel) { - std::string in_buffer = read_all_data_in_file(in_path); - std::unique_ptr<std::string> out_buffer; - - auto err = BasicOperator::GetInstance(_channel).Encrypt( - std::move(keys), in_buffer, out_buffer, result); - - if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_path, *out_buffer)) { - throw std::runtime_error("write_buffer_to_file error"); - }; - - return err; -} - -GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile( - const std::string& in_path, const std::string& out_path, - GpgDecrResult& result) { - std::string in_buffer = read_all_data_in_file(in_path); - std::unique_ptr<std::string> out_buffer; - - auto err = - BasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result); - - assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR); - - if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_path, *out_buffer)) { - throw std::runtime_error("write_buffer_to_file error"); - }; - - return err; -} - -gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys, - const std::string& in_path, - const std::string& out_path, - GpgSignResult& result, - int _channel) { - auto in_buffer = read_all_data_in_file(in_path); - std::unique_ptr<std::string> out_buffer; - - auto err = BasicOperator::GetInstance(_channel).Sign( - std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result); - - if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_path, *out_buffer)) { - throw std::runtime_error("write_buffer_to_file error"); - }; - - return err; -} - -gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile( - const std::string& data_path, const std::string& sign_path, - GpgVerifyResult& result, int _channel) { - auto in_buffer = read_all_data_in_file(data_path); - std::unique_ptr<std::string> sign_buffer = nullptr; - if (!sign_path.empty()) { - sign_buffer = - std::make_unique<std::string>(read_all_data_in_file(sign_path)); - } - auto err = BasicOperator::GetInstance(_channel).Verify(in_buffer, sign_buffer, - result); - return err; -} - -gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile( - KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path, - const std::string& out_path, GpgEncrResult& encr_res, - GpgSignResult& sign_res, int _channel) { - auto in_buffer = read_all_data_in_file(in_path); - std::unique_ptr<std::string> out_buffer = nullptr; - - auto err = BasicOperator::GetInstance(_channel).EncryptSign( - std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res, - sign_res); - - if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_path, *out_buffer)) { - throw std::runtime_error("write_buffer_to_file error"); - }; - - return err; -} - -gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile( - const std::string& in_path, const std::string& out_path, - GpgDecrResult& decr_res, GpgVerifyResult& verify_res) { - auto in_buffer = read_all_data_in_file(in_path); - - std::unique_ptr<std::string> out_buffer = nullptr; - - auto err = BasicOperator::GetInstance().DecryptVerify(in_buffer, out_buffer, - decr_res, verify_res); - - if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_path, *out_buffer)) { - throw std::runtime_error("write_buffer_to_file error"); - }; - - return err; -} -unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric( - const std::string& in_path, const std::string& out_path, - GpgFrontend::GpgEncrResult& result, int _channel) { - std::string in_buffer = read_all_data_in_file(in_path); - std::unique_ptr<std::string> out_buffer; - - auto err = BasicOperator::GetInstance(_channel).EncryptSymmetric( - in_buffer, out_buffer, result); - - if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_path, *out_buffer)) { - throw std::runtime_error("write_buffer_to_file error"); - }; - - return err; -} diff --git a/src/gpg/model/GpgData.h b/src/gpg/model/GpgData.h deleted file mode 100644 index e3202af6..00000000 --- a/src/gpg/model/GpgData.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef _GPGDATA_H -#define _GPGDATA_H - -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { - -class GpgData { - public: - GpgData(); - - GpgData(void* buffer, size_t size, bool copy = true); - - operator gpgme_data_t() { return data_.get(); } - - ByteArrayPtr Read2Buffer(); - - private: - struct __data_ref_deletor { - void operator()(gpgme_data_t _data) { - if (_data != nullptr) gpgme_data_release(_data); - } - }; - - std::unique_ptr<struct gpgme_data, __data_ref_deletor> data_ = nullptr; -}; - -} // namespace GpgFrontend - -#endif // _GPGDATA_H
\ No newline at end of file diff --git a/src/gpg/model/GpgKey.cpp b/src/gpg/model/GpgKey.cpp deleted file mode 100644 index c14edd2d..00000000 --- a/src/gpg/model/GpgKey.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/model/GpgKey.h" - -GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : _key_ref(std::move(key)) {} - -GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(_key_ref, k._key_ref); } - -GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept { - swap(_key_ref, k._key_ref); - return *this; -} - -std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>> -GpgFrontend::GpgKey::subKeys() const { - auto p_keys = std::make_unique<std::vector<GpgSubKey>>(); - auto next = _key_ref->subkeys; - while (next != nullptr) { - p_keys->push_back(GpgSubKey(next)); - next = next->next; - } - return p_keys; -} - -std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::uids() - const { - auto p_uids = std::make_unique<std::vector<GpgUID>>(); - auto uid_next = _key_ref->uids; - while (uid_next != nullptr) { - p_uids->push_back(GpgUID(uid_next)); - uid_next = uid_next->next; - } - return p_uids; -} - -bool GpgFrontend::GpgKey::CanSignActual() const { - auto subkeys = subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), - [](const GpgSubKey &subkey) -> bool { - return subkey.secret() && subkey.can_sign() && - !subkey.disabled() && !subkey.revoked() && - !subkey.expired(); - })) - return true; - else - return false; -} - -bool GpgFrontend::GpgKey::CanAuthActual() const { - auto subkeys = subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), - [](const GpgSubKey &subkey) -> bool { - return subkey.secret() && subkey.can_authenticate() && - !subkey.disabled() && !subkey.revoked() && - !subkey.expired(); - })) - return true; - else - return false; -} - -/** - * check if key can certify(actually) - * @param key target key - * @return if key certify - */ -bool GpgFrontend::GpgKey::CanCertActual() const { - return has_master_key() && !expired() && !revoked() && !disabled(); -} - -/** - * check if key can encrypt(actually) - * @param key target key - * @return if key encrypt - */ -bool GpgFrontend::GpgKey::CanEncrActual() const { - auto subkeys = subKeys(); - if (std::any_of(subkeys->begin(), subkeys->end(), - [](const GpgSubKey &subkey) -> bool { - return subkey.can_encrypt() && !subkey.disabled() && - !subkey.revoked() && !subkey.expired(); - })) - return true; - else - return false; -} diff --git a/src/gpg/model/GpgKey.h b/src/gpg/model/GpgKey.h deleted file mode 100644 index 0ce83372..00000000 --- a/src/gpg/model/GpgKey.h +++ /dev/null @@ -1,174 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGKEY_H -#define GPGFRONTEND_GPGKEY_H - -#include <boost/date_time.hpp> -#include <boost/date_time/posix_time/conversion.hpp> - -#include "GpgSubKey.h" -#include "GpgUID.h" - -namespace GpgFrontend { - -class GpgKey { - public: - [[nodiscard]] bool good() const { return _key_ref != nullptr; } - - [[nodiscard]] std::string id() const { return _key_ref->subkeys->keyid; } - - [[nodiscard]] std::string name() const { return _key_ref->uids->name; }; - - [[nodiscard]] std::string email() const { return _key_ref->uids->email; } - - [[nodiscard]] std::string comment() const { return _key_ref->uids->comment; } - - [[nodiscard]] std::string fpr() const { return _key_ref->fpr; } - - [[nodiscard]] std::string protocol() const { - return gpgme_get_protocol_name(_key_ref->protocol); - } - - [[nodiscard]] std::string owner_trust() const { - switch (_key_ref->owner_trust) { - case GPGME_VALIDITY_UNKNOWN: - return "Unknown"; - case GPGME_VALIDITY_UNDEFINED: - return "Undefined"; - case GPGME_VALIDITY_NEVER: - return "Never"; - case GPGME_VALIDITY_MARGINAL: - return "Marginal"; - case GPGME_VALIDITY_FULL: - return "FULL"; - case GPGME_VALIDITY_ULTIMATE: - return "Ultimate"; - } - return "Invalid"; - } - - [[nodiscard]] std::string pubkey_algo() const { - return gpgme_pubkey_algo_name(_key_ref->subkeys->pubkey_algo); - } - - [[nodiscard]] boost::posix_time::ptime last_update() const { - return boost::posix_time::from_time_t( - static_cast<time_t>(_key_ref->last_update)); - } - - [[nodiscard]] boost::posix_time::ptime expires() const { - return boost::posix_time::from_time_t(_key_ref->subkeys->expires); - }; - - [[nodiscard]] boost::posix_time::ptime create_time() const { - return boost::posix_time::from_time_t(_key_ref->subkeys->timestamp); - }; - - [[nodiscard]] unsigned int length() const { - return _key_ref->subkeys->length; - } - - [[nodiscard]] bool can_encrypt() const { return _key_ref->can_encrypt; } - - [[nodiscard]] bool CanEncrActual() const; - - [[nodiscard]] bool can_sign() const { return _key_ref->can_sign; } - - [[nodiscard]] bool CanSignActual() const; - - [[nodiscard]] bool can_certify() const { return _key_ref->can_certify; } - - [[nodiscard]] bool CanCertActual() const; - - [[nodiscard]] bool can_authenticate() const { - return _key_ref->can_authenticate; - } - - [[nodiscard]] bool CanAuthActual() const; - - [[nodiscard]] bool HasCardKey() const { - auto subkeys = subKeys(); - return std::any_of( - subkeys->begin(), subkeys->end(), - [](const GpgSubKey& subkey) -> bool { return subkey.is_cardkey(); }); - } - - [[nodiscard]] bool is_private_key() const { return _key_ref->secret; } - - [[nodiscard]] bool expired() const { return _key_ref->expired; } - - [[nodiscard]] bool revoked() const { return _key_ref->revoked; } - - [[nodiscard]] bool disabled() const { return _key_ref->disabled; } - - [[nodiscard]] bool has_master_key() const { - return _key_ref->subkeys->secret; - } - - [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> subKeys() const; - - [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> uids() const; - - GpgKey() = default; - - explicit GpgKey(gpgme_key_t&& key); - - ~GpgKey() = default; - - GpgKey(const gpgme_key_t& key) = delete; - - GpgKey(GpgKey&& k) noexcept; - - GpgKey& operator=(GpgKey&& k) noexcept; - - GpgKey& operator=(const gpgme_key_t& key) = delete; - - bool operator==(const GpgKey& o) const { return o.id() == this->id(); } - - bool operator<=(const GpgKey& o) const { return this->id() < o.id(); } - - explicit operator gpgme_key_t() const { return _key_ref.get(); } - - [[nodiscard]] GpgKey copy() const { - gpgme_key_ref(_key_ref.get()); - auto* _new_key_ref = _key_ref.get(); - return GpgKey(std::move(_new_key_ref)); - } - - private: - struct _key_ref_deletor { - void operator()(gpgme_key_t _key) { - if (_key != nullptr) gpgme_key_unref(_key); - } - }; - - using KeyRefHandler = std::unique_ptr<struct _gpgme_key, _key_ref_deletor>; - - KeyRefHandler _key_ref = nullptr; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGKEY_H diff --git a/src/gpg/model/GpgKeySignature.h b/src/gpg/model/GpgKeySignature.h deleted file mode 100644 index d08162fc..00000000 --- a/src/gpg/model/GpgKeySignature.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H -#define GPGFRONTEND_GPGKEYSIGNATURE_H - -#include <boost/date_time.hpp> -#include <string> - -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { - -class GpgKeySignature { - public: - [[nodiscard]] bool revoked() const { return _signature_ref->revoked; } - [[nodiscard]] bool expired() const { return _signature_ref->expired; } - [[nodiscard]] bool invalid() const { return _signature_ref->invalid; } - [[nodiscard]] bool exportable() const { return _signature_ref->exportable; } - - [[nodiscard]] gpgme_error_t status() const { return _signature_ref->status; } - - [[nodiscard]] std::string keyid() const { return _signature_ref->keyid; } - [[nodiscard]] std::string pubkey_algo() const { - return gpgme_pubkey_algo_name(_signature_ref->pubkey_algo); - } - - [[nodiscard]] boost::posix_time::ptime create_time() const { - return boost::posix_time::from_time_t(_signature_ref->timestamp); - } - [[nodiscard]] boost::posix_time::ptime expire_time() const { - return boost::posix_time::from_time_t(_signature_ref->expires); - } - - [[nodiscard]] std::string uid() const { return _signature_ref->uid; } - [[nodiscard]] std::string name() const { return _signature_ref->name; } - [[nodiscard]] std::string email() const { return _signature_ref->email; } - [[nodiscard]] std::string comment() const { return _signature_ref->comment; } - - GpgKeySignature() = default; - - ~GpgKeySignature() = default; - - explicit GpgKeySignature(gpgme_key_sig_t sig); - - GpgKeySignature(GpgKeySignature &&) noexcept = default; - - GpgKeySignature(const GpgKeySignature &) = delete; - - GpgKeySignature &operator=(GpgKeySignature &&) noexcept = default; - - GpgKeySignature &operator=(const GpgKeySignature &) = delete; - - private: - using KeySignatrueRefHandler = - std::unique_ptr<struct _gpgme_key_sig, - std::function<void(gpgme_key_sig_t)>>; - - KeySignatrueRefHandler _signature_ref = nullptr; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGKEYSIGNATURE_H diff --git a/src/gpg/model/GpgSignature.h b/src/gpg/model/GpgSignature.h deleted file mode 100644 index 419bf9cf..00000000 --- a/src/gpg/model/GpgSignature.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGSIGNATURE_H -#define GPGFRONTEND_GPGSIGNATURE_H - -#include <boost/date_time/gregorian/greg_date.hpp> -#include <boost/date_time/posix_time/conversion.hpp> - -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { -class GpgSignature { - public: - [[nodiscard]] gpgme_validity_t validity() const { - return _signature_ref->validity; - } - - [[nodiscard]] gpgme_error_t status() const { return _signature_ref->status; } - - [[nodiscard]] gpgme_error_t summary() const { - return _signature_ref->summary; - } - - [[nodiscard]] std::string pubkey_algo() const { - return gpgme_pubkey_algo_name(_signature_ref->pubkey_algo); - } - - [[nodiscard]] std::string hash_algo() const { - return gpgme_hash_algo_name(_signature_ref->hash_algo); - } - - [[nodiscard]] boost::posix_time::ptime create_time() const { - return boost::posix_time::from_time_t(_signature_ref->timestamp); - } - [[nodiscard]] boost::posix_time::ptime expire_time() const { - return boost::posix_time::from_time_t(_signature_ref->exp_timestamp); - } - - [[nodiscard]] std::string fpr() const { return _signature_ref->fpr; } - - GpgSignature() = default; - - ~GpgSignature() = default; - - explicit GpgSignature(gpgme_signature_t sig); - - GpgSignature(GpgSignature &&) noexcept = default; - - GpgSignature(const GpgSignature &) = delete; - - GpgSignature &operator=(GpgSignature &&) noexcept = default; - - GpgSignature &operator=(const GpgSignature &) = delete; - - private: - using KeySignatrueRefHandler = - std::unique_ptr<struct _gpgme_signature, - std::function<void(gpgme_signature_t)>>; - - KeySignatrueRefHandler _signature_ref = nullptr; -}; -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGSIGNATURE_H diff --git a/src/gpg/model/GpgSubKey.h b/src/gpg/model/GpgSubKey.h deleted file mode 100644 index 462dcbca..00000000 --- a/src/gpg/model/GpgSubKey.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGSUBKEY_H -#define GPGFRONTEND_GPGSUBKEY_H - -#include <boost/date_time.hpp> -#include <string> - -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { - -class GpgSubKey { - public: - [[nodiscard]] std::string id() const { return _subkey_ref->keyid; } - - [[nodiscard]] std::string fpr() const { return _subkey_ref->fpr; } - - [[nodiscard]] std::string pubkey_algo() const { - return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo); - } - - [[nodiscard]] unsigned int length() const { return _subkey_ref->length; } - - [[nodiscard]] bool can_encrypt() const { return _subkey_ref->can_encrypt; } - - [[nodiscard]] bool can_sign() const { return _subkey_ref->can_sign; } - - [[nodiscard]] bool can_certify() const { return _subkey_ref->can_certify; } - - [[nodiscard]] bool can_authenticate() const { - return _subkey_ref->can_authenticate; - } - - [[nodiscard]] bool is_private_key() const { return _subkey_ref->secret; } - - [[nodiscard]] bool expired() const { return _subkey_ref->expired; } - - [[nodiscard]] bool revoked() const { return _subkey_ref->revoked; } - - [[nodiscard]] bool disabled() const { return _subkey_ref->disabled; } - - [[nodiscard]] bool secret() const { return _subkey_ref->secret; } - - [[nodiscard]] bool is_cardkey() const { return _subkey_ref->is_cardkey; } - - [[nodiscard]] boost::posix_time::ptime timestamp() const { - return boost::posix_time::from_time_t(_subkey_ref->timestamp); - } - - [[nodiscard]] boost::posix_time::ptime expires() const { - return boost::posix_time::from_time_t(_subkey_ref->expires); - } - - GpgSubKey() = default; - - explicit GpgSubKey(gpgme_subkey_t subkey); - - GpgSubKey(GpgSubKey&& o) noexcept { swap(_subkey_ref, o._subkey_ref); } - - GpgSubKey(const GpgSubKey&) = delete; - - GpgSubKey& operator=(GpgSubKey&& o) noexcept { - swap(_subkey_ref, o._subkey_ref); - return *this; - }; - - GpgSubKey& operator=(const GpgSubKey&) = delete; - - bool operator==(const GpgSubKey& o) const { return fpr() == o.fpr(); } - - private: - using SubkeyRefHandler = std::unique_ptr<struct _gpgme_subkey, - std::function<void(gpgme_subkey_t)>>; - - SubkeyRefHandler _subkey_ref = nullptr; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGSUBKEY_H diff --git a/src/gpg/model/GpgTOFUInfo.h b/src/gpg/model/GpgTOFUInfo.h deleted file mode 100644 index 3d1e379d..00000000 --- a/src/gpg/model/GpgTOFUInfo.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGTOFU_H -#define GPGFRONTEND_GPGTOFU_H - -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { - -class GpgTOFUInfo { - public: - [[nodiscard]] unsigned validity() const { return _tofu_info_ref->validity; } - - [[nodiscard]] unsigned policy() const { return _tofu_info_ref->policy; } - - [[nodiscard]] unsigned long sign_count() const { - return _tofu_info_ref->signcount; - } - - [[nodiscard]] unsigned long encr_count() const { - return _tofu_info_ref->encrcount; - } - - [[nodiscard]] unsigned long sign_first() const { - return _tofu_info_ref->signfirst; - } - - [[nodiscard]] unsigned long sign_last() const { - return _tofu_info_ref->signlast; - } - - [[nodiscard]] unsigned long encr_last() const { - return _tofu_info_ref->encrlast; - } - - [[nodiscard]] std::string description() const { - return _tofu_info_ref->description; - } - - GpgTOFUInfo() = default; - - explicit GpgTOFUInfo(gpgme_tofu_info_t tofu_info); - - GpgTOFUInfo(GpgTOFUInfo&& o) noexcept { - swap(_tofu_info_ref, o._tofu_info_ref); - } - - GpgTOFUInfo(const GpgTOFUInfo&) = delete; - - GpgTOFUInfo& operator=(GpgTOFUInfo&& o) noexcept { - swap(_tofu_info_ref, o._tofu_info_ref); - return *this; - }; - - GpgTOFUInfo& operator=(const GpgTOFUInfo&) = delete; - - private: - using SubkeyRefHandler = - std::unique_ptr<struct _gpgme_tofu_info, - std::function<void(gpgme_tofu_info_t)>>; - - SubkeyRefHandler _tofu_info_ref = nullptr; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGTOFU_H diff --git a/src/gpg/model/GpgUID.h b/src/gpg/model/GpgUID.h deleted file mode 100644 index 8cac4cf7..00000000 --- a/src/gpg/model/GpgUID.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GPGUID_H -#define GPGFRONTEND_GPGUID_H - -#include "GpgKeySignature.h" -#include "GpgTOFUInfo.h" - -namespace GpgFrontend { - -class GpgUID { - public: - [[nodiscard]] std::string name() const { return _uid_ref->name; } - - [[nodiscard]] std::string email() const { return _uid_ref->email; } - - [[nodiscard]] std::string comment() const { return _uid_ref->comment; } - - [[nodiscard]] std::string uid() const { return _uid_ref->uid; } - - [[nodiscard]] bool revoked() const { return _uid_ref->revoked; } - - [[nodiscard]] bool invalid() const { return _uid_ref->invalid; } - - [[nodiscard]] std::unique_ptr<std::vector<GpgTOFUInfo>> tofu_infos() const { - auto infos = std::make_unique<std::vector<GpgTOFUInfo>>(); - auto info_next = _uid_ref->tofu; - while (info_next != nullptr) { - infos->push_back(GpgTOFUInfo(info_next)); - info_next = info_next->next; - } - return infos; - } - - [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> signatures() - const { - auto sigs = std::make_unique<std::vector<GpgKeySignature>>(); - auto sig_next = _uid_ref->signatures; - while (sig_next != nullptr) { - sigs->push_back(GpgKeySignature(sig_next)); - sig_next = sig_next->next; - } - return sigs; - } - - GpgUID() = default; - - explicit GpgUID(gpgme_user_id_t uid); - - GpgUID(GpgUID &&o) noexcept { swap(_uid_ref, o._uid_ref); } - - GpgUID(const GpgUID &) = delete; - - GpgUID &operator=(GpgUID &&o) noexcept { - swap(_uid_ref, o._uid_ref); - return *this; - } - - GpgUID &operator=(const GpgUID &) = delete; - - private: - using UidRefHandler = std::unique_ptr<struct _gpgme_user_id, - std::function<void(gpgme_user_id_t)>>; - - UidRefHandler _uid_ref = nullptr; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_GPGUID_H
\ No newline at end of file diff --git a/src/gpg/result_analyse/DecryptResultAnalyse.cpp b/src/gpg/result_analyse/DecryptResultAnalyse.cpp deleted file mode 100644 index f2e9f947..00000000 --- a/src/gpg/result_analyse/DecryptResultAnalyse.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/result_analyse/DecryptResultAnalyse.h" - -#include "gpg/function/GpgKeyGetter.h" - -GpgFrontend::DecryptResultAnalyse::DecryptResultAnalyse(GpgError m_error, - GpgDecrResult m_result) - : error(m_error), result(std::move(m_result)) {} - -void GpgFrontend::DecryptResultAnalyse::do_analyse() { - stream << "[#] " << _("Decrypt Operation"); - - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { - stream << "[" << _("Success") << "]" << std::endl; - } else { - stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl; - setStatus(-1); - if (result != nullptr && result->unsupported_algorithm != nullptr) { - stream << "------------>" << std::endl; - stream << _("Unsupported Algo") << ": " << result->unsupported_algorithm - << std::endl; - } - } - - if (result != nullptr && result->recipients != nullptr) { - stream << "------------>" << std::endl; - if (result->file_name != nullptr) { - stream << _("File Name") << ": " << result->file_name << std::endl; - stream << std::endl; - } - if (result->is_mime) { - stream << _("MIME") << ": " << _("true") << std::endl; - } - - auto recipient = result->recipients; - if (recipient != nullptr) stream << _("Recipient(s)") << ": " << std::endl; - while (recipient != nullptr) { - print_recipient(stream, recipient); - recipient = recipient->next; - } - stream << "<------------" << std::endl; - } - - stream << std::endl; -} - -void GpgFrontend::DecryptResultAnalyse::print_recipient( - std::stringstream &stream, gpgme_recipient_t recipient) { - // check - if (recipient->keyid == nullptr) return; - - stream << " {>} " << _("Recipient") << ": "; - auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(recipient->keyid); - if (key.good()) { - stream << key.name().c_str(); - if (!key.email().empty()) { - stream << "<" << key.email().c_str() << ">"; - } - } else { - stream << "<" << _("Unknown") << ">"; - setStatus(0); - } - - stream << std::endl; - - stream << " " << _("Key ID") << ": " << recipient->keyid << std::endl; - stream << " " << _("Public Key Algo") << ": " - << gpgme_pubkey_algo_name(recipient->pubkey_algo) << std::endl; -} diff --git a/src/gpg/result_analyse/DecryptResultAnalyse.h b/src/gpg/result_analyse/DecryptResultAnalyse.h deleted file mode 100644 index 729d8853..00000000 --- a/src/gpg/result_analyse/DecryptResultAnalyse.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_DECRYPTRESULTANALYSE_H -#define GPGFRONTEND_DECRYPTRESULTANALYSE_H - -#include "ResultAnalyse.h" -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { - -class DecryptResultAnalyse : public ResultAnalyse { - public: - explicit DecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result); - - protected: - void do_analyse() final; - - private: - void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient); - - GpgError error; - GpgDecrResult result; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_DECRYPTRESULTANALYSE_H diff --git a/src/gpg/result_analyse/EncryptResultAnalyse.cpp b/src/gpg/result_analyse/EncryptResultAnalyse.cpp deleted file mode 100644 index df240a1d..00000000 --- a/src/gpg/result_analyse/EncryptResultAnalyse.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/result_analyse/EncryptResultAnalyse.h" - -GpgFrontend::EncryptResultAnalyse::EncryptResultAnalyse(GpgError error, - GpgEncrResult result) - : error(error), result(std::move(result)) {} - -void GpgFrontend::EncryptResultAnalyse::do_analyse() { - LOG(INFO) << _("Start Encrypt Result Analyse"); - - stream << "[#] " << _("Encrypt Operation") << " "; - - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - stream << "[" << _("Success") << "]" << std::endl; - else { - stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl; - setStatus(-1); - } - - if (!~status) { - stream << "------------>" << std::endl; - if (result != nullptr) { - stream << _("Invalid Recipients") << ": " << std::endl; - auto inv_reci = result->invalid_recipients; - while (inv_reci != nullptr) { - stream << _("Fingerprint") << ": " << inv_reci->fpr << std::endl; - stream << _("Reason") << ": " << gpgme_strerror(inv_reci->reason) - << std::endl; - stream << std::endl; - - inv_reci = inv_reci->next; - } - } - stream << "<------------" << std::endl; - } - - stream << std::endl; -} diff --git a/src/gpg/result_analyse/EncryptResultAnalyse.h b/src/gpg/result_analyse/EncryptResultAnalyse.h deleted file mode 100644 index e0a411d1..00000000 --- a/src/gpg/result_analyse/EncryptResultAnalyse.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ENCRYPTRESULTANALYSE_H -#define GPGFRONTEND_ENCRYPTRESULTANALYSE_H - -#include "ResultAnalyse.h" -#include "gpg/GpgConstants.h" - -namespace GpgFrontend { -class EncryptResultAnalyse : public ResultAnalyse { - public: - explicit EncryptResultAnalyse(GpgError error, GpgEncrResult result); - - protected: - void do_analyse() final; - - private: - GpgError error; - GpgEncrResult result; -}; -} // namespace GpgFrontend - -#endif // GPGFRONTEND_ENCRYPTRESULTANALYSE_H diff --git a/src/gpg/result_analyse/ResultAnalyse.cpp b/src/gpg/result_analyse/ResultAnalyse.cpp deleted file mode 100644 index 821da2ee..00000000 --- a/src/gpg/result_analyse/ResultAnalyse.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/result_analyse/ResultAnalyse.h" - -const std::string GpgFrontend::ResultAnalyse::getResultReport() const { - return stream.str(); -} - -int GpgFrontend::ResultAnalyse::getStatus() const { return status; } - -void GpgFrontend::ResultAnalyse::setStatus(int mStatus) { - if (mStatus < status) status = mStatus; -} - -void GpgFrontend::ResultAnalyse::analyse() { - if (!analysed_) { - do_analyse(); - analysed_ = true; - } -} diff --git a/src/gpg/result_analyse/ResultAnalyse.h b/src/gpg/result_analyse/ResultAnalyse.h deleted file mode 100644 index 33341b44..00000000 --- a/src/gpg/result_analyse/ResultAnalyse.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ -#ifndef GPGFRONTEND_RESULTANALYSE_H -#define GPGFRONTEND_RESULTANALYSE_H - -#include <sstream> -#include <string> - -#include "gpg/GpgConstants.h" -namespace GpgFrontend { - -class ResultAnalyse { - public: - ResultAnalyse() = default; - - [[nodiscard]] const std::string getResultReport() const; - - [[nodiscard]] int getStatus() const; - - void analyse(); - - protected: - virtual void do_analyse() = 0; - - std::stringstream stream; - - int status = 1; - - bool analysed_ = false; - - void setStatus(int mStatus); -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_RESULTANALYSE_H diff --git a/src/gpg/result_analyse/SignResultAnalyse.cpp b/src/gpg/result_analyse/SignResultAnalyse.cpp deleted file mode 100644 index a65c4a9d..00000000 --- a/src/gpg/result_analyse/SignResultAnalyse.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/result_analyse/SignResultAnalyse.h" - -#include "gpg/function/GpgKeyGetter.h" - -GpgFrontend::SignResultAnalyse::SignResultAnalyse(GpgError error, - GpgSignResult result) - : error(error), result(std::move(result)) {} - -void GpgFrontend::SignResultAnalyse::do_analyse() { - LOG(INFO) << _("Start Sign Result Analyse"); - - stream << "[#] " << _("Sign Operation") << " "; - - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - stream << "[" << _("Success") << "]" << std::endl; - else { - stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl; - setStatus(-1); - } - - if (result != nullptr && - (result->signatures != nullptr || result->invalid_signers != nullptr)) { - LOG(INFO) << _("Sign Result Analyse Getting Result"); - stream << "------------>" << std::endl; - auto new_sign = result->signatures; - - while (new_sign != nullptr) { - stream << "[>]" << _("New Signature") << ": " << std::endl; - - LOG(INFO) << _("Signers Fingerprint") << ": " << new_sign->fpr; - - stream << " " << _("Sign Mode") << ": "; - if (new_sign->type == GPGME_SIG_MODE_NORMAL) - stream << _("Normal"); - else if (new_sign->type == GPGME_SIG_MODE_CLEAR) - stream << _("Clear"); - else if (new_sign->type == GPGME_SIG_MODE_DETACH) - stream << _("Detach"); - - stream << std::endl; - - auto singerKey = - GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr); - if (singerKey.good()) { - stream << " " << _("Signer") << ": " - << singerKey.uids()->front().uid() << std::endl; - } else { - stream << " " << _("Signer") << ": " - << "<unknown>" << std::endl; - } - stream << " " << _("Public Key Algo") << ": " - << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl; - stream << " " << _("Hash Algo") << ": " - << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl; - stream << " " << _("Date") << "(" << _("UTC") << ")" - << ": " - << boost::posix_time::to_iso_extended_string( - boost::posix_time::from_time_t(new_sign->timestamp)) - << std::endl; - - stream << std::endl; - - new_sign = new_sign->next; - } - - LOG(INFO) << _("Sign Result Analyse Getting Invalid Signer"); - - auto invalid_signer = result->invalid_signers; - - if (invalid_signer != nullptr) - stream << _("Invalid Signers") << ": " << std::endl; - - while (invalid_signer != nullptr) { - setStatus(0); - stream << "[>] " << _("Signer") << ": " << std::endl; - stream << " " << _("Fingerprint") << ": " << invalid_signer->fpr - << std::endl; - stream << " " << _("Reason") << ": " - << gpgme_strerror(invalid_signer->reason) << std::endl; - stream << std::endl; - - invalid_signer = invalid_signer->next; - } - stream << "<------------" << std::endl; - } -}
\ No newline at end of file diff --git a/src/gpg/result_analyse/SignResultAnalyse.h b/src/gpg/result_analyse/SignResultAnalyse.h deleted file mode 100644 index 988ddf99..00000000 --- a/src/gpg/result_analyse/SignResultAnalyse.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_SIGNRESULTANALYSE_H -#define GPGFRONTEND_SIGNRESULTANALYSE_H - -#include "ResultAnalyse.h" - -namespace GpgFrontend { - -class SignResultAnalyse : public ResultAnalyse { - public: - explicit SignResultAnalyse(GpgError error, GpgSignResult result); - - protected: - void do_analyse(); - - private: - GpgError error; - - GpgSignResult result; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_SIGNRESULTANALYSE_H diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.cpp b/src/gpg/result_analyse/VerifyResultAnalyse.cpp deleted file mode 100644 index 99cbd528..00000000 --- a/src/gpg/result_analyse/VerifyResultAnalyse.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "gpg/result_analyse/VerifyResultAnalyse.h" - -#include <boost/format.hpp> - -#include "GpgFrontend.h" -#include "gpg/GpgConstants.h" -#include "gpg/function/GpgKeyGetter.h" - -GpgFrontend::VerifyResultAnalyse::VerifyResultAnalyse(GpgError error, - GpgVerifyResult result) - : error(error), result(std::move(result)) {} - -void GpgFrontend::VerifyResultAnalyse::do_analyse() { - LOG(INFO) << _("started"); - - stream << "[#] " << _("Verify Operation") << " "; - - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - stream << "[" << _("Success") << "]" << std::endl; - else { - stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl; - setStatus(-1); - } - - if (result != nullptr && result->signatures != nullptr) { - stream << "------------>" << std::endl; - auto sign = result->signatures; - - stream << "[>] " << _("Signed On") << "(" << _("UTC") << ")" - << " " - << boost::posix_time::to_iso_extended_string( - boost::posix_time::from_time_t(sign->timestamp)) - << std::endl; - - stream << std::endl << "[>] " << _("Signatures List") << ":" << std::endl; - - bool canContinue = true; - - int count = 1; - while (sign && canContinue) { - stream << boost::format(_("Signature [%1%]:")) % count++ << std::endl; - switch (gpg_err_code(sign->status)) { - case GPG_ERR_BAD_SIGNATURE: - stream << _("A Bad Signature.") << std::endl; - print_signer(stream, sign); - stream << _("This Signature is invalid.") << std::endl; - canContinue = false; - setStatus(-1); - break; - case GPG_ERR_NO_ERROR: - stream << _("A") << " "; - if (sign->summary & GPGME_SIGSUM_GREEN) { - stream << _("Good") << " "; - } - if (sign->summary & GPGME_SIGSUM_RED) { - stream << _("Bad") << " "; - } - if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) { - stream << _("Expired") << " "; - } - if (sign->summary & GPGME_SIGSUM_KEY_MISSING) { - stream << _("Missing Key's") << " "; - } - if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) { - stream << _("Revoked Key's") << " "; - } - if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) { - stream << _("Expired Key's") << " "; - } - if (sign->summary & GPGME_SIGSUM_CRL_MISSING) { - stream << _("Missing CRL's") << " "; - } - - if (sign->summary & GPGME_SIGSUM_VALID) { - stream << _("Signature Fully Valid.") << std::endl; - } else { - stream << _("Signature Not Fully Valid.") << std::endl; - } - - if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) { - if (!print_signer(stream, sign)) setStatus(0); - } else { - stream << _("Key is NOT present with ID 0x") << sign->fpr - << std::endl; - } - - setStatus(1); - - break; - case GPG_ERR_NO_PUBKEY: - stream << _("A signature could NOT be verified due to a Missing Key") - << std::endl; - setStatus(-2); - break; - case GPG_ERR_CERT_REVOKED: - stream << _("A signature is valid but the key used to verify the " - "signature has been revoked") - << std::endl; - if (!print_signer(stream, sign)) { - setStatus(0); - } - setStatus(-1); - break; - case GPG_ERR_SIG_EXPIRED: - stream << _("A signature is valid but expired") << std::endl; - if (!print_signer(stream, sign)) { - setStatus(0); - } - setStatus(-1); - break; - case GPG_ERR_KEY_EXPIRED: - stream << _("A signature is valid but the key used to " - "verify the signature has expired.") - << std::endl; - if (!print_signer(stream, sign)) { - setStatus(0); - } - break; - case GPG_ERR_GENERAL: - stream << _("There was some other error which prevented " - "the signature verification.") - << std::endl; - status = -1; - canContinue = false; - break; - default: - auto fpr = std::string(sign->fpr); - stream << _("Error for key with fingerprint") << " " - << GpgFrontend::beautify_fingerprint(fpr); - setStatus(-1); - } - stream << std::endl; - sign = sign->next; - } - stream << "<------------" << std::endl; - } else { - stream << "[>] " - << _("Could not find information that can be used for verification.") - << std::endl; - setStatus(0); - return; - } -} - -bool GpgFrontend::VerifyResultAnalyse::print_signer(std::stringstream &stream, - gpgme_signature_t sign) { - bool keyFound = true; - auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr); - - if (!key.good()) { - stream << " " << _("Signed By") << ": " - << "<" << _("Unknown") << ">" << std::endl; - setStatus(0); - keyFound = false; - } else { - stream << " " << _("Signed By") << ": " << key.uids()->front().uid() - << std::endl; - } - if (sign->pubkey_algo) - stream << " " << _("Public Key Algo") << ": " - << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl; - if (sign->hash_algo) - stream << " " << _("Hash Algo") << ": " - << gpgme_hash_algo_name(sign->hash_algo) << std::endl; - if (sign->timestamp) - stream << " " << _("Date") << "(" << _("UTC") << ")" - << ": " - << boost::posix_time::to_iso_extended_string( - boost::posix_time::from_time_t(sign->timestamp)) - << std::endl; - stream << std::endl; - return keyFound; -} - -gpgme_signature_t GpgFrontend::VerifyResultAnalyse::GetSignatures() const { - if (result) - return result->signatures; - else - return nullptr; -} -GpgFrontend::GpgVerifyResult -GpgFrontend::VerifyResultAnalyse::TakeChargeOfResult() { - return std::move(result); -} diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.h b/src/gpg/result_analyse/VerifyResultAnalyse.h deleted file mode 100644 index 8bf75f85..00000000 --- a/src/gpg/result_analyse/VerifyResultAnalyse.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_VERIFYRESULTANALYSE_H -#define GPGFRONTEND_VERIFYRESULTANALYSE_H - -#include "ResultAnalyse.h" -#include "gpg/model/GpgKeySignature.h" - -namespace GpgFrontend { - -class VerifyResultAnalyse : public ResultAnalyse { - public: - explicit VerifyResultAnalyse(GpgError error, GpgVerifyResult result); - - gpgme_signature_t GetSignatures() const; - - GpgVerifyResult TakeChargeOfResult(); - - private: - void do_analyse(); - - private: - bool print_signer(std::stringstream &stream, gpgme_signature_t sign); - - GpgError error; - GpgVerifyResult result; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_VERIFYRESULTANALYSE_H diff --git a/src/init.cpp b/src/init.cpp index 4f441c29..f5bbb750 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,26 +8,53 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include <boost/date_time.hpp> -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" + +/** + * @brief Get the files of a given directory + * + * @param _path target directory + * @return std::vector<std::filesystem::path> + */ +std::vector<std::filesystem::path> get_files_of_directory( + const std::filesystem::path& _path) { + namespace fs = std::filesystem; + std::vector<fs::path> path_list; + if (!_path.empty()) { + fs::recursive_directory_iterator end; + + for (fs::recursive_directory_iterator i(_path); i != end; ++i) { + const fs::path cp = (*i); + path_list.push_back(cp); + } + } + return path_list; +} +/** + * @brief setup logging system and do proper initialization + * + */ void init_logging() { using namespace boost::posix_time; using namespace boost::gregorian; @@ -37,25 +66,53 @@ void init_logging() { defaultConf.setToDefault(); el::Loggers::reconfigureLogger("default", defaultConf); + // apply settings defaultConf.setGlobally(el::ConfigurationType::Format, "%datetime %level %func %msg"); + // get the log directory auto logfile_path = - (GpgFrontend::UI::GlobalSettingStation::GetInstance().GetLogDir() / + (GpgFrontend::GlobalSettingStation::GetInstance().GetLogDir() / to_iso_string(now)); logfile_path.replace_extension(".log"); defaultConf.setGlobally(el::ConfigurationType::Filename, - logfile_path.string()); + logfile_path.u8string()); el::Loggers::reconfigureLogger("default", defaultConf); - LOG(INFO) << _("Logfile Path") << logfile_path; + LOG(INFO) << _("log file path") << logfile_path; +} + +/** + * @brief load all certificates from the given path + * and add them to the given certificate store in GlobalSettingStation + */ +void init_certs() { + // get the certificate directory + auto cert_file_paths = get_files_of_directory( + GpgFrontend::GlobalSettingStation::GetInstance().GetCertsDir()); + + // get the instance of the GlobalSettingStation + auto& _instance = GpgFrontend::GlobalSettingStation::GetInstance(); + for (const auto& cert_file_path : cert_file_paths) { + // add the certificate to the store + _instance.AddRootCert(cert_file_path); + } + + // show the number of loaded certificates + LOG(INFO) << _("root certs loaded") << _instance.GetRootCerts().size(); } +/** + * @brief setup the locale and load the translations + * + */ void init_locale() { + // get the instance of the GlobalSettingStation auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); + // create general settings if not exist if (!settings.exists("general") || settings.lookup("general").getType() != libconfig::Setting::TypeGroup) settings.add("general", libconfig::Setting::TypeGroup); @@ -65,20 +122,21 @@ void init_locale() { if (!general.exists("lang")) general.add("lang", libconfig::Setting::TypeString) = ""; - GpgFrontend::UI::GlobalSettingStation::GetInstance().Sync(); + // sync the settings to the file + GpgFrontend::GlobalSettingStation::GetInstance().SyncSettings(); LOG(INFO) << "current system locale" << setlocale(LC_ALL, nullptr); // read from settings file std::string lang; if (!general.lookupValue("lang", lang)) { - LOG(ERROR) << _("Could not read properly from configure file"); + LOG(ERROR) << _("could not read properly from configure file"); }; LOG(INFO) << "lang from settings" << lang; - LOG(INFO) << "PROJECT_NAME" << PROJECT_NAME; + LOG(INFO) << "project name" << PROJECT_NAME; LOG(INFO) << "locales path" - << GpgFrontend::UI::GlobalSettingStation::GetInstance() + << GpgFrontend::GlobalSettingStation::GetInstance() .GetLocaleDir() .c_str(); @@ -119,9 +177,9 @@ void init_locale() { #endif bindtextdomain(PROJECT_NAME, - GpgFrontend::UI::GlobalSettingStation::GetInstance() + GpgFrontend::GlobalSettingStation::GetInstance() .GetLocaleDir() - .string() + .u8string() .c_str()); bind_textdomain_codeset(PROJECT_NAME, "utf-8"); textdomain(PROJECT_NAME); diff --git a/src/main.cpp b/src/main.cpp index fa4195ce..a63d2d02 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,53 +8,101 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ +/** + * \mainpage GpgFrontend Develop Document Main Page + */ + #include <csetjmp> #include <csignal> #include <cstdlib> #include "GpgFrontendBuildInfo.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgFunctionObject.h" -#include "ui/MainWindow.h" -#include "ui/function/CtxCheckThread.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/GpgFunctionObject.h" +#include "ui/main_window/MainWindow.h" +#include "ui/thread/CtxCheckThread.h" -// Easy Logging Cpp +#if !defined(RELEASE) && defined(WINDOWS) +#include "core/function/GlobalSettingStation.h" +#endif + +/** + * \brief initialize the easylogging++ library. + */ INITIALIZE_EASYLOGGINGPP -// Recover buff +/** + * \brief Store the jump buff and make it possible to recover from a crash. + */ jmp_buf recover_env; +/** + * @brief + * + */ extern void init_logging(); + +/** + * @brief + * + */ +extern void init_certs(); + +/** + * @brief + * + */ extern void init_locale(); + +/** + * @brief + * + * @param sig + */ extern void handle_signal(int sig); +/** + * @brief + * + */ +extern void before_exit(); + +/** + * + * @param argc + * @param argv + * @return + */ int main(int argc, char* argv[]) { - // Register Signals + // re signal(SIGSEGV, handle_signal); signal(SIGFPE, handle_signal); signal(SIGILL, handle_signal); - // Qt + // clean something before exit + atexit(before_exit); + + // initialize qt resources Q_INIT_RESOURCE(gpgfrontend); - // Qt App + // create qt application QApplication app(argc, argv); #ifndef MACOS @@ -64,10 +114,13 @@ int main(int argc, char* argv[]) { QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif - // logging system + // initialize logging system init_logging(); - // App config + // init certs for tls connection + init_certs(); + + // set the extra information of the build QApplication::setApplicationVersion(BUILD_VERSION); QApplication::setApplicationName(PROJECT_NAME); @@ -79,10 +132,10 @@ int main(int argc, char* argv[]) { #if !defined(RELEASE) && defined(WINDOWS) // css - boost::filesystem::path css_path = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetResourceDir() / + std::filesystem::path css_path = + GpgFrontend::GlobalSettingStation::GetInstance().GetResourceDir() / "css" / "default.qss"; - QFile file(css_path.string().c_str()); + QFile file(css_path.u8string().c_str()); file.open(QFile::ReadOnly); QString styleSheet = QLatin1String(file.readAll()); qApp->setStyleSheet(styleSheet); @@ -91,23 +144,23 @@ int main(int argc, char* argv[]) { #ifdef GPG_STANDALONE_MODE LOG(INFO) << "GPG_STANDALONE_MODE Enabled"; - auto gpg_path = GpgFrontend::UI::GlobalSettingStation::GetInstance() + auto gpg_path = GpgFrontend::GlobalSettingStation::GetInstance() .GetStandaloneGpgBinDir(); - auto db_path = GpgFrontend::UI::GlobalSettingStation::GetInstance() + auto db_path = GpgFrontend::GlobalSettingStation::GetInstance() .GetStandaloneDatabaseDir(); GpgFrontend::GpgContext::CreateInstance( GpgFrontend::SingletonFunctionObject< GpgFrontend::GpgContext>::GetDefaultChannel(), - std::make_unique<GpgFrontend::GpgContext>(true, db_path.string(), true, - gpg_path.string())); + std::make_unique<GpgFrontend::GpgContext>(true, db_path.u8string(), true, + gpg_path.u8string())); #endif + // create the thread to load the gpg context auto* init_ctx_thread = new GpgFrontend::UI::CtxCheckThread(); - QApplication::connect(init_ctx_thread, &QThread::finished, init_ctx_thread, &QThread::deleteLater); - // Waiting Dialog + // create and show loading window before starting the main window auto* waiting_dialog = new QProgressDialog(); waiting_dialog->setMaximum(0); waiting_dialog->setMinimum(0); @@ -131,10 +184,11 @@ int main(int argc, char* argv[]) { exit(0); }); - // Show Waiting Dialog + // show the loading window waiting_dialog->show(); waiting_dialog->setFocus(); + // start the thread to load the gpg context init_ctx_thread->start(); QEventLoop loop; QApplication::connect(init_ctx_thread, &QThread::finished, &loop, @@ -154,18 +208,22 @@ int main(int argc, char* argv[]) { int r = setjmp(recover_env); #endif if (!r) { +#ifdef RELEASE try { - // i18n +#endif + // init the i18n support init_locale(); QApplication::setQuitOnLastWindowClosed(true); + // create main window and show it auto main_window = std::make_unique<GpgFrontend::UI::MainWindow>(); - main_window->init(); + main_window->Init(); main_window->show(); return_from_event_loop_code = QApplication::exec(); - +#ifdef RELEASE } catch (...) { + // catch all unhandled exceptions and notify the user QMessageBox::information( nullptr, _("Unhandled Exception Thrown"), _("Oops, an unhandled exception was thrown " @@ -176,14 +234,16 @@ int main(int argc, char* argv[]) { return_from_event_loop_code = RESTART_CODE; continue; } +#endif } else { - QApplication::exit(RESTART_CODE); + // when signal is caught, restart the main window QMessageBox::information( nullptr, _("A serious error has occurred"), _("Oh no! GpgFrontend caught a serious error in the software, so it " "needs to be restarted. If the problem recurs, please manually " "terminate the program and report the problem to the developer.")); + QCoreApplication::quit(); return_from_event_loop_code = RESTART_CODE; LOG(INFO) << "return_from_event_loop_code" << return_from_event_loop_code; continue; @@ -191,5 +251,6 @@ int main(int argc, char* argv[]) { LOG(INFO) << "loop refresh"; } while (return_from_event_loop_code == RESTART_CODE); + // exit the program return return_from_event_loop_code; } diff --git a/src/server/BaseAPI.cpp b/src/server/BaseAPI.cpp deleted file mode 100644 index aa4c3f98..00000000 --- a/src/server/BaseAPI.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "server/BaseAPI.h" - -#include "rapidjson/writer.h" - -BaseAPI::BaseAPI(ComUtils::ServiceType serviceType) - : utils(new ComUtils(nullptr)), - reqUrl(utils->getUrl(serviceType)), - request(reqUrl) { - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); -} - -BaseAPI::~BaseAPI() { utils->deleteLater(); } - -QNetworkReply *BaseAPI::send_json_data() { - rapidjson::StringBuffer sb; - rapidjson::Writer<rapidjson::StringBuffer> writer(sb); - document.Accept(writer); - - QByteArray postData(sb.GetString()); - qDebug() << "postData" << QString::fromUtf8(postData); - - auto reply = utils->getNetworkManager().post(request, postData); - - while (reply->isRunning()) QApplication::processEvents(); - - QByteArray replyData = reply->readAll().constData(); - if (utils->checkServerReply(replyData)) { - good = true, deal_reply(); - } - - return reply; -} - -void BaseAPI::start() { - construct_json(); - send_json_data()->deleteLater(); -} - -void BaseAPI::refresh() { - document.Clear(); - utils->clear(); - good = false; -} - -bool BaseAPI::result() const { return good; } diff --git a/src/server/BaseAPI.h b/src/server/BaseAPI.h deleted file mode 100644 index 46766fed..00000000 --- a/src/server/BaseAPI.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_BASEAPI_H -#define GPGFRONTEND_ZH_CN_TS_BASEAPI_H - -#include "ComUtils.h" -#include "GpgFrontend.h" -#include "rapidjson/document.h" - -class BaseAPI : public QObject { - Q_OBJECT - public: - explicit BaseAPI(ComUtils::ServiceType serviceType); - - ~BaseAPI() override; - - void start(); - - void refresh(); - - [[nodiscard]] bool result() const; - - private: - ComUtils *utils; - - QUrl reqUrl; - - QNetworkRequest request; - - QNetworkReply *send_json_data(); - - protected: - bool good = false; - - rapidjson::Document document; - - const ComUtils &getUtils() { return *utils; }; - - virtual void construct_json() = 0; - - virtual void deal_reply() = 0; -}; - -#endif // GPGFRONTEND_ZH_CN_TS_BASEAPI_H diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt deleted file mode 100644 index 423e9d1e..00000000 --- a/src/server/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -aux_source_directory(./api SERVER_SOURCE) -aux_source_directory(. SERVER_SOURCE) - -add_library(server STATIC ${SERVER_SOURCE}) - -target_link_libraries(server - Qt5::Network Qt5::Widgets Qt5::Core) diff --git a/src/server/ComUtils.cpp b/src/server/ComUtils.cpp deleted file mode 100644 index 6a5ce7b0..00000000 --- a/src/server/ComUtils.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "server/ComUtils.h" - -/** - * check server reply if it can parse into a json object - * @param reply reply data in byte array - * @return if successful - */ -bool GpgFrontend::ComUtils::checkServerReply(const QByteArray &reply) { - if (reply.isEmpty()) { - QMessageBox::critical( - this, _("Error"), - _("Nothing Reply. Please check the Internet connection.")); - return false; - } - - qDebug() << "Reply" << reply; - - /** - * Server Reply Format(Except Timeout) - * { - * "status": 200, - * "msg": "OK", - * "timestamp": 1628652783895 - * "data" : { - * ... - * } - * } - */ - - // check if reply is a json object - if (replyDoc.Parse(reply).HasParseError() || !replyDoc.IsObject()) { - QMessageBox::critical(this, _("Error"), _("Unknown Error")); - return false; - } - - // check status(int) and message(string) - if (replyDoc.HasMember("status") && replyDoc.HasMember("msg") && - replyDoc.HasMember("timestamp") && replyDoc.HasMember("data") && - replyDoc["status"].IsNumber() && replyDoc["msg"].IsString() && - replyDoc["timestamp"].IsNumber() && replyDoc["data"].IsObject()) { - int status = replyDoc["status"].GetInt(); - QDateTime time; - time.setMSecsSinceEpoch(replyDoc["timestamp"].GetInt64()); - auto message = replyDoc["msg"].GetString(); - dataVal = replyDoc["data"].GetObject(); - - qDebug() << "Reply Date & Time" << time; - - // check reply timestamp - if (time < QDateTime::currentDateTime().addSecs(-10)) { - QMessageBox::critical(this, _("Network Error"), _("Outdated Reply")); - return false; - } - - // check status code if successful (200-299) - // check data object - if (status / 100 == 2) { - is_good = true; - return true; - } else { - if (dataVal.HasMember("exceptionMessage") && - dataVal["exceptionMessage"].IsString()) - QMessageBox::critical(this, message, - dataVal["exceptionMessage"].GetString()); - else - QMessageBox::critical(this, message, _("Unknown Reason")); - } - - } else - QMessageBox::critical(this, _("Network Error"), _("Unknown Reply Format")); - - return false; -} - -/** - * get value in data - * @param key key of value - * @return value in string format - */ -QString GpgFrontend::ComUtils::getDataValueStr(const QString &key) const { - if (is_good) { - auto k_byte_array = key.toUtf8(); - if (dataVal.HasMember(k_byte_array.data())) { - return dataVal[k_byte_array.data()].GetString(); - } else - return {}; - } else - return {}; -} - -/** - * Get eventually url by service type - * @param type service which server provides - * @return url - */ -QString GpgFrontend::ComUtils::getUrl(ComUtils::ServiceType type) const { - auto host = - settings - .value("general/currentGpgfrontendServer", "service.gpgfrontend.pub") - .toString(); - - auto protocol = QString(); - // Localhost Debug Server - if (host == "localhost") - protocol = "http://"; - else - protocol = "https://"; - - auto url = protocol + host + ":9049/"; - - switch (type) { - case GetServiceToken: - url += "/user"; - break; - case ShortenCryptText: - url += "/text/new"; - break; - case GetFullCryptText: - url += "/text/get"; - break; - case UploadPubkey: - url += "/key/upload"; - break; - case GetPubkey: - url += "/key/get"; - break; - } - - qDebug() << "ComUtils getUrl" << url; - - return url; -} - -bool GpgFrontend::ComUtils::checkDataValueStr(const QString &key) const { - auto key_byte_array_data = key.toUtf8().constData(); - if (is_good) { - return dataVal.HasMember(key_byte_array_data) && - dataVal[key_byte_array_data].IsString(); - } else - return false; -} - -bool GpgFrontend::ComUtils::checkServiceTokenFormat(const QString &uuid) const { - return re_uuid.match(uuid).hasMatch(); -} - -QByteArray GpgFrontend::ComUtils::getSignStringBase64( - GpgFrontend::GpgContext *ctx, const QString &str, const GpgKey &key) { - std::vector<GpgKey> keys{key}; - QByteArray outSignText; - auto signData = str.toUtf8(); - - // The use of multi-threading brings an improvement in UI smoothness - gpgme_error_t error; - auto thread = QThread::create([&]() { - error = ctx->sign(keys, signData, &outSignText, GPGME_SIG_MODE_NORMAL, - nullptr, false); - }); - thread->start(); - while (thread->isRunning()) QApplication::processEvents(); - thread->deleteLater(); - - return outSignText.toBase64(); -} - -const rapidjson::Value &GpgFrontend::ComUtils::getDataValue( - const QString &key) const { - if (is_good) { - auto k_byte_array = key.toUtf8(); - if (dataVal.HasMember(k_byte_array.data())) { - return dataVal[k_byte_array.data()]; - } - } - throw std::runtime_error("Inner Error"); -} - -bool GpgFrontend::ComUtils::checkDataValue(const QString &key) const { - auto key_byte_array_data = key.toUtf8().constData(); - if (is_good) { - return dataVal.HasMember(key_byte_array_data); - } else - return false; -} - -void GpgFrontend::ComUtils::clear() { - this->dataVal.Clear(); - this->replyDoc.Clear(); - is_good = false; -}
\ No newline at end of file diff --git a/src/server/ComUtils.h b/src/server/ComUtils.h deleted file mode 100644 index f281f256..00000000 --- a/src/server/ComUtils.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_COMUTILS_H -#define GPGFRONTEND_ZH_CN_TS_COMUTILS_H - -#include "GpgFrontend.h" -#include "gpg/GpgContext.h" -#include "rapidjson/document.h" - -namespace GpgFrontend { - -class ComUtils : public QWidget { - Q_OBJECT - public: - enum ServiceType { - GetServiceToken, - ShortenCryptText, - GetFullCryptText, - UploadPubkey, - GetPubkey - }; - - explicit ComUtils(QWidget *parent) - : QWidget(parent), - appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) {} - - [[nodiscard]] QString getUrl(ServiceType type) const; - - bool checkServerReply(const QByteArray &reply); - - [[nodiscard]] QString getDataValueStr(const QString &key) const; - - [[nodiscard]] bool checkDataValueStr(const QString &key) const; - - [[nodiscard]] const rapidjson::Value &getDataValue(const QString &key) const; - - [[nodiscard]] bool checkDataValue(const QString &key) const; - - [[nodiscard]] bool checkServiceTokenFormat(const QString &serviceToken) const; - - static QByteArray getSignStringBase64(GpgFrontend::GpgContext *ctx, - const QString &str, const GpgKey &key); - - [[nodiscard]] bool good() const { return is_good; } - - QNetworkAccessManager &getNetworkManager() { return networkMgr; } - - void clear(); - - private: - QString appPath; - QSettings settings; - rapidjson::Document replyDoc; - rapidjson::Value dataVal; - QNetworkAccessManager networkMgr; - QRegularExpression re_uuid{ - R"(\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b)"}; - - bool is_good = false; -}; - -} // namespace GpgFrontend - -#endif // GPGFRONTEND_ZH_CN_TS_COMUTILS_H diff --git a/src/server/api/PubkeyGetter.cpp b/src/server/api/PubkeyGetter.cpp deleted file mode 100644 index e2cb8708..00000000 --- a/src/server/api/PubkeyGetter.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "server/api/PubkeyGetter.h" - -PubkeyGetter::PubkeyGetter(GpgFrontend::GpgContext *ctx, - const QVector<QString> &fprs) - : BaseAPI(ComUtils::GetPubkey), mCtx(ctx), mFprs(fprs) {} - -void PubkeyGetter::construct_json() { - document.SetArray(); - QStringList keyIds; - - rapidjson::Document::AllocatorType &allocator = document.GetAllocator(); - - for (const auto &fprStr : mFprs) { - rapidjson::Value fpr; - - auto fprByteArray = fprStr.toUtf8(); - fpr.SetString(fprByteArray.constData(), fprByteArray.count()); - - document.PushBack(fpr, allocator); - keyIds.clear(); - } -} - -void PubkeyGetter::deal_reply() { - const auto &utils = getUtils(); - - /** - * { - * "pubkeys" : [ - * { - * "publicKey" : ..., - * "fpr" : ..., - * "sha" : ... - * }, - * ... - * ] - * } - */ - - if (!utils.checkDataValue("pubkeys")) { - QMessageBox::critical(nullptr, _("Error"), - _("The communication content with the server does " - "not meet the requirements")); - } else { - auto &pubkeys = utils.getDataValue("pubkeys"); - qDebug() << "Pubkey Getter" << pubkeys.IsArray() - << pubkeys.GetArray().Size(); - if (pubkeys.IsArray()) { - for (const auto &pubkey : pubkeys.GetArray()) { - if (pubkey.IsObject() && pubkey.HasMember("publicKey") && - pubkey.HasMember("fpr") && pubkey.HasMember("sha") && - pubkey["publicKey"].IsString() && pubkey["fpr"].IsString() && - pubkey["sha"].IsString()) { - auto pubkeyData = QString(pubkey["publicKey"].GetString()); - - QCryptographicHash shaGen(QCryptographicHash::Sha256); - shaGen.addData(pubkeyData.toUtf8()); - - if (shaGen.result().toHex() == pubkey["sha"].GetString()) { - mCtx->importKey(pubkeyData.toUtf8()); - } - } - } - - } else { - QMessageBox::critical(nullptr, _("Error"), - _("The communication content with the server does " - "not meet the requirements")); - } - } -} diff --git a/src/server/api/PubkeyGetter.h b/src/server/api/PubkeyGetter.h deleted file mode 100644 index 6a3d50e9..00000000 --- a/src/server/api/PubkeyGetter.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_PUBKEYGETTER_H -#define GPGFRONTEND_ZH_CN_TS_PUBKEYGETTER_H - -#include "GpgFrontend.h" -#include "gpg/GpgContext.h" -#include "server/BaseAPI.h" - -class ComUtils; - -/** - * Get and Import Pubkey from server - */ -class PubkeyGetter : public BaseAPI { - public: - PubkeyGetter(GpgFrontend::GpgContext *ctx, const QVector<QString> &fprs); - - private: - GpgFrontend::GpgContext *mCtx; - - const QVector<QString> &mFprs; - - protected: - void construct_json() final; - - void deal_reply() final; -}; - -#endif // GPGFRONTEND_ZH_CN_TS_PUBKEYGETTER_H diff --git a/src/server/api/PubkeyUploader.cpp b/src/server/api/PubkeyUploader.cpp deleted file mode 100644 index 35f764d8..00000000 --- a/src/server/api/PubkeyUploader.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "server/api/PubkeyUploader.h" - -PubkeyUploader::PubkeyUploader(GpgFrontend::GpgContext *ctx, - const QVector<GpgKey> &keys) - : BaseAPI(ComUtils::UploadPubkey), mCtx(ctx), mKeys(keys) {} - -void PubkeyUploader::construct_json() { - document.SetArray(); - QStringList keyIds; - QCryptographicHash shaGen(QCryptographicHash::Sha256); - - auto &allocator = document.GetAllocator(); - - QVector<QByteArray> keysData; - for (const auto &key : mKeys) { - QByteArray keyDataBuf; - keyIds << key.id; - - // The use of multi-threading brings an improvement in UI smoothness - gpgme_error_t error; - auto thread = QThread::create( - [&]() { error = mCtx->exportKeys(&keyIds, &keyDataBuf); }); - thread->start(); - while (thread->isRunning()) QApplication::processEvents(); - thread->deleteLater(); - keysData.push_back(keyDataBuf); - keyIds.clear(); - } - - int index = 0; - for (const auto &keyData : keysData) { - rapidjson::Value publicKeyObj, pubkey, sha, signedFpr; - - shaGen.addData(keyData); - auto shaStr = shaGen.result().toHex(); - shaGen.reset(); - - auto signFprStr = - ComUtils::getSignStringBase64(mCtx, mKeys[index].fpr, mKeys[index]); - qDebug() << "signFprStr" << signFprStr; - - pubkey.SetString(keyData.data(), keyData.count(), allocator); - sha.SetString(shaStr.data(), shaStr.count(), allocator); - signedFpr.SetString(signFprStr.data(), signFprStr.count(), allocator); - - publicKeyObj.SetObject(); - publicKeyObj.AddMember("publicKey", pubkey, allocator); - publicKeyObj.AddMember("sha", sha, allocator); - publicKeyObj.AddMember("signedFpr", signedFpr, allocator); - - document.PushBack(publicKeyObj, allocator); - index++; - } -} - -void PubkeyUploader::deal_reply() { - const auto &utils = getUtils(); - - /** - * { - * "strings" : [ - * "...", - * "..." - * ] - * } - */ - - if (!utils.checkDataValue("strings")) { - QMessageBox::critical(nullptr, _("Error"), - _("The communication content with the server does " - "not meet the requirements")); - } else { - auto &strings = utils.getDataValue("strings"); - qDebug() << "Pubkey Uploader" << strings.IsArray() - << strings.GetArray().Size(); - if (strings.IsArray() && strings.GetArray().Size() == mKeys.size()) { - good = true; - } else { - good = false; - } - } -} diff --git a/src/server/api/PubkeyUploader.h b/src/server/api/PubkeyUploader.h deleted file mode 100644 index efad27ac..00000000 --- a/src/server/api/PubkeyUploader.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_PUBKEYUPLOADER_H -#define GPGFRONTEND_ZH_CN_TS_PUBKEYUPLOADER_H - -#include "GpgFrontend.h" -#include "gpg/GpgContext.h" -#include "rapidjson/document.h" -#include "server/BaseAPI.h" - -/** - * Upload pubkey into server - */ -class PubkeyUploader : public BaseAPI { - public: - PubkeyUploader(GpgFrontend::GpgContext *ctx, const QVector<GpgKey> &keys); - - private: - const QVector<GpgKey> &mKeys; - - GpgFrontend::GpgContext *mCtx; - - protected: - void construct_json() final; - - void deal_reply() final; -}; - -#endif // GPGFRONTEND_ZH_CN_TS_PUBKEYUPLOADER_H diff --git a/src/signal.cpp b/src/signal.cpp index efcd8146..135bdead 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,30 +8,50 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include <easyloggingpp/easylogging++.h> - #include <csetjmp> +#include "GpgFrontend.h" + extern jmp_buf recover_env; +/** + * @brief handle the signal caught. + * + * @param sig signal number + */ void handle_signal(int sig) { - LOG(INFO) << "signal caught"; + static int _repeat_handle_num = 1, last_sig = sig; + LOG(INFO) << "signal caught" << sig; + + if (last_sig == sig) + _repeat_handle_num++; + else + _repeat_handle_num = 1, last_sig = sig; + + if (_repeat_handle_num > 3) { + LOG(INFO) << "The same signal appears three times, execute the termination " + "operation. "; + exit(-1); + } + #ifndef WINDOWS siglongjmp(recover_env, 1); #else diff --git a/src/smtp/CMakeLists.txt b/src/smtp/CMakeLists.txt deleted file mode 100644 index afae322e..00000000 --- a/src/smtp/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -aux_source_directory(. SMTP_MIME_SOURCE) - -add_library(smtp STATIC ${SMTP_MIME_SOURCE}) - -target_link_libraries(smtp - Qt5::Network Qt5::Core) - -if(XCODE_BUILD) -set_target_properties(smtp - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) -endif()
\ No newline at end of file diff --git a/src/smtp/SmtpMime b/src/smtp/SmtpMime deleted file mode 100644 index 940996b8..00000000 --- a/src/smtp/SmtpMime +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef SMTPMIME_H -#define SMTPMIME_H - -#include "smtpclient.h" -#include "mimepart.h" -#include "mimehtml.h" -#include "mimeattachment.h" -#include "mimemessage.h" -#include "mimetext.h" -#include "mimeinlinefile.h" -#include "mimefile.h" - -#endif // SMTPMIME_H diff --git a/src/smtp/emailaddress.cpp b/src/smtp/emailaddress.cpp deleted file mode 100644 index c0ecaa0d..00000000 --- a/src/smtp/emailaddress.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/emailaddress.h" - -/* [1] Constructors and Destructors */ - -EmailAddress::EmailAddress(const QString &address, const QString &name) { - this->address = address; - this->name = name; -} - -EmailAddress::~EmailAddress() {} - -/* [1] --- */ - -/* [2] Getters and Setters */ - -void EmailAddress::setName(const QString &name) { this->name = name; } - -void EmailAddress::setAddress(const QString &address) { - this->address = address; -} - -const QString &EmailAddress::getName() const { return name; } - -const QString &EmailAddress::getAddress() const { return address; } - -/* [2] --- */ diff --git a/src/smtp/emailaddress.h b/src/smtp/emailaddress.h deleted file mode 100644 index 90e4c1e9..00000000 --- a/src/smtp/emailaddress.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef EMAILADDRESS_H -#define EMAILADDRESS_H - -#include <QObject> - -#include "smtpexports.h" - -class SMTP_EXPORT EmailAddress : public QObject { -Q_OBJECT -public: - - /* [1] Constructors and Destructors */ - - EmailAddress() = default; - - explicit EmailAddress(const QString &address, const QString &name = ""); - - ~EmailAddress() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - void setName(const QString &name); - - void setAddress(const QString &address); - - [[nodiscard]] const QString &getName() const; - - [[nodiscard]] const QString &getAddress() const; - - /* [2] --- */ - - -private: - - /* [3] Private members */ - - QString name; - QString address; - - /* [3] --- */ -}; - -#endif // EMAILADDRESS_H diff --git a/src/smtp/mimeattachment.cpp b/src/smtp/mimeattachment.cpp deleted file mode 100644 index 033eecfb..00000000 --- a/src/smtp/mimeattachment.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimeattachment.h" -#include <QFileInfo> - -/* [1] Constructors and Destructors */ - -MimeAttachment::MimeAttachment(QFile *file) : MimeFile(file) {} - -MimeAttachment::MimeAttachment(const QByteArray &stream, - const QString &fileName) - : MimeFile(stream, fileName) {} - -MimeAttachment::~MimeAttachment() = default; - -/* [1] --- */ - -/* [2] Protected methods */ - -void MimeAttachment::prepare() { - this->header += "Content-disposition: attachment\r\n"; - - /* !!! IMPORTANT !!! */ - MimeFile::prepare(); -} - -/* [2] --- */ diff --git a/src/smtp/mimeattachment.h b/src/smtp/mimeattachment.h deleted file mode 100644 index 6b98a65a..00000000 --- a/src/smtp/mimeattachment.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEATTACHMENT_H -#define MIMEATTACHMENT_H - -#include <QFile> -#include "mimepart.h" -#include "mimefile.h" - -#include "smtpexports.h" - -class SMTP_EXPORT MimeAttachment : public MimeFile { -Q_OBJECT -public: - - /* [1] Constructors and Destructors */ - - explicit MimeAttachment(QFile *file); - - MimeAttachment(const QByteArray &stream, const QString &fileName); - - ~MimeAttachment() override; - - /* [1] --- */ - -protected: - - /* [2] Protected methods */ - - void prepare() override; - - /* [2] --- */ -}; - -#endif // MIMEATTACHMENT_H diff --git a/src/smtp/mimecontentformatter.cpp b/src/smtp/mimecontentformatter.cpp deleted file mode 100644 index 8f538457..00000000 --- a/src/smtp/mimecontentformatter.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimecontentformatter.h" - -MimeContentFormatter::MimeContentFormatter(int max_length) - : max_length(max_length) {} - -QString MimeContentFormatter::format(const QString &content, - bool quotedPrintable) const { - - QString out; - - int chars = 0; - for (auto i : content) { - chars++; - if (!quotedPrintable) { - if (chars > max_length) { - out.append("\r\n"); - chars = 1; - } - } else { - if (i == '\n') { // new line - out.append(i); - chars = 0; - continue; - } - - if ((chars > max_length - 1) || - ((i == '=') && (chars > max_length - 3))) { - out.append('='); - out.append("\r\n"); - chars = 1; - } - } - out.append(i); - } - - return out; -} - -void MimeContentFormatter::setMaxLength(int l) { max_length = l; } - -int MimeContentFormatter::getMaxLength() const { return max_length; } diff --git a/src/smtp/mimecontentformatter.h b/src/smtp/mimecontentformatter.h deleted file mode 100644 index e6e3637f..00000000 --- a/src/smtp/mimecontentformatter.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMECONTENTFORMATTER_H -#define MIMECONTENTFORMATTER_H - -#include <QObject> -#include <QByteArray> - -#include "smtpexports.h" - -class SMTP_EXPORT MimeContentFormatter : public QObject { -Q_OBJECT -public: - explicit MimeContentFormatter(int max_length = 76); - - void setMaxLength(int l); - - [[nodiscard]] int getMaxLength() const; - - [[nodiscard]] QString format(const QString &content, bool quotedPrintable = false) const; - -protected: - int max_length; - -}; - -#endif // MIMECONTENTFORMATTER_H diff --git a/src/smtp/mimefile.cpp b/src/smtp/mimefile.cpp deleted file mode 100644 index 4f095b84..00000000 --- a/src/smtp/mimefile.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimefile.h" -#include <QFileInfo> - -/* [1] Constructors and Destructors */ - -MimeFile::MimeFile(QFile *file) { - this->file = file; - this->cType = "application/octet-stream"; - this->cName = QFileInfo(*file).fileName(); - this->cEncoding = Base64; -} - -MimeFile::MimeFile(const QByteArray &stream, const QString &fileName) { - this->cEncoding = Base64; - this->cType = "application/octet-stream"; - this->file = nullptr; - this->cName = fileName; - this->content = stream; -} - -MimeFile::~MimeFile() { - delete file; -} - -/* [1] --- */ - -/* [2] Getters and setters */ - -/* [2] --- */ - -/* [3] Protected methods */ - -void MimeFile::prepare() { - if (this->file) { - file->open(QIODevice::ReadOnly); - this->content = file->readAll(); - file->close(); - } - /* !!! IMPORTANT !!!! */ - MimePart::prepare(); -} - -/* [3] --- */ diff --git a/src/smtp/mimefile.h b/src/smtp/mimefile.h deleted file mode 100644 index 46903da9..00000000 --- a/src/smtp/mimefile.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEFILE_H -#define MIMEFILE_H - -#include "mimepart.h" -#include <QFile> - -#include "smtpexports.h" - -class SMTP_EXPORT MimeFile : public MimePart { -Q_OBJECT -public: - - /* [1] Constructors and Destructors */ - - MimeFile(const QByteArray &stream, const QString &fileName); - - explicit MimeFile(QFile *f); - - ~MimeFile() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - QFile *file; - - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ - -}; - -#endif // MIMEFILE_H diff --git a/src/smtp/mimehtml.cpp b/src/smtp/mimehtml.cpp deleted file mode 100644 index 9f3a53c3..00000000 --- a/src/smtp/mimehtml.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimehtml.h" - -/* [1] Constructors and Destructors */ - -MimeHtml::MimeHtml(const QString &html) : MimeText(html) { - this->cType = "text/html"; -} - -MimeHtml::~MimeHtml() = default; - -/* [1] --- */ - -/* [2] Getters and Setters */ - -void MimeHtml::setHtml(const QString &html) { this->text = html; } - -const QString &MimeHtml::getHtml() const { return text; } - -/* [2] --- */ - -/* [3] Protected methods */ - -void MimeHtml::prepare() { - /* !!! IMPORTANT !!! */ - MimeText::prepare(); -} - -/* [3] --- */ diff --git a/src/smtp/mimehtml.h b/src/smtp/mimehtml.h deleted file mode 100644 index 8ce8c454..00000000 --- a/src/smtp/mimehtml.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEHTML_H -#define MIMEHTML_H - -#include "mimetext.h" - -#include "smtpexports.h" - -class SMTP_EXPORT MimeHtml : public MimeText { -Q_OBJECT -public: - - /* [1] Constructors and Destructors */ - - explicit MimeHtml(const QString &html = ""); - - ~MimeHtml() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - void setHtml(const QString &html); - - [[nodiscard]] const QString &getHtml() const; - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ -}; - -#endif // MIMEHTML_H diff --git a/src/smtp/mimeinlinefile.cpp b/src/smtp/mimeinlinefile.cpp deleted file mode 100644 index a49167e8..00000000 --- a/src/smtp/mimeinlinefile.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimeinlinefile.h" - -/* [1] Constructors and Destructors */ - -MimeInlineFile::MimeInlineFile(QFile *f) : MimeFile(f) {} - -MimeInlineFile::~MimeInlineFile() = default; - -/* [1] --- */ - -/* [2] Getters and Setters */ - -/* [2] --- */ - -/* [3] Protected methods */ - -void MimeInlineFile::prepare() { - this->header += "Content-Disposition: inline\r\n"; - - /* !!! IMPORTANT !!! */ - MimeFile::prepare(); -} - -/* [3] --- */ diff --git a/src/smtp/mimeinlinefile.h b/src/smtp/mimeinlinefile.h deleted file mode 100644 index 916f7b76..00000000 --- a/src/smtp/mimeinlinefile.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEINLINEFILE_H -#define MIMEINLINEFILE_H - -#include "mimefile.h" - -#include "smtpexports.h" - -class SMTP_EXPORT MimeInlineFile : public MimeFile { -public: - - /* [1] Constructors and Destructors */ - - explicit MimeInlineFile(QFile *f); - - ~MimeInlineFile() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ -}; - -#endif // MIMEINLINEFILE_H diff --git a/src/smtp/mimemessage.cpp b/src/smtp/mimemessage.cpp deleted file mode 100644 index 6c058e89..00000000 --- a/src/smtp/mimemessage.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimemessage.h" - -#include <QDateTime> -#include <QLocale> -#include <typeinfo> - -#include "smtp/quotedprintable.h" - -/* [1] Constructors and Destructors */ -MimeMessage::MimeMessage(bool createAutoMimeContent) - : replyTo(nullptr), hEncoding(MimePart::_8Bit) { - if (createAutoMimeContent) this->content = new MimeMultiPart(); - - autoMimeContentCreated = createAutoMimeContent; -} - -MimeMessage::~MimeMessage() { - if (this->autoMimeContentCreated) { - this->autoMimeContentCreated = false; - delete (this->content); - } -} - -/* [1] --- */ - -/* [2] Getters and Setters */ -MimePart &MimeMessage::getContent() { return *content; } - -void MimeMessage::setContent(MimePart *content) { - if (this->autoMimeContentCreated) { - this->autoMimeContentCreated = false; - delete (this->content); - } - this->content = content; -} - -void MimeMessage::setReplyTo(EmailAddress *rto) { replyTo = rto; } - -void MimeMessage::setSender(EmailAddress *e) { - this->sender = e; - e->setParent(this); -} - -void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type) { - switch (type) { - case To: - recipientsTo << rcpt; - break; - case Cc: - recipientsCc << rcpt; - break; - case Bcc: - recipientsBcc << rcpt; - break; - } - - rcpt->setParent(this); -} - -void MimeMessage::addTo(EmailAddress *rcpt) { this->recipientsTo << rcpt; } - -void MimeMessage::addCc(EmailAddress *rcpt) { this->recipientsCc << rcpt; } - -void MimeMessage::addBcc(EmailAddress *rcpt) { this->recipientsBcc << rcpt; } - -void MimeMessage::setSubject(const QString &subject) { - this->subject = subject; -} - -void MimeMessage::addPart(MimePart *part) { - if (typeid(*content) == typeid(MimeMultiPart)) { - ((MimeMultiPart *)content)->addPart(part); - }; -} - -void MimeMessage::setInReplyTo(const QString &inReplyTo) { - mInReplyTo = inReplyTo; -} - -void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc) { - this->hEncoding = hEnc; -} - -const EmailAddress &MimeMessage::getSender() const { return *sender; } - -const QList<EmailAddress *> &MimeMessage::getRecipients( - RecipientType type) const { - switch (type) { - default: - case To: - return recipientsTo; - case Cc: - return recipientsCc; - case Bcc: - return recipientsBcc; - } -} - -const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; } - -const QString &MimeMessage::getSubject() const { return subject; } - -const QList<MimePart *> &MimeMessage::getParts() const { - if (typeid(*content) == typeid(MimeMultiPart)) { - return ((MimeMultiPart *)content)->getParts(); - } else { - auto *res = new QList<MimePart *>(); - res->append(content); - return *res; - } -} - -/* [2] --- */ - -/* [3] Public Methods */ - -QString MimeMessage::toString() { - QString mime; - - /* =========== MIME HEADER ============ */ - - /* ---------- Sender / From ----------- */ - mime = "From:"; - if (!sender->getName().isEmpty()) { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append(sender->getName().toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append(sender->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + sender->getName(); - } - } - mime += " <" + sender->getAddress() + ">\r\n"; - /* ---------------------------------- */ - - /* ------- Recipients / To ---------- */ - mime += "To:"; - QList<EmailAddress *>::iterator it; - int i; - for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) { - if (i != 0) { - mime += ","; - } - - if (!(*it)->getName().isEmpty()) { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append((*it)->getName().toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append((*it)->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + (*it)->getName(); - } - } - mime += " <" + (*it)->getAddress() + ">"; - } - mime += "\r\n"; - /* ---------------------------------- */ - - /* ------- Recipients / Cc ---------- */ - if (!recipientsCc.empty()) { - mime += "Cc:"; - } - for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) { - if (i != 0) { - mime += ","; - } - - if ((*it)->getName() != "") { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append((*it)->getName().toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append((*it)->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + (*it)->getName(); - } - } - mime += " <" + (*it)->getAddress() + ">"; - } - if (!recipientsCc.empty()) { - mime += "\r\n"; - } - /* ---------------------------------- */ - - /* ------------ Subject ------------- */ - mime += "Subject: "; - - switch (hEncoding) { - case MimePart::Base64: - mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += "=?utf-8?Q?" + - QuotedPrintable::encode(QByteArray().append(subject.toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += subject; - } - mime += "\r\n"; - /* ---------------------------------- */ - - /* ---------- Reply-To -------------- */ - if (replyTo) { - mime += "Reply-To: "; - if (!replyTo->getName().isEmpty()) { - switch (hEncoding) { - case MimePart::Base64: - mime += " =?utf-8?B?" + - QByteArray().append(replyTo->getName().toUtf8()).toBase64() + - "?="; - break; - case MimePart::QuotedPrintable: - mime += " =?utf-8?Q?" + - QuotedPrintable::encode( - QByteArray().append(replyTo->getName().toUtf8())) - .replace(' ', "_") - .replace(':', "=3A") + - "?="; - break; - default: - mime += " " + replyTo->getName(); - } - } - mime += " <" + replyTo->getAddress() + ">\r\n"; - } - - /* ---------------------------------- */ - - mime += "MIME-Version: 1.0\r\n"; - if (!mInReplyTo.isEmpty()) { - mime += "In-Reply-To: <" + mInReplyTo + ">\r\n"; - mime += "References: <" + mInReplyTo + ">\r\n"; - } - - QDateTime now = QDateTime::currentDateTime(); -#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined - QString shortDayName = - QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat); - QString shortMonthName = - QLocale::c().monthName(now.date().month(), QLocale::ShortFormat); - int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60; - char timezoneSign = utcOffset >= 0 ? '+' : '-'; - utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset; - QString timezone = QString("%1%2%3") - .arg(timezoneSign) - .arg(utcOffset / 60, 2, 10, QChar('0')) - .arg(utcOffset % 60, 2, 10, QChar('0')); - mime += QString("Date: %1\r\n") - .arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3") - .arg(shortDayName) - .arg(shortMonthName) - .arg(timezone)); -#else // Qt5 supported - mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date)); -#endif // support RFC2822Date - - mime += content->toString(); - return mime; -} - -/* [3] --- */ diff --git a/src/smtp/mimemessage.h b/src/smtp/mimemessage.h deleted file mode 100644 index 24e4f108..00000000 --- a/src/smtp/mimemessage.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEMESSAGE_H -#define MIMEMESSAGE_H - -#include "mimepart.h" -#include "mimemultipart.h" -#include "emailaddress.h" -#include <QList> - -#include "smtpexports.h" - -class SMTP_EXPORT MimeMessage : public QObject { -public: - - enum RecipientType { - To, // primary - Cc, // carbon copy - Bcc // blind carbon copy - }; - - /* [1] Constructors and Destructors */ - - explicit MimeMessage(bool createAutoMimeConent = true); - - ~MimeMessage() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - void setSender(EmailAddress *e); - - void addRecipient(EmailAddress *rcpt, RecipientType type = To); - - void addTo(EmailAddress *rcpt); - - void addCc(EmailAddress *rcpt); - - void addBcc(EmailAddress *rcpt); - - void setSubject(const QString &subject); - - void addPart(MimePart *part); - - void setReplyTo(EmailAddress *rto); - - void setInReplyTo(const QString &inReplyTo); - - void setHeaderEncoding(MimePart::Encoding); - - [[nodiscard]] const EmailAddress &getSender() const; - - [[nodiscard]] const QList<EmailAddress *> &getRecipients(RecipientType type = To) const; - - [[nodiscard]] const QString &getSubject() const; - - [[nodiscard]] const QList<MimePart *> &getParts() const; - - [[nodiscard]] const EmailAddress *getReplyTo() const; - - MimePart &getContent(); - - void setContent(MimePart *content); - /* [2] --- */ - - - /* [3] Public methods */ - - virtual QString toString(); - - /* [3] --- */ - -protected: - - /* [4] Protected members */ - - EmailAddress *sender{}; - EmailAddress *replyTo; - QList<EmailAddress *> recipientsTo, recipientsCc, recipientsBcc; - QString subject; - QString mInReplyTo; - MimePart *content; - bool autoMimeContentCreated; - - MimePart::Encoding hEncoding; - - /* [4] --- */ - - -}; - -#endif // MIMEMESSAGE_H diff --git a/src/smtp/mimemultipart.cpp b/src/smtp/mimemultipart.cpp deleted file mode 100644 index 4dd00d1a..00000000 --- a/src/smtp/mimemultipart.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimemultipart.h" - -#include <QCryptographicHash> -#include <QRandomGenerator> -#include <QTime> - -const QString MULTI_PART_NAMES[] = { - "multipart/mixed", // Mixed - "multipart/digest", // Digest - "multipart/alternative", // Alternative - "multipart/related", // Related - "multipart/report", // Report - "multipart/signed", // Signed - "multipart/encrypted" // Encrypted -}; - -MimeMultiPart::MimeMultiPart(MultiPartType type) { - this->type = type; - this->cType = MULTI_PART_NAMES[this->type]; - this->cEncoding = _8Bit; - - QRandomGenerator generator; - - QCryptographicHash md5(QCryptographicHash::Md5); - md5.addData(QByteArray().append((char)generator.generate())); - cBoundary = md5.result().toHex(); -} - -void MimeMultiPart::addPart(MimePart *part) { parts.append(part); } - -const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; } - -void MimeMultiPart::prepare() { - QList<MimePart *>::iterator it; - - content.clear(); - for (it = parts.begin(); it != parts.end(); it++) { - content += QString("--" + cBoundary + "\r\n").toUtf8(); - (*it)->prepare(); - content += (*it)->toString().toUtf8(); - }; - - content += QString("--" + cBoundary + "--\r\n").toUtf8(); - - MimePart::prepare(); -} - -void MimeMultiPart::setMimeType(const MultiPartType type) { - this->type = type; - this->cType = MULTI_PART_NAMES[type]; -} - -MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const { return type; } diff --git a/src/smtp/mimemultipart.h b/src/smtp/mimemultipart.h deleted file mode 100644 index b829a66f..00000000 --- a/src/smtp/mimemultipart.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEMULTIPART_H -#define MIMEMULTIPART_H - -#include "mimepart.h" - -#include "smtpexports.h" - -class SMTP_EXPORT MimeMultiPart : public MimePart { -Q_OBJECT -public: - /* [0] Enums */ - enum MultiPartType { - Mixed = 0, // RFC 2046, section 5.1.3 - Digest = 1, // RFC 2046, section 5.1.5 - Alternative = 2, // RFC 2046, section 5.1.4 - Related = 3, // RFC 2387 - Report = 4, // RFC 6522 - Signed = 5, // RFC 1847, section 2.1 - Encrypted = 6 // RFC 1847, section 2.2 - }; - - /* [0] --- */ - - /* [1] Constructors and Destructors */ - explicit MimeMultiPart(MultiPartType type = Related); - - /* [1] --- */ - - /* [2] Getters and Setters */ - - void setMimeType(MultiPartType type); - - [[nodiscard]] MultiPartType getMimeType() const; - - [[nodiscard]] const QList<MimePart *> &getParts() const; - - /* [2] --- */ - - /* [3] Public methods */ - - void addPart(MimePart *part); - - void prepare() override; - - /* [3] --- */ - -protected: - QList<MimePart *> parts; - - MultiPartType type; -}; - -#endif // MIMEMULTIPART_H diff --git a/src/smtp/mimepart.cpp b/src/smtp/mimepart.cpp deleted file mode 100644 index 10aa6cbc..00000000 --- a/src/smtp/mimepart.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimepart.h" - -#include "smtp/quotedprintable.h" - -/* [1] Constructors and Destructors */ - -MimePart::MimePart() { - cEncoding = _7Bit; - prepared = false; - cBoundary.clear(); -} - -/* [1] --- */ - -/* [2] Getters and Setters */ - -void MimePart::setContent(const QByteArray &content) { - this->content = content; -} - -void MimePart::setHeader(const QString &header) { this->header = header; } - -void MimePart::addHeaderLine(const QString &line) { - this->header += line + "\r\n"; -} - -const QString &MimePart::getHeader() const { return header; } - -const QByteArray &MimePart::getContent() const { return content; } - -void MimePart::setContentId(const QString &cId) { this->cId = cId; } - -const QString &MimePart::getContentId() const { return this->cId; } - -void MimePart::setContentName(const QString &cName) { this->cName = cName; } - -const QString &MimePart::getContentName() const { return this->cName; } - -void MimePart::setContentType(const QString &cType) { this->cType = cType; } - -const QString &MimePart::getContentType() const { return this->cType; } - -void MimePart::setCharset(const QString &charset) { this->cCharset = charset; } - -const QString &MimePart::getCharset() const { return this->cCharset; } - -void MimePart::setEncoding(Encoding enc) { this->cEncoding = enc; } - -MimePart::Encoding MimePart::getEncoding() const { return this->cEncoding; } - -MimeContentFormatter &MimePart::getContentFormatter() { - return this->formatter; -} - -/* [2] --- */ - -/* [3] Public methods */ - -QString MimePart::toString() { - if (!prepared) prepare(); - - return mimeString; -} - -/* [3] --- */ - -/* [4] Protected methods */ - -void MimePart::prepare() { - mimeString = QString(); - - /* === Header Prepare === */ - - /* Content-Type */ - mimeString.append("Content-Type: ").append(cType); - - if (!cName.isEmpty()) - mimeString.append("; name=\"").append(cName).append("\""); - - if (!cCharset.isEmpty()) mimeString.append("; charset=").append(cCharset); - - if (!cBoundary.isEmpty()) mimeString.append("; boundary=").append(cBoundary); - - mimeString.append("\r\n"); - /* ------------ */ - - /* Content-Transfer-Encoding */ - mimeString.append("Content-Transfer-Encoding: "); - switch (cEncoding) { - case _7Bit: - mimeString.append("7bit\r\n"); - break; - case _8Bit: - mimeString.append("8bit\r\n"); - break; - case Base64: - mimeString.append("base64\r\n"); - break; - case QuotedPrintable: - mimeString.append("quoted-printable\r\n"); - break; - } - /* ------------------------ */ - - /* Content-Id */ - if (cId != nullptr) - mimeString.append("Content-ID: <").append(cId).append(">\r\n"); - /* ---------- */ - - /* Addition header lines */ - - mimeString.append(header).append("\r\n"); - - /* ------------------------- */ - - /* === End of Header Prepare === */ - - /* === Content === */ - switch (cEncoding) { - case _7Bit: - mimeString.append(QString(content).toLatin1()); - break; - case _8Bit: - mimeString.append(content); - break; - case Base64: - mimeString.append(formatter.format(content.toBase64())); - break; - case QuotedPrintable: - mimeString.append( - formatter.format(QuotedPrintable::encode(content), true)); - break; - } - mimeString.append("\r\n"); - /* === End of Content === */ - - prepared = true; -} - -/* [4] --- */ diff --git a/src/smtp/mimepart.h b/src/smtp/mimepart.h deleted file mode 100644 index 1a1386de..00000000 --- a/src/smtp/mimepart.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMEPART_H -#define MIMEPART_H - -#include "mimecontentformatter.h" -#include <QObject> - -#include "smtpexports.h" - -class SMTP_EXPORT MimePart : public QObject { -Q_OBJECT -public: - /* [0] Enumerations */ - enum Encoding { - _7Bit, _8Bit, Base64, QuotedPrintable - }; - - /* [0] --- */ - - /* [1] Constructors and Destructors */ - - MimePart(); - - ~MimePart() = default; - - /* [1] --- */ - - /* [2] Getters and Setters */ - - [[nodiscard]] const QString &getHeader() const; - - [[nodiscard]] const QByteArray &getContent() const; - - void setContent(const QByteArray &content); - - void setHeader(const QString &header); - - void addHeaderLine(const QString &line); - - void setContentId(const QString &cId); - - [[nodiscard]] const QString &getContentId() const; - - void setContentName(const QString &cName); - - [[nodiscard]] const QString &getContentName() const; - - void setContentType(const QString &cType); - - [[nodiscard]] const QString &getContentType() const; - - void setCharset(const QString &charset); - - [[nodiscard]] const QString &getCharset() const; - - void setEncoding(Encoding enc); - - [[nodiscard]] Encoding getEncoding() const; - - MimeContentFormatter &getContentFormatter(); - - /* [2] --- */ - - /* [3] Public methods */ - - virtual QString toString(); - - virtual void prepare(); - - /* [3] --- */ - -protected: - /* [4] Protected members */ - - QString header; - QByteArray content; - - QString cId; - QString cName; - QString cType; - QString cCharset; - QString cBoundary; - Encoding cEncoding; - - QString mimeString; - bool prepared; - - MimeContentFormatter formatter; - - /* [4] --- */ -}; - -#endif // MIMEPART_H diff --git a/src/smtp/mimetext.cpp b/src/smtp/mimetext.cpp deleted file mode 100644 index 3726647e..00000000 --- a/src/smtp/mimetext.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/mimetext.h" - -/* [1] Constructors and Destructors */ - -MimeText::MimeText(const QString &txt) { - this->text = txt; - this->cType = "text/plain"; - this->cCharset = "utf-8"; - this->cEncoding = _8Bit; -} - -MimeText::~MimeText() = default; - -/* [1] --- */ - -/* [2] Getters and Setters */ - -void MimeText::setText(const QString &text) { this->text = text; } - -const QString &MimeText::getText() const { return text; } - -/* [2] --- */ - -/* [3] Protected Methods */ - -void MimeText::prepare() { - this->content.clear(); - this->content.append(text.toUtf8()); - - /* !!! IMPORTANT !!! */ - MimePart::prepare(); -} - -/* [3] --- */ diff --git a/src/smtp/mimetext.h b/src/smtp/mimetext.h deleted file mode 100644 index c21a1c5e..00000000 --- a/src/smtp/mimetext.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef MIMETEXT_H -#define MIMETEXT_H - -#include "mimepart.h" - -#include "smtpexports.h" - -class SMTP_EXPORT MimeText : public MimePart { -public: - - /* [1] Constructors and Destructors */ - - explicit MimeText(const QString &text = ""); - - ~MimeText() override; - - /* [1] --- */ - - - /* [2] Getters and Setters*/ - - void setText(const QString &text); - - [[nodiscard]] const QString &getText() const; - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - QString text; - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ - -}; - -#endif // MIMETEXT_H diff --git a/src/smtp/quotedprintable.cpp b/src/smtp/quotedprintable.cpp deleted file mode 100644 index 93e51122..00000000 --- a/src/smtp/quotedprintable.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/quotedprintable.h" - -QString QuotedPrintable::encode(const QByteArray &input) { - QString output; - - char byte; - const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - for (char i : input) { - byte = i; - - if ((byte == 0x20) || ((byte >= 33) && (byte <= 126) && (byte != 61))) { - output.append(byte); - } else { - output.append('='); - output.append(hex[((byte >> 4) & 0x0F)]); - output.append(hex[(byte & 0x0F)]); - } - } - - return output; -} - -QByteArray QuotedPrintable::decode(const QString &input) { - // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B - // C D E F - const int hexVal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, - 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15}; - - QByteArray output; - - for (int i = 0; i < input.length(); ++i) { - if (input.at(i).toLatin1() == '=') { - output.append((hexVal[input.at(i + 1).toLatin1() - '0'] << 4) + - hexVal[input.at(i + 2).toLatin1() - '0']); - i += 2; - } else { - output.append(input.at(i).toLatin1()); - } - } - - return output; -} diff --git a/src/smtp/quotedprintable.h b/src/smtp/quotedprintable.h deleted file mode 100644 index 00ca3cf8..00000000 --- a/src/smtp/quotedprintable.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef QUOTEDPRINTABLE_H -#define QUOTEDPRINTABLE_H - -#include <QObject> -#include <QByteArray> - -#include "smtpexports.h" - -class SMTP_EXPORT QuotedPrintable : public QObject { -Q_OBJECT -public: - - static QString encode(const QByteArray &input); - - static QByteArray decode(const QString &input); - -private: - QuotedPrintable(); -}; - -#endif // QUOTEDPRINTABLE_H diff --git a/src/smtp/smtpclient.cpp b/src/smtp/smtpclient.cpp deleted file mode 100644 index 63202998..00000000 --- a/src/smtp/smtpclient.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#include "smtp/smtpclient.h" - -#include <QByteArray> -#include <QFileInfo> - -/* [1] Constructors and destructors */ - -SmtpClient::SmtpClient(const QString &host, int port, - ConnectionType connectionType) - : socket(NULL), name("localhost"), authMethod(AuthPlain), - connectionTimeout(5000), responseTimeout(5000), - sendMessageTimeout(60000) { - setConnectionType(connectionType); - - this->host = host; - this->port = port; - - connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, - SLOT(socketStateChanged(QAbstractSocket::SocketState))); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, - SLOT(socketError(QAbstractSocket::SocketError))); - connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())); -} - -SmtpClient::~SmtpClient() { - if (socket) - delete socket; -} - -/* [1] --- */ - -/* [2] Getters and Setters */ - -void SmtpClient::setUser(const QString &user) { this->user = user; } - -void SmtpClient::setPassword(const QString &password) { - this->password = password; -} - -void SmtpClient::setAuthMethod(AuthMethod method) { this->authMethod = method; } - -void SmtpClient::setHost(const QString &host) { this->host = host; } - -void SmtpClient::setPort(int port) { this->port = port; } - -void SmtpClient::setConnectionType(ConnectionType ct) { - this->connectionType = ct; - - if (socket) - delete socket; - - switch (connectionType) { - case TcpConnection: - socket = new QTcpSocket(this); - break; - case SslConnection: - case TlsConnection: - socket = new QSslSocket(this); - } -} - -const QString &SmtpClient::getHost() const { return this->host; } - -const QString &SmtpClient::getUser() const { return this->user; } - -const QString &SmtpClient::getPassword() const { return this->password; } - -SmtpClient::AuthMethod SmtpClient::getAuthMethod() const { - return this->authMethod; -} - -int SmtpClient::getPort() const { return this->port; } - -SmtpClient::ConnectionType SmtpClient::getConnectionType() const { - return connectionType; -} - -const QString &SmtpClient::getName() const { return this->name; } - -void SmtpClient::setName(const QString &name) { this->name = name; } - -const QString &SmtpClient::getResponseText() const { return responseText; } - -int SmtpClient::getResponseCode() const { return responseCode; } - -QTcpSocket *SmtpClient::getSocket() { return socket; } - -int SmtpClient::getConnectionTimeout() const { return connectionTimeout; } - -void SmtpClient::setConnectionTimeout(int msec) { connectionTimeout = msec; } - -int SmtpClient::getResponseTimeout() const { return responseTimeout; } - -void SmtpClient::setResponseTimeout(int msec) { responseTimeout = msec; } - -int SmtpClient::getSendMessageTimeout() const { return sendMessageTimeout; } - -void SmtpClient::setSendMessageTimeout(int msec) { sendMessageTimeout = msec; } - -/* [2] --- */ - -/* [3] Public methods */ - -bool SmtpClient::connectToHost() { - switch (connectionType) { - case TlsConnection: - case TcpConnection: - socket->connectToHost(host, port); - break; - case SslConnection: - ((QSslSocket *) socket)->connectToHostEncrypted(host, port); - break; - } - - // Tries to connect to server - if (!socket->waitForConnected(connectionTimeout)) { - emit smtpError(ConnectionTimeoutError); - return false; - } - - try { - // Wait for the server's response - waitForResponse(); - - // If the response code is not 220 (Service ready) - // means that is something wrong with the server - if (responseCode != 220) { - emit smtpError(ServerError); - return false; - } - - // Send a EHLO/HELO message to the server - // The client's first command must be EHLO/HELO - sendMessage("EHLO " + name); - - // Wait for the server's response - waitForResponse(); - - // The response code needs to be 250. - if (responseCode != 250) { - emit smtpError(ServerError); - return false; - } - - if (connectionType == TlsConnection) { - // send a request to start TLS handshake - sendMessage("STARTTLS"); - - // Wait for the server's response - waitForResponse(); - - // The response code needs to be 220. - if (responseCode != 220) { - emit smtpError(ServerError); - return false; - }; - - ((QSslSocket *) socket)->startClientEncryption(); - - if (!((QSslSocket *) socket)->waitForEncrypted(connectionTimeout)) { - qDebug() << ((QSslSocket *) socket)->errorString(); - emit smtpError(ConnectionTimeoutError); - return false; - } - - // Send ELHO one more time - sendMessage("EHLO " + name); - - // Wait for the server's response - waitForResponse(); - - // The response code needs to be 250. - if (responseCode != 250) { - emit smtpError(ServerError); - return false; - } - } - } catch (ResponseTimeoutException) { - return false; - } catch (SendMessageTimeoutException) { - return false; - } - - // If no errors occured the function returns true. - return true; -} - -bool SmtpClient::login() { return login(user, password, authMethod); } - -bool SmtpClient::login(const QString &user, const QString &password, - AuthMethod method) { - try { - if (method == AuthPlain) { - // Sending command: AUTH PLAIN base64('\0' + username + '\0' + password) - sendMessage("AUTH PLAIN " + QByteArray() - .append((char) 0) - .append(user.toUtf8()) - .append((char) 0) - .append(password.toUtf8()) - .toBase64()); - - // Wait for the server's response - waitForResponse(); - - // If the response is not 235 then the authentication was faild - if (responseCode != 235) { - emit smtpError(AuthenticationFailedError); - return false; - } - } else if (method == AuthLogin) { - // Sending command: AUTH LOGIN - sendMessage("AUTH LOGIN"); - - // Wait for 334 response code - waitForResponse(); - if (responseCode != 334) { - emit smtpError(AuthenticationFailedError); - return false; - } - - // Send the username in base64 - sendMessage(QByteArray().append(user.toUtf8()).toBase64()); - - // Wait for 334 - waitForResponse(); - if (responseCode != 334) { - emit smtpError(AuthenticationFailedError); - return false; - } - - // Send the password in base64 - sendMessage(QByteArray().append(password.toUtf8()).toBase64()); - - // Wait for the server's responce - waitForResponse(); - - // If the response is not 235 then the authentication was faild - if (responseCode != 235) { - emit smtpError(AuthenticationFailedError); - return false; - } - } - } catch (ResponseTimeoutException) { - // Responce Timeout exceeded - emit smtpError(AuthenticationFailedError); - return false; - } catch (SendMessageTimeoutException) { - // Send Timeout exceeded - emit smtpError(AuthenticationFailedError); - return false; - } - - return true; -} - -bool SmtpClient::sendMail(MimeMessage &email) { - try { - // Send the MAIL command with the sender - sendMessage("MAIL FROM:<" + email.getSender().getAddress() + ">"); - - waitForResponse(); - - if (responseCode != 250) - return false; - - // Send RCPT command for each recipient - QList<EmailAddress *>::const_iterator it, itEnd; - // To (primary recipients) - for (it = email.getRecipients().begin(), - itEnd = email.getRecipients().end(); - it != itEnd; ++it) { - - sendMessage("RCPT TO:<" + (*it)->getAddress() + ">"); - waitForResponse(); - - if (responseCode != 250) - return false; - } - - // Cc (carbon copy) - for (it = email.getRecipients(MimeMessage::Cc).begin(), - itEnd = email.getRecipients(MimeMessage::Cc).end(); - it != itEnd; ++it) { - sendMessage("RCPT TO:<" + (*it)->getAddress() + ">"); - waitForResponse(); - - if (responseCode != 250) - return false; - } - - // Bcc (blind carbon copy) - for (it = email.getRecipients(MimeMessage::Bcc).begin(), - itEnd = email.getRecipients(MimeMessage::Bcc).end(); - it != itEnd; ++it) { - sendMessage("RCPT TO:<" + (*it)->getAddress() + ">"); - waitForResponse(); - - if (responseCode != 250) - return false; - } - - // Send DATA command - sendMessage("DATA"); - waitForResponse(); - - if (responseCode != 354) - return false; - - sendMessage(email.toString()); - - // Send \r\n.\r\n to end the mail data - sendMessage("."); - - waitForResponse(); - - if (responseCode != 250) - return false; - } catch (ResponseTimeoutException) { - return false; - } catch (SendMessageTimeoutException) { - return false; - } - - return true; -} - -void SmtpClient::quit() { - try { - sendMessage("QUIT"); - } catch (SmtpClient::SendMessageTimeoutException) { - // Manually close the connection to the smtp server if message "QUIT" wasn't - // received by the smtp server - if (socket->state() == QAbstractSocket::ConnectedState || - socket->state() == QAbstractSocket::ConnectingState || - socket->state() == QAbstractSocket::HostLookupState) - socket->disconnectFromHost(); - } -} - -/* [3] --- */ - -/* [4] Protected methods */ - -void SmtpClient::waitForResponse() { - do { - if (!socket->waitForReadyRead(responseTimeout)) { - emit smtpError(ResponseTimeoutError); - throw ResponseTimeoutException(); - } - - while (socket->canReadLine()) { - // Save the server's response - responseText = socket->readLine(); - - // Extract the respose code from the server's responce (first 3 digits) - responseCode = responseText.leftRef(3).toInt(); - - if (responseCode / 100 == 4) - emit smtpError(ServerError); - - if (responseCode / 100 == 5) - emit smtpError(ClientError); - - if (responseText[3] == ' ') { - return; - } - } - } while (true); -} - -void SmtpClient::sendMessage(const QString &text) { - socket->write(text.toUtf8() + "\r\n"); - if (!socket->waitForBytesWritten(sendMessageTimeout)) { - emit smtpError(SendDataTimeoutError); - throw SendMessageTimeoutException(); - } -} - -/* [4] --- */ - -/* [5] Slots for the socket's signals */ - -void SmtpClient::socketStateChanged(QAbstractSocket::SocketState /*state*/) {} - -void SmtpClient::socketError(QAbstractSocket::SocketError /*socketError*/) {} - -void SmtpClient::socketReadyRead() {} - -/* [5] --- */ diff --git a/src/smtp/smtpclient.h b/src/smtp/smtpclient.h deleted file mode 100644 index 29c507dc..00000000 --- a/src/smtp/smtpclient.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (c) 2011-2012 - Tőkés Attila - - This file is part of SmtpClient for Qt. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - See the LICENSE file for more details. -*/ - -#ifndef SMTPCLIENT_H -#define SMTPCLIENT_H - -#include <QObject> -#include <QtNetwork/QSslSocket> - -#include "mimemessage.h" -#include "smtpexports.h" - -class SMTP_EXPORT SmtpClient : public QObject { -Q_OBJECT -public: - - /* [0] Enumerations */ - - enum AuthMethod { - AuthPlain, - AuthLogin - }; - - enum SmtpError { - ConnectionTimeoutError, - ResponseTimeoutError, - SendDataTimeoutError, - AuthenticationFailedError, - ServerError, // 4xx smtp error - ClientError // 5xx smtp error - }; - - enum ConnectionType { - TcpConnection, - SslConnection, - TlsConnection // STARTTLS - }; - - /* [0] --- */ - - - /* [1] Constructors and Destructors */ - - explicit SmtpClient(const QString &host = "localhost", int port = 25, ConnectionType ct = TcpConnection); - - ~SmtpClient() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - [[nodiscard]] const QString &getHost() const; - - void setHost(const QString &host); - - [[nodiscard]] int getPort() const; - - void setPort(int port); - - [[nodiscard]] const QString &getName() const; - - void setName(const QString &name); - - [[nodiscard]] ConnectionType getConnectionType() const; - - void setConnectionType(ConnectionType ct); - - [[nodiscard]] const QString &getUser() const; - - void setUser(const QString &user); - - [[nodiscard]] const QString &getPassword() const; - - void setPassword(const QString &password); - - [[nodiscard]] SmtpClient::AuthMethod getAuthMethod() const; - - void setAuthMethod(AuthMethod method); - - [[nodiscard]] const QString &getResponseText() const; - - [[nodiscard]] int getResponseCode() const; - - [[nodiscard]] int getConnectionTimeout() const; - - void setConnectionTimeout(int msec); - - [[nodiscard]] int getResponseTimeout() const; - - void setResponseTimeout(int msec); - - [[nodiscard]] int getSendMessageTimeout() const; - - void setSendMessageTimeout(int msec); - - QTcpSocket *getSocket(); - - - /* [2] --- */ - - - /* [3] Public methods */ - - bool connectToHost(); - - bool login(); - - bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin); - - bool sendMail(MimeMessage &email); - - void quit(); - - - /* [3] --- */ - -protected: - - /* [4] Protected members */ - - QTcpSocket *socket; - - QString host; - int port; - ConnectionType connectionType; - QString name; - - QString user; - QString password; - AuthMethod authMethod; - - int connectionTimeout; - int responseTimeout; - int sendMessageTimeout; - - - QString responseText; - int responseCode; - - - class ResponseTimeoutException : public std::exception { - }; - - class SendMessageTimeoutException : public std::exception { - }; - - /* [4] --- */ - - - /* [5] Protected methods */ - - void waitForResponse(); - - void sendMessage(const QString &text); - - /* [5] --- */ - -protected slots: - - /* [6] Protected slots */ - - void socketStateChanged(QAbstractSocket::SocketState state); - - void socketError(QAbstractSocket::SocketError error); - - void socketReadyRead(); - - /* [6] --- */ - - -signals: - - /* [7] Signals */ - - void smtpError(SmtpClient::SmtpError e); - - /* [7] --- */ - -}; - -#endif // SMTPCLIENT_H diff --git a/src/smtp/smtpexports.h b/src/smtp/smtpexports.h deleted file mode 100644 index 4bad0da0..00000000 --- a/src/smtp/smtpexports.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SMTPEXPORTS_H -#define SMTPEXPORTS_H - -#ifdef SMTP_BUILD -#define SMTP_EXPORT -#else -#define SMTP_EXPORT -#endif - -#endif // SMTPEXPORTS_H diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 3e44a0d6..001a776d 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -1,31 +1,96 @@ +# +# Copyright (C) 2021 Saturneric +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric<[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# tracking source files aux_source_directory(. UI_SOURCE) -aux_source_directory(./aes UI_SOURCE) -aux_source_directory(./keypair_details UI_SOURCE) -aux_source_directory(./widgets UI_SOURCE) -aux_source_directory(./keygen UI_SOURCE) -aux_source_directory(./main_window UI_SOURCE) -aux_source_directory(./help UI_SOURCE) -aux_source_directory(./settings UI_SOURCE) -aux_source_directory(./function UI_SOURCE) -aux_source_directory(./details UI_SOURCE) -aux_source_directory(./data_struct UI_SOURCE) +aux_source_directory(keypair_details UI_SOURCE) +aux_source_directory(widgets UI_SOURCE) +aux_source_directory(key_generate UI_SOURCE) +aux_source_directory(main_window UI_SOURCE) +aux_source_directory(help UI_SOURCE) +aux_source_directory(settings UI_SOURCE) +aux_source_directory(thread UI_SOURCE) +aux_source_directory(details UI_SOURCE) +aux_source_directory(struct UI_SOURCE) +aux_source_directory(import_export UI_SOURCE) +aux_source_directory(dialog UI_SOURCE) + +if (SMTP_SUPPORT) + aux_source_directory(mail UI_SOURCE) +endif () + +# define libgpgfrontend_ui +add_library(gpgfrontend_ui STATIC ${UI_SOURCE}) +# link smtp-mime if (SMTP_SUPPORT) - aux_source_directory(./smtp UI_SOURCE) + target_link_libraries(gpgfrontend_ui + smtp-mime) endif () -add_library(gpgfrontend-ui STATIC ${UI_SOURCE}) -set(GPGFRONTEND_UI_LIB_NAME gpgfrontend-ui) -target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} +# link Qt +target_link_libraries(gpgfrontend_ui Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core) -target_include_directories(gpgfrontend-ui PUBLIC - ${CMAKE_CURRENT_BINARY_DIR}/${GPGFRONTEND_UI_LIB_NAME}_autogen/include) +# link vmime +if (NOT LINUX) + # macOS + target_link_libraries(gpgfrontend_ui + gpgfrontend_vmime intl iconv) + if (MINGW) + target_link_libraries(gpgfrontend_ui ws2_32) + endif () +else () + target_link_libraries(gpgfrontend_ui + gpgfrontend_vmime anl ssl crypto) +endif () + +# link gpgfrontend_core +target_link_libraries(gpgfrontend_ui + gpgfrontend_core) + +# link encoding_detect +target_link_libraries(gpgfrontend_ui encoding_detect) + +# set up pch +target_precompile_headers(gpgfrontend_ui PUBLIC GpgFrontendUI.h) + +# add ui generator include path +target_include_directories(gpgfrontend_ui PUBLIC + ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_ui_autogen/include) + +# using std c++ 17 +target_compile_features(gpgfrontend_ui PUBLIC cxx_std_17) + +# for xcode archive build if (XCODE_BUILD) - set_target_properties(gpgfrontend-ui + set_target_properties(gpgfrontend_ui PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) endif () -target_compile_features(gpgfrontend-ui PUBLIC cxx_std_17)
\ No newline at end of file +target_compile_features(gpgfrontend_ui PUBLIC cxx_std_17)
\ No newline at end of file diff --git a/src/ui/FindWidget.cpp b/src/ui/FindWidget.cpp deleted file mode 100644 index 6326b119..00000000 --- a/src/ui/FindWidget.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "ui/FindWidget.h" - -namespace GpgFrontend::UI { - -FindWidget::FindWidget(QWidget* parent, QTextEdit* edit) : QWidget(parent) { - mTextpage = edit; - findEdit = new QLineEdit(this); - auto* closeButton = new QPushButton( - this->style()->standardIcon(QStyle::SP_TitleBarCloseButton), QString(), - this); - auto* nextButton = new QPushButton(QIcon(":button_next.png"), QString()); - auto* previousButton = new QPushButton(QIcon(":button_previous.png"), ""); - - auto* notificationWidgetLayout = new QHBoxLayout(this); - notificationWidgetLayout->setContentsMargins(10, 0, 0, 0); - notificationWidgetLayout->addWidget(new QLabel(QString(_("Find")) + ": ")); - notificationWidgetLayout->addWidget(findEdit, 2); - notificationWidgetLayout->addWidget(nextButton); - notificationWidgetLayout->addWidget(previousButton); - notificationWidgetLayout->addWidget(closeButton); - - this->setLayout(notificationWidgetLayout); - connect(findEdit, SIGNAL(textEdited(QString)), this, SLOT(slotFind())); - connect(findEdit, SIGNAL(returnPressed()), this, SLOT(slotFindNext())); - connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFindNext())); - connect(previousButton, SIGNAL(clicked()), this, SLOT(slotFindPrevious())); - connect(closeButton, SIGNAL(clicked()), this, SLOT(slotClose())); - - // The timer is necessary for setting the focus - QTimer::singleShot(0, findEdit, SLOT(setFocus())); -} - -void FindWidget::setBackground() { - QTextCursor cursor = mTextpage->textCursor(); - // if match is found set background of QLineEdit to white, otherwise to red - QPalette bgPalette(findEdit->palette()); - - if (!findEdit->text().isEmpty() && - mTextpage->document()->find(findEdit->text()).position() < 0) { - bgPalette.setColor(QPalette::Base, "#ececba"); - } else { - bgPalette.setColor(QPalette::Base, Qt::white); - } - findEdit->setPalette(bgPalette); -} - -void FindWidget::slotFindNext() { - QTextCursor cursor = mTextpage->textCursor(); - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); - - // if end of document is reached, restart search from beginning - if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); - } - - // cursor should not stay at -1, otherwise text is not editable - // todo: check how gedit handles this - if (cursor.position() != -1) { - mTextpage->setTextCursor(cursor); - } - this->setBackground(); -} - -void FindWidget::slotFind() { - QTextCursor cursor = mTextpage->textCursor(); - - if (cursor.anchor() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); - } else { - cursor = mTextpage->document()->find(findEdit->text(), cursor.anchor(), - QTextDocument::FindCaseSensitively); - } - - // if end of document is reached, restart search from beginning - if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); - } - - // cursor should not stay at -1, otherwise text is not editable - // todo: check how gedit handles this - if (cursor.position() != -1) { - mTextpage->setTextCursor(cursor); - } - this->setBackground(); -} - -void FindWidget::slotFindPrevious() { - QTextDocument::FindFlags flags; - flags |= QTextDocument::FindBackward; - flags |= QTextDocument::FindCaseSensitively; - - QTextCursor cursor = mTextpage->textCursor(); - cursor = mTextpage->document()->find(findEdit->text(), cursor, flags); - - // if begin of document is reached, restart search from end - if (cursor.position() == -1) { - cursor = - mTextpage->document()->find(findEdit->text(), QTextCursor::End, flags); - } - - // cursor should not stay at -1, otherwise text is not editable - // todo: check how gedit handles this - if (cursor.position() != -1) { - mTextpage->setTextCursor(cursor); - } - this->setBackground(); -} - -void FindWidget::keyPressEvent(QKeyEvent* e) { - switch (e->key()) { - case Qt::Key_Escape: - this->slotClose(); - break; - case Qt::Key_F3: - if (e->modifiers() & Qt::ShiftModifier) { - this->slotFindPrevious(); - } else { - this->slotFindNext(); - } - break; - } -} - -void FindWidget::slotClose() { - QTextCursor cursor = mTextpage->textCursor(); - - if (cursor.position() == -1) { - cursor.setPosition(0); - mTextpage->setTextCursor(cursor); - } - mTextpage->setFocus(); - close(); -} - -} // namespace GpgFrontend::UI diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h index 90e15324..ab6e9366 100644 --- a/src/ui/GpgFrontendUI.h +++ b/src/ui/GpgFrontendUI.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,50 +8,51 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_GPGFRONTENDUI_H #define GPGFRONTEND_GPGFRONTENDUI_H +/** + * Basic dependency + */ #include <QtCore> #include <QtNetwork> #include <QtPrintSupport> #include <QtWidgets> +#include <optional> +/** + * Project internal dependencies + */ #include "GpgFrontend.h" -#include "gpg/GpgConstants.h" -#include "gpg/GpgModel.h" - -#undef LIBCONFIGXX_STATIC -#define LIBCONFIGXX_STATIC -#include <libconfig.h++> +#include "core/GpgConstants.h" +#include "core/GpgModel.h" /** - * Resources File(s) Path Vars + * 3rd party dependencies */ -#if defined(MACOS) && defined(RELEASE) -#define RESOURCE_DIR(appDir) (appDir + "/../Resources/") -#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir / ".." / "Resources") -#elif defined(LINUX) && defined(RELEASE) -#define RESOURCE_DIR(appDir) (appDir + "/../share/") -#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir / ".." / "share") -#else -#define RESOURCE_DIR(appDir) (appDir) -#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir) + +#include <qt-aes/qaesencryption.h> + +#ifdef SMTP_SUPPORT +#include <SmtpMime> #endif #endif // GPGFRONTEND_GPGFRONTENDUI_H diff --git a/src/ui/KeyImportDetailDialog.h b/src/ui/KeyImportDetailDialog.h deleted file mode 100644 index a75d466d..00000000 --- a/src/ui/KeyImportDetailDialog.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __KEYIMPORTDETAILSDIALOG_H__ -#define __KEYIMPORTDETAILSDIALOG_H__ - -#include <gpg/function/GpgKeyImportExporter.h> - -#include "gpg/GpgContext.h" -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { -class KeyImportDetailDialog : public QDialog { - Q_OBJECT - - public: - KeyImportDetailDialog(GpgImportInformation result, bool automatic, - QWidget* parent = nullptr); - - private: - void createGeneralInfoBox(); - void createKeysTable(); - void createButtonBox(); - static QString getStatusString(int keyStatus); - - QTableWidget* keysTable{}; - QGroupBox* generalInfoBox{}; - QGroupBox* keyInfoBox{}; - QDialogButtonBox* buttonBox{}; - GpgImportInformation mResult; -}; -} // namespace GpgFrontend::UI - -#endif // __KEYIMPORTDETAILSDIALOG_H__ diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp index 3715b01a..57d8ba1f 100755 --- a/src/ui/KeyMgmt.cpp +++ b/src/ui/KeyMgmt.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,74 +30,77 @@ #include <utility> -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExporter.h" -#include "gpg/function/GpgKeyOpera.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/function/gpg/GpgKeyOpera.h" +#include "core/function/KeyPackageOperator.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" -#include "ui/aes/qaesencryption.h" -#include "ui/keygen/SubkeyGenerateDialog.h" -#include "ui/settings/GlobalSettingStation.h" -#include "ui/widgets/ExportKeyPackageDialog.h" +#include "ui/import_export/ExportKeyPackageDialog.h" +#include "ui/key_generate/SubkeyGenerateDialog.h" +#include "ui/main_window/MainWindow.h" +#include "core/function/GlobalSettingStation.h" namespace GpgFrontend::UI { KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) { /* the list of Keys available*/ key_list_ = new KeyList(KeyMenuAbility::ALL, this); - key_list_->addListGroupTab(_("All"), KeyListRow::SECRET_OR_PUBLIC_KEY); + key_list_->AddListGroupTab(_("All"), KeyListRow::SECRET_OR_PUBLIC_KEY); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, [](const GpgKey& key) -> bool { - return !key.is_private_key() && - !(key.revoked() || key.disabled() || key.expired()); + return !key.IsPrivateKey() && + !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, [](const GpgKey& key) -> bool { - return key.is_private_key() && - !(key.revoked() || key.disabled() || key.expired()); + return key.IsPrivateKey() && + !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("No Primary Key"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, [](const GpgKey& key) -> bool { - return !key.has_master_key() && - !(key.revoked() || key.disabled() || key.expired()); + return !key.IsHasMasterKey() && + !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("Revoked"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, - [](const GpgKey& key) -> bool { return key.revoked(); }); + [](const GpgKey& key) -> bool { return key.IsRevoked(); }); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("Expired"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, - [](const GpgKey& key) -> bool { return key.expired(); }); + [](const GpgKey& key) -> bool { return key.IsExpired(); }); setCentralWidget(key_list_); - key_list_->setDoubleClickedAction([this](const GpgKey& key, QWidget* parent) { + key_list_->SetDoubleClickedAction([this](const GpgKey& key, QWidget* parent) { new KeyDetailsDialog(key, parent); }); - key_list_->slotRefresh(); + key_list_->SlotRefresh(); + + create_actions(); + create_menus(); + create_tool_bars(); - createActions(); - createMenus(); - createToolBars(); - connect(this, SIGNAL(signalStatusBarChanged(QString)), this->parent(), - SLOT(slotSetStatusBarText(QString))); + connect(this, &KeyMgmt::SignalStatusBarChanged, + qobject_cast<MainWindow*>(this->parent()), + &MainWindow::SlotSetStatusBarText); auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); @@ -147,137 +154,143 @@ KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) { this->statusBar()->show(); setWindowTitle(_("KeyPair Management")); - key_list_->addMenuAction(deleteSelectedKeysAct); - key_list_->addMenuAction(showKeyDetailsAct); + key_list_->AddMenuAction(delete_selected_keys_act_); + key_list_->AddMenuAction(show_key_details_act_); - connect(this, SIGNAL(signalKeyStatusUpdated()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); - connect(SignalStation::GetInstance(), &SignalStation::signalRefreshStatusBar, + connect(this, &KeyMgmt::SignalKeyStatusUpdated, SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); + connect(SignalStation::GetInstance(), &SignalStation::SignalRefreshStatusBar, this, [=](const QString& message, int timeout) { statusBar()->showMessage(message, timeout); }); } -void KeyMgmt::createActions() { - openKeyFileAct = new QAction(_("Open"), this); - openKeyFileAct->setShortcut(QKeySequence(_("Ctrl+O"))); - openKeyFileAct->setToolTip(_("Open Key File")); - connect(importKeyFromFileAct, &QAction::triggered, this, - [&]() { CommonUtils::GetInstance()->slotImportKeyFromFile(this); }); - - closeAct = new QAction(_("Close"), this); - closeAct->setShortcut(QKeySequence(_("Ctrl+Q"))); - closeAct->setIcon(QIcon(":exit.png")); - closeAct->setToolTip(_("Close")); - connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); - - generateKeyPairAct = new QAction(_("New Keypair"), this); - generateKeyPairAct->setShortcut(QKeySequence(_("Ctrl+N"))); - generateKeyPairAct->setIcon(QIcon(":key_generate.png")); - generateKeyPairAct->setToolTip(_("Generate KeyPair")); - connect(generateKeyPairAct, SIGNAL(triggered()), this, - SLOT(slotGenerateKeyDialog())); - - generateSubKeyAct = new QAction(_("New Subkey"), this); - generateSubKeyAct->setShortcut(QKeySequence(_("Ctrl+Shift+N"))); - generateSubKeyAct->setIcon(QIcon(":key_generate.png")); - generateSubKeyAct->setToolTip(_("Generate Subkey For Selected KeyPair")); - connect(generateSubKeyAct, SIGNAL(triggered()), this, - SLOT(slotGenerateSubKey())); - - importKeyFromFileAct = new QAction(_("File"), this); - importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png")); - importKeyFromFileAct->setToolTip(_("Import New Key From File")); - connect(importKeyFromFileAct, &QAction::triggered, this, - [&]() { CommonUtils::GetInstance()->slotImportKeyFromFile(this); }); - - importKeyFromClipboardAct = new QAction(_("Clipboard"), this); - importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png")); - importKeyFromClipboardAct->setToolTip(_("Import New Key From Clipboard")); - connect(importKeyFromClipboardAct, &QAction::triggered, this, [&]() { - CommonUtils::GetInstance()->slotImportKeyFromClipboard(this); +void KeyMgmt::create_actions() { + open_key_file_act_ = new QAction(_("Open"), this); + open_key_file_act_->setShortcut(QKeySequence(_("Ctrl+O"))); + open_key_file_act_->setToolTip(_("Open Key File")); + connect(open_key_file_act_, &QAction::triggered, this, + [&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); }); + + close_act_ = new QAction(_("Close"), this); + close_act_->setShortcut(QKeySequence(_("Ctrl+Q"))); + close_act_->setIcon(QIcon(":exit.png")); + close_act_->setToolTip(_("Close")); + connect(close_act_, &QAction::triggered, this, &KeyMgmt::close); + + generate_key_pair_act_ = new QAction(_("New Keypair"), this); + generate_key_pair_act_->setShortcut(QKeySequence(_("Ctrl+N"))); + generate_key_pair_act_->setIcon(QIcon(":key_generate.png")); + generate_key_pair_act_->setToolTip(_("Generate KeyPair")); + connect(generate_key_pair_act_, &QAction::triggered, this, + &KeyMgmt::SlotGenerateKeyDialog); + + generate_subkey_act_ = new QAction(_("New Subkey"), this); + generate_subkey_act_->setShortcut(QKeySequence(_("Ctrl+Shift+N"))); + generate_subkey_act_->setIcon(QIcon(":key_generate.png")); + generate_subkey_act_->setToolTip(_("Generate Subkey For Selected KeyPair")); + connect(generate_subkey_act_, &QAction::triggered, this, + &KeyMgmt::SlotGenerateSubKey); + + import_key_from_file_act_ = new QAction(_("File"), this); + import_key_from_file_act_->setIcon(QIcon(":import_key_from_file.png")); + import_key_from_file_act_->setToolTip(_("Import New Key From File")); + connect(import_key_from_file_act_, &QAction::triggered, this, + [&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); }); + + import_key_from_clipboard_act_ = new QAction(_("Clipboard"), this); + import_key_from_clipboard_act_->setIcon( + QIcon(":import_key_from_clipboard.png")); + import_key_from_clipboard_act_->setToolTip( + _("Import New Key From Clipboard")); + connect(import_key_from_clipboard_act_, &QAction::triggered, this, [&]() { + CommonUtils::GetInstance()->SlotImportKeyFromClipboard(this); }); - importKeyFromKeyServerAct = new QAction(_("Keyserver"), this); - importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png")); - importKeyFromKeyServerAct->setToolTip(_("Import New Key From Keyserver")); - connect(importKeyFromKeyServerAct, &QAction::triggered, this, [&]() { - CommonUtils::GetInstance()->slotImportKeyFromKeyServer(this); + import_key_from_key_server_act_ = new QAction(_("Keyserver"), this); + import_key_from_key_server_act_->setIcon( + QIcon(":import_key_from_server.png")); + import_key_from_key_server_act_->setToolTip( + _("Import New Key From Keyserver")); + connect(import_key_from_key_server_act_, &QAction::triggered, this, [&]() { + CommonUtils::GetInstance()->SlotImportKeyFromKeyServer(this); }); - importKeysFromKeyPackageAct = new QAction(_("Key Package"), this); - importKeysFromKeyPackageAct->setIcon(QIcon(":key_package.png")); - importKeysFromKeyPackageAct->setToolTip( + import_keys_from_key_package_act_ = new QAction(_("Key Package"), this); + import_keys_from_key_package_act_->setIcon(QIcon(":key_package.png")); + import_keys_from_key_package_act_->setToolTip( _("Import Key(s) From a Key Package")); - connect(importKeysFromKeyPackageAct, &QAction::triggered, this, - &KeyMgmt::slotImportKeyPackage); - - exportKeyToClipboardAct = new QAction(_("Export To Clipboard"), this); - exportKeyToClipboardAct->setIcon(QIcon(":export_key_to_clipboard.png")); - exportKeyToClipboardAct->setToolTip(_("Export Selected Key(s) To Clipboard")); - connect(exportKeyToClipboardAct, SIGNAL(triggered()), this, - SLOT(slotExportKeyToClipboard())); - - exportKeyToFileAct = new QAction(_("Export To Key Package"), this); - exportKeyToFileAct->setIcon(QIcon(":key_package.png")); - exportKeyToFileAct->setToolTip(_("Export Checked Key(s) To a Key Package")); - connect(exportKeyToFileAct, SIGNAL(triggered()), this, - SLOT(slotExportKeyToKeyPackage())); - - exportKeyAsOpenSSHFormat = new QAction(_("Export As OpenSSH"), this); - exportKeyAsOpenSSHFormat->setIcon(QIcon(":ssh-key.png")); - exportKeyAsOpenSSHFormat->setToolTip( + connect(import_keys_from_key_package_act_, &QAction::triggered, this, + &KeyMgmt::SlotImportKeyPackage); + + export_key_to_clipboard_act_ = new QAction(_("Export To Clipboard"), this); + export_key_to_clipboard_act_->setIcon(QIcon(":export_key_to_clipboard.png")); + export_key_to_clipboard_act_->setToolTip( + _("Export Selected Key(s) To Clipboard")); + connect(export_key_to_clipboard_act_, &QAction::triggered, this, + &KeyMgmt::SlotExportKeyToClipboard); + + export_key_to_file_act_ = new QAction(_("Export To Key Package"), this); + export_key_to_file_act_->setIcon(QIcon(":key_package.png")); + export_key_to_file_act_->setToolTip( + _("Export Checked Key(s) To a Key Package")); + connect(export_key_to_file_act_, &QAction::triggered, this, + &KeyMgmt::SlotExportKeyToKeyPackage); + + export_key_as_open_ssh_format_ = new QAction(_("Export As OpenSSH"), this); + export_key_as_open_ssh_format_->setIcon(QIcon(":ssh-key.png")); + export_key_as_open_ssh_format_->setToolTip( _("Export Selected Key(s) As OpenSSH Format to File")); - connect(exportKeyAsOpenSSHFormat, SIGNAL(triggered()), this, - SLOT(slotExportAsOpenSSHFormat())); - - deleteSelectedKeysAct = new QAction(_("Delete Selected Key(s)"), this); - deleteSelectedKeysAct->setToolTip(_("Delete the Selected keys")); - connect(deleteSelectedKeysAct, SIGNAL(triggered()), this, - SLOT(slotDeleteSelectedKeys())); - - deleteCheckedKeysAct = new QAction(_("Delete Checked Key(s)"), this); - deleteCheckedKeysAct->setToolTip(_("Delete the Checked keys")); - deleteCheckedKeysAct->setIcon(QIcon(":button_delete.png")); - connect(deleteCheckedKeysAct, SIGNAL(triggered()), this, - SLOT(slotDeleteCheckedKeys())); - - showKeyDetailsAct = new QAction(_("Show Key Details"), this); - showKeyDetailsAct->setToolTip(_("Show Details for this Key")); - connect(showKeyDetailsAct, SIGNAL(triggered()), this, - SLOT(slotShowKeyDetails())); + connect(export_key_as_open_ssh_format_, &QAction::triggered, this, + &KeyMgmt::SlotExportAsOpenSSHFormat); + + delete_selected_keys_act_ = new QAction(_("Delete Selected Key(s)"), this); + delete_selected_keys_act_->setToolTip(_("Delete the Selected keys")); + connect(delete_selected_keys_act_, &QAction::triggered, this, + &KeyMgmt::SlotDeleteSelectedKeys); + + delete_checked_keys_act_ = new QAction(_("Delete Checked Key(s)"), this); + delete_checked_keys_act_->setToolTip(_("Delete the Checked keys")); + delete_checked_keys_act_->setIcon(QIcon(":button_delete.png")); + connect(delete_checked_keys_act_, &QAction::triggered, this, + &KeyMgmt::SlotDeleteCheckedKeys); + + show_key_details_act_ = new QAction(_("Show Key Details"), this); + show_key_details_act_->setToolTip(_("Show Details for this Key")); + connect(show_key_details_act_, &QAction::triggered, this, + &KeyMgmt::SlotShowKeyDetails); } -void KeyMgmt::createMenus() { - fileMenu = menuBar()->addMenu(_("File")); - fileMenu->addAction(openKeyFileAct); - fileMenu->addAction(closeAct); - - keyMenu = menuBar()->addMenu(_("Key")); - generateKeyMenu = keyMenu->addMenu(_("Generate Key")); - generateKeyMenu->addAction(generateKeyPairAct); - generateKeyMenu->addAction(generateSubKeyAct); - - importKeyMenu = keyMenu->addMenu(_("Import Key")); - importKeyMenu->addAction(importKeyFromFileAct); - importKeyMenu->addAction(importKeyFromClipboardAct); - importKeyMenu->addAction(importKeyFromKeyServerAct); - importKeyMenu->addAction(importKeysFromKeyPackageAct); - - keyMenu->addAction(exportKeyToFileAct); - keyMenu->addAction(exportKeyToClipboardAct); - keyMenu->addAction(exportKeyAsOpenSSHFormat); - keyMenu->addSeparator(); - keyMenu->addAction(deleteCheckedKeysAct); +void KeyMgmt::create_menus() { + file_menu_ = menuBar()->addMenu(_("File")); + file_menu_->addAction(open_key_file_act_); + file_menu_->addAction(close_act_); + + key_menu_ = menuBar()->addMenu(_("Key")); + generate_key_menu_ = key_menu_->addMenu(_("Generate Key")); + generate_key_menu_->addAction(generate_key_pair_act_); + generate_key_menu_->addAction(generate_subkey_act_); + + import_key_menu_ = key_menu_->addMenu(_("Import Key")); + import_key_menu_->addAction(import_key_from_file_act_); + import_key_menu_->addAction(import_key_from_clipboard_act_); + import_key_menu_->addAction(import_key_from_key_server_act_); + import_key_menu_->addAction(import_keys_from_key_package_act_); + + key_menu_->addAction(export_key_to_file_act_); + key_menu_->addAction(export_key_to_clipboard_act_); + key_menu_->addAction(export_key_as_open_ssh_format_); + key_menu_->addSeparator(); + key_menu_->addAction(delete_checked_keys_act_); } -void KeyMgmt::createToolBars() { +void KeyMgmt::create_tool_bars() { QToolBar* keyToolBar = addToolBar(_("Key")); keyToolBar->setObjectName("keytoolbar"); // add button with popup menu for import auto* generateToolButton = new QToolButton(this); - generateToolButton->setMenu(generateKeyMenu); + generateToolButton->setMenu(generate_key_menu_); generateToolButton->setPopupMode(QToolButton::InstantPopup); generateToolButton->setIcon(QIcon(":key_generate.png")); generateToolButton->setText(_("Generate")); @@ -287,7 +300,7 @@ void KeyMgmt::createToolBars() { // add button with popup menu for import auto* toolButton = new QToolButton(this); - toolButton->setMenu(importKeyMenu); + toolButton->setMenu(import_key_menu_); toolButton->setPopupMode(QToolButton::InstantPopup); toolButton->setIcon(QIcon(":key_import.png")); toolButton->setToolTip(_("Import key")); @@ -296,35 +309,35 @@ void KeyMgmt::createToolBars() { keyToolBar->addWidget(toolButton); keyToolBar->addSeparator(); - keyToolBar->addAction(deleteCheckedKeysAct); + keyToolBar->addAction(delete_checked_keys_act_); keyToolBar->addSeparator(); - keyToolBar->addAction(exportKeyToFileAct); - keyToolBar->addAction(exportKeyToClipboardAct); - keyToolBar->addAction(exportKeyAsOpenSSHFormat); + keyToolBar->addAction(export_key_to_file_act_); + keyToolBar->addAction(export_key_to_clipboard_act_); + keyToolBar->addAction(export_key_as_open_ssh_format_); } -void KeyMgmt::slotDeleteSelectedKeys() { - deleteKeysWithWarning(key_list_->getSelected()); +void KeyMgmt::SlotDeleteSelectedKeys() { + delete_keys_with_warning(key_list_->GetSelected()); } -void KeyMgmt::slotDeleteCheckedKeys() { - deleteKeysWithWarning(key_list_->getChecked()); +void KeyMgmt::SlotDeleteCheckedKeys() { + delete_keys_with_warning(key_list_->GetChecked()); } -void KeyMgmt::deleteKeysWithWarning(KeyIdArgsListPtr key_ids) { +void KeyMgmt::delete_keys_with_warning(KeyIdArgsListPtr uidList) { /** * TODO: Different Messages for private/public key, check if * more than one selected... compare to seahorse "delete-dialog" */ - if (key_ids->empty()) return; + if (uidList->empty()) return; QString keynames; - for (const auto& key_id : *key_ids) { + for (const auto& key_id : *uidList) { auto key = GpgKeyGetter::GetInstance().GetKey(key_id); - if (!key.good()) continue; - keynames.append(QString::fromStdString(key.name())); + if (!key.IsGood()) continue; + keynames.append(QString::fromStdString(key.GetName())); keynames.append("<i> <"); - keynames.append(QString::fromStdString(key.email())); + keynames.append(QString::fromStdString(key.GetEmail())); keynames.append("> </i><br/>"); } @@ -338,18 +351,18 @@ void KeyMgmt::deleteKeysWithWarning(KeyIdArgsListPtr key_ids) { QMessageBox::No | QMessageBox::Yes); if (ret == QMessageBox::Yes) { - GpgKeyOpera::GetInstance().DeleteKeys(std::move(key_ids)); - emit signalKeyStatusUpdated(); + GpgKeyOpera::GetInstance().DeleteKeys(std::move(uidList)); + emit SignalKeyStatusUpdated(); } } -void KeyMgmt::slotShowKeyDetails() { - auto keys_selected = key_list_->getSelected(); +void KeyMgmt::SlotShowKeyDetails() { + auto keys_selected = key_list_->GetSelected(); if (keys_selected->empty()) return; auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front()); - if (!key.good()) { + if (!key.IsGood()) { QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } @@ -357,8 +370,8 @@ void KeyMgmt::slotShowKeyDetails() { new KeyDetailsDialog(key); } -void KeyMgmt::slotExportKeyToKeyPackage() { - auto keys_checked = key_list_->getChecked(); +void KeyMgmt::SlotExportKeyToKeyPackage() { + auto keys_checked = key_list_->GetChecked(); if (keys_checked->empty()) { QMessageBox::critical( this, _("Forbidden"), @@ -367,12 +380,11 @@ void KeyMgmt::slotExportKeyToKeyPackage() { } auto dialog = new ExportKeyPackageDialog(std::move(keys_checked), this); dialog->exec(); - emit signalStatusBarChanged(QString(_("key(s) exported"))); + emit SignalStatusBarChanged(QString(_("key(s) exported"))); } -void KeyMgmt::slotExportKeyToClipboard() { - - auto keys_checked = key_list_->getChecked(); +void KeyMgmt::SlotExportKeyToClipboard() { + auto keys_checked = key_list_->GetChecked(); if (keys_checked->empty()) { QMessageBox::critical( this, _("Forbidden"), @@ -388,18 +400,18 @@ void KeyMgmt::slotExportKeyToClipboard() { QApplication::clipboard()->setText(QString::fromStdString(*key_export_data)); } -void KeyMgmt::slotGenerateKeyDialog() { +void KeyMgmt::SlotGenerateKeyDialog() { auto* keyGenDialog = new KeyGenDialog(this); keyGenDialog->show(); } void KeyMgmt::closeEvent(QCloseEvent* event) { - slotSaveWindowState(); + SlotSaveWindowState(); QMainWindow::closeEvent(event); } -void KeyMgmt::slotGenerateSubKey() { - auto keys_selected = key_list_->getSelected(); +void KeyMgmt::SlotGenerateSubKey() { + auto keys_selected = key_list_->GetSelected(); if (keys_selected->empty()) { QMessageBox::information( this, _("Invalid Operation"), @@ -407,23 +419,23 @@ void KeyMgmt::slotGenerateSubKey() { return; } const auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front()); - if (!key.good()) { + if (!key.IsGood()) { QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } - if (!key.is_private_key()) { + if (!key.IsPrivateKey()) { QMessageBox::critical(this, _("Invalid Operation"), _("If a key pair does not have a private key then " "it will not be able to generate sub-keys.")); return; } - auto dialog = new SubkeyGenerateDialog(key.id(), this); + auto dialog = new SubkeyGenerateDialog(key.GetId(), this); dialog->show(); } -void KeyMgmt::slotSaveWindowState() { +void KeyMgmt::SlotSaveWindowState() { auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); if (!settings.exists("window") || settings.lookup("window").getType() != libconfig::Setting::TypeGroup) @@ -465,12 +477,12 @@ void KeyMgmt::slotSaveWindowState() { key_management.add("window_state", libconfig::Setting::TypeString) = saveState().toBase64().toStdString(); - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } -void KeyMgmt::slotExportAsOpenSSHFormat() { +void KeyMgmt::SlotExportAsOpenSSHFormat() { ByteArrayPtr key_export_data = nullptr; - auto keys_checked = key_list_->getChecked(); + auto keys_checked = key_list_->GetChecked(); if (keys_checked->empty()) { QMessageBox::critical( @@ -496,12 +508,12 @@ void KeyMgmt::slotExportAsOpenSSHFormat() { } key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front()); - if (!key.good()) { + if (!key.IsGood()) { QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } - QString fileString = QString::fromStdString(key.name() + " " + key.email() + - "(" + key.id() + ").pub"); + QString fileString = QString::fromStdString( + key.GetName() + " " + key.GetEmail() + "(" + key.GetId() + ").pub"); QString file_name = QFileDialog::getSaveFileName( this, _("Export OpenSSH Key To File"), fileString, @@ -509,63 +521,40 @@ void KeyMgmt::slotExportAsOpenSSHFormat() { if (!file_name.isEmpty()) { write_buffer_to_file(file_name.toStdString(), *key_export_data); - emit signalStatusBarChanged(QString(_("key(s) exported"))); + emit SignalStatusBarChanged(QString(_("key(s) exported"))); } } -void KeyMgmt::slotImportKeyPackage() { +void KeyMgmt::SlotImportKeyPackage() { + + LOG(INFO) << "Importing key package..."; + auto key_package_file_name = QFileDialog::getOpenFileName( this, _("Import Key Package"), {}, QString(_("Key Package")) + " (*.gfepack);;All Files (*)"); - if (key_package_file_name.isEmpty()) return; - - auto encrypted_data = - read_all_data_in_file(key_package_file_name.toStdString()); - - if (encrypted_data.empty()) { - QMessageBox::critical(this, _("Error"), - _("No data was read from the key package.")); - return; - }; - auto key_file_name = QFileDialog::getOpenFileName( this, _("Import Key Package Passphrase File"), {}, QString(_("Key Package Passphrase File")) + " (*.key);;All Files (*)"); - auto passphrase = read_all_data_in_file(key_file_name.toStdString()); - - LOG(INFO) << "passphrase size" << passphrase.size(); - if (passphrase.size() != 256) { - QMessageBox::critical( - this, _("Wrong Passphrase"), - _("Please double check the passphrase you entered is correct.")); + if(key_package_file_name.isEmpty() || key_file_name.isEmpty()) return; - } - auto hash_key = QCryptographicHash::hash( - QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256); - auto encoded = QByteArray::fromStdString(encrypted_data); - QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, - QAESEncryption::Padding::ISO); + GpgImportInformation info; - auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key)); - auto key_data = QByteArray::fromBase64(decoded); + LOG(INFO) << "Importing key package: " << key_package_file_name.toStdString(); - if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) && - !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) { - QMessageBox::critical( - this, _("Wrong Passphrase"), - _("Please double check the passphrase you entered is correct.")); - return; - } + if (KeyPackageOperator::ImportKeyPackage(key_package_file_name.toStdString(), + key_file_name.toStdString(), info)) { + emit SignalStatusBarChanged(QString(_("key(s) imported"))); + emit SignalKeyStatusUpdated(); - auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString()); - auto info = - GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr)); - - auto dialog = new KeyImportDetailDialog(info, false, this); - dialog->exec(); + auto dialog = new KeyImportDetailDialog(info, false, this); + dialog->exec(); + } else { + QMessageBox::critical(this, _("Error"), + _("An error occur in importing key package.")); + } } } // namespace GpgFrontend::UI diff --git a/src/ui/KeyMgmt.h b/src/ui/KeyMgmt.h index e3f250eb..ad58a5aa 100755 --- a/src/ui/KeyMgmt.h +++ b/src/ui/KeyMgmt.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,100 +8,181 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef __KEYMGMT_H__ #define __KEYMGMT_H__ -#include "KeyImportDetailDialog.h" -#include "KeyServerImportDialog.h" +#include "import_export/KeyImportDetailDialog.h" +#include "import_export/KeyServerImportDialog.h" #include "ui/GpgFrontendUI.h" -#include "ui/keygen/KeygenDialog.h" +#include "ui/key_generate/KeygenDialog.h" #include "ui/keypair_details/KeyDetailsDialog.h" #include "ui/widgets/KeyList.h" namespace GpgFrontend::UI { +/** + * @brief + * + */ class KeyMgmt : public QMainWindow { Q_OBJECT public: + /** + * @brief Construct a new Key Mgmt object + * + * @param parent + */ explicit KeyMgmt(QWidget* parent = nullptr); public slots: - void slotGenerateSubKey(); - - void slotExportKeyToKeyPackage(); - - void slotExportKeyToClipboard(); - - void slotExportAsOpenSSHFormat(); - - void slotDeleteSelectedKeys(); - - void slotDeleteCheckedKeys(); - - void slotGenerateKeyDialog(); - - void slotShowKeyDetails(); - - void slotSaveWindowState(); - - void slotImportKeyPackage(); + /** + * @brief + * + */ + void SlotGenerateSubKey(); + + /** + * @brief + * + */ + void SlotExportKeyToKeyPackage(); + + /** + * @brief + * + */ + void SlotExportKeyToClipboard(); + + /** + * @brief + * + */ + void SlotExportAsOpenSSHFormat(); + + /** + * @brief + * + */ + void SlotDeleteSelectedKeys(); + + /** + * @brief + * + */ + void SlotDeleteCheckedKeys(); + + /** + * @brief + * + */ + void SlotGenerateKeyDialog(); + + /** + * @brief + * + */ + void SlotShowKeyDetails(); + + /** + * @brief + * + */ + void SlotSaveWindowState(); + + /** + * @brief + * + */ + void SlotImportKeyPackage(); signals: - void signalStatusBarChanged(QString); + /** + * @brief + * + */ + void SignalStatusBarChanged(QString); - void signalKeyStatusUpdated(); + /** + * @brief + * + */ + void SignalKeyStatusUpdated(); private: - void createMenus(); - - void createActions(); - - void createToolBars(); - - void deleteKeysWithWarning(GpgFrontend::KeyIdArgsListPtr uidList); - - KeyList* key_list_; - QMenu* fileMenu{}; - QMenu* keyMenu{}; - QMenu* generateKeyMenu{}; - QMenu* importKeyMenu{}; - QAction* openKeyFileAct{}; - QAction* exportKeyToFileAct{}; - QAction* exportKeyAsOpenSSHFormat{}; - QAction* exportKeyToClipboardAct{}; - QAction* deleteCheckedKeysAct{}; - QAction* deleteSelectedKeysAct{}; - QAction* generateKeyDialogAct{}; - QAction* generateKeyPairAct{}; - QAction* generateSubKeyAct{}; - QAction* importKeyFromClipboardAct{}; - QAction* importKeyFromFileAct{}; - QAction* importKeyFromKeyServerAct{}; - QAction* importKeysFromKeyPackageAct{}; - QAction* closeAct{}; - QAction* showKeyDetailsAct{}; - KeyServerImportDialog* importDialog{}; + /** + * @brief Create a menus object + * + */ + void create_menus(); + + /** + * @brief Create a actions object + * + */ + void create_actions(); + + /** + * @brief Create a tool bars object + * + */ + void create_tool_bars(); + + /** + * @brief + * + * @param uidList + */ + void delete_keys_with_warning(GpgFrontend::KeyIdArgsListPtr uidList); + + KeyList* key_list_; ///< + QMenu* file_menu_{}; ///< + QMenu* key_menu_{}; ///< + QMenu* generate_key_menu_{}; ///< + QMenu* import_key_menu_{}; ///< + QAction* open_key_file_act_{}; ///< + QAction* export_key_to_file_act_{}; ///< + QAction* export_key_as_open_ssh_format_{}; ///< + QAction* export_key_to_clipboard_act_{}; ///< + QAction* delete_checked_keys_act_{}; ///< + QAction* delete_selected_keys_act_{}; ///< + QAction* generate_key_dialog_act_{}; ///< + QAction* generate_key_pair_act_{}; ///< + QAction* generate_subkey_act_{}; ///< + QAction* import_key_from_clipboard_act_{}; ///< + QAction* import_key_from_file_act_{}; ///< + QAction* import_key_from_key_server_act_{}; ///< + QAction* import_keys_from_key_package_act_{}; ///< + QAction* close_act_{}; ///< + QAction* show_key_details_act_{}; ///< + KeyServerImportDialog* import_dialog_{}; ///< protected: + /** + * @brief + * + * @param event + */ void closeEvent(QCloseEvent* event) override; }; diff --git a/src/ui/KeyServerImportDialog.h b/src/ui/KeyServerImportDialog.h deleted file mode 100644 index e3761f5c..00000000 --- a/src/ui/KeyServerImportDialog.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __KEY_SERVER_IMPORT_DIALOG_H__ -#define __KEY_SERVER_IMPORT_DIALOG_H__ - -#include "KeyImportDetailDialog.h" -#include "gpg/GpgContext.h" -#include "ui/GpgFrontendUI.h" -#include "ui/widgets/KeyList.h" - -namespace GpgFrontend::UI { - -class KeyServerImportDialog : public QDialog { - Q_OBJECT - - public: - KeyServerImportDialog(bool automatic, QWidget* parent); - - explicit KeyServerImportDialog(QWidget* parent); - - void slotImport(const KeyIdArgsListPtr& keys); - - void slotImport(const QStringList& keyIds, const QUrl& keyserverUrl); - - signals: - void signalKeyImported(); - - private slots: - - void slotImport(); - - void slotSearchFinished(); - - void slotImportFinished(const QString& keyid); - - void slotSearch(); - - void slotSaveWindowState(); - - private: - void createKeysTable(); - - void setMessage(const QString& text, bool error); - - void importKeys(ByteArrayPtr in_data); - - void setLoading(bool status); - - QPushButton* createButton(const QString& text, const char* member); - - QComboBox* createComboBox(); - - bool mAutomatic = false; - - QLineEdit* searchLineEdit{}; - QComboBox* keyServerComboBox{}; - QProgressBar* waitingBar; - QLabel* searchLabel{}; - QLabel* keyServerLabel{}; - QLabel* message{}; - QLabel* icon{}; - QPushButton* closeButton{}; - QPushButton* importButton{}; - QPushButton* searchButton{}; - QTableWidget* keysTable{}; - QNetworkAccessManager* qnam{}; -}; - -} // namespace GpgFrontend::UI - -#endif // __KEY_SERVER_IMPORT_DIALOG_H__ diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp deleted file mode 100644 index 2af6da78..00000000 --- a/src/ui/MainWindow.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "MainWindow.h" - -#include "ui/UserInterfaceUtils.h" -#ifdef RELEASE -#include "ui/function/VersionCheckThread.h" -#endif -#include "ui/SignalStation.h" -#include "ui/settings/GlobalSettingStation.h" - -namespace GpgFrontend::UI { - -MainWindow::MainWindow() { - this->setMinimumSize(1200, 700); - this->setWindowTitle(qApp->applicationName()); -} - -void MainWindow::init() noexcept { - try { - networkAccessManager = new QNetworkAccessManager(this); - - /* get path where app was started */ - setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - - edit = new TextEdit(this); - setCentralWidget(edit); - - /* the list of Keys available*/ - mKeyList = new KeyList( - KeyMenuAbility::REFRESH | KeyMenuAbility::UNCHECK_ALL, this); - - infoBoard = new InfoBoardWidget(this); - - /* List of binary Attachments */ - attachmentDockCreated = false; - - /* Variable containing if restart is needed */ - this->slotSetRestartNeeded(false); - - createActions(); - createMenus(); - createToolBars(); - createStatusBar(); - createDockWindows(); - - connect(edit->tabWidget, SIGNAL(currentChanged(int)), this, - SLOT(slotDisableTabActions(int))); - connect(SignalStation::GetInstance(), - &SignalStation::signalRefreshStatusBar, this, - [=](const QString& message, int timeout) { - statusBar()->showMessage(message, timeout); - }); - - mKeyList->addMenuAction(appendSelectedKeysAct); - mKeyList->addMenuAction(copyMailAddressToClipboardAct); - mKeyList->addSeparator(); - mKeyList->addMenuAction(showKeyDetailsAct); - - restoreSettings(); - - // open filename if provided as first command line parameter - QStringList args = qApp->arguments(); - if (args.size() > 1) { - if (!args[1].startsWith("-")) { - if (QFile::exists(args[1])) edit->loadFile(args[1]); - } - } - edit->curTextPage()->setFocus(); - - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - if (!settings.exists("wizard") || - settings.lookup("wizard").getType() != libconfig::Setting::TypeGroup) - settings.add("wizard", libconfig::Setting::TypeGroup); - - auto& wizard = settings["wizard"]; - - // Show wizard, if the don't show wizard message box wasn't checked - // and keylist doesn't contain a private key - - if (!wizard.exists("show_wizard")) - wizard.add("show_wizard", libconfig::Setting::TypeBoolean) = true; - - bool show_wizard = true; - wizard.lookupValue("show_wizard", show_wizard); - - LOG(INFO) << "wizard show_wizard" << show_wizard; - - if (show_wizard) { - slotStartWizard(); - } - - emit loaded(); - - // if not prohibit update checking - if (!prohibit_update_checking_) { -#ifdef RELEASE - auto version_thread = new VersionCheckThread(); - - connect(version_thread, SIGNAL(finished()), version_thread, - SLOT(deleteLater())); - connect(version_thread, &VersionCheckThread::upgradeVersion, this, - &MainWindow::slotVersionUpgrade); - - version_thread->start(); -#endif - } - - } catch (...) { - LOG(FATAL) << _("Critical error occur while loading GpgFrontend."); - QMessageBox::critical(nullptr, _("Loading Failed"), - _("Critical error occur while loading GpgFrontend.")); - QCoreApplication::quit(); - exit(0); - } -} - -void MainWindow::restoreSettings() { - LOG(INFO) << _("Called"); - - try { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - if (!settings.exists("window") || - settings.lookup("window").getType() != libconfig::Setting::TypeGroup) - settings.add("window", libconfig::Setting::TypeGroup); - - auto& window = settings["window"]; - - if (!window.exists("window_state")) - window.add("window_state", libconfig::Setting::TypeString) = - saveState().toBase64().toStdString(); - - std::string window_state = settings.lookup("window.window_state"); - // state sets pos & size of dock-widgets - this->restoreState( - QByteArray::fromBase64(QByteArray::fromStdString(window_state))); - - if (!window.exists("window_save")) - window.add("window_save", libconfig::Setting::TypeBoolean) = true; - - bool window_save; - window.lookupValue("window_save", window_save); - - // Restore window size & location - if (window_save) { - if (!window.exists("window_pos")) - window.add("window_pos", libconfig::Setting::TypeGroup); - - auto& window_pos = window["window_pos"]; - - if (!window_pos.exists("x")) - window_pos.add("x", libconfig::Setting::TypeInt) = 100; - - if (!window_pos.exists("y")) - window_pos.add("y", libconfig::Setting::TypeInt) = 100; - - int x, y; - window_pos.lookupValue("x", x); - window_pos.lookupValue("y", y); - - auto pos = QPoint(x, y); - - if (!window.exists("window_size")) - window.add("window_size", libconfig::Setting::TypeGroup); - - auto& window_size = window["window_size"]; - - if (!window_size.exists("width")) - window_size.add("width", libconfig::Setting::TypeInt) = 800; - - if (!window_size.exists("height")) - window_size.add("height", libconfig::Setting::TypeInt) = 450; - - int width, height; - window_size.lookupValue("width", width); - window_size.lookupValue("height", height); - - auto size = QSize(width, height); - this->resize(size); - this->move(pos); - } else { - this->resize(QSize(800, 450)); - this->move(QPoint(100, 100)); - } - - if (!window.exists("icon_size")) - window.add("icon_size", libconfig::Setting::TypeGroup); - - auto& icon_size = window["icon_size"]; - - if (!icon_size.exists("width")) - icon_size.add("width", libconfig::Setting::TypeInt) = 24; - - if (!icon_size.exists("height")) - icon_size.add("height", libconfig::Setting::TypeInt) = 24; - - int width = icon_size["width"], height = icon_size["height"]; - LOG(INFO) << "icon_size" << width << height; - - // info board font size - if (!window.exists("info_font_size")) - window.add("info_font_size", libconfig::Setting::TypeInt) = 10; - - // icons ize - this->setIconSize(QSize(width, height)); - importButton->setIconSize(QSize(width, height)); - - if (!settings.exists("keyserver") || - settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup) - settings.add("keyserver", libconfig::Setting::TypeGroup); - - auto& keyserver = settings["keyserver"]; - - if (!keyserver.exists("server_list")) { - keyserver.add("server_list", libconfig::Setting::TypeList); - - auto& server_list = keyserver["server_list"]; - server_list.add(libconfig::Setting::TypeString) = "http://keys.gnupg.net"; - server_list.add(libconfig::Setting::TypeString) = - "https://keyserver.ubuntu.com"; - server_list.add(libconfig::Setting::TypeString) = - "http://pool.sks-keyservers.net"; - } - - if (!keyserver.exists("default_server")) { - keyserver.add("default_server", libconfig::Setting::TypeString) = - "https://keyserver.ubuntu.com"; - } - - if (!window.exists("icon_style")) { - window.add("icon_style", libconfig::Setting::TypeInt) = - Qt::ToolButtonTextUnderIcon; - } - - int s_icon_style = window.lookup("icon_style"); - - // icon_style - auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); - this->setToolButtonStyle(icon_style); - importButton->setToolButtonStyle(icon_style); - - if (!settings.exists("general") || - settings.lookup("general").getType() != libconfig::Setting::TypeGroup) - settings.add("general", libconfig::Setting::TypeGroup); - - auto& general = settings["general"]; - - if (!general.exists("save_key_checked")) { - general.add("save_key_checked", libconfig::Setting::TypeBoolean) = true; - } - - if (!general.exists("non_ascii_when_export")) { - general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) = - true; - } - - bool save_key_checked = true; - general.lookupValue("save_key_checked", save_key_checked); - - // Checked Keys - if (save_key_checked) { - if (!general.exists("save_key_checked_key_ids")) { - general.add("save_key_checked_key_ids", libconfig::Setting::TypeList); - } - auto key_ids_ptr = std::make_unique<KeyIdArgsList>(); - auto& save_key_checked_key_ids = general["save_key_checked_key_ids"]; - const auto key_ids_size = - general.lookup("save_key_checked_key_ids").getLength(); - for (auto i = 0; i < key_ids_size; i++) { - std::string key_id = save_key_checked_key_ids[i]; - LOG(INFO) << "get checked key id" << key_id; - key_ids_ptr->push_back(key_id); - } - mKeyList->setChecked(std::move(key_ids_ptr)); - } - - auto& smtp = settings["smtp"]; - - if (!smtp.exists("enable")) { - smtp.add("enable", libconfig::Setting::TypeBoolean) = true; - } - - prohibit_update_checking_ = false; - try { - prohibit_update_checking_ = - settings.lookup("network.prohibit_update_checking"); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") - << _("prohibit_update_checking"); - } - - } catch (...) { - LOG(ERROR) << "cannot resolve settings"; - } - - GlobalSettingStation::GetInstance().Sync(); -} - -void MainWindow::saveSettings() { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - try { - // window position and size - settings["window"]["window_state"] = saveState().toBase64().toStdString(); - settings["window"]["window_pos"]["x"] = pos().x(); - settings["window"]["window_pos"]["y"] = pos().y(); - - settings["window"]["window_size"]["width"] = size().width(); - settings["window"]["window_size"]["height"] = size().height(); - - bool save_key_checked = settings.lookup("general.save_key_checked"); - - // keyid-list of private checked keys - if (save_key_checked) { - auto& key_ids = settings.lookup("general.save_key_checked_key_ids"); - const int key_ids_size = key_ids.getLength(); - for (auto i = 0; i < key_ids_size; i++) key_ids.remove(i); - auto key_ids_need_to_store = mKeyList->getChecked(); - - for (size_t i = 0; i < key_ids_need_to_store->size(); i++) { - std::string key_id = (*key_ids_need_to_store)[i]; - key_ids.add(libconfig::Setting::TypeString) = key_id; - } - - } else { - settings["general"].remove("save_key_checked"); - } - } catch (...) { - LOG(ERROR) << "cannot save settings"; - }; - - GlobalSettingStation::GetInstance().Sync(); -} - -void MainWindow::closeAttachmentDock() { - if (!attachmentDockCreated) { - return; - } - attachmentDock->close(); - attachmentDock->deleteLater(); - attachmentDockCreated = false; -} - -void MainWindow::closeEvent(QCloseEvent* event) { - /* - * ask to save changes, if there are - * modified documents in any tab - */ - if (edit->maybeSaveAnyTab()) { - saveSettings(); - event->accept(); - } else { - event->ignore(); - } - - // clear password from memory - // GpgContext::GetInstance().clearPasswordCache(); -} - -} // namespace GpgFrontend::UI diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h deleted file mode 100644 index 5f9d9b50..00000000 --- a/src/ui/MainWindow.h +++ /dev/null @@ -1,406 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __GPGWIN_H__ -#define __GPGWIN_H__ - -#include "gpg/GpgConstants.h" -#include "gpg/result_analyse/DecryptResultAnalyse.h" -#include "gpg/result_analyse/EncryptResultAnalyse.h" -#include "gpg/result_analyse/SignResultAnalyse.h" -#include "ui/FindWidget.h" -#include "ui/GpgFrontendUI.h" -#include "ui/KeyMgmt.h" -#include "ui/KeyUploadDialog.h" -#include "ui/WaitingDialog.h" -#include "ui/Wizard.h" -#include "ui/help/AboutDialog.h" -#include "ui/settings/SettingsDialog.h" -#include "ui/widgets/InfoBoardWidget.h" -#include "ui/widgets/TextEdit.h" - -namespace GpgFrontend::UI { -/** - * @brief - * - */ -class MainWindow : public QMainWindow { - Q_OBJECT - - public: - /** - * @brief - * - */ - MainWindow(); - - /** - * ONLY Called from main() - */ - void init() noexcept; - - signals: - void loaded(); - - public slots: - - void slotSetStatusBarText(const QString& text); - - protected: - /** - * @details Close event shows a save dialog, if there are unsaved documents on - * exit. - * @param event - */ - void closeEvent(QCloseEvent* event) override; - - public slots: - - /** - * @details Open a new tab for path - */ - void slotOpenFile(QString& path); - - /** - * @details Open dialog for encrypting file. - */ - void slotFileEncrypt(); - - /** - * @details Open dialog for decrypting file. - */ - void slotFileDecrypt(); - - /** - * @details Open dialog for signing file. - */ - void slotFileSign(); - - /** - * @details Open dialog for verifying file. - */ - void slotFileVerify(); - - /** - * @details Open dialog for signing file. - */ - void slotFileEncryptSign(); - - /** - * @details Open dialog for verifying file. - */ - void slotFileDecryptVerify(); - - private slots: - - /** - * @details encrypt the text of currently active textedit-page - * with the currently checked keys - */ - void slotEncrypt(); - - /** - * @details encrypt and sign the text of currently active textedit-page - * with the currently checked keys - */ - void slotEncryptSign(); - - /** - * @details Show a passphrase dialog and decrypt the text of currently active - * tab. - */ - void slotDecrypt(); - - /** - * @details Sign the text of currently active tab with the checked private - * keys - */ - void slotSign(); - - /** - * @details Verify the text of currently active tab and show verify - * information. If document is signed with a key, which is not in keylist, - * show import missing key from keyserver in Menu of verifynotification. - */ - void slotVerify(); - - /** - * @details decrypt and verify the text of currently active textedit-page - * with the currently checked keys - */ - void slotDecryptVerify(); - - /** - * @details Show the details of the first of the first of selected keys - */ - void slotShowKeyDetails(); - - /** - * @details Refresh key information of selected keys from default keyserver - */ - void refreshKeysFromKeyserver(); - - /** - * @details upload the selected key to the keyserver - */ - void uploadKeyToServer(); - - /** - * @details Open find widget. - */ - void slotFind(); - - /** - * @details start the wizard - */ - void slotStartWizard(); - - /** - * @details Import keys from currently active tab to keylist if possible. - */ - void slotImportKeyFromEdit(); - - /** - * @details Append the selected keys to currently active textedit. - */ - void slotAppendSelectedKeys(); - - /** - * @details Copy the mailaddress of selected key to clipboard. - * Method for keylists contextmenu. - */ - void slotCopyMailAddressToClipboard(); - - /** - * @details Open key management dialog. - */ - void slotOpenKeyManagement(); - - /** - * @details Open File Opera Tab - */ - void slotOpenFileTab(); - - /** - * @details Open settings-dialog. - */ - void slotOpenSettingsDialog(); - - // /** - // * @details Show a warn message in status bar, if there are files in - // * attachment folder. - // */ - // void slotCheckAttachmentFolder(); - - /** - * @details Replace double linebreaks by single linebreaks in currently active - * tab. - */ - void slotCleanDoubleLinebreaks(); - - /** - * @details Cut the existing PGP header and footer from current tab. - */ - void slotCutPgpHeader(); - - /** - * @details Add PGP header and footer to current tab. - */ - void slotAddPgpHeader(); - - /** - * @details Disable tab related actions, if number of tabs is 0. - * @param number number of the opened tabs and -1, if no tab is opened - */ - void slotDisableTabActions(int number); - - /** - * @details get value of member restartNeeded to needed. - * @param needed true, if application has to be restarted - */ - void slotSetRestartNeeded(bool needed); - - /** - * @details called when need to upgrade. - */ - void slotVersionUpgrade(const SoftwareVersion& version); - - private: - /** - * @details Create actions for the main-menu and the context-menu of the - * keylist. - */ - void createActions(); - - /** - * @details create the menu of the main-window. - */ - void createMenus(); - - /** - * @details Create edit-, crypt- and key-toolbars. - */ - void createToolBars(); - - /** - * @details Create statusbar of mainwindow. - */ - void createStatusBar(); - - /** - * @details Create keylist- and attachment-dockwindows. - */ - void createDockWindows(); - - /** - * @details Create attachment-dockwindow. - */ - void createAttachmentDock(); - - /** - * @details close attachment-dockwindow. - */ - void closeAttachmentDock(); - - /** - * @details Load settings from ini-file. - */ - void restoreSettings(); - - /** - * @details Save settings to ini-file. - */ - void saveSettings(); - -#ifdef ADVANCE_SUPPORT - - /** - * @details Get full crypto text - */ - QString getCryptText(const QString& shortenCryptoText); - - /** - * @details Shorten crypto text - */ - void shortenCryptText(); - -#endif - - /** - * @brief return true, if restart is needed - */ - [[nodiscard]] bool getRestartNeeded() const; - - TextEdit* edit{}; /** Tabwidget holding the edit-windows */ - QMenu* fileMenu{}; /** Submenu for file-operations*/ - QMenu* editMenu{}; /** Submenu for text-operations*/ - QMenu* cryptMenu{}; /** Submenu for crypt-operations */ - QMenu* helpMenu{}; /** Submenu for help-operations */ - QMenu* keyMenu{}; /** Submenu for key-operations */ - QMenu* viewMenu{}; /** Submenu for view operations */ - QMenu* importKeyMenu{}; /** Sumenu for import operations */ -#ifdef SMTP_SUPPORT - QMenu* emailMenu{}; /** Sumenu for email operations */ -#endif - - QMenu* steganoMenu{}; /** Submenu for steganographic operations*/ - QToolBar* cryptToolBar{}; /** Toolbar holding crypt actions */ - QToolBar* fileToolBar{}; /** Toolbar holding file actions */ - QToolBar* editToolBar{}; /** Toolbar holding edit actions */ - QToolBar* specialEditToolBar{}; /** Toolbar holding special edit actions */ - QToolBar* keyToolBar{}; /** Toolbar holding key operations */ - QToolBar* emailToolBar{}; /** Toolbar holding key operations */ - QToolButton* - importButton{}; /** Toolbutton for import dropdown menu in toolbar */ - QDockWidget* keyListDock{}; /** Encrypt Dock*/ - QDockWidget* attachmentDock{}; /** Attachment Dock */ - QDockWidget* infoBoardDock{}; - - QAction* newTabAct{}; /** Action to create new tab */ - QAction* switchTabUpAct{}; /** Action to switch tab up*/ - QAction* switchTabDownAct{}; /** Action to switch tab down */ - QAction* openAct{}; /** Action to open file */ - QAction* browserAct{}; /** Action to open file browser*/ - QAction* saveAct{}; /** Action to save file */ - QAction* saveAsAct{}; /** Action to save file as */ - QAction* printAct{}; /** Action to print */ - QAction* closeTabAct{}; /** Action to print */ - QAction* quitAct{}; /** Action to quit application */ - QAction* encryptAct{}; /** Action to encrypt text */ - QAction* encryptSignAct{}; /** Action to encrypt and sign text */ - QAction* decryptVerifyAct{}; /** Action to encrypt and sign text */ - QAction* decryptAct{}; /** Action to decrypt text */ - QAction* signAct{}; /** Action to sign text */ - QAction* verifyAct{}; /** Action to verify text */ - QAction* importKeyFromEditAct{}; /** Action to import key from edit */ - QAction* - cleanDoubleLinebreaksAct{}; /** Action to remove double line breaks */ - - QAction* - appendSelectedKeysAct{}; /** Action to append selected keys to edit */ - QAction* - copyMailAddressToClipboardAct{}; /** Action to copy mail to clipboard */ - QAction* openKeyManagementAct{}; /** Action to open key management */ - QAction* copyAct{}; /** Action to copy text */ - QAction* quoteAct{}; /** Action to quote text */ - QAction* cutAct{}; /** Action to cut text */ - QAction* pasteAct{}; /** Action to paste text */ - QAction* selectAllAct{}; /** Action to select whole text */ - QAction* findAct{}; /** Action to find text */ - QAction* undoAct{}; /** Action to undo last action */ - QAction* redoAct{}; /** Action to redo last action */ - QAction* zoomInAct{}; /** Action to zoom in */ - QAction* zoomOutAct{}; /** Action to zoom out */ - QAction* aboutAct{}; /** Action to open about dialog */ - QAction* checkUpdateAct{}; /** Action to open about dialog */ - QAction* translateAct{}; /** Action to open about dialog */ - QAction* openSettingsAct{}; /** Action to open settings dialog */ - QAction* showKeyDetailsAct{}; /** Action to open key-details dialog */ - QAction* startWizardAct{}; /** Action to open the wizard */ - QAction* cutPgpHeaderAct{}; /** Action for cutting the PGP header */ - QAction* addPgpHeaderAct{}; /** Action for adding the PGP header */ - -#ifdef SMTP_SUPPORT - QAction* sendMailAct{}; /** Action for sending a email */ -#endif - - QAction* importKeyFromFileAct{}; - QAction* importKeyFromClipboardAct{}; - QAction* importKeyFromKeyServerAct{}; - - QLabel* statusBarIcon{}; - - KeyList* mKeyList{}; - InfoBoardWidget* infoBoard{}; - - QNetworkAccessManager* networkAccessManager{}; - - bool attachmentDockCreated{}; - bool restartNeeded{}; - bool prohibit_update_checking_ = false; -}; - -} // namespace GpgFrontend::UI - -#endif // __GPGWIN_H__ diff --git a/src/ui/QuitDialog.h b/src/ui/QuitDialog.h deleted file mode 100755 index 2b1dd37f..00000000 --- a/src/ui/QuitDialog.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __QUITDIALOG_H__ -#define __QUITDIALOG_H__ - -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { - -class QuitDialog : public QDialog { - Q_OBJECT - - public: - QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs); - - [[nodiscard]] bool isDiscarded() const; - - QList<int> getTabIdsToSave(); - - private slots: - - void slotMyDiscard(); - - private: - bool discarded; - QTableWidget* mFileList; -}; - -} // namespace GpgFrontend::UI - -#endif // __QUITDIALOG_H__ diff --git a/src/ui/ShowCopyDialog.cpp b/src/ui/ShowCopyDialog.cpp deleted file mode 100644 index 0503e079..00000000 --- a/src/ui/ShowCopyDialog.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "ui/ShowCopyDialog.h" - -namespace GpgFrontend::UI { - -ShowCopyDialog::ShowCopyDialog(const QString& text, const QString& info, - QWidget* parent) - : QDialog(parent) { - textEdit = new QTextEdit(); - textEdit->setReadOnly(true); - textEdit->setLineWrapMode(QTextEdit::WidgetWidth); - textEdit->setText(text); - copyButton = new QPushButton("Copy"); - connect(copyButton, SIGNAL(clicked(bool)), this, SLOT(slotCopyText())); - - infoLabel = new QLabel(); - infoLabel->setText(info); - infoLabel->setWordWrap(true); - - auto* layout = new QVBoxLayout(); - layout->addWidget(textEdit); - layout->addWidget(copyButton); - layout->addWidget(infoLabel); - - this->setWindowTitle("Short Ciphertext"); - this->resize(320, 120); - this->setModal(true); - this->setLayout(layout); -} - -void ShowCopyDialog::slotCopyText() { - QClipboard* cb = QApplication::clipboard(); - cb->setText(textEdit->toPlainText()); -} - -} // namespace GpgFrontend::UI diff --git a/src/ui/ShowCopyDialog.h b/src/ui/ShowCopyDialog.h deleted file mode 100644 index fefef7ab..00000000 --- a/src/ui/ShowCopyDialog.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H -#define GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H - -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { - -class ShowCopyDialog : public QDialog { - Q_OBJECT - public: - explicit ShowCopyDialog(const QString& text, const QString& info = "", - QWidget* parent = nullptr); - - private slots: - - void slotCopyText(); - - private: - QLabel* infoLabel; - QTextEdit* textEdit; - QPushButton* copyButton; -}; - -} // namespace GpgFrontend::UI - -#endif // GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H diff --git a/src/ui/SignalStation.cpp b/src/ui/SignalStation.cpp index 0c550f88..045b63f5 100644 --- a/src/ui/SignalStation.cpp +++ b/src/ui/SignalStation.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/ui/SignalStation.h b/src/ui/SignalStation.h index 394a7323..dbf978be 100644 --- a/src/ui/SignalStation.h +++ b/src/ui/SignalStation.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,20 +34,45 @@ namespace GpgFrontend::UI { +/** + * @brief + * + */ class SignalStation : public QObject { Q_OBJECT static std::unique_ptr<SignalStation> _instance; public: + /** + * @brief Get the Instance object + * + * @return SignalStation* + */ static SignalStation* GetInstance(); signals: - void KeyDatabaseRefresh(); + /** + * @brief + * + */ + void SignalKeyDatabaseRefresh(); - void signalRefreshInfoBoard(const QString& text, + /** + * @brief + * + * @param text + * @param verify_label_status + */ + void SignalRefreshInfoBoard(const QString& text, InfoBoardStatus verify_label_status); - void signalRefreshStatusBar(const QString& message, int timeout); + /** + * @brief + * + * @param message + * @param timeout + */ + void SignalRefreshStatusBar(const QString& message, int timeout); }; } // namespace GpgFrontend::UI diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index 967dcc32..8353d28b 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,23 +30,24 @@ #include <utility> -#include "gpg/result_analyse/ResultAnalyse.h" +#include "core/function/FileOperator.h" +#include "core/function/result_analyse/GpgResultAnalyse.h" #include "ui/SignalStation.h" -#include "ui/WaitingDialog.h" -#include "ui/settings/GlobalSettingStation.h" -#include "ui/smtp/SendMailDialog.h" +#include "ui/dialog/WaitingDialog.h" +#include "ui/mail/SendMailDialog.h" +#include "core/function/GlobalSettingStation.h" #include "ui/widgets/InfoBoardWidget.h" #include "ui/widgets/TextEdit.h" namespace GpgFrontend::UI { std::unique_ptr<GpgFrontend::UI::CommonUtils> - GpgFrontend::UI::CommonUtils::_instance = nullptr; + GpgFrontend::UI::CommonUtils::instance_ = nullptr; #ifdef SMTP_SUPPORT -void send_an_email(QWidget* parent, InfoBoardWidget* info_board, - const QString& text, bool attach_signature) { - info_board->addOptionalAction(_("Send Encrypted Mail"), [=]() { +void send_an_email(QWidget *parent, InfoBoardWidget *info_board, + const QString &text, bool attach_signature) { + info_board->AddOptionalAction(_("Send Encrypted Mail"), [=]() { bool smtp_enabled = false; try { smtp_enabled = GlobalSettingStation::GetInstance().GetUISettings().lookup( @@ -52,8 +57,8 @@ void send_an_email(QWidget* parent, InfoBoardWidget* info_board, } if (smtp_enabled) { auto dialog = new SendMailDialog(text, parent); - dialog->setContentEncryption(false); - dialog->setAttachSignature(attach_signature); + dialog->SetContentEncryption(false); + dialog->SetAttachSignature(attach_signature); dialog->show(); } else { QMessageBox::warning(nullptr, _("Function Disabled"), @@ -64,17 +69,17 @@ void send_an_email(QWidget* parent, InfoBoardWidget* info_board, } #endif -void show_verify_details(QWidget* parent, InfoBoardWidget* info_board, - GpgError error, const GpgVerifyResult& verify_result) { +void show_verify_details(QWidget *parent, InfoBoardWidget *info_board, + GpgError error, const GpgVerifyResult &verify_result) { // take out result - info_board->resetOptionActionsMenu(); - info_board->addOptionalAction("Show Verify Details", [=]() { + info_board->ResetOptionActionsMenu(); + info_board->AddOptionalAction("Show Verify Details", [=]() { VerifyDetailsDialog(parent, error, verify_result); }); } -void import_unknown_key_from_keyserver(QWidget* parent, - const VerifyResultAnalyse& verify_res) { +void import_unknown_key_from_keyserver( + QWidget *parent, const GpgVerifyResultAnalyse &verify_res) { QMessageBox::StandardButton reply; reply = QMessageBox::question( parent, _("Public key not found locally"), @@ -85,57 +90,57 @@ void import_unknown_key_from_keyserver(QWidget* parent, if (reply == QMessageBox::Yes) { auto dialog = KeyServerImportDialog(true, parent); auto key_ids = std::make_unique<KeyIdArgsList>(); - auto* signature = verify_res.GetSignatures(); + auto *signature = verify_res.GetSignatures(); while (signature != nullptr) { LOG(INFO) << "signature fpr" << signature->fpr; key_ids->push_back(signature->fpr); signature = signature->next; } dialog.show(); - dialog.slotImport(key_ids); + dialog.SlotImport(key_ids); } } -void refresh_info_board(InfoBoardWidget* info_board, int status, - const std::string& report_text) { +void refresh_info_board(InfoBoardWidget *info_board, int status, + const std::string &report_text) { if (status < 0) - info_board->slotRefresh(QString::fromStdString(report_text), + info_board->SlotRefresh(QString::fromStdString(report_text), INFO_ERROR_CRITICAL); else if (status > 0) - info_board->slotRefresh(QString::fromStdString(report_text), INFO_ERROR_OK); + info_board->SlotRefresh(QString::fromStdString(report_text), INFO_ERROR_OK); else - info_board->slotRefresh(QString::fromStdString(report_text), + info_board->SlotRefresh(QString::fromStdString(report_text), INFO_ERROR_WARN); } -void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board, - const ResultAnalyse& result_analyse) { - info_board->associateTabWidget(edit->tabWidget); - refresh_info_board(info_board, result_analyse.getStatus(), - result_analyse.getResultReport()); +void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board, + const GpgResultAnalyse &result_analyse) { + info_board->AssociateTabWidget(edit->tab_widget_); + refresh_info_board(info_board, result_analyse.GetStatus(), + result_analyse.GetResultReport()); } -void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board, - const ResultAnalyse& result_analyse_a, - const ResultAnalyse& result_analyse_b) { +void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board, + const GpgResultAnalyse &result_analyse_a, + const GpgResultAnalyse &result_analyse_b) { LOG(INFO) << "process_result_analyse Started"; - info_board->associateTabWidget(edit->tabWidget); + info_board->AssociateTabWidget(edit->tab_widget_); refresh_info_board( info_board, - std::min(result_analyse_a.getStatus(), result_analyse_b.getStatus()), - result_analyse_a.getResultReport() + result_analyse_b.getResultReport()); + std::min(result_analyse_a.GetStatus(), result_analyse_b.GetStatus()), + result_analyse_a.GetResultReport() + result_analyse_b.GetResultReport()); } -void process_operation(QWidget* parent, const std::string& waiting_title, - const std::function<void()>& func) { +void process_operation(QWidget *parent, const std::string &waiting_title, + const std::function<void()> &func) { auto thread = QThread::create(func); - QApplication::connect(thread, SIGNAL(finished()), thread, - SLOT(deleteLater())); + QApplication::connect(thread, &QThread::finished, thread, + &QThread::deleteLater); thread->start(); - auto* dialog = + auto *dialog = new WaitingDialog(QString::fromStdString(waiting_title), parent); while (thread->isRunning()) { QApplication::processEvents(); @@ -143,17 +148,18 @@ void process_operation(QWidget* parent, const std::string& waiting_title, dialog->close(); } -CommonUtils* CommonUtils::GetInstance() { - if (_instance == nullptr) { - _instance = std::make_unique<CommonUtils>(); +CommonUtils *CommonUtils::GetInstance() { + if (instance_ == nullptr) { + instance_ = std::make_unique<CommonUtils>(); } - return _instance.get(); + return instance_.get(); } CommonUtils::CommonUtils() : QWidget(nullptr) { - connect(this, SIGNAL(signalKeyStatusUpdated()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); - connect(this, &CommonUtils::signalGnupgNotInstall, this, []() { + connect(this, &CommonUtils::SignalKeyStatusUpdated, + SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); + connect(this, &CommonUtils::SignalGnupgNotInstall, this, []() { QMessageBox::critical( nullptr, _("ENV Loading Failed"), _("Gnupg(gpg) is not installed correctly, please follow the " @@ -164,42 +170,48 @@ CommonUtils::CommonUtils() : QWidget(nullptr) { }); } -void CommonUtils::slotImportKeys(QWidget* parent, - const std::string& in_buffer) { +void CommonUtils::SlotImportKeys(QWidget *parent, + const std::string &in_buffer) { GpgImportInformation result = GpgKeyImportExporter::GetInstance().ImportKey( std::make_unique<ByteArray>(in_buffer)); - emit signalKeyStatusUpdated(); + emit SignalKeyStatusUpdated(); new KeyImportDetailDialog(result, false, parent); } -void CommonUtils::slotImportKeyFromFile(QWidget* parent) { +void CommonUtils::SlotImportKeyFromFile(QWidget *parent) { QString file_name = QFileDialog::getOpenFileName( this, _("Open Key"), QString(), QString(_("Key Files")) + " (*.asc *.txt);;" + _("Keyring files") + " (*.gpg);;All Files (*)"); if (!file_name.isNull()) { - slotImportKeys(parent, read_all_data_in_file(file_name.toStdString())); + QByteArray key_buffer; + if (!FileOperator::ReadFile(file_name, key_buffer)) { + QMessageBox::critical(nullptr, _("File Open Failed"), + _("Failed to open file: ") + file_name); + return; + } + SlotImportKeys(parent, key_buffer.toStdString()); } } -void CommonUtils::slotImportKeyFromKeyServer(QWidget* parent) { +void CommonUtils::SlotImportKeyFromKeyServer(QWidget *parent) { auto dialog = new KeyServerImportDialog(false, parent); dialog->show(); } -void CommonUtils::slotImportKeyFromClipboard(QWidget* parent) { - QClipboard* cb = QApplication::clipboard(); - slotImportKeys(parent, +void CommonUtils::SlotImportKeyFromClipboard(QWidget *parent) { + QClipboard *cb = QApplication::clipboard(); + SlotImportKeys(parent, cb->text(QClipboard::Clipboard).toUtf8().toStdString()); } -void CommonUtils::slotExecuteGpgCommand( - const QStringList& arguments, - const std::function<void(QProcess*)>& interact_func) { +void CommonUtils::SlotExecuteGpgCommand( + const QStringList &arguments, + const std::function<void(QProcess *)> &interact_func) { QEventLoop looper; auto dialog = new WaitingDialog(_("Processing"), nullptr); dialog->show(); - auto* gpg_process = new QProcess(&looper); + auto *gpg_process = new QProcess(&looper); gpg_process->setProcessChannelMode(QProcess::MergedChannels); connect(gpg_process, @@ -239,13 +251,13 @@ void CommonUtils::slotExecuteGpgCommand( dialog->deleteLater(); } -void CommonUtils::slotImportKeyFromKeyServer( - int ctx_channel, const KeyIdArgsList& key_ids, - const ImportCallbackFunctiopn& callback) { +void CommonUtils::SlotImportKeyFromKeyServer( + int ctx_channel, const KeyIdArgsList &key_ids, + const ImportCallbackFunctiopn &callback) { std::string target_keyserver; if (target_keyserver.empty()) { try { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + auto &settings = GlobalSettingStation::GetInstance().GetUISettings(); target_keyserver = settings.lookup("keyserver.default_server").c_str(); @@ -268,7 +280,7 @@ void CommonUtils::slotImportKeyFromKeyServer( auto network_manager = std::make_unique<QNetworkAccessManager>(); // LOOP decltype(key_ids.size()) current_index = 1, all_index = key_ids.size(); - for (const auto& key_id : key_ids) { + for (const auto &key_id : key_ids) { // New Req Url QUrl req_url(target_keyserver_url.scheme() + "://" + target_keyserver_url.host() + @@ -278,7 +290,7 @@ void CommonUtils::slotImportKeyFromKeyServer( LOG(INFO) << "request url" << req_url.toString().toStdString(); // Waiting for reply - QNetworkReply* reply = network_manager->get(QNetworkRequest(req_url)); + QNetworkReply *reply = network_manager->get(QNetworkRequest(req_url)); QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); loop.exec(); diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h index d64b06b0..9d73e9b5 100644 --- a/src/ui/UserInterfaceUtils.h +++ b/src/ui/UserInterfaceUtils.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,31 +8,33 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_USER_INTERFACE_UTILS_H #define GPGFRONTEND_USER_INTERFACE_UTILS_H -#include "gpg/GpgModel.h" -#include "gpg/result_analyse/VerifyResultAnalyse.h" +#include "core/GpgModel.h" +#include "core/function/result_analyse/GpgVerifyResultAnalyse.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend { -class ResultAnalyse; +class GpgResultAnalyse; } namespace GpgFrontend::UI { @@ -39,66 +43,172 @@ class InfoBoardWidget; class TextEdit; #ifdef SMTP_SUPPORT +/** + * @brief + * + * @param parent + * @param info_board + * @param text + * @param attach_signature + */ void send_an_email(QWidget* parent, InfoBoardWidget* info_board, const QString& text, bool attach_signature = true); #endif - +/** + * @brief + * + * @param parent + * @param info_board + * @param error + * @param verify_result + */ void show_verify_details(QWidget* parent, InfoBoardWidget* info_board, GpgError error, const GpgVerifyResult& verify_result); +/** + * @brief + * + * @param parent + * @param verify_res + */ void import_unknown_key_from_keyserver(QWidget* parent, - const VerifyResultAnalyse& verify_res); + const GpgVerifyResultAnalyse& verify_res); +/** + * @brief + * + * @param info_board + * @param status + * @param report_text + */ void refresh_info_board(InfoBoardWidget* info_board, int status, const std::string& report_text); +/** + * @brief + * + * @param edit + * @param info_board + * @param result_analyse + */ void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board, - const ResultAnalyse& result_analyse); + const GpgResultAnalyse& result_analyse); +/** + * @brief + * + * @param edit + * @param info_board + * @param result_analyse_a + * @param result_analyse_b + */ void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board, - const ResultAnalyse& result_analyse_a, - const ResultAnalyse& result_analyse_b); + const GpgResultAnalyse& result_analyse_a, + const GpgResultAnalyse& result_analyse_b); +/** + * @brief + * + * @param parent + * @param waiting_title + * @param func + */ void process_operation(QWidget* parent, const std::string& waiting_title, const std::function<void()>& func); +/** + * @brief + * + */ class CommonUtils : public QWidget { Q_OBJECT public: - static CommonUtils* GetInstance(); + /** + * @brief + * + */ + using ImportCallbackFunctiopn = std::function<void( + const std::string&, const std::string&, size_t, size_t)>; + /** + * @brief Construct a new Common Utils object + * + */ CommonUtils(); - using ImportCallbackFunctiopn = std::function<void( - const std::string&, const std::string&, size_t, size_t)>; + /** + * @brief Get the Instance object + * + * @return CommonUtils* + */ + static CommonUtils* GetInstance(); signals: - void signalKeyStatusUpdated(); - - void signalGnupgNotInstall(); + /** + * @brief + * + */ + void SignalKeyStatusUpdated(); + + /** + * @brief + * + */ + void SignalGnupgNotInstall(); public slots: - - void slotImportKeys(QWidget* parent, const std::string& in_buffer); - - void slotImportKeyFromFile(QWidget* parent); - - void slotImportKeyFromKeyServer(QWidget* parent); - - void slotImportKeyFromClipboard(QWidget* parent); - - static void slotImportKeyFromKeyServer( + /** + * @brief + * + * @param parent + * @param in_buffer + */ + void SlotImportKeys(QWidget* parent, const std::string& in_buffer); + + /** + * @brief + * + * @param parent + */ + void SlotImportKeyFromFile(QWidget* parent); + + /** + * @brief + * + * @param parent + */ + void SlotImportKeyFromKeyServer(QWidget* parent); + + /** + * @brief + * + * @param parent + */ + void SlotImportKeyFromClipboard(QWidget* parent); + + /** + * @brief + * + * @param ctx_channel + * @param key_ids + * @param callback + */ + static void SlotImportKeyFromKeyServer( int ctx_channel, const GpgFrontend::KeyIdArgsList& key_ids, const GpgFrontend::UI::CommonUtils::ImportCallbackFunctiopn& callback); - void slotExecuteGpgCommand( + /** + * @brief + * + * @param arguments + * @param interact_func + */ + void SlotExecuteGpgCommand( const QStringList& arguments, const std::function<void(QProcess*)>& interact_func); - private slots: - private: - static std::unique_ptr<CommonUtils> _instance; + static std::unique_ptr<CommonUtils> instance_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/aes/qaesencryption.cpp b/src/ui/aes/qaesencryption.cpp deleted file mode 100644 index 9103fb8e..00000000 --- a/src/ui/aes/qaesencryption.cpp +++ /dev/null @@ -1,626 +0,0 @@ -#include "qaesencryption.h" -#include <QDebug> -#include <QVector> - -#ifdef USE_INTEL_AES_IF_AVAILABLE -#include "aesni/aesni-key-exp.h" -#include "aesni/aesni-enc-ecb.h" -#include "aesni/aesni-enc-cbc.h" -#endif - -/* - * Static Functions - * */ -QByteArray QAESEncryption::Crypt(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &rawText, - const QByteArray &key, const QByteArray &iv, QAESEncryption::Padding padding) -{ - return QAESEncryption(level, mode, padding).encode(rawText, key, iv); -} - -QByteArray QAESEncryption::Decrypt(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &rawText, - const QByteArray &key, const QByteArray &iv, QAESEncryption::Padding padding) -{ - return QAESEncryption(level, mode, padding).decode(rawText, key, iv); -} - -QByteArray QAESEncryption::ExpandKey(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &key) -{ - return QAESEncryption(level, mode).expandKey(key); -} - -QByteArray QAESEncryption::RemovePadding(const QByteArray &rawText, QAESEncryption::Padding padding) -{ - if (rawText.isEmpty()) - return rawText; - - QByteArray ret(rawText); - switch (padding) - { - case Padding::ZERO: - //Works only if the last byte of the decoded array is not zero - while (ret.at(ret.length()-1) == 0x00) - ret.remove(ret.length()-1, 1); - break; - case Padding::PKCS7: -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - ret.remove(ret.length() - ret.back(), ret.back()); -#else - ret.remove(ret.length() - ret.at(ret.length() - 1), ret.at(ret.length() - 1)); -#endif - break; - case Padding::ISO: - { - // Find the last byte which is not zero - int marker_index = ret.length() - 1; - for (; marker_index >= 0; --marker_index) - { - if (ret.at(marker_index) != 0x00) - { - break; - } - } - - // And check if it's the byte for marking padding - if (ret.at(marker_index) == '\x80') - { - ret.truncate(marker_index); - } - break; - } - default: - //do nothing - break; - } - return ret; -} -/* - * End Static function declarations - * */ - -/* - * Local Functions - * */ - -namespace { - -quint8 xTime(quint8 x) -{ - return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); -} - -quint8 multiply(quint8 x, quint8 y) -{ - return (((y & 1) * x) ^ ((y>>1 & 1) * xTime(x)) ^ ((y>>2 & 1) * xTime(xTime(x))) ^ ((y>>3 & 1) - * xTime(xTime(xTime(x)))) ^ ((y>>4 & 1) * xTime(xTime(xTime(xTime(x)))))); -} - -} - -/* - * End Local functions - * */ - -QAESEncryption::QAESEncryption(Aes level, Mode mode, - Padding padding) - : m_nb(4), m_blocklen(16), m_level(level), m_mode(mode), m_padding(padding) - , m_aesNIAvailable(false), m_state(nullptr) -{ -#ifdef USE_INTEL_AES_IF_AVAILABLE - m_aesNIAvailable = check_aesni_support(); -#endif - - switch (level) - { - case AES_128: { - AES128 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - case AES_192: { - AES192 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - case AES_256: { - AES256 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - default: { - AES128 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - } - -} -QByteArray QAESEncryption::getPadding(int currSize, int alignment) -{ - int size = (alignment - currSize % alignment) % alignment; - switch(m_padding) - { - case Padding::ZERO: - return QByteArray(size, 0x00); - break; - case Padding::PKCS7: - if (size == 0) - size = alignment; - return QByteArray(size, size); - break; - case Padding::ISO: - if (size > 0) - return QByteArray (size - 1, 0x00).prepend('\x80'); - break; - default: - return QByteArray(size, 0x00); - break; - } - return QByteArray(); -} - -QByteArray QAESEncryption::expandKey(const QByteArray &key) -{ - -#ifdef USE_INTEL_AES_IF_AVAILABLE - if (true){ - switch(m_level) { - case AES_128: { - AES128 aes128; - quint8 ret[aes128.expandedKey]; - memset(ret, 0x00, sizeof(ret)); - quint8 uchar_key[key.size()]; - memcpy(uchar_key, key.data(), key.size()); - AES_128_Key_Expansion(uchar_key, ret); - return QByteArray((char*) ret, aes128.expandedKey); - } - break; - case AES_192: { - AES192 aes192; - quint8 ret[aes192.expandedKey]; - memset(ret, 0x00, sizeof(ret)); - quint8 uchar_key[key.size()]; - memcpy(uchar_key, key.data(), key.size()); - - AES_192_Key_Expansion(uchar_key, ret); - return QByteArray((char*) ret, aes192.expandedKey); - } - break; - case AES_256: { - AES256 aes256; - quint8 ret[aes256.expandedKey]; - memset(ret, 0x00, sizeof(ret)); - quint8 uchar_key[key.size()]; - memcpy(uchar_key, key.data(), key.size()); - - AES_256_Key_Expansion(uchar_key, ret); - return QByteArray((char*) ret, aes256.expandedKey); - } - break; - default: - return QByteArray(); - break; - } - } else -#endif - { - - int i, k; - quint8 tempa[4]; // Used for the column/row operations - QByteArray roundKey(key); // The first round key is the key itself. - - // All other round keys are found from the previous round keys. - //i == Nk - for(i = m_nk; i < m_nb * (m_nr + 1); i++) - { - tempa[0] = (quint8) roundKey.at((i-1) * 4 + 0); - tempa[1] = (quint8) roundKey.at((i-1) * 4 + 1); - tempa[2] = (quint8) roundKey.at((i-1) * 4 + 2); - tempa[3] = (quint8) roundKey.at((i-1) * 4 + 3); - - if (i % m_nk == 0) - { - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - - // Function RotWord() - k = tempa[0]; - tempa[0] = tempa[1]; - tempa[1] = tempa[2]; - tempa[2] = tempa[3]; - tempa[3] = k; - - // Function Subword() - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); - - tempa[0] = tempa[0] ^ Rcon[i/m_nk]; - } - - if (m_level == AES_256 && i % m_nk == 4) - { - // Function Subword() - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); - } - roundKey.insert(i * 4 + 0, (quint8) roundKey.at((i - m_nk) * 4 + 0) ^ tempa[0]); - roundKey.insert(i * 4 + 1, (quint8) roundKey.at((i - m_nk) * 4 + 1) ^ tempa[1]); - roundKey.insert(i * 4 + 2, (quint8) roundKey.at((i - m_nk) * 4 + 2) ^ tempa[2]); - roundKey.insert(i * 4 + 3, (quint8) roundKey.at((i - m_nk) * 4 + 3) ^ tempa[3]); - } - return roundKey; - } -} - -// This function adds the round key to state. -// The round key is added to the state by an XOR function. -void QAESEncryption::addRoundKey(const quint8 round, const QByteArray &expKey) -{ - QByteArray::iterator it = m_state->begin(); - for(int i=0; i < 16; ++i) - it[i] = (quint8) it[i] ^ (quint8) expKey.at(round * m_nb * 4 + (i/4) * m_nb + (i%4)); -} - -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -void QAESEncryption::subBytes() -{ - QByteArray::iterator it = m_state->begin(); - for(int i = 0; i < 16; i++) - it[i] = getSBoxValue((quint8) it[i]); -} - -// The ShiftRows() function shifts the rows in the state to the left. -// Each row is shifted with different offset. -// Offset = Row number. So the first row is not shifted. -void QAESEncryption::shiftRows() -{ - QByteArray::iterator it = m_state->begin(); - quint8 temp; - //Keep in mind that QByteArray is column-driven!! - - //Shift 1 to left - temp = (quint8)it[1]; - it[1] = (quint8)it[5]; - it[5] = (quint8)it[9]; - it[9] = (quint8)it[13]; - it[13] = (quint8)temp; - - //Shift 2 to left - temp = (quint8)it[2]; - it[2] = (quint8)it[10]; - it[10] = (quint8)temp; - temp = (quint8)it[6]; - it[6] = (quint8)it[14]; - it[14] = (quint8)temp; - - //Shift 3 to left - temp = (quint8)it[3]; - it[3] = (quint8)it[15]; - it[15] = (quint8)it[11]; - it[11] = (quint8)it[7]; - it[7] = (quint8)temp; -} - -// MixColumns function mixes the columns of the state matrix -//optimized!! -void QAESEncryption::mixColumns() -{ - QByteArray::iterator it = m_state->begin(); - quint8 tmp, tm, t; - - for(int i = 0; i < 16; i += 4){ - t = (quint8)it[i]; - tmp = (quint8)it[i] ^ (quint8)it[i+1] ^ (quint8)it[i+2] ^ (quint8)it[i+3] ; - - tm = xTime( (quint8)it[i] ^ (quint8)it[i+1] ); - it[i] = (quint8)it[i] ^ (quint8)tm ^ (quint8)tmp; - - tm = xTime( (quint8)it[i+1] ^ (quint8)it[i+2]); - it[i+1] = (quint8)it[i+1] ^ (quint8)tm ^ (quint8)tmp; - - tm = xTime( (quint8)it[i+2] ^ (quint8)it[i+3]); - it[i+2] =(quint8)it[i+2] ^ (quint8)tm ^ (quint8)tmp; - - tm = xTime((quint8)it[i+3] ^ (quint8)t); - it[i+3] =(quint8)it[i+3] ^ (quint8)tm ^ (quint8)tmp; - } -} - -// MixColumns function mixes the columns of the state matrix. -// The method used to multiply may be difficult to understand for the inexperienced. -// Please use the references to gain more information. -void QAESEncryption::invMixColumns() -{ - QByteArray::iterator it = m_state->begin(); - quint8 a,b,c,d; - for(int i = 0; i < 16; i+=4){ - a = (quint8) it[i]; - b = (quint8) it[i+1]; - c = (quint8) it[i+2]; - d = (quint8) it[i+3]; - - it[i] = (quint8) (multiply(a, 0x0e) ^ multiply(b, 0x0b) ^ multiply(c, 0x0d) ^ multiply(d, 0x09)); - it[i+1] = (quint8) (multiply(a, 0x09) ^ multiply(b, 0x0e) ^ multiply(c, 0x0b) ^ multiply(d, 0x0d)); - it[i+2] = (quint8) (multiply(a, 0x0d) ^ multiply(b, 0x09) ^ multiply(c, 0x0e) ^ multiply(d, 0x0b)); - it[i+3] = (quint8) (multiply(a, 0x0b) ^ multiply(b, 0x0d) ^ multiply(c, 0x09) ^ multiply(d, 0x0e)); - } -} - -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -void QAESEncryption::invSubBytes() -{ - QByteArray::iterator it = m_state->begin(); - for(int i = 0; i < 16; ++i) - it[i] = getSBoxInvert((quint8) it[i]); -} - -void QAESEncryption::invShiftRows() -{ - QByteArray::iterator it = m_state->begin(); - uint8_t temp; - - //Keep in mind that QByteArray is column-driven!! - - //Shift 1 to right - temp = (quint8)it[13]; - it[13] = (quint8)it[9]; - it[9] = (quint8)it[5]; - it[5] = (quint8)it[1]; - it[1] = (quint8)temp; - - //Shift 2 - temp = (quint8)it[10]; - it[10] = (quint8)it[2]; - it[2] = (quint8)temp; - temp = (quint8)it[14]; - it[14] = (quint8)it[6]; - it[6] = (quint8)temp; - - //Shift 3 - temp = (quint8)it[7]; - it[7] = (quint8)it[11]; - it[11] = (quint8)it[15]; - it[15] = (quint8)it[3]; - it[3] = (quint8)temp; -} - -QByteArray QAESEncryption::byteXor(const QByteArray &a, const QByteArray &b) -{ - QByteArray::const_iterator it_a = a.begin(); - QByteArray::const_iterator it_b = b.begin(); - QByteArray ret; - - //for(int i = 0; i < m_blocklen; i++) - for(int i = 0; i < std::min(a.size(), b.size()); i++) - ret.insert(i,it_a[i] ^ it_b[i]); - - return ret; -} - -// Cipher is the main function that encrypts the PlainText. -QByteArray QAESEncryption::cipher(const QByteArray &expKey, const QByteArray &in) -{ - - //m_state is the input buffer... - QByteArray output(in); - m_state = &output; - - // Add the First round key to the state before starting the rounds. - addRoundKey(0, expKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr-1 rounds are executed in the loop below. - for(quint8 round = 1; round < m_nr; ++round){ - subBytes(); - shiftRows(); - mixColumns(); - addRoundKey(round, expKey); - } - - // The last round is given below. - // The MixColumns function is not here in the last round. - subBytes(); - shiftRows(); - addRoundKey(m_nr, expKey); - - return output; -} - -QByteArray QAESEncryption::invCipher(const QByteArray &expKey, const QByteArray &in) -{ - //m_state is the input buffer.... handle it! - QByteArray output(in); - m_state = &output; - - // Add the First round key to the state before starting the rounds. - addRoundKey(m_nr, expKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr-1 rounds are executed in the loop below. - for(quint8 round=m_nr-1; round>0 ; round--){ - invShiftRows(); - invSubBytes(); - addRoundKey(round, expKey); - invMixColumns(); - } - - // The last round is given below. - // The MixColumns function is not here in the last round. - invShiftRows(); - invSubBytes(); - addRoundKey(0, expKey); - - return output; -} - -QByteArray QAESEncryption::printArray(uchar* arr, int size) -{ - QByteArray print(""); - for(int i=0; i<size; i++) - print.append(arr[i]); - - return print.toHex(); -} - -QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) -{ - if (m_mode >= CBC && (iv.isEmpty() || iv.size() != m_blocklen)) - return QByteArray(); - - QByteArray expandedKey = expandKey(key); - QByteArray alignedText(rawText); - - //Fill array with padding - alignedText.append(getPadding(rawText.size(), m_blocklen)); - - switch(m_mode) - { - case ECB: { -#ifdef USE_INTEL_AES_IF_AVAILABLE - if (m_aesNIAvailable){ - unsigned char in[alignedText.size()]; - memcpy(in, alignedText.data(), alignedText.size()); - unsigned char out[alignedText.size()]; - memcpy(out, alignedText.data(), alignedText.size()); - char expKey[expandedKey.size()]; - memcpy(expKey, expandedKey.data(), expandedKey.size()); - AES_ECB_encrypt(in, out, alignedText.size(), - expKey, m_nr); - return QByteArray((char*)out, alignedText.size()); - } -#endif - QByteArray ret; - for(int i=0; i < alignedText.size(); i+= m_blocklen) - ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - return ret; - } - break; - case CBC: { -#ifdef USE_INTEL_AES_IF_AVAILABLE - if (m_aesNIAvailable){ - quint8 in[alignedText.size()]; - memcpy(in, alignedText.constData(), alignedText.size()); - quint8 ivec[iv.size()]; - memcpy(ivec, iv.data(), iv.size()); - char out[alignedText.size()]; - memset(out, 0x00, alignedText.size()); - char expKey[expandedKey.size()]; - memcpy(expKey, expandedKey.data(), expandedKey.size()); - AES_CBC_encrypt(in, - (unsigned char*) out, - ivec, - alignedText.size(), - expKey, - m_nr); - return QByteArray(out, alignedText.size()); - } -#endif - QByteArray ret; - QByteArray ivTemp(iv); - for(int i=0; i < alignedText.size(); i+= m_blocklen) { - alignedText.replace(i, m_blocklen, byteXor(alignedText.mid(i, m_blocklen),ivTemp)); - ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - ivTemp = ret.mid(i, m_blocklen); - } - return ret; - } - break; - case CFB: { - QByteArray ret; - ret.append(byteXor(alignedText.left(m_blocklen), cipher(expandedKey, iv))); - for(int i=0; i < alignedText.size(); i+= m_blocklen) { - if (i+m_blocklen < alignedText.size()) - ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, ret.mid(i, m_blocklen)))); - } - return ret; - } - break; - case OFB: { - QByteArray ret; - QByteArray ofbTemp; - ofbTemp.append(cipher(expandedKey, iv)); - for (int i=m_blocklen; i < alignedText.size(); i += m_blocklen){ - ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); - } - ret.append(byteXor(alignedText, ofbTemp)); - return ret; - } - break; - default: break; - } - return QByteArray(); -} - -QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) -{ - if (m_mode >= CBC && (iv.isEmpty() || iv.size() != m_blocklen)) - return QByteArray(); - - QByteArray ret; - QByteArray expandedKey = expandKey(key); - - switch(m_mode) - { - case ECB: - for(int i=0; i < rawText.size(); i+= m_blocklen) - ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); - break; - case CBC: { - QByteArray ivTemp(iv); - for(int i=0; i < rawText.size(); i+= m_blocklen){ - ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); - ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp)); - ivTemp = rawText.mid(i, m_blocklen); - } - } - break; - case CFB: { - ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv))); - for(int i=0; i < rawText.size(); i+= m_blocklen){ - if (i+m_blocklen < rawText.size()) { - ret.append(byteXor(rawText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, rawText.mid(i, m_blocklen)))); - } - } - } - break; - case OFB: { - QByteArray ofbTemp; - ofbTemp.append(cipher(expandedKey, iv)); - for (int i=m_blocklen; i < rawText.size(); i += m_blocklen){ - ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); - } - ret.append(byteXor(rawText, ofbTemp)); - } - break; - default: - //do nothing - break; - } - return ret; -} - -QByteArray QAESEncryption::removePadding(const QByteArray &rawText) -{ - return RemovePadding(rawText, (Padding) m_padding); -} diff --git a/src/ui/aes/qaesencryption.h b/src/ui/aes/qaesencryption.h deleted file mode 100644 index ec8023b3..00000000 --- a/src/ui/aes/qaesencryption.h +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef QAESENCRYPTION_H -#define QAESENCRYPTION_H - -#ifdef QtAES_EXPORTS -#include "qtaes_export.h" -#else -#define QTAESSHARED_EXPORT -#endif - -#include <QByteArray> -#include <QObject> - -#ifdef __linux__ -#ifndef __LP64__ -#define do_rdtsc _do_rdtsc -#endif -#endif - -class QTAESSHARED_EXPORT QAESEncryption : public QObject { - Q_OBJECT - public: - enum Aes { AES_128, AES_192, AES_256 }; - - enum Mode { ECB, CBC, CFB, OFB }; - - enum Padding { ZERO, PKCS7, ISO }; - - static QByteArray Crypt( - QAESEncryption::Aes level, QAESEncryption::Mode mode, - const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray(), - QAESEncryption::Padding padding = QAESEncryption::ISO); - static QByteArray Decrypt( - QAESEncryption::Aes level, QAESEncryption::Mode mode, - const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray(), - QAESEncryption::Padding padding = QAESEncryption::ISO); - static QByteArray ExpandKey(QAESEncryption::Aes level, - QAESEncryption::Mode mode, const QByteArray &key); - static QByteArray RemovePadding( - const QByteArray &rawText, - QAESEncryption::Padding padding = QAESEncryption::ISO); - - QAESEncryption(QAESEncryption::Aes level, QAESEncryption::Mode mode, - QAESEncryption::Padding padding = QAESEncryption::ISO); - - QByteArray encode(const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray()); - QByteArray decode(const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray()); - QByteArray removePadding(const QByteArray &rawText); - QByteArray expandKey(const QByteArray &key); - - QByteArray printArray(uchar *arr, int size); - Q_SIGNALS: - - public Q_SLOTS: - - private: - int m_nb; - int m_blocklen; - int m_level; - int m_mode; - int m_nk; - int m_keyLen; - quint8 m_nr; - int m_expandedKey; - int m_padding; - bool m_aesNIAvailable; - QByteArray *m_state; - - struct AES256 { - int nk = 8; - int keylen = 32; - int nr = 14; - int expandedKey = 240; - }; - - struct AES192 { - int nk = 6; - int keylen = 24; - int nr = 12; - int expandedKey = 209; - }; - - struct AES128 { - int nk = 4; - int keylen = 16; - int nr = 10; - int expandedKey = 176; - }; - - quint8 getSBoxValue(quint8 num) { return sbox[num]; } - quint8 getSBoxInvert(quint8 num) { return rsbox[num]; } - - void addRoundKey(const quint8 round, const QByteArray &expKey); - void subBytes(); - void shiftRows(); - void mixColumns(); - void invMixColumns(); - void invSubBytes(); - void invShiftRows(); - QByteArray getPadding(int currSize, int alignment); - QByteArray cipher(const QByteArray &expKey, const QByteArray &in); - QByteArray invCipher(const QByteArray &expKey, const QByteArray &in); - QByteArray byteXor(const QByteArray &a, const QByteArray &b); - - const quint8 sbox[256] = { - // 0 1 2 3 4 5 6 7 8 9 A B C - // D E F - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, - 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, - 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, - 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, - 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, - 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, - 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, - 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, - 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, - 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, - 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, - 0xb0, 0x54, 0xbb, 0x16}; - - const quint8 rsbox[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, - 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, - 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, - 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, - 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, - 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, - 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, - 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, - 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, - 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0c, 0x7d}; - - // The round constant word array, Rcon[i], contains the values given by - // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field - // GF(2^8) Only the first 14 elements are needed - const quint8 Rcon[14] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, - 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab}; -}; - -#endif // QAESENCRYPTION_H diff --git a/src/ui/details/SignatureDetailsDialog.cpp b/src/ui/details/SignatureDetailsDialog.cpp index b9ab6b78..a3ad03b3 100644 --- a/src/ui/details/SignatureDetailsDialog.cpp +++ b/src/ui/details/SignatureDetailsDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/ui/details/SignatureDetailsDialog.h b/src/ui/details/SignatureDetailsDialog.h index ea69d1f2..847b320b 100644 --- a/src/ui/details/SignatureDetailsDialog.h +++ b/src/ui/details/SignatureDetailsDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,7 +33,6 @@ class SignatureDetailsDialog : public QDialog { Q_OBJECT public: - }; #endif // GPGFRONTEND_SIGNATUREDETAILSDIALOG_H diff --git a/src/ui/details/VerifyDetailsDialog.cpp b/src/ui/details/VerifyDetailsDialog.cpp index c03feea5..14407396 100644 --- a/src/ui/details/VerifyDetailsDialog.cpp +++ b/src/ui/details/VerifyDetailsDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,34 +34,34 @@ namespace GpgFrontend::UI { VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, GpgError error, GpgVerifyResult result) - : QDialog(parent), mResult(std::move(result)), error(error) { + : QDialog(parent), m_result_(std::move(result)), error_(error) { this->setWindowTitle(_("Signatures Details")); - mainLayout = new QHBoxLayout(); - this->setLayout(mainLayout); + main_layout_ = new QHBoxLayout(); + this->setLayout(main_layout_); - slotRefresh(); + slot_refresh(); this->exec(); } -void VerifyDetailsDialog::slotRefresh() { - mVbox = new QWidget(); - auto* mVboxLayout = new QVBoxLayout(mVbox); - mainLayout->addWidget(mVbox); +void VerifyDetailsDialog::slot_refresh() { + m_vbox_ = new QWidget(); + auto* mVboxLayout = new QVBoxLayout(m_vbox_); + main_layout_->addWidget(m_vbox_); // Button Box for close button - buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); + button_box_ = new QDialogButtonBox(QDialogButtonBox::Close); + connect(button_box_, &QDialogButtonBox::rejected, this, &VerifyDetailsDialog::close); mVboxLayout->addWidget(new QLabel(QString::fromStdString( - std::string(_("Status")) + ": " + gpgme_strerror(error)))); + std::string(_("Status")) + ": " + gpgme_strerror(error_)))); - auto sign = mResult->signatures; + auto sign = m_result_->signatures; if (sign == nullptr) { mVboxLayout->addWidget(new QLabel(_("No valid input found"))); - mVboxLayout->addWidget(buttonBox); + mVboxLayout->addWidget(button_box_); return; } @@ -68,7 +72,7 @@ void VerifyDetailsDialog::slotRefresh() { // Set the title widget depending on sign status if (gpg_err_code(sign->status) == GPG_ERR_BAD_SIGNATURE) { mVboxLayout->addWidget(new QLabel(_("Error Validating signature"))); - } else if (mInputSignature != nullptr) { + } else if (input_signature_ != nullptr) { const auto info = (boost::format(_("File was signed on %1%")) % QLocale::system().toString(timestamp).toStdString()) .str() + @@ -89,7 +93,7 @@ void VerifyDetailsDialog::slotRefresh() { mVboxLayout->addWidget(sign_box); } - mVboxLayout->addWidget(buttonBox); + mVboxLayout->addWidget(button_box_); } } // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/details/VerifyDetailsDialog.h b/src/ui/details/VerifyDetailsDialog.h index 5de648f6..97e2cc2d 100644 --- a/src/ui/details/VerifyDetailsDialog.h +++ b/src/ui/details/VerifyDetailsDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,30 +30,44 @@ #define __VERIFYDETAILSDIALOG_H__ #include "ui/GpgFrontendUI.h" -#include "ui/widgets/EditorPage.h" +#include "ui/widgets/PlainTextEditorPage.h" #include "ui/widgets/VerifyKeyDetailBox.h" namespace GpgFrontend::UI { - +/** + * @brief + * + */ class VerifyDetailsDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Verify Details Dialog object + * + * @param parent + * @param error + * @param result + */ explicit VerifyDetailsDialog(QWidget* parent, GpgError error, GpgVerifyResult result); private slots: - void slotRefresh(); + /** + * @brief + * + */ + void slot_refresh(); private: - KeyList* mKeyList; - QHBoxLayout* mainLayout; - QWidget* mVbox{}; - QByteArray* mInputData{}; /** Data to be verified */ - QByteArray* mInputSignature{}; /** Data to be verified */ - QDialogButtonBox* buttonBox{}; - GpgVerifyResult mResult; - gpgme_error_t error; + KeyList* key_list_; ///< + QHBoxLayout* main_layout_; ///< + QWidget* m_vbox_{}; ///< + QByteArray* input_data_{}; ///< + QByteArray* input_signature_{}; ///< + QDialogButtonBox* button_box_{}; ///< + GpgVerifyResult m_result_; ///< + gpgme_error_t error_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/QuitDialog.cpp b/src/ui/dialog/QuitDialog.cpp index a5ed7c3f..da0be488 100755 --- a/src/ui/QuitDialog.cpp +++ b/src/ui/dialog/QuitDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/QuitDialog.h" +#include "QuitDialog.h" #include <boost/format.hpp> @@ -32,42 +36,42 @@ QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs) : QDialog(parent) { setWindowTitle(_("Unsaved Files")); setModal(true); - discarded = false; + discarded_ = false; /* * Table of unsaved documents */ QHashIterator<int, QString> i(unsavedDocs); int row = 0; - mFileList = new QTableWidget(this); - mFileList->horizontalHeader()->hide(); - mFileList->setColumnCount(3); - mFileList->setColumnWidth(0, 20); - mFileList->setColumnHidden(2, true); - mFileList->verticalHeader()->hide(); - mFileList->setShowGrid(false); - mFileList->setEditTriggers(QAbstractItemView::NoEditTriggers); - mFileList->setFocusPolicy(Qt::NoFocus); - mFileList->horizontalHeader()->setStretchLastSection(true); + m_fileList_ = new QTableWidget(this); + m_fileList_->horizontalHeader()->hide(); + m_fileList_->setColumnCount(3); + m_fileList_->setColumnWidth(0, 20); + m_fileList_->setColumnHidden(2, true); + m_fileList_->verticalHeader()->hide(); + m_fileList_->setShowGrid(false); + m_fileList_->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_fileList_->setFocusPolicy(Qt::NoFocus); + m_fileList_->horizontalHeader()->setStretchLastSection(true); // fill the table i.toFront(); // jump to the end of list to fill the table backwards while (i.hasNext()) { i.next(); - mFileList->setRowCount(mFileList->rowCount() + 1); + m_fileList_->setRowCount(m_fileList_->rowCount() + 1); // checkbox in front of filename auto* tmp0 = new QTableWidgetItem(); tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); tmp0->setCheckState(Qt::Checked); - mFileList->setItem(row, 0, tmp0); + m_fileList_->setItem(row, 0, tmp0); // filename auto* tmp1 = new QTableWidgetItem(i.value()); - mFileList->setItem(row, 1, tmp1); + m_fileList_->setItem(row, 1, tmp1); // tab-index in hidden column auto* tmp2 = new QTableWidgetItem(QString::number(i.key())); - mFileList->setItem(row, 2, tmp2); + m_fileList_->setItem(row, 2, tmp2); ++row; } /* @@ -104,10 +108,10 @@ QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs) auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Discard | QDialogButtonBox::Save | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QuitDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QuitDialog::reject); QPushButton* btnNoKey = buttonBox->button(QDialogButtonBox::Discard); - connect(btnNoKey, SIGNAL(clicked()), SLOT(slotMyDiscard())); + connect(btnNoKey, &QPushButton::clicked, this,&QuitDialog::slot_my_discard); /* * Set the layout @@ -115,24 +119,24 @@ QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs) auto* vbox = new QVBoxLayout(); vbox->addWidget(warnBox); vbox->addWidget(checkLabel); - vbox->addWidget(mFileList); + vbox->addWidget(m_fileList_); vbox->addWidget(note_label); vbox->addWidget(buttonBox); this->setLayout(vbox); } -void QuitDialog::slotMyDiscard() { - discarded = true; +void QuitDialog::slot_my_discard() { + discarded_ = true; reject(); } -bool QuitDialog::isDiscarded() const { return discarded; } +bool QuitDialog::IsDiscarded() const { return discarded_; } -QList<int> QuitDialog::getTabIdsToSave() { +QList<int> QuitDialog::GetTabIdsToSave() { QList<int> tabIdsToSave; - for (int i = 0; i < mFileList->rowCount(); i++) { - if (mFileList->item(i, 0)->checkState() == Qt::Checked) { - tabIdsToSave << mFileList->item(i, 2)->text().toInt(); + for (int i = 0; i < m_fileList_->rowCount(); i++) { + if (m_fileList_->item(i, 0)->checkState() == Qt::Checked) { + tabIdsToSave << m_fileList_->item(i, 2)->text().toInt(); } } return tabIdsToSave; diff --git a/src/ui/dialog/QuitDialog.h b/src/ui/dialog/QuitDialog.h new file mode 100755 index 00000000..2d09790b --- /dev/null +++ b/src/ui/dialog/QuitDialog.h @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef __QUITDIALOG_H__ +#define __QUITDIALOG_H__ + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +class QuitDialog : public QDialog { + Q_OBJECT + + public: + /** + * @brief Construct a new Quit Dialog object + * + * @param parent + * @param unsavedDocs + */ + QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool IsDiscarded() const; + + /** + * @brief Get the Tab Ids To Save object + * + * @return QList<int> + */ + QList<int> GetTabIdsToSave(); + + private slots: + + /** + * @brief + * + */ + void slot_my_discard(); + + private: + bool discarded_; ///< + QTableWidget* m_fileList_; ///< +}; + +} // namespace GpgFrontend::UI + +#endif // __QUITDIALOG_H__ diff --git a/src/ui/WaitingDialog.cpp b/src/ui/dialog/WaitingDialog.cpp index a83845ab..a4412e57 100644 --- a/src/ui/WaitingDialog.cpp +++ b/src/ui/dialog/WaitingDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,23 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/WaitingDialog.h" +#include "WaitingDialog.h" namespace GpgFrontend::UI { diff --git a/src/ui/WaitingDialog.h b/src/ui/dialog/WaitingDialog.h index 798c2a3c..1bb6a22b 100644 --- a/src/ui/WaitingDialog.h +++ b/src/ui/dialog/WaitingDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,16 +33,20 @@ namespace GpgFrontend::UI { +/** + * @brief + * + */ class WaitingDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Waiting Dialog object + * + * @param title + * @param parent + */ WaitingDialog(const QString& title, QWidget* parent); - - public slots: - - private slots: - - private: }; } // namespace GpgFrontend::UI diff --git a/src/ui/Wizard.cpp b/src/ui/dialog/Wizard.cpp index a8576627..0f051874 100644 --- a/src/ui/Wizard.cpp +++ b/src/ui/dialog/Wizard.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,25 +8,27 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/Wizard.h" +#include "Wizard.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" namespace GpgFrontend::UI { @@ -52,10 +56,10 @@ Wizard::Wizard(QWidget* parent) : QWizard(parent) { } setStartId(next_page_id); - connect(this, SIGNAL(accepted()), this, SLOT(slotWizardAccepted())); + connect(this, &Wizard::accepted, this, &Wizard::slot_wizard_accepted); } -void Wizard::slotWizardAccepted() { +void Wizard::slot_wizard_accepted() { LOG(INFO) << _("Called"); // Don't show is mapped to show -> negation try { @@ -69,12 +73,12 @@ void Wizard::slotWizardAccepted() { } else { wizard["show_wizard"] = false; } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } catch (...) { LOG(ERROR) << _("Setting Operation Error"); } if (field("openHelp").toBool()) { - emit signalOpenHelp("docu.html#content"); + emit SignalOpenHelp("docu.html#content"); } } @@ -169,17 +173,17 @@ ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) { layout->addWidget(encrDecyTextLabel); layout->addWidget(signVerifyTextLabel); setLayout(layout); - nextPage = Wizard::Page_Conclusion; + next_page_ = Wizard::Page_Conclusion; } -int ChoosePage::nextId() const { return nextPage; } +int ChoosePage::nextId() const { return next_page_; } -void ChoosePage::slotJumpPage(const QString& page) { +void ChoosePage::slot_jump_page(const QString& page) { QMetaObject qmo = Wizard::staticMetaObject; int index = qmo.indexOfEnumerator("WizardPages"); QMetaEnum m = qmo.enumerator(index); - nextPage = m.keyToValue(page.toUtf8().data()); + next_page_ = m.keyToValue(page.toUtf8().data()); wizard()->next(); } @@ -200,10 +204,6 @@ KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) { "docu_keygen.html#content" ">" + QString(_("Offline tutorial")) + "</a>"); - // linkLabel->setOpenExternalLinks(true); - - // connect(linkLabel, SIGNAL(linkActivated(QString)), - // parentWidget()->parentWidget(), SLOT(openHelp(QString))); auto* createKeyButtonBox = new QWidget(this); auto* createKeyButtonBoxLayout = new QHBoxLayout(createKeyButtonBox); @@ -214,15 +214,15 @@ KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) { layout->addWidget(topLabel); layout->addWidget(linkLabel); layout->addWidget(createKeyButtonBox); - connect(createKeyButton, SIGNAL(clicked(bool)), this, - SLOT(slotGenerateKeyDialog())); + connect(createKeyButton, &QPushButton::clicked, this, + &KeyGenPage::slot_generate_key_dialog); setLayout(layout); } int KeyGenPage::nextId() const { return Wizard::Page_Conclusion; } -void KeyGenPage::slotGenerateKeyDialog() { +void KeyGenPage::slot_generate_key_dialog() { LOG(INFO) << "Try Opening KeyGenDialog"; (new KeyGenDialog(this))->show(); wizard()->next(); @@ -247,19 +247,19 @@ ConclusionPage::ConclusionPage(QWidget* parent) : QWizardPage(parent) { bottomLabel->setOpenExternalLinks(true); bottomLabel->setWordWrap(true); - openHelpCheckBox = new QCheckBox(_("Open offline help.")); - openHelpCheckBox->setChecked(true); + open_help_check_box_ = new QCheckBox(_("Open offline help.")); + open_help_check_box_->setChecked(true); - dontShowWizardCheckBox = new QCheckBox(_("Dont show the wizard again.")); - dontShowWizardCheckBox->setChecked(true); + dont_show_wizard_checkbox_ = new QCheckBox(_("Dont show the wizard again.")); + dont_show_wizard_checkbox_->setChecked(true); - registerField("showWizard", dontShowWizardCheckBox); + registerField("showWizard", dont_show_wizard_checkbox_); // registerField("openHelp", openHelpCheckBox); auto* layout = new QVBoxLayout; layout->addWidget(bottomLabel); // layout->addWidget(openHelpCheckBox); - layout->addWidget(dontShowWizardCheckBox); + layout->addWidget(dont_show_wizard_checkbox_); setLayout(layout); setVisible(true); } diff --git a/src/ui/Wizard.h b/src/ui/dialog/Wizard.h index 7145d310..eb093550 100644 --- a/src/ui/Wizard.h +++ b/src/ui/dialog/Wizard.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,33 +8,39 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef WIZARD_H #define WIZARD_H -#include "gpg/GpgConstants.h" +#include "core/GpgConstants.h" #include "ui/GpgFrontendUI.h" #include "ui/KeyMgmt.h" -#include "ui/keygen/KeygenDialog.h" +#include "ui/key_generate/KeygenDialog.h" #include "ui/settings/SettingsDialog.h" namespace GpgFrontend::UI { +/** + * @brief + * + */ class Wizard : public QWizard { Q_OBJECT Q_ENUMS(WizardPages) @@ -40,21 +48,50 @@ class Wizard : public QWizard { public: enum WizardPages { Page_Intro, Page_Choose, Page_GenKey, Page_Conclusion }; + /** + * @brief Construct a new Wizard object + * + * @param parent + */ explicit Wizard(QWidget* parent = nullptr); private slots: - void slotWizardAccepted(); + /** + * @brief + * + */ + void slot_wizard_accepted(); signals: - void signalOpenHelp(QString page); + /** + * @brief + * + * @param page + */ + void SignalOpenHelp(QString page); }; +/** + * @brief + * + */ class IntroPage : public QWizardPage { Q_OBJECT public: + /** + * @brief Construct a new Intro Page object + * + * @param parent + */ explicit IntroPage(QWidget* parent = nullptr); + protected: + /** + * @brief + * + * @return int + */ [[nodiscard]] int nextId() const override; }; @@ -62,42 +99,89 @@ class ChoosePage : public QWizardPage { Q_OBJECT public: + /** + * @brief Construct a new Choose Page object + * + * @param parent + */ explicit ChoosePage(QWidget* parent = nullptr); private slots: - void slotJumpPage(const QString& page); - - private: + /** + * @brief + * + * @param page + */ + void slot_jump_page(const QString& page); + + protected: + /** + * @brief + * + * @return int + */ [[nodiscard]] int nextId() const override; - int nextPage; + int next_page_; ///< }; +/** + * @brief + * + */ class KeyGenPage : public QWizardPage { Q_OBJECT public: + /** + * @brief Construct a new Key Gen Page object + * + * @param parent + */ explicit KeyGenPage(QWidget* parent = nullptr); + /** + * @brief + * + * @return int + */ [[nodiscard]] int nextId() const override; private slots: - void slotGenerateKeyDialog(); + /** + * @brief + * + */ + void slot_generate_key_dialog(); }; +/** + * @brief + * + */ class ConclusionPage : public QWizardPage { Q_OBJECT public: + /** + * @brief Construct a new Conclusion Page object + * + * @param parent + */ explicit ConclusionPage(QWidget* parent = nullptr); + /** + * @brief + * + * @return int + */ [[nodiscard]] int nextId() const override; private: - QCheckBox* dontShowWizardCheckBox; - QCheckBox* openHelpCheckBox; + QCheckBox* dont_show_wizard_checkbox_; ///< + QCheckBox* open_help_check_box_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/function/FileReadThread.cpp b/src/ui/function/FileReadThread.cpp deleted file mode 100644 index 270f50e7..00000000 --- a/src/ui/function/FileReadThread.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#include "FileReadThread.h" - -#include <boost/filesystem.hpp> -#include <utility> - -namespace GpgFrontend::UI { - -FileReadThread::FileReadThread(std::string path) : path(std::move(path)) {} - -void FileReadThread::run() { - LOG(INFO) << "Started"; - boost::filesystem::path read_file_path(this->path); - if (is_regular_file(read_file_path)) { - LOG(INFO) << "Read Open"; - - auto fp = fopen(read_file_path.string().c_str(), "r"); - size_t read_size; - LOG(INFO) << "Thread Start Reading"; - - char buffer[8192]; - while ((read_size = fread(buffer, sizeof(char), sizeof buffer, fp)) > 0) { - // Check isInterruptionRequested - if (QThread::currentThread()->isInterruptionRequested()) { - LOG(INFO) << "Read Thread isInterruptionRequested "; - fclose(fp); - return; - } - LOG(INFO) << "Read Thread Read block size " << read_size; - std::string buffer_str(buffer, read_size); - - emit sendReadBlock(QString::fromStdString(buffer_str)); -#ifdef RELEASE - QThread::msleep(32); -#else - QThread::msleep(48); -#endif - } - fclose(fp); - emit readDone(); - LOG(INFO) << "Thread End Reading"; - } -} - -} // namespace GpgFrontend::UI diff --git a/src/ui/function/SMTPSendMailThread.h b/src/ui/function/SMTPSendMailThread.h deleted file mode 100644 index e5c9e27f..00000000 --- a/src/ui/function/SMTPSendMailThread.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_SMTPSENDMAILTHREAD_H -#define GPGFRONTEND_SMTPSENDMAILTHREAD_H - -#include <utility> - -#ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#endif - -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { -class SMTPSendMailThread : public QThread { - Q_OBJECT - public: - explicit SMTPSendMailThread(std::string host, int port, - SmtpClient::ConnectionType connection_type, - bool identify, std::string username, - std::string password, QWidget* parent = nullptr) - : QThread(parent), - host_(std::move(host)), - port_(port), - connection_type_(connection_type), - identify_(identify), - username_(std::move(username)), - password_(std::move(password)) {} - - void setSender(const QString& sender); - - void setRecipient(const QString& recipients); - - void setCC(const QString& ccs); - - void setBCC(const QString& bccs); - - void setSubject(const QString& subject) { message.setSubject(subject); } - - void addTextContent(const QString& content); - - void addFileContent(const QString& file_name, const QByteArray& content); - - void setEncryptContent(bool encrypt_content, - GpgFrontend::KeyIdArgsListPtr public_key_ids); - - void setAttachSignatureFile(bool attach_signature_file, - GpgFrontend::KeyId private_key_id); - - void setAttachPublicKey(bool attach_public_key_file, - GpgFrontend::KeyId attached_public_key_ids); - - signals: - void signalSMTPResult(const QString& result); - - protected: - void run() override; - - private: - // SMTP Options - std::string host_; - int port_; - SmtpClient::ConnectionType connection_type_; - - bool identify_; - std::string username_; - std::string password_; - - MimeMessage message; - std::vector<std::unique_ptr<MimeText>> texts_; - std::vector<std::unique_ptr<MimeText>> send_texts_; - std::vector<std::unique_ptr<MimeFile>> files_; - - // GPG Options - bool encrypt_content_ = false; - GpgFrontend::KeyIdArgsListPtr public_key_ids_; - bool attach_signature_file_ = false; - GpgFrontend::KeyId private_key_id_; - bool attach_public_key_file_ = false; - GpgFrontend::KeyId attached_public_key_ids_; -}; -} // namespace GpgFrontend::UI - -#endif // GPGFRONTEND_SMTPSENDMAILTHREAD_H diff --git a/src/ui/function/SMTPTestThread.h b/src/ui/function/SMTPTestThread.h deleted file mode 100644 index db61d97d..00000000 --- a/src/ui/function/SMTPTestThread.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_SMTPTESTTHREAD_H -#define GPGFRONTEND_SMTPTESTTHREAD_H - -#include <utility> - -#ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#endif - -#include "ui/GpgFrontendUI.h" -namespace GpgFrontend::UI { - -class SMTPTestThread : public QThread { - Q_OBJECT - public: - explicit SMTPTestThread(std::string host, int port, - SmtpClient::ConnectionType connection_type, - bool identify, std::string username, - std::string password, QWidget* parent = nullptr) - : QThread(parent), - host_(std::move(host)), - port_(port), - connection_type_(connection_type), - identify_(identify), - username_(std::move(username)), - password_(std::move(password)) {} - - signals: - void signalSMTPTestResult(const QString& result); - - protected: - void run() override; - - private: - std::string host_; - int port_; - SmtpClient::ConnectionType connection_type_; - - bool identify_; - std::string username_; - std::string password_; -}; - -} // namespace GpgFrontend::UI - -#endif // GPGFRONTEND_SMTPTESTTHREAD_H diff --git a/src/ui/help/AboutDialog.cpp b/src/ui/help/AboutDialog.cpp index 78ff5557..bcb397cc 100644 --- a/src/ui/help/AboutDialog.cpp +++ b/src/ui/help/AboutDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,27 +8,29 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "ui/help/AboutDialog.h" #include "GpgFrontendBuildInfo.h" -#include "function/VersionCheckThread.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" +#include "ui/thread/VersionCheckThread.h" namespace GpgFrontend::UI { @@ -36,11 +40,11 @@ AboutDialog::AboutDialog(int defaultIndex, QWidget* parent) : QDialog(parent) { auto* tabWidget = new QTabWidget; auto* infoTab = new InfoTab(); auto* translatorsTab = new TranslatorsTab(); - updateTab = new UpdateTab(); + update_tab_ = new UpdateTab(); tabWidget->addTab(infoTab, _("About Software")); tabWidget->addTab(translatorsTab, _("Translators")); - tabWidget->addTab(updateTab, _("Update")); + tabWidget->addTab(update_tab_, _("Update")); connect(tabWidget, &QTabWidget::currentChanged, this, [&](int index) { LOG(INFO) << "Current Index" << index; }); @@ -50,7 +54,7 @@ AboutDialog::AboutDialog(int defaultIndex, QWidget* parent) : QDialog(parent) { } auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); + connect(buttonBox, &QDialogButtonBox::accepted, this, &AboutDialog::close); auto* mainLayout = new QVBoxLayout; mainLayout->addWidget(tabWidget); @@ -64,7 +68,7 @@ AboutDialog::AboutDialog(int defaultIndex, QWidget* parent) : QDialog(parent) { void AboutDialog::showEvent(QShowEvent* ev) { QDialog::showEvent(ev); - updateTab->getLatestVersion(); + update_tab_->getLatestVersion(); } InfoTab::InfoTab(QWidget* parent) : QWidget(parent) { @@ -106,18 +110,24 @@ InfoTab::InfoTab(QWidget* parent) : QWidget(parent) { } TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) { - QFile translatorsFile; + QFile translators_qfile; auto translators_file = GlobalSettingStation::GetInstance().GetResourceDir() / "TRANSLATORS"; - translatorsFile.setFileName(translators_file.string().c_str()); - translatorsFile.open(QIODevice::ReadOnly); - QByteArray inBuffer = translatorsFile.readAll(); + translators_qfile.setFileName(translators_file.u8string().c_str()); +#ifdef LINUX + if(!translators_qfile.exists()) { + translators_qfile.setFileName("/usr/local/share/GpgFrontend/TRANSLATORS"); + } +#endif + + translators_qfile.open(QIODevice::ReadOnly); + QByteArray in_buffer = translators_qfile.readAll(); - auto* label = new QLabel(inBuffer); + auto* label = new QLabel(in_buffer); - auto* mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(label); - mainLayout->addStretch(); + auto* main_layout = new QVBoxLayout(this); + main_layout->addWidget(label); + main_layout->addStretch(); auto notice_label = new QLabel( _("If you think there are any problems with the translation, why not " @@ -126,24 +136,24 @@ TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) { "read the document or contact me via email."), this); notice_label->setWordWrap(true); - mainLayout->addWidget(notice_label); + main_layout->addWidget(notice_label); - setLayout(mainLayout); + setLayout(main_layout); } UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) { auto* pixmap = new QPixmap(":gpgfrontend-logo.png"); auto* layout = new QGridLayout(); - auto* pixmapLabel = new QLabel(); - pixmapLabel->setPixmap(*pixmap); - layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); + auto* pixmap_label = new QLabel(); + pixmap_label->setPixmap(*pixmap); + layout->addWidget(pixmap_label, 0, 0, 1, -1, Qt::AlignCenter); - currentVersion = "v" + QString::number(VERSION_MAJOR) + "." + - QString::number(VERSION_MINOR) + "." + - QString::number(VERSION_PATCH); + current_version_ = "v" + QString::number(VERSION_MAJOR) + "." + + QString::number(VERSION_MINOR) + "." + + QString::number(VERSION_PATCH); - auto tipsLabel = new QLabel(); - tipsLabel->setText( + auto tips_label = new QLabel(); + tips_label->setText( "<center>" + QString(_("It is recommended that you always check the version " "of GpgFrontend and upgrade to the latest version.")) + @@ -151,31 +161,31 @@ UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) { _("New versions not only represent new features, but " "also often represent functional and security fixes.") + "</center>"); - tipsLabel->setWordWrap(true); - - currentVersionLabel = new QLabel(); - currentVersionLabel->setText("<center>" + QString(_("Current Version")) + - _(": ") + "<b>" + currentVersion + - "</b></center>"); - currentVersionLabel->setWordWrap(true); - - latestVersionLabel = new QLabel(); - latestVersionLabel->setWordWrap(true); - - upgradeLabel = new QLabel(); - upgradeLabel->setWordWrap(true); - upgradeLabel->setOpenExternalLinks(true); - upgradeLabel->setHidden(true); - - pb = new QProgressBar(); - pb->setRange(0, 0); - pb->setTextVisible(false); - - layout->addWidget(tipsLabel, 1, 0, 1, -1); - layout->addWidget(currentVersionLabel, 2, 0, 1, -1); - layout->addWidget(latestVersionLabel, 3, 0, 1, -1); - layout->addWidget(upgradeLabel, 4, 0, 1, -1); - layout->addWidget(pb, 5, 0, 1, -1); + tips_label->setWordWrap(true); + + current_version_label_ = new QLabel(); + current_version_label_->setText("<center>" + QString(_("Current Version")) + + _(": ") + "<b>" + current_version_ + + "</b></center>"); + current_version_label_->setWordWrap(true); + + latest_version_label_ = new QLabel(); + latest_version_label_->setWordWrap(true); + + upgrade_label_ = new QLabel(); + upgrade_label_->setWordWrap(true); + upgrade_label_->setOpenExternalLinks(true); + upgrade_label_->setHidden(true); + + pb_ = new QProgressBar(); + pb_->setRange(0, 0); + pb_->setTextVisible(false); + + layout->addWidget(tips_label, 1, 0, 1, -1); + layout->addWidget(current_version_label_, 2, 0, 1, -1); + layout->addWidget(latest_version_label_, 3, 0, 1, -1); + layout->addWidget(upgrade_label_, 4, 0, 1, -1); + layout->addWidget(pb_, 5, 0, 1, -1); layout->addItem( new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1, 1, 1); @@ -184,28 +194,28 @@ UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) { } void UpdateTab::getLatestVersion() { - this->pb->setHidden(false); + this->pb_->setHidden(false); LOG(INFO) << _("try to get latest version"); auto version_thread = new VersionCheckThread(); - connect(version_thread, SIGNAL(finished()), version_thread, - SLOT(deleteLater())); - connect(version_thread, &VersionCheckThread::upgradeVersion, this, - &UpdateTab::slotShowVersionStatus); + connect(version_thread, &VersionCheckThread::finished, version_thread, + &VersionCheckThread::deleteLater); + connect(version_thread, &VersionCheckThread::SignalUpgradeVersion, this, + &UpdateTab::slot_show_version_status); version_thread->start(); } -void UpdateTab::slotShowVersionStatus(const SoftwareVersion& version) { - this->pb->setHidden(true); - latestVersionLabel->setText("<center><b>" + - QString(_("Latest Version From Github")) + ": " + - version.latest_version.c_str() + "</b></center>"); +void UpdateTab::slot_show_version_status(const SoftwareVersion& version) { + this->pb_->setHidden(true); + latest_version_label_->setText( + "<center><b>" + QString(_("Latest Version From Github")) + ": " + + version.latest_version.c_str() + "</b></center>"); if (version.NeedUpgrade()) { - upgradeLabel->setText( + upgrade_label_->setText( "<center>" + QString(_("The current version is less than the latest version on " "github.")) + @@ -214,9 +224,9 @@ void UpdateTab::slotShowVersionStatus(const SoftwareVersion& version) { "href=\"https://github.com/saturneric/GpgFrontend/releases\">" + _("Here") + "</a> " + _("to download the latest stable version.") + "</center>"); - upgradeLabel->show(); + upgrade_label_->show(); } else if (version.VersionWithDrawn()) { - upgradeLabel->setText( + upgrade_label_->setText( "<center>" + QString(_("This version has serious problems and has been withdrawn. " "Please stop using it immediately.")) + @@ -225,9 +235,9 @@ void UpdateTab::slotShowVersionStatus(const SoftwareVersion& version) { "href=\"https://github.com/saturneric/GpgFrontend/releases\">" + _("Here") + "</a> " + _("to download the latest stable version.") + "</center>"); - upgradeLabel->show(); + upgrade_label_->show(); } else if (!version.CurrentVersionReleased()) { - upgradeLabel->setText( + upgrade_label_->setText( "<center>" + QString(_("This version has not been released yet, it may be a beta " "version. If you are not a tester and care about version " @@ -237,7 +247,7 @@ void UpdateTab::slotShowVersionStatus(const SoftwareVersion& version) { "href=\"https://github.com/saturneric/GpgFrontend/releases\">" + _("Here") + "</a> " + _("to download the latest stable version.") + "</center>"); - upgradeLabel->show(); + upgrade_label_->show(); } } diff --git a/src/ui/help/AboutDialog.h b/src/ui/help/AboutDialog.h index 44ab0e3c..40d93f3e 100644 --- a/src/ui/help/AboutDialog.h +++ b/src/ui/help/AboutDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,28 +8,30 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef __ABOUTDIALOG_H__ #define __ABOUTDIALOG_H__ -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" -#include "ui/data_struct/SoftwareVersion.h" +#include "ui/struct/SoftwareVersion.h" namespace GpgFrontend::UI { @@ -39,6 +43,11 @@ class InfoTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Info Tab object + * + * @param parent + */ explicit InfoTab(QWidget* parent = nullptr); }; @@ -50,6 +59,11 @@ class TranslatorsTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Translators Tab object + * + * @param parent + */ explicit TranslatorsTab(QWidget* parent = nullptr); }; @@ -60,25 +74,42 @@ class TranslatorsTab : public QWidget { class UpdateTab : public QWidget { Q_OBJECT - QLabel* currentVersionLabel; - QLabel* latestVersionLabel; - QLabel* upgradeLabel; - QProgressBar* pb; - QString currentVersion; - QPushButton* downloadButton; - - QNetworkAccessManager* manager = new QNetworkAccessManager(this); + QLabel* current_version_label_; ///< + QLabel* latest_version_label_; ///< + QLabel* upgrade_label_; ///< + QProgressBar* pb_; ///< + QString current_version_; ///< + QPushButton* download_button_; ///< public: + /** + * @brief Construct a new Update Tab object + * + * @param parent + */ explicit UpdateTab(QWidget* parent = nullptr); + /** + * @brief Get the Latest Version object + * + */ void getLatestVersion(); private slots: - void slotShowVersionStatus(const SoftwareVersion& version); + /** + * @brief + * + * @param version + */ + void slot_show_version_status(const SoftwareVersion& version); signals: - void replyFromUpdateServer(QByteArray data); + /** + * @brief + * + * @param data + */ + void SignalReplyFromUpdateServer(QByteArray data); }; /** @@ -89,13 +120,24 @@ class AboutDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new About Dialog object + * + * @param defaultIndex + * @param parent + */ explicit AboutDialog(int defaultIndex, QWidget* parent); protected: + /** + * @brief + * + * @param ev + */ void showEvent(QShowEvent* ev) override; private: - UpdateTab* updateTab; + UpdateTab* update_tab_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/import_export/ExportKeyPackageDialog.cpp b/src/ui/import_export/ExportKeyPackageDialog.cpp new file mode 100644 index 00000000..d6f303f6 --- /dev/null +++ b/src/ui/import_export/ExportKeyPackageDialog.cpp @@ -0,0 +1,145 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "ExportKeyPackageDialog.h" + +#include <boost/format.hpp> + +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/KeyPackageOperator.h" +#include "ui_ExportKeyPackageDialog.h" + +GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( + KeyIdArgsListPtr key_ids, QWidget* parent) + : QDialog(parent), + ui_(std::make_shared<Ui_exportKeyPackageDialog>()), + key_ids_(std::move(key_ids)) { + ui_->setupUi(this); + + ui_->nameValueLabel->setText( + KeyPackageOperator::GenerateKeyPackageName().c_str()); + + connect(ui_->gnerateNameButton, &QPushButton::clicked, this, [=]() { + ui_->nameValueLabel->setText( + KeyPackageOperator::GenerateKeyPackageName().c_str()); + }); + + connect(ui_->setOutputPathButton, &QPushButton::clicked, this, [=]() { + auto file_name = QFileDialog::getSaveFileName( + this, _("Export Key Package"), ui_->nameValueLabel->text() + ".gfepack", + QString(_("Key Package")) + " (*.gfepack);;All Files (*)"); + ui_->outputPathLabel->setText(file_name); + }); + + connect(ui_->generatePassphraseButton, &QPushButton::clicked, this, [=]() { + auto file_name = QFileDialog::getSaveFileName( + this, _("Export Key Package Passphrase"), + ui_->nameValueLabel->text() + ".key", + QString(_("Key File")) + " (*.key);;All Files (*)"); + + if (!KeyPackageOperator::GeneratePassphrase(file_name.toStdString(), + passphrase_)) { + QMessageBox::critical( + this, _("Error"), + _("An error occurred while generating the passphrase file.")); + return; + } + ui_->passphraseValueLabel->setText(file_name); + }); + + connect(ui_->button_box_, &QDialogButtonBox::accepted, this, [=]() { + if (ui_->outputPathLabel->text().isEmpty()) { + QMessageBox::critical( + this, _("Forbidden"), + _("Please select an output path before exporting.")); + return; + } + + if (ui_->passphraseValueLabel->text().isEmpty()) { + QMessageBox::critical( + this, _("Forbidden"), + _("Please generate a password to protect your key before exporting, " + "it is very important. Don't forget to back up your password in a " + "safe place.")); + return; + } + + // get suitable key ids + auto key_id_exported = std::make_unique<KeyIdArgsList>(); + auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids_); + for (const auto& key : *keys) { + if (ui_->noPublicKeyCheckBox->isChecked() && !key.IsPrivateKey()) + continue; + key_id_exported->push_back(key.GetId()); + } + + if (KeyPackageOperator::GenerateKeyPackage( + ui_->outputPathLabel->text().toStdString(), + ui_->nameValueLabel->text().toStdString(), key_id_exported, + passphrase_, ui_->includeSecretKeyCheckBox->isChecked())) { + QMessageBox::information( + this, _("Success"), + QString( + _("The Key Package has been successfully generated and has been " + "protected by encryption algorithms(AES-256-ECB). You can " + "safely transfer your Key Package.")) + + "<br /><br />" + "<b>" + + _("But the key file cannot be leaked under any " + "circumstances. Please delete the Key Package and key file as " + "soon " + "as possible after completing the transfer operation.") + + "</b>"); + accept(); + } else { + QMessageBox::critical( + this, _("Error"), + _("An error occurred while exporting the key package.")); + } + }); + + connect(ui_->button_box_, &QDialogButtonBox::rejected, this, + [=]() { this->close(); }); + + ui_->nameLabel->setText(_("Key Package Name")); + ui_->selectOutputPathLabel->setText(_("Output Path")); + ui_->passphraseLabel->setText(_("Passphrase")); + ui_->tipsLabel->setText( + _("Tips: You can use Key Package to safely and conveniently transfer " + "your public and private keys between devices.")); + ui_->generatePassphraseButton->setText(_("Generate and Save Passphrase")); + ui_->gnerateNameButton->setText(_("Generate Key Package Name")); + ui_->setOutputPathButton->setText(_("Select Output Path")); + + ui_->includeSecretKeyCheckBox->setText( + _("Include secret key (Think twice before acting)")); + ui_->noPublicKeyCheckBox->setText( + _("Exclude keys that do not have a private key")); + + setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(_("exportKeyPackageDialog")); +} diff --git a/src/ui/widgets/ExportKeyPackageDialog.h b/src/ui/import_export/ExportKeyPackageDialog.h index a254b453..ecf13b1d 100644 --- a/src/ui/widgets/ExportKeyPackageDialog.h +++ b/src/ui/import_export/ExportKeyPackageDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -31,24 +35,26 @@ class Ui_exportKeyPackageDialog; namespace GpgFrontend::UI { +/** + * @brief + * + */ class ExportKeyPackageDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Export Key Package Dialog object + * + * @param key_ids + * @param parent + */ explicit ExportKeyPackageDialog(KeyIdArgsListPtr key_ids, QWidget* parent); - std::string generate_passphrase(const int len); - private: - std::shared_ptr<Ui_exportKeyPackageDialog> ui; - KeyIdArgsListPtr key_ids_; - - std::random_device rd; - std::mt19937 mt; - - std::string passphrase_; - - void generate_key_package_name(); + std::shared_ptr<Ui_exportKeyPackageDialog> ui_; ///< + KeyIdArgsListPtr key_ids_; ///< + std::string passphrase_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/KeyImportDetailDialog.cpp b/src/ui/import_export/KeyImportDetailDialog.cpp index c4a7f6e8..766d2d81 100644 --- a/src/ui/KeyImportDetailDialog.cpp +++ b/src/ui/import_export/KeyImportDetailDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,32 +8,34 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/KeyImportDetailDialog.h" +#include "KeyImportDetailDialog.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyGetter.h" namespace GpgFrontend::UI { KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result, bool automatic, QWidget* parent) - : QDialog(parent), mResult(std::move(result)) { + : QDialog(parent), m_result_(std::move(result)) { // If no key for import found, just show a message - if (mResult.considered == 0) { + if (m_result_.considered == 0) { if (automatic) QMessageBox::information(parent, _("Key Update Details"), _("No keys found")); @@ -44,12 +48,12 @@ KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result, } else { auto* mv_box = new QVBoxLayout(); - this->createGeneralInfoBox(); - mv_box->addWidget(generalInfoBox); - this->createKeysTable(); - mv_box->addWidget(keysTable); - this->createButtonBox(); - mv_box->addWidget(buttonBox); + this->create_general_info_box(); + mv_box->addWidget(general_info_box_); + this->create_keys_table(); + mv_box->addWidget(keys_table_); + this->create_button_box(); + mv_box->addWidget(button_box_); this->setLayout(mv_box); if (automatic) @@ -69,97 +73,97 @@ KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result, } } -void KeyImportDetailDialog::createGeneralInfoBox() { +void KeyImportDetailDialog::create_general_info_box() { // GridBox for general import information - generalInfoBox = new QGroupBox(_("General key info")); - auto* generalInfoBoxLayout = new QGridLayout(generalInfoBox); + general_info_box_ = new QGroupBox(_("General key info")); + auto* generalInfoBoxLayout = new QGridLayout(general_info_box_); generalInfoBoxLayout->addWidget(new QLabel(QString(_("Considered")) + ": "), 1, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.considered)), 1, 1); + new QLabel(QString::number(m_result_.considered)), 1, 1); int row = 2; - if (mResult.unchanged != 0) { + if (m_result_.unchanged != 0) { generalInfoBoxLayout->addWidget( new QLabel(QString(_("Public unchanged")) + ": "), row, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.unchanged)), row, 1); + new QLabel(QString::number(m_result_.unchanged)), row, 1); row++; } - if (mResult.imported != 0) { + if (m_result_.imported != 0) { generalInfoBoxLayout->addWidget(new QLabel(QString(_("Imported")) + ": "), row, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.imported)), row, 1); + new QLabel(QString::number(m_result_.imported)), row, 1); row++; } - if (mResult.not_imported != 0) { + if (m_result_.not_imported != 0) { generalInfoBoxLayout->addWidget( new QLabel(QString(_("Not Imported")) + ": "), row, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.not_imported)), row, 1); + new QLabel(QString::number(m_result_.not_imported)), row, 1); row++; } - if (mResult.secret_read != 0) { + if (m_result_.secret_read != 0) { generalInfoBoxLayout->addWidget( new QLabel(QString(_("Private Read")) + ": "), row, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.secret_read)), row, 1); + new QLabel(QString::number(m_result_.secret_read)), row, 1); row++; } - if (mResult.secret_imported != 0) { + if (m_result_.secret_imported != 0) { generalInfoBoxLayout->addWidget( new QLabel(QString(_("Private Imported")) + ": "), row, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.secret_imported)), row, 1); + new QLabel(QString::number(m_result_.secret_imported)), row, 1); row++; } - if (mResult.secret_unchanged != 0) { + if (m_result_.secret_unchanged != 0) { generalInfoBoxLayout->addWidget( new QLabel(QString(_("Private Unchanged")) + ": "), row, 0); generalInfoBoxLayout->addWidget( - new QLabel(QString::number(mResult.secret_unchanged)), row, 1); + new QLabel(QString::number(m_result_.secret_unchanged)), row, 1); row++; } } -void KeyImportDetailDialog::createKeysTable() { - LOG(INFO) << "KeyImportDetailDialog::createKeysTable() Called"; +void KeyImportDetailDialog::create_keys_table() { + LOG(INFO) << "KeyImportDetailDialog::create_keys_table() Called"; - keysTable = new QTableWidget(this); - keysTable->setRowCount(0); - keysTable->setColumnCount(4); - keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + keys_table_ = new QTableWidget(this); + keys_table_->setRowCount(0); + keys_table_->setColumnCount(4); + keys_table_->setEditTriggers(QAbstractItemView::NoEditTriggers); // Nothing is selectable - keysTable->setSelectionMode(QAbstractItemView::NoSelection); + keys_table_->setSelectionMode(QAbstractItemView::NoSelection); QStringList headerLabels; headerLabels << _("Name") << _("Email") << _("Status") << _("Fingerprint"); - keysTable->verticalHeader()->hide(); + keys_table_->verticalHeader()->hide(); - keysTable->setHorizontalHeaderLabels(headerLabels); + keys_table_->setHorizontalHeaderLabels(headerLabels); int row = 0; - for (const auto& imp_key : mResult.importedKeys) { - keysTable->setRowCount(row + 1); + for (const auto& imp_key : m_result_.importedKeys) { + keys_table_->setRowCount(row + 1); GpgKey key = GpgKeyGetter::GetInstance().GetKey(imp_key.fpr); - if (!key.good()) continue; - keysTable->setItem( - row, 0, new QTableWidgetItem(QString::fromStdString(key.name()))); - keysTable->setItem( - row, 1, new QTableWidgetItem(QString::fromStdString(key.email()))); - keysTable->setItem( - row, 2, new QTableWidgetItem(getStatusString(imp_key.import_status))); - keysTable->setItem( + if (!key.IsGood()) continue; + keys_table_->setItem( + row, 0, new QTableWidgetItem(QString::fromStdString(key.GetName()))); + keys_table_->setItem( + row, 1, new QTableWidgetItem(QString::fromStdString(key.GetEmail()))); + keys_table_->setItem( + row, 2, new QTableWidgetItem(get_status_string(imp_key.import_status))); + keys_table_->setItem( row, 3, new QTableWidgetItem(QString::fromStdString(imp_key.fpr))); row++; } - keysTable->horizontalHeader()->setSectionResizeMode( + keys_table_->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::ResizeToContents); - keysTable->horizontalHeader()->setStretchLastSection(true); - keysTable->resizeColumnsToContents(); + keys_table_->horizontalHeader()->setStretchLastSection(true); + keys_table_->resizeColumnsToContents(); } -QString KeyImportDetailDialog::getStatusString(int keyStatus) { +QString KeyImportDetailDialog::get_status_string(int keyStatus) { QString statusString; // keystatus is greater than 15, if key is private if (keyStatus > 15) { @@ -191,8 +195,8 @@ QString KeyImportDetailDialog::getStatusString(int keyStatus) { return statusString; } -void KeyImportDetailDialog::createButtonBox() { - buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); +void KeyImportDetailDialog::create_button_box() { + button_box_ = new QDialogButtonBox(QDialogButtonBox::Ok); + connect(button_box_, &QDialogButtonBox::accepted, this, &KeyImportDetailDialog::close); } } // namespace GpgFrontend::UI diff --git a/src/ui/import_export/KeyImportDetailDialog.h b/src/ui/import_export/KeyImportDetailDialog.h new file mode 100644 index 00000000..a648f205 --- /dev/null +++ b/src/ui/import_export/KeyImportDetailDialog.h @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef __KEYIMPORTDETAILSDIALOG_H__ +#define __KEYIMPORTDETAILSDIALOG_H__ + +#include "core/GpgContext.h" +#include "core/function/gpg/GpgKeyImportExporter.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +class KeyImportDetailDialog : public QDialog { + Q_OBJECT + + public: + /** + * @brief Construct a new Key Import Detail Dialog object + * + * @param result + * @param automatic + * @param parent + */ + KeyImportDetailDialog(GpgImportInformation result, bool automatic, + QWidget* parent = nullptr); + + private: + /** + * @brief Create a general info box object + * + */ + void create_general_info_box(); + + /** + * @brief Create a keys table object + * + */ + void create_keys_table(); + + /** + * @brief Create a button box object + * + */ + void create_button_box(); + + /** + * @brief Get the status string object + * + * @param keyStatus + * @return QString + */ + static QString get_status_string(int keyStatus); + + QTableWidget* keys_table_{}; ///< + QGroupBox* general_info_box_{}; ///< + QGroupBox* key_info_box_{}; ///< + QDialogButtonBox* button_box_{}; ///< + GpgImportInformation m_result_; ///< +}; +} // namespace GpgFrontend::UI + +#endif // __KEYIMPORTDETAILSDIALOG_H__ diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/import_export/KeyServerImportDialog.cpp index 9a118b93..c35e3db7 100644 --- a/src/ui/KeyServerImportDialog.cpp +++ b/src/ui/import_export/KeyServerImportDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,34 +8,36 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/KeyServerImportDialog.h" +#include "KeyServerImportDialog.h" #include <utility> -#include "gpg/function/GpgKeyImportExporter.h" +#include "core/function/gpg/GpgKeyImportExporter.h" #include "ui/SignalStation.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" namespace GpgFrontend::UI { KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent) - : QDialog(parent), mAutomatic(automatic) { + : QDialog(parent), m_automatic_(automatic) { // Layout for messagebox auto* messageLayout = new QHBoxLayout; @@ -41,37 +45,41 @@ KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent) setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); } else { // Buttons - closeButton = createButton(_("Close"), SLOT(close())); - importButton = createButton(_("Import ALL"), SLOT(slotImport())); - importButton->setDisabled(true); - searchButton = createButton(_("Search"), SLOT(slotSearch())); - // Line edit for search string - searchLabel = new QLabel(QString(_("Search String")) + _(": ")); - searchLineEdit = new QLineEdit(); + close_button_ = new QPushButton(_("Close")); + connect(close_button_, &QPushButton::clicked, this, &KeyServerImportDialog::close); + import_button_ = new QPushButton(_("Import ALL")); + connect(import_button_, &QPushButton::clicked, this, &KeyServerImportDialog::slot_import); + import_button_->setDisabled(true); + search_button_ = new QPushButton(_("Search")); + connect(search_button_, &QPushButton::clicked, this, &KeyServerImportDialog::slot_search); + + // Line edits for search string + search_label_ = new QLabel(QString(_("Search String")) + _(": ")); + search_line_edit_ = new QLineEdit(); - // combobox for keyserverlist - keyServerLabel = new QLabel(QString(_("Key Server")) + _(": ")); - keyServerComboBox = createComboBox(); + // combobox for keyserver list + key_server_label_ = new QLabel(QString(_("Key Server")) + _(": ")); + key_server_combo_box_ = create_comboBox(); // table containing the keys found - createKeysTable(); - message = new QLabel; - message->setFixedHeight(24); - icon = new QLabel; - icon->setFixedHeight(24); - - messageLayout->addWidget(icon); - messageLayout->addWidget(message); + create_keys_table(); + message_ = new QLabel; + message_->setFixedHeight(24); + icon_ = new QLabel; + icon_->setFixedHeight(24); + + messageLayout->addWidget(icon_); + messageLayout->addWidget(message_); messageLayout->addStretch(); } // Network Waiting - waitingBar = new QProgressBar(); - waitingBar->setVisible(false); - waitingBar->setRange(0, 0); - waitingBar->setFixedWidth(200); - messageLayout->addWidget(waitingBar); + waiting_bar_ = new QProgressBar(); + waiting_bar_->setVisible(false); + waiting_bar_->setRange(0, 0); + waiting_bar_->setFixedWidth(200); + messageLayout->addWidget(waiting_bar_); auto* mainLayout = new QGridLayout; @@ -79,19 +87,19 @@ KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent) if (automatic) { mainLayout->addLayout(messageLayout, 0, 0, 1, 3); } else { - mainLayout->addWidget(searchLabel, 1, 0); - mainLayout->addWidget(searchLineEdit, 1, 1); - mainLayout->addWidget(searchButton, 1, 2); - mainLayout->addWidget(keyServerLabel, 2, 0); - mainLayout->addWidget(keyServerComboBox, 2, 1); - mainLayout->addWidget(keysTable, 3, 0, 1, 3); + mainLayout->addWidget(search_label_, 1, 0); + mainLayout->addWidget(search_line_edit_, 1, 1); + mainLayout->addWidget(search_button_, 1, 2); + mainLayout->addWidget(key_server_label_, 2, 0); + mainLayout->addWidget(key_server_combo_box_, 2, 1); + mainLayout->addWidget(keys_table_, 3, 0, 1, 3); mainLayout->addLayout(messageLayout, 4, 0, 1, 3); // Layout for import and close button auto* buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(); - buttonsLayout->addWidget(importButton); - buttonsLayout->addWidget(closeButton); + buttonsLayout->addWidget(import_button_); + buttonsLayout->addWidget(close_button_); mainLayout->addLayout(buttonsLayout, 6, 0, 1, 3); } @@ -131,21 +139,14 @@ KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent) this->setModal(true); - connect(this, SIGNAL(signalKeyImported()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); + connect(this, &KeyServerImportDialog::SignalKeyImported, SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); // save window pos and size to configure file - connect(this, SIGNAL(finished(int)), this, SLOT(slotSaveWindowState())); + connect(this, &KeyServerImportDialog::finished, this, &KeyServerImportDialog::slot_save_window_state); } -QPushButton* KeyServerImportDialog::createButton(const QString& text, - const char* member) { - auto* button = new QPushButton(text); - connect(button, SIGNAL(clicked()), this, member); - return button; -} - -QComboBox* KeyServerImportDialog::createComboBox() { +QComboBox* KeyServerImportDialog::create_comboBox() { auto* comboBox = new QComboBox; comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -173,95 +174,98 @@ QComboBox* KeyServerImportDialog::createComboBox() { return comboBox; } -void KeyServerImportDialog::createKeysTable() { - keysTable = new QTableWidget(); - keysTable->setColumnCount(4); +void KeyServerImportDialog::create_keys_table() { + keys_table_ = new QTableWidget(); + keys_table_->setColumnCount(4); // always a whole row is marked - keysTable->setSelectionBehavior(QAbstractItemView::SelectRows); - keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + keys_table_->setSelectionBehavior(QAbstractItemView::SelectRows); + keys_table_->setEditTriggers(QAbstractItemView::NoEditTriggers); // Make just one row selectable - keysTable->setSelectionMode(QAbstractItemView::SingleSelection); + keys_table_->setSelectionMode(QAbstractItemView::SingleSelection); QStringList labels; labels << _("UID") << _("Creation date") << _("KeyID") << _("Tag"); - keysTable->horizontalHeader()->setSectionResizeMode( + keys_table_->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::ResizeToContents); - keysTable->setHorizontalHeaderLabels(labels); - keysTable->verticalHeader()->hide(); + keys_table_->setHorizontalHeaderLabels(labels); + keys_table_->verticalHeader()->hide(); - connect(keysTable, SIGNAL(cellActivated(int, int)), this, SLOT(slotImport())); + connect(keys_table_, &QTableWidget::cellActivated, this, + &KeyServerImportDialog::slot_import); } -void KeyServerImportDialog::setMessage(const QString& text, bool error) { - if (mAutomatic) return; +void KeyServerImportDialog::set_message(const QString& text, bool error) { + if (m_automatic_) return; - message->setText(text); + message_->setText(text); if (error) { - icon->setPixmap( + icon_->setPixmap( QPixmap(":error.png").scaled(QSize(24, 24), Qt::KeepAspectRatio)); } else { - icon->setPixmap( + icon_->setPixmap( QPixmap(":info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio)); } } -void KeyServerImportDialog::slotSearch() { - if (searchLineEdit->text().isEmpty()) { - setMessage("<h4>" + QString(_("Text is empty.")) + "</h4>", false); +void KeyServerImportDialog::slot_search() { + if (search_line_edit_->text().isEmpty()) { + set_message("<h4>" + QString(_("Text is empty.")) + "</h4>", false); return; } - QUrl url_from_remote = keyServerComboBox->currentText() + - "/pks/lookup?search=" + searchLineEdit->text() + + QUrl url_from_remote = key_server_combo_box_->currentText() + + "/pks/lookup?search=" + search_line_edit_->text() + "&op=index&options=mr"; - qnam = new QNetworkAccessManager(this); - QNetworkReply* reply = qnam->get(QNetworkRequest(url_from_remote)); + network_access_manager_ = new QNetworkAccessManager(this); + QNetworkReply* reply = + network_access_manager_->get(QNetworkRequest(url_from_remote)); - connect(reply, SIGNAL(finished()), this, SLOT(slotSearchFinished())); + connect(reply, &QNetworkReply::finished, this, &KeyServerImportDialog::slot_search_finished); - setLoading(true); - this->searchButton->setDisabled(true); - this->keyServerComboBox->setDisabled(true); - this->searchLineEdit->setReadOnly(true); - this->importButton->setDisabled(true); + set_loading(true); + this->search_button_->setDisabled(true); + this->key_server_combo_box_->setDisabled(true); + this->search_line_edit_->setReadOnly(true); + this->import_button_->setDisabled(true); while (reply->isRunning()) { QApplication::processEvents(); } - this->searchButton->setDisabled(false); - this->keyServerComboBox->setDisabled(false); - this->searchLineEdit->setReadOnly(false); - this->importButton->setDisabled(false); - setLoading(false); + this->search_button_->setDisabled(false); + this->key_server_combo_box_->setDisabled(false); + this->search_line_edit_->setReadOnly(false); + this->import_button_->setDisabled(false); + set_loading(false); } -void KeyServerImportDialog::slotSearchFinished() { - LOG(INFO) << "KeyServerImportDialog::slotSearchFinished Called"; +void KeyServerImportDialog::slot_search_finished() { + LOG(INFO) << "Called"; auto* reply = qobject_cast<QNetworkReply*>(sender()); - keysTable->clearContents(); - keysTable->setRowCount(0); + keys_table_->clearContents(); + keys_table_->setRowCount(0); QString first_line = QString(reply->readLine(1024)); auto error = reply->error(); if (error != QNetworkReply::NoError) { - qDebug() << "Error From Reply" << reply->errorString(); + LOG(INFO) << "Error From Reply" << reply->errorString().toStdString(); + switch (error) { case QNetworkReply::ContentNotFoundError: - setMessage(_("Not Key Found"), true); + set_message(_("Not Key Found"), true); break; case QNetworkReply::TimeoutError: - setMessage(_("Timeout"), true); + set_message(_("Timeout"), true); break; case QNetworkReply::HostNotFoundError: - setMessage(_("Key Server Not Found"), true); + set_message(_("Key Server Not Found"), true); break; default: - setMessage(_("Connection Error"), true); + set_message(_("Connection Error"), true); } return; } @@ -269,38 +273,39 @@ void KeyServerImportDialog::slotSearchFinished() { if (first_line.contains("Error")) { QString text = QString(reply->readLine(1024)); if (text.contains("Too many responses")) { - setMessage( + set_message( "<h4>" + QString(_("Too many responses from keyserver!")) + "</h4>", true); return; } else if (text.contains("No keys found")) { // if string looks like hex string, search again with 0x prepended QRegExp rx("[0-9A-Fa-f]*"); - QString query = searchLineEdit->text(); + QString query = search_line_edit_->text(); if (rx.exactMatch(query)) { - setMessage( + set_message( "<h4>" + QString(_("No keys found, input may be kexId, retrying search " "with 0x.")) + "</h4>", true); - searchLineEdit->setText(query.prepend("0x")); - this->slotSearch(); + search_line_edit_->setText(query.prepend("0x")); + this->slot_search(); return; } else { - setMessage( + set_message( "<h4>" + QString(_("No keys found containing the search string!")) + "</h4>", true); return; } } else if (text.contains("Insufficiently specific words")) { - setMessage("<h4>" + QString(_("Insufficiently specific search string!")) + - "</h4>", - true); + set_message("<h4>" + + QString(_("Insufficiently specific search string!")) + + "</h4>", + true); return; } else { - setMessage(text, true); + set_message(text, true); return; } } else { @@ -316,23 +321,23 @@ void KeyServerImportDialog::slotSearchFinished() { strikeout = false; QString flags = line[line.size() - 1]; - keysTable->setRowCount(row + 1); + keys_table_->setRowCount(row + 1); // flags can be "d" for disabled, "r" for revoked // or "e" for expired if (flags.contains("r") or flags.contains("d") or flags.contains("e")) { strikeout = true; if (flags.contains("e")) { - keysTable->setItem(row, 3, - new QTableWidgetItem(QString("expired"))); + keys_table_->setItem(row, 3, + new QTableWidgetItem(QString("expired"))); } if (flags.contains("r")) { - keysTable->setItem(row, 3, - new QTableWidgetItem(QString(_("revoked")))); + keys_table_->setItem(row, 3, + new QTableWidgetItem(QString(_("revoked")))); } if (flags.contains("d")) { - keysTable->setItem(row, 3, - new QTableWidgetItem(QString(_("disabled")))); + keys_table_->setItem(row, 3, + new QTableWidgetItem(QString(_("disabled")))); } } @@ -341,13 +346,13 @@ void KeyServerImportDialog::slotSearchFinished() { auto* uid = new QTableWidgetItem(); if (line2.size() > 1) { uid->setText(line2[1]); - keysTable->setItem(row, 0, uid); + keys_table_->setItem(row, 0, uid); } auto* creation_date = new QTableWidgetItem( QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy")); - keysTable->setItem(row, 1, creation_date); + keys_table_->setItem(row, 1, creation_date); auto* keyid = new QTableWidgetItem(line[1]); - keysTable->setItem(row, 2, keyid); + keys_table_->setItem(row, 2, keyid); if (strikeout) { QFont strike = uid->font(); strike.setStrikeOut(true); @@ -359,12 +364,12 @@ void KeyServerImportDialog::slotSearchFinished() { } else { if (line[0] == "uid") { QStringList l; - int height = keysTable->rowHeight(row - 1); - keysTable->setRowHeight(row - 1, height + 16); - QString tmp = keysTable->item(row - 1, 0)->text(); + int height = keys_table_->rowHeight(row - 1); + keys_table_->setRowHeight(row - 1, height + 16); + QString tmp = keys_table_->item(row - 1, 0)->text(); tmp.append(QString("\n") + line[1]); auto* tmp1 = new QTableWidgetItem(tmp); - keysTable->setItem(row - 1, 0, tmp1); + keys_table_->setItem(row - 1, 0, tmp1); if (strikeout) { QFont strike = tmp1->font(); strike.setStrikeOut(true); @@ -372,31 +377,31 @@ void KeyServerImportDialog::slotSearchFinished() { } } } - setMessage( + set_message( QString("<h4>") + QString(_("%1 keys found. Double click a key to import it.")) .arg(row) + "</h4>", false); } - keysTable->resizeColumnsToContents(); - importButton->setDisabled(keysTable->size().isEmpty()); + keys_table_->resizeColumnsToContents(); + import_button_->setDisabled(keys_table_->size().isEmpty()); } reply->deleteLater(); } -void KeyServerImportDialog::slotImport() { - LOG(INFO) << _("Current Row") << keysTable->currentRow(); - if (keysTable->currentRow() > -1) { - QString keyid = keysTable->item(keysTable->currentRow(), 2)->text(); - slotImport(QStringList(keyid), keyServerComboBox->currentText()); +void KeyServerImportDialog::slot_import() { + LOG(INFO) << _("Current Row") << keys_table_->currentRow(); + if (keys_table_->currentRow() > -1) { + QString keyid = keys_table_->item(keys_table_->currentRow(), 2)->text(); + SlotImport(QStringList(keyid), key_server_combo_box_->currentText()); } } -void KeyServerImportDialog::slotImport(const KeyIdArgsListPtr& keys) { +void KeyServerImportDialog::SlotImport(const KeyIdArgsListPtr& keys) { std::string target_keyserver; - if (keyServerComboBox != nullptr) { - target_keyserver = keyServerComboBox->currentText().toStdString(); + if (key_server_combo_box_ != nullptr) { + target_keyserver = key_server_combo_box_->currentText().toStdString(); } if (target_keyserver.empty()) { try { @@ -418,13 +423,13 @@ void KeyServerImportDialog::slotImport(const KeyIdArgsListPtr& keys) { auto key_ids = QStringList(); for (const auto& key_id : *keys) key_ids.append(QString::fromStdString(key_id)); - slotImport(key_ids, QUrl(target_keyserver.c_str())); + SlotImport(key_ids, QUrl(target_keyserver.c_str())); } -void KeyServerImportDialog::slotImport(const QStringList& keyIds, - const QUrl& keyServerUrl) { +void KeyServerImportDialog::SlotImport(const QStringList& keyIds, + const QUrl& keyserverUrl) { for (const auto& keyId : keyIds) { - QUrl req_url(keyServerUrl.scheme() + "://" + keyServerUrl.host() + + QUrl req_url(keyserverUrl.scheme() + "://" + keyserverUrl.host() + "/pks/lookup?op=get&search=0x" + keyId + "&options=mr"); LOG(INFO) << "request url" << req_url.toString().toStdString(); @@ -432,16 +437,16 @@ void KeyServerImportDialog::slotImport(const QStringList& keyIds, QNetworkReply* reply = manager->get(QNetworkRequest(req_url)); connect(reply, &QNetworkReply::finished, this, - [&, keyId]() { this->slotImportFinished(keyId); }); + [&, keyId]() { this->slot_import_finished(keyId); }); LOG(INFO) << "loading start"; - setLoading(true); + set_loading(true); while (reply->isRunning()) QApplication::processEvents(); - setLoading(false); + set_loading(false); LOG(INFO) << "loading done"; } } -void KeyServerImportDialog::slotImportFinished(const QString& keyid) { +void KeyServerImportDialog::slot_import_finished(const QString& keyid) { LOG(INFO) << _("Called"); auto* reply = qobject_cast<QNetworkReply*>(sender()); @@ -451,19 +456,19 @@ void KeyServerImportDialog::slotImportFinished(const QString& keyid) { auto error = reply->error(); if (error != QNetworkReply::NoError) { LOG(ERROR) << "Error From Reply" << reply->errorString().toStdString(); - if (!mAutomatic) { + if (!m_automatic_) { switch (error) { case QNetworkReply::ContentNotFoundError: - setMessage(_("Key Not Found"), true); + set_message(_("Key Not Found"), true); break; case QNetworkReply::TimeoutError: - setMessage(_("Timeout"), true); + set_message(_("Timeout"), true); break; case QNetworkReply::HostNotFoundError: - setMessage(_("Key Server Not Found"), true); + set_message(_("Key Server Not Found"), true); break; default: - setMessage(_("Connection Error"), true); + set_message(_("Connection Error"), true); } } else { switch (error) { @@ -485,7 +490,7 @@ void KeyServerImportDialog::slotImportFinished(const QString& keyid) { _("General Connection Error")); } } - if (mAutomatic) { + if (m_automatic_) { setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); } @@ -494,19 +499,19 @@ void KeyServerImportDialog::slotImportFinished(const QString& keyid) { reply->deleteLater(); - this->importKeys(std::make_unique<ByteArray>(key.constData(), key.length())); + this->import_keys(std::make_unique<ByteArray>(key.constData(), key.length())); - if (!mAutomatic) { - setMessage(QString("<h4>") + _("Key Imported") + "</h4>", false); + if (!m_automatic_) { + set_message(QString("<h4>") + _("Key Imported") + "</h4>", false); } } -void KeyServerImportDialog::importKeys(ByteArrayPtr in_data) { +void KeyServerImportDialog::import_keys(ByteArrayPtr in_data) { GpgImportInformation result = GpgKeyImportExporter::GetInstance().ImportKey(std::move(in_data)); - emit signalKeyImported(); + emit SignalKeyImported(); QWidget* _parent = qobject_cast<QWidget*>(parent()); - if (mAutomatic) { + if (m_automatic_) { auto dialog = new KeyImportDetailDialog(result, true, _parent); dialog->show(); this->accept(); @@ -516,32 +521,32 @@ void KeyServerImportDialog::importKeys(ByteArrayPtr in_data) { } } -void KeyServerImportDialog::setLoading(bool status) { - waitingBar->setVisible(status); - if (!mAutomatic) { - icon->setVisible(!status); - message->setVisible(!status); +void KeyServerImportDialog::set_loading(bool status) { + waiting_bar_->setVisible(status); + if (!m_automatic_) { + icon_->setVisible(!status); + message_->setVisible(!status); } } KeyServerImportDialog::KeyServerImportDialog(QWidget* parent) - : QDialog(parent), mAutomatic(true) { + : QDialog(parent), m_automatic_(true) { setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); // Network Waiting - waitingBar = new QProgressBar(); - waitingBar->setVisible(false); - waitingBar->setRange(0, 0); - waitingBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - waitingBar->setTextVisible(false); + waiting_bar_ = new QProgressBar(); + waiting_bar_->setVisible(false); + waiting_bar_->setRange(0, 0); + waiting_bar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + waiting_bar_->setTextVisible(false); // Layout for messagebox auto* layout = new QHBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); - layout->addWidget(waitingBar); + layout->addWidget(waiting_bar_); - keyServerComboBox = createComboBox(); + key_server_combo_box_ = create_comboBox(); this->setLayout(layout); this->setWindowTitle(_("Update Keys from Keyserver")); @@ -549,13 +554,13 @@ KeyServerImportDialog::KeyServerImportDialog(QWidget* parent) this->setModal(true); } -void KeyServerImportDialog::slotSaveWindowState() { +void KeyServerImportDialog::slot_save_window_state() { LOG(INFO) << _("Called"); - if (mAutomatic) return; + if (m_automatic_) return; auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); if (!settings.exists("window") || settings.lookup("window").getType() != libconfig::Setting::TypeGroup) @@ -594,7 +599,7 @@ void KeyServerImportDialog::slotSaveWindowState() { import_from_keyserver["size"]["height"] = QWidget::height(); } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } } // namespace GpgFrontend::UI diff --git a/src/ui/import_export/KeyServerImportDialog.h b/src/ui/import_export/KeyServerImportDialog.h new file mode 100644 index 00000000..37362859 --- /dev/null +++ b/src/ui/import_export/KeyServerImportDialog.h @@ -0,0 +1,183 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef __KEY_SERVER_IMPORT_DIALOG_H__ +#define __KEY_SERVER_IMPORT_DIALOG_H__ + +#include "KeyImportDetailDialog.h" +#include "core/GpgContext.h" +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +class KeyServerImportDialog : public QDialog { + Q_OBJECT + + public: + /** + * @brief Construct a new Key Server Import Dialog object + * + * @param automatic + * @param parent + */ + KeyServerImportDialog(bool automatic, QWidget* parent); + + /** + * @brief Construct a new Key Server Import Dialog object + * + * @param parent + */ + explicit KeyServerImportDialog(QWidget* parent); + + public slots: + + /** + * @brief + * + * @param keys + */ + void SlotImport(const KeyIdArgsListPtr& keys); + + /** + * @brief + * + * @param keyIds + * @param keyserverUrl + */ + void SlotImport(const QStringList& keyIds, const QUrl& keyserverUrl); + + signals: + + /** + * @brief + * + */ + void SignalKeyImported(); + + private slots: + + /** + * @brief + * + */ + void slot_import(); + + /** + * @brief + * + */ + void slot_search_finished(); + + /** + * @brief + * + * @param keyid + */ + void slot_import_finished(const QString& keyid); + + /** + * @brief + * + */ + void slot_search(); + + /** + * @brief + * + */ + void slot_save_window_state(); + + private: + /** + * @brief Create a keys table object + * + */ + void create_keys_table(); + + /** + * @brief Set the message object + * + * @param text + * @param error + */ + void set_message(const QString& text, bool error); + + /** + * @brief + * + * @param in_data + */ + void import_keys(ByteArrayPtr in_data); + + /** + * @brief Set the loading object + * + * @param status + */ + void set_loading(bool status); + + /** + * @brief Create a button object + * + * @param text + * @param member + * @return QPushButton* + */ + QPushButton* create_button(const QString& text, const char* member); + + /** + * @brief Create a comboBox object + * + * @return QComboBox* + */ + QComboBox* create_comboBox(); + + bool m_automatic_ = false; ///< + + QLineEdit* search_line_edit_{}; ///< + QComboBox* key_server_combo_box_{}; ///< + QProgressBar* waiting_bar_; ///< + QLabel* search_label_{}; ///< + QLabel* key_server_label_{}; ///< + QLabel* message_{}; ///< + QLabel* icon_{}; ///< + QPushButton* close_button_{}; ///< + QPushButton* import_button_{}; ///< + QPushButton* search_button_{}; ///< + QTableWidget* keys_table_{}; ///< + QNetworkAccessManager* network_access_manager_{}; ///< +}; + +} // namespace GpgFrontend::UI + +#endif // __KEY_SERVER_IMPORT_DIALOG_H__ diff --git a/src/ui/KeyUploadDialog.cpp b/src/ui/import_export/KeyUploadDialog.cpp index d2b8c0bf..a0436a8e 100644 --- a/src/ui/KeyUploadDialog.cpp +++ b/src/ui/import_export/KeyUploadDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,35 +8,37 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/KeyUploadDialog.h" +#include "KeyUploadDialog.h" #include <algorithm> -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExporter.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/function/GlobalSettingStation.h" namespace GpgFrontend::UI { KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, QWidget* parent) - : QDialog(parent), mKeys(GpgKeyGetter::GetInstance().GetKeys(keys_ids)) { + : QDialog(parent), m_keys_(GpgKeyGetter::GetInstance().GetKeys(keys_ids)) { auto* pb = new QProgressBar(); pb->setRange(0, 0); pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -51,13 +55,13 @@ KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, this->setFixedSize(240, 42); } -void KeyUploadDialog::slotUpload() { +void KeyUploadDialog::SlotUpload() { auto out_data = std::make_unique<ByteArray>(); - GpgKeyImportExporter::GetInstance().ExportKeys(*mKeys, out_data); - uploadKeyToServer(*out_data); + GpgKeyImportExporter::GetInstance().ExportKeys(*m_keys_, out_data); + slot_upload_key_to_server(*out_data); } -void KeyUploadDialog::uploadKeyToServer( +void KeyUploadDialog::slot_upload_key_to_server( const GpgFrontend::ByteArray& keys_data) { std::string target_keyserver; if (target_keyserver.empty()) { @@ -105,7 +109,7 @@ void KeyUploadDialog::uploadKeyToServer( // Send Post Data QNetworkReply* reply = qnam->post(request, postData); - connect(reply, SIGNAL(finished()), this, SLOT(slotUploadFinished())); + connect(reply, &QNetworkReply::finished, this, &KeyUploadDialog::slot_upload_finished); // Keep Waiting while (reply->isRunning()) { @@ -117,7 +121,7 @@ void KeyUploadDialog::uploadKeyToServer( this->close(); } -void KeyUploadDialog::slotUploadFinished() { +void KeyUploadDialog::slot_upload_finished() { auto* reply = qobject_cast<QNetworkReply*>(sender()); QByteArray response = reply->readAll(); diff --git a/src/ui/KeyUploadDialog.h b/src/ui/import_export/KeyUploadDialog.h index 6f292d2b..05cba083 100644 --- a/src/ui/KeyUploadDialog.h +++ b/src/ui/import_export/KeyUploadDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,48 +8,73 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_KEYUPLOADWIDGET_H #define GPGFRONTEND_KEYUPLOADWIDGET_H -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { +/** + * @brief + * + */ class KeyUploadDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Key Upload Dialog object + * + * @param keys_ids + * @param parent + */ explicit KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, QWidget* parent); public slots: - void slotUpload(); + /** + * @brief + * + */ + void SlotUpload(); private slots: - void uploadKeyToServer(const GpgFrontend::ByteArray& keys_data); + /** + * @brief + * + * @param keys_data + */ + void slot_upload_key_to_server(const GpgFrontend::ByteArray& keys_data); - void slotUploadFinished(); + /** + * @brief + * + */ + void slot_upload_finished(); private: - KeyListPtr mKeys; - QByteArray mKeyData; + KeyListPtr m_keys_; ///< + QByteArray m_key_data_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/keygen/KeygenDialog.cpp b/src/ui/key_generate/KeygenDialog.cpp index 2baa22f4..6df0bcf0 100644 --- a/src/ui/keygen/KeygenDialog.cpp +++ b/src/ui/key_generate/KeygenDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,33 +8,35 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ -#include "ui/keygen/KeygenDialog.h" +#include "ui/key_generate/KeygenDialog.h" -#include "gpg/function/GpgKeyOpera.h" +#include "dialog/WaitingDialog.h" +#include "core/function/gpg/GpgKeyOpera.h" #include "ui/SignalStation.h" -#include "ui/WaitingDialog.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" namespace GpgFrontend::UI { KeyGenDialog::KeyGenDialog(QWidget* parent) : QDialog(parent) { - buttonBox = + button_box_ = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); @@ -54,26 +58,26 @@ KeyGenDialog::KeyGenDialog(QWidget* parent) : QDialog(parent) { this->setWindowTitle(_("Generate Key")); this->setModal(true); - connect(this, SIGNAL(KeyGenerated()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); + connect(this, &KeyGenDialog::SignalKeyGenerated, SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); - generateKeyDialog(); + generate_key_dialog(); } -void KeyGenDialog::generateKeyDialog() { - keyUsageGroupBox = create_key_usage_group_box(); +void KeyGenDialog::generate_key_dialog() { + key_usage_group_box_ = create_key_usage_group_box(); auto* groupGrid = new QGridLayout(this); groupGrid->addWidget(create_basic_info_group_box(), 0, 0); - groupGrid->addWidget(keyUsageGroupBox, 1, 0); + groupGrid->addWidget(key_usage_group_box_, 1, 0); auto* nameList = new QWidget(this); nameList->setLayout(groupGrid); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(nameList); - vbox2->addWidget(errorLabel); - vbox2->addWidget(buttonBox); + vbox2->addWidget(error_label_); + vbox2->addWidget(button_box_); this->setLayout(vbox2); @@ -82,17 +86,18 @@ void KeyGenDialog::generateKeyDialog() { refresh_widgets_state(); } -void KeyGenDialog::slotKeyGenAccept() { +void KeyGenDialog::slot_key_gen_accept() { std::stringstream error_stream; /** * check for errors in keygen dialog input */ - if ((nameEdit->text()).size() < 5) { + if ((name_edit_->text()).size() < 5) { error_stream << " " << _("Name must contain at least five characters.") << std::endl; } - if (emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) { + if (email_edit_->text().isEmpty() || + !check_email_address(email_edit_->text())) { error_stream << " " << _("Please give a email address.") << std::endl; } @@ -100,7 +105,7 @@ void KeyGenDialog::slotKeyGenAccept() { * primary keys should have a reasonable expiration date (no more than 2 years * in the future) */ - if (dateEdit->dateTime() > max_date_time_) { + if (date_edit_->dateTime() > max_date_time_) { error_stream << " " << _("Expiration time too long.") << std::endl; } @@ -110,17 +115,17 @@ void KeyGenDialog::slotKeyGenAccept() { /** * create the string for key generation */ - gen_key_info_->setName(nameEdit->text().toStdString()); - gen_key_info_->setEmail(emailEdit->text().toStdString()); - gen_key_info_->setComment(commentEdit->text().toStdString()); + gen_key_info_->SetName(name_edit_->text().toStdString()); + gen_key_info_->SetEmail(email_edit_->text().toStdString()); + gen_key_info_->SetComment(comment_edit_->text().toStdString()); - gen_key_info_->setKeySize(keySizeSpinBox->value()); + gen_key_info_->SetKeyLength(key_size_spin_box_->value()); - if (expireCheckBox->checkState()) { - gen_key_info_->setNonExpired(true); + if (expire_check_box_->checkState()) { + gen_key_info_->SetNonExpired(true); } else { - gen_key_info_->setExpired( - boost::posix_time::from_time_t(dateEdit->dateTime().toTime_t())); + gen_key_info_->SetExpireTime( + boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t())); } GpgGenKeyResult result; @@ -148,7 +153,7 @@ void KeyGenDialog::slotKeyGenAccept() { msg_box->setModal(false); msg_box->open(); - emit KeyGenerated(); + emit SignalKeyGenerated(); this->close(); } else { QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(error))); @@ -158,21 +163,21 @@ void KeyGenDialog::slotKeyGenAccept() { /** * create error message */ - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); + error_label_->setAutoFillBackground(true); + QPalette error = error_label_->palette(); error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(err_string.c_str()); + error_label_->setPalette(error); + error_label_->setText(err_string.c_str()); this->show(); } } -void KeyGenDialog::slotExpireBoxChanged() { - if (expireCheckBox->checkState()) { - dateEdit->setEnabled(false); +void KeyGenDialog::slot_expire_box_changed() { + if (expire_check_box_->checkState()) { + date_edit_->setEnabled(false); } else { - dateEdit->setEnabled(true); + date_edit_->setEnabled(true); } } @@ -209,159 +214,163 @@ QGroupBox* KeyGenDialog::create_key_usage_group_box() { return groupBox; } -void KeyGenDialog::slotEncryptionBoxChanged(int state) { +void KeyGenDialog::slot_encryption_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowEncryption(false); + gen_key_info_->SetAllowEncryption(false); } else { - gen_key_info_->setAllowEncryption(true); + gen_key_info_->SetAllowEncryption(true); } } -void KeyGenDialog::slotSigningBoxChanged(int state) { +void KeyGenDialog::slot_signing_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowSigning(false); + gen_key_info_->SetAllowSigning(false); } else { - gen_key_info_->setAllowSigning(true); + gen_key_info_->SetAllowSigning(true); } } -void KeyGenDialog::slotCertificationBoxChanged(int state) { +void KeyGenDialog::slot_certification_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowCertification(false); + gen_key_info_->SetAllowCertification(false); } else { - gen_key_info_->setAllowCertification(true); + gen_key_info_->SetAllowCertification(true); } } -void KeyGenDialog::slotAuthenticationBoxChanged(int state) { +void KeyGenDialog::slot_authentication_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowAuthentication(false); + gen_key_info_->SetAllowAuthentication(false); } else { - gen_key_info_->setAllowAuthentication(true); + gen_key_info_->SetAllowAuthentication(true); } } -void KeyGenDialog::slotActivatedKeyType(int index) { +void KeyGenDialog::slot_activated_key_type(int index) { qDebug() << "key type index changed " << index; - gen_key_info_->setAlgo(this->keyTypeComboBox->itemText(index).toStdString()); + gen_key_info_->SetAlgo( + this->key_type_combo_box_->itemText(index).toStdString()); refresh_widgets_state(); } void KeyGenDialog::refresh_widgets_state() { qDebug() << "refresh_widgets_state called"; - if (gen_key_info_->isAllowEncryption()) + if (gen_key_info_->IsAllowEncryption()) key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeEncryption()) + if (gen_key_info_->IsAllowChangeEncryption()) key_usage_check_boxes_[0]->setDisabled(false); else key_usage_check_boxes_[0]->setDisabled(true); - if (gen_key_info_->isAllowSigning()) + if (gen_key_info_->IsAllowSigning()) key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeSigning()) + if (gen_key_info_->IsAllowChangeSigning()) key_usage_check_boxes_[1]->setDisabled(false); else key_usage_check_boxes_[1]->setDisabled(true); - if (gen_key_info_->isAllowCertification()) + if (gen_key_info_->IsAllowCertification()) key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeCertification()) + if (gen_key_info_->IsAllowChangeCertification()) key_usage_check_boxes_[2]->setDisabled(false); else key_usage_check_boxes_[2]->setDisabled(true); - if (gen_key_info_->isAllowAuthentication()) + if (gen_key_info_->IsAllowAuthentication()) key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeAuthentication()) + if (gen_key_info_->IsAllowChangeAuthentication()) key_usage_check_boxes_[3]->setDisabled(false); else key_usage_check_boxes_[3]->setDisabled(true); - if (gen_key_info_->isAllowNoPassPhrase()) - noPassPhraseCheckBox->setDisabled(false); + if (gen_key_info_->IsAllowNoPassPhrase()) + no_pass_phrase_check_box_->setDisabled(false); else - noPassPhraseCheckBox->setDisabled(true); + no_pass_phrase_check_box_->setDisabled(true); - keySizeSpinBox->setRange(gen_key_info_->getSuggestMinKeySize(), - gen_key_info_->getSuggestMaxKeySize()); - keySizeSpinBox->setValue(gen_key_info_->getKeySize()); - keySizeSpinBox->setSingleStep(gen_key_info_->getSizeChangeStep()); + key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(), + gen_key_info_->GetSuggestMaxKeySize()); + key_size_spin_box_->setValue(gen_key_info_->GetKeyLength()); + key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep()); } void KeyGenDialog::set_signal_slot() { - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(expireCheckBox, SIGNAL(stateChanged(int)), this, - SLOT(slotExpireBoxChanged())); - - connect(key_usage_check_boxes_[0], SIGNAL(stateChanged(int)), this, - SLOT(slotEncryptionBoxChanged(int))); - connect(key_usage_check_boxes_[1], SIGNAL(stateChanged(int)), this, - SLOT(slotSigningBoxChanged(int))); - connect(key_usage_check_boxes_[2], SIGNAL(stateChanged(int)), this, - SLOT(slotCertificationBoxChanged(int))); - connect(key_usage_check_boxes_[3], SIGNAL(stateChanged(int)), this, - SLOT(slotAuthenticationBoxChanged(int))); - - connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(slotActivatedKeyType(int))); - - connect(noPassPhraseCheckBox, &QCheckBox::stateChanged, this, + connect(button_box_, &QDialogButtonBox::accepted, this, + &KeyGenDialog::slot_key_gen_accept); + connect(button_box_, &QDialogButtonBox::rejected, this, + &KeyGenDialog::reject); + + connect(expire_check_box_, &QCheckBox::stateChanged, this, + &KeyGenDialog::slot_expire_box_changed); + + connect(key_usage_check_boxes_[0], &QCheckBox::stateChanged, this, + &KeyGenDialog::slot_encryption_box_changed); + connect(key_usage_check_boxes_[1], &QCheckBox::stateChanged, this, + &KeyGenDialog::slot_signing_box_changed); + connect(key_usage_check_boxes_[2], &QCheckBox::stateChanged, this, + &KeyGenDialog::slot_certification_box_changed); + connect(key_usage_check_boxes_[3], &QCheckBox::stateChanged, this, + &KeyGenDialog::slot_authentication_box_changed); + + connect(key_type_combo_box_, qOverload<int>(&QComboBox::currentIndexChanged), + this, &KeyGenDialog::slot_activated_key_type); + + connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this, [this](int state) -> void { if (state == 0) { - gen_key_info_->setNonPassPhrase(false); + gen_key_info_->SetNonPassPhrase(false); } else { - gen_key_info_->setNonPassPhrase(true); + gen_key_info_->SetNonPassPhrase(true); } }); } bool KeyGenDialog::check_email_address(const QString& str) { - return re_email.match(str).hasMatch(); + return re_email_.match(str).hasMatch(); } QGroupBox* KeyGenDialog::create_basic_info_group_box() { - errorLabel = new QLabel(); - nameEdit = new QLineEdit(this); - emailEdit = new QLineEdit(this); - commentEdit = new QLineEdit(this); - keySizeSpinBox = new QSpinBox(this); - keyTypeComboBox = new QComboBox(this); - - for (auto& algo : GenKeyInfo::getSupportedKeyAlgo()) { - keyTypeComboBox->addItem(QString::fromStdString(algo)); + error_label_ = new QLabel(); + name_edit_ = new QLineEdit(this); + email_edit_ = new QLineEdit(this); + comment_edit_ = new QLineEdit(this); + key_size_spin_box_ = new QSpinBox(this); + key_type_combo_box_ = new QComboBox(this); + + for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { + key_type_combo_box_->addItem(QString::fromStdString(algo)); } - if (!GenKeyInfo::getSupportedKeyAlgo().empty()) { - keyTypeComboBox->setCurrentIndex(0); + if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) { + key_type_combo_box_->setCurrentIndex(0); } - dateEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(2), this); - dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); - dateEdit->setMaximumDateTime(max_date_time_); - dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); - dateEdit->setCalendarPopup(true); - dateEdit->setEnabled(true); + date_edit_ = + new QDateTimeEdit(QDateTime::currentDateTime().addYears(2), this); + date_edit_->setMinimumDateTime(QDateTime::currentDateTime()); + date_edit_->setMaximumDateTime(max_date_time_); + date_edit_->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); + date_edit_->setCalendarPopup(true); + date_edit_->setEnabled(true); - expireCheckBox = new QCheckBox(this); - expireCheckBox->setCheckState(Qt::Unchecked); + expire_check_box_ = new QCheckBox(this); + expire_check_box_->setCheckState(Qt::Unchecked); - noPassPhraseCheckBox = new QCheckBox(this); - noPassPhraseCheckBox->setCheckState(Qt::Unchecked); + no_pass_phrase_check_box_ = new QCheckBox(this); + no_pass_phrase_check_box_->setCheckState(Qt::Unchecked); auto* vbox1 = new QGridLayout; @@ -374,14 +383,14 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 5, 0); vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase")) + ": "), 6, 0); - vbox1->addWidget(nameEdit, 0, 1, 1, 3); - vbox1->addWidget(emailEdit, 1, 1, 1, 3); - vbox1->addWidget(commentEdit, 2, 1, 1, 3); - vbox1->addWidget(dateEdit, 3, 1); - vbox1->addWidget(expireCheckBox, 3, 2); - vbox1->addWidget(keySizeSpinBox, 4, 1); - vbox1->addWidget(keyTypeComboBox, 5, 1); - vbox1->addWidget(noPassPhraseCheckBox, 6, 1); + vbox1->addWidget(name_edit_, 0, 1, 1, 3); + vbox1->addWidget(email_edit_, 1, 1, 1, 3); + vbox1->addWidget(comment_edit_, 2, 1, 1, 3); + vbox1->addWidget(date_edit_, 3, 1); + vbox1->addWidget(expire_check_box_, 3, 2); + vbox1->addWidget(key_size_spin_box_, 4, 1); + vbox1->addWidget(key_type_combo_box_, 5, 1); + vbox1->addWidget(no_pass_phrase_check_box_, 6, 1); auto basicInfoGroupBox = new QGroupBox(); basicInfoGroupBox->setLayout(vbox1); diff --git a/src/ui/key_generate/KeygenDialog.h b/src/ui/key_generate/KeygenDialog.h new file mode 100644 index 00000000..751ebdd8 --- /dev/null +++ b/src/ui/key_generate/KeygenDialog.h @@ -0,0 +1,183 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYGENDIALOG_H__ +#define __KEYGENDIALOG_H__ + +#include "core/GpgContext.h" +#include "core/GpgGenKeyInfo.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +class KeyGenDialog : public QDialog { + Q_OBJECT + + public: + /** + * @details Constructor of this class + * + * @param ctx The current GpgME context + * @param key The key to show details of + * @param parent The parent of this widget + */ + explicit KeyGenDialog(QWidget* parent = nullptr); + + signals: + /** + * @brief + * + */ + void SignalKeyGenerated(); + + private: + /** + * @brief Create a key usage group box object + * + * @return QGroupBox* + */ + QGroupBox* create_key_usage_group_box(); + + /** + * @brief Create a basic info group box object + * + * @return QGroupBox* + */ + QGroupBox* create_basic_info_group_box(); + + /** + * @brief + * + */ + QRegularExpression re_email_{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + + /** + * @brief + * + */ + QStringList error_messages_; ///< List of errors occurring when checking + ///< entries of line edits + std::unique_ptr<GenKeyInfo> gen_key_info_ = + std::make_unique<GenKeyInfo>(); ///< + QDialogButtonBox* button_box_; ///< Box for standard buttons + QLabel* error_label_{}; ///< Label containing error message + QLineEdit* name_edit_{}; ///< Line edit for the keys name + QLineEdit* email_edit_{}; ///< Line edit for the keys email + QLineEdit* comment_edit_{}; ///< Line edit for the keys comment + QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit) + QComboBox* key_type_combo_box_{}; ///< Combobox for Key type + QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date + QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire + QCheckBox* no_pass_phrase_check_box_{}; + QGroupBox* key_usage_group_box_{}; ///< Group of Widgets detecting the usage + ///< of the Key + QDateTime max_date_time_; ///< + std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH + + /** + * @brief + * + */ + void generate_key_dialog(); + + /** + * @details Refresh widgets state by GenKeyInfo + */ + void refresh_widgets_state(); + + /** + * @brief Set the signal slot object + * + */ + void set_signal_slot(); + + /** + * @brief + * + * @param str + * @return true + * @return false + */ + bool check_email_address(const QString& str); + + private slots: + + /** + * @details when expirebox was checked/unchecked, enable/disable the + * expiration date box + */ + void slot_expire_box_changed(); + + /** + * @details check all lineedits for false entries. Show error, when there is + * one, otherwise generate the key + */ + void slot_key_gen_accept(); + + /** + * @brief + * + * @param state + */ + void slot_encryption_box_changed(int state); + + /** + * @brief + * + * @param state + */ + void slot_signing_box_changed(int state); + + /** + * @brief + * + * @param state + */ + void slot_certification_box_changed(int state); + + /** + * @brief + * + * @param state + */ + void slot_authentication_box_changed(int state); + + /** + * @brief + * + * @param index + */ + void slot_activated_key_type(int index); +}; + +} // namespace GpgFrontend::UI + +#endif // __KEYGENDIALOG_H__ diff --git a/src/ui/keygen/SubkeyGenerateDialog.cpp b/src/ui/key_generate/SubkeyGenerateDialog.cpp index 70d3ee3c..4eb041aa 100644 --- a/src/ui/keygen/SubkeyGenerateDialog.cpp +++ b/src/ui/key_generate/SubkeyGenerateDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,29 +8,29 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. * */ -#include "ui/keygen/SubkeyGenerateDialog.h" +#include "ui/key_generate/SubkeyGenerateDialog.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyOpera.h" +#include "dialog/WaitingDialog.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyOpera.h" #include "ui/SignalStation.h" -#include "ui/WaitingDialog.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" namespace GpgFrontend::UI { @@ -50,29 +52,29 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent) ? QDateTime::currentDateTime().toLocalTime().addYears(30) : QDateTime::currentDateTime().toLocalTime().addYears(2); - buttonBox = + button_box_ = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - keyUsageGroupBox = create_key_usage_group_box(); + key_usage_group_box_ = create_key_usage_group_box(); auto* groupGrid = new QGridLayout(this); groupGrid->addWidget(create_basic_info_group_box(), 0, 0); - groupGrid->addWidget(keyUsageGroupBox, 1, 0); + groupGrid->addWidget(key_usage_group_box_, 1, 0); auto* nameList = new QWidget(this); nameList->setLayout(groupGrid); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(nameList); - vbox2->addWidget(errorLabel); - vbox2->addWidget(buttonBox); + vbox2->addWidget(error_label_); + vbox2->addWidget(button_box_); this->setWindowTitle(_("Generate New Subkey")); this->setLayout(vbox2); this->setModal(true); - connect(this, SIGNAL(SubKeyGenerated()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); + connect(this, &SubkeyGenerateDialog::SignalSubKeyGenerated, SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); set_signal_slot(); refresh_widgets_state(); @@ -112,27 +114,27 @@ QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() { } QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { - errorLabel = new QLabel(); - keySizeSpinBox = new QSpinBox(this); - keyTypeComboBox = new QComboBox(this); + error_label_ = new QLabel(); + key_size_spin_box_ = new QSpinBox(this); + key_type_combo_box_ = new QComboBox(this); - for (auto& algo : GenKeyInfo::getSupportedKeyAlgo()) { - keyTypeComboBox->addItem(QString::fromStdString(algo)); + for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { + key_type_combo_box_->addItem(QString::fromStdString(algo)); } - if (!GenKeyInfo::getSupportedKeyAlgo().empty()) { - keyTypeComboBox->setCurrentIndex(0); + if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) { + key_type_combo_box_->setCurrentIndex(0); } + date_edit_ = + new QDateTimeEdit(QDateTime::currentDateTime().addYears(2), this); + date_edit_->setMinimumDateTime(QDateTime::currentDateTime()); + date_edit_->setMaximumDateTime(max_date_time_); + date_edit_->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); + date_edit_->setCalendarPopup(true); + date_edit_->setEnabled(true); - dateEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(2), this); - dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); - dateEdit->setMaximumDateTime(max_date_time_); - dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); - dateEdit->setCalendarPopup(true); - dateEdit->setEnabled(true); - - expireCheckBox = new QCheckBox(this); - expireCheckBox->setCheckState(Qt::Unchecked); + expire_check_box_ = new QCheckBox(this); + expire_check_box_->setCheckState(Qt::Unchecked); auto* vbox1 = new QGridLayout; @@ -141,10 +143,10 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 1, 0); vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 0, 0); - vbox1->addWidget(dateEdit, 2, 1); - vbox1->addWidget(expireCheckBox, 2, 2); - vbox1->addWidget(keySizeSpinBox, 1, 1); - vbox1->addWidget(keyTypeComboBox, 0, 1); + vbox1->addWidget(date_edit_, 2, 1); + vbox1->addWidget(expire_check_box_, 2, 2); + vbox1->addWidget(key_size_spin_box_, 1, 1); + vbox1->addWidget(key_type_combo_box_, 0, 1); auto basicInfoGroupBox = new QGroupBox(); basicInfoGroupBox->setLayout(vbox1); @@ -154,103 +156,103 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { } void SubkeyGenerateDialog::set_signal_slot() { - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(expireCheckBox, SIGNAL(stateChanged(int)), this, - SLOT(slotExpireBoxChanged())); - - connect(key_usage_check_boxes_[0], SIGNAL(stateChanged(int)), this, - SLOT(slotEncryptionBoxChanged(int))); - connect(key_usage_check_boxes_[1], SIGNAL(stateChanged(int)), this, - SLOT(slotSigningBoxChanged(int))); - connect(key_usage_check_boxes_[2], SIGNAL(stateChanged(int)), this, - SLOT(slotCertificationBoxChanged(int))); - connect(key_usage_check_boxes_[3], SIGNAL(stateChanged(int)), this, - SLOT(slotAuthenticationBoxChanged(int))); - - connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(slotActivatedKeyType(int))); + connect(button_box_, &QDialogButtonBox::accepted, this, &SubkeyGenerateDialog::slot_key_gen_accept); + connect(button_box_, &QDialogButtonBox::rejected, this, &SubkeyGenerateDialog::reject); + + connect(expire_check_box_, &QCheckBox::stateChanged, this, + &SubkeyGenerateDialog::slot_expire_box_changed); + + connect(key_usage_check_boxes_[0], &QCheckBox::stateChanged, this, + &SubkeyGenerateDialog::slot_encryption_box_changed); + connect(key_usage_check_boxes_[1], &QCheckBox::stateChanged, this, + &SubkeyGenerateDialog::slot_signing_box_changed); + connect(key_usage_check_boxes_[2], &QCheckBox::stateChanged, this, + &SubkeyGenerateDialog::slot_certification_box_changed); + connect(key_usage_check_boxes_[3], &QCheckBox::stateChanged, this, + &SubkeyGenerateDialog::slot_authentication_box_changed); + + connect(key_type_combo_box_, qOverload<int>(&QComboBox::currentIndexChanged), this, + &SubkeyGenerateDialog::slot_activated_key_type); } -void SubkeyGenerateDialog::slotExpireBoxChanged() { - if (expireCheckBox->checkState()) { - dateEdit->setEnabled(false); +void SubkeyGenerateDialog::slot_expire_box_changed() { + if (expire_check_box_->checkState()) { + date_edit_->setEnabled(false); } else { - dateEdit->setEnabled(true); + date_edit_->setEnabled(true); } } void SubkeyGenerateDialog::refresh_widgets_state() { qDebug() << "refresh_widgets_state called"; - if (gen_key_info_->isAllowEncryption()) + if (gen_key_info_->IsAllowEncryption()) key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeEncryption()) + if (gen_key_info_->IsAllowChangeEncryption()) key_usage_check_boxes_[0]->setDisabled(false); else key_usage_check_boxes_[0]->setDisabled(true); - if (gen_key_info_->isAllowSigning()) + if (gen_key_info_->IsAllowSigning()) key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeSigning()) + if (gen_key_info_->IsAllowChangeSigning()) key_usage_check_boxes_[1]->setDisabled(false); else key_usage_check_boxes_[1]->setDisabled(true); - if (gen_key_info_->isAllowCertification()) + if (gen_key_info_->IsAllowCertification()) key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeCertification()) + if (gen_key_info_->IsAllowChangeCertification()) key_usage_check_boxes_[2]->setDisabled(false); else key_usage_check_boxes_[2]->setDisabled(true); - if (gen_key_info_->isAllowAuthentication()) + if (gen_key_info_->IsAllowAuthentication()) key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked); else key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked); - if (gen_key_info_->isAllowChangeAuthentication()) + if (gen_key_info_->IsAllowChangeAuthentication()) key_usage_check_boxes_[3]->setDisabled(false); else key_usage_check_boxes_[3]->setDisabled(true); - keySizeSpinBox->setRange(gen_key_info_->getSuggestMinKeySize(), - gen_key_info_->getSuggestMaxKeySize()); - keySizeSpinBox->setValue(gen_key_info_->getKeySize()); - keySizeSpinBox->setSingleStep(gen_key_info_->getSizeChangeStep()); + key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(), + gen_key_info_->GetSuggestMaxKeySize()); + key_size_spin_box_->setValue(gen_key_info_->GetKeyLength()); + key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep()); } -void SubkeyGenerateDialog::slotKeyGenAccept() { +void SubkeyGenerateDialog::slot_key_gen_accept() { std::stringstream err_stream; /** * primary keys should have a reasonable expiration date (no more than 2 years * in the future) */ - if (dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) { + if (date_edit_->dateTime() > QDateTime::currentDateTime().addYears(2)) { err_stream << " " << _("Expiration time no more than 2 years.") << " "; } auto err_string = err_stream.str(); if (err_string.empty()) { - gen_key_info_->setKeySize(keySizeSpinBox->value()); + gen_key_info_->SetKeyLength(key_size_spin_box_->value()); - if (expireCheckBox->checkState()) { - gen_key_info_->setNonExpired(true); + if (expire_check_box_->checkState()) { + gen_key_info_->SetNonExpired(true); } else { - gen_key_info_->setExpired( - boost::posix_time::from_time_t(dateEdit->dateTime().toTime_t())); + gen_key_info_->SetExpireTime( + boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t())); } GpgError error; @@ -277,7 +279,7 @@ void SubkeyGenerateDialog::slotKeyGenAccept() { msg_box->setModal(false); msg_box->open(); - emit SubKeyGenerated(); + emit SignalSubKeyGenerated(); this->close(); } else QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(error))); @@ -286,51 +288,52 @@ void SubkeyGenerateDialog::slotKeyGenAccept() { /** * create error message */ - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); + error_label_->setAutoFillBackground(true); + QPalette error = error_label_->palette(); error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(err_string.c_str()); + error_label_->setPalette(error); + error_label_->setText(err_string.c_str()); this->show(); } } -void SubkeyGenerateDialog::slotEncryptionBoxChanged(int state) { +void SubkeyGenerateDialog::slot_encryption_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowEncryption(false); + gen_key_info_->SetAllowEncryption(false); } else { - gen_key_info_->setAllowEncryption(true); + gen_key_info_->SetAllowEncryption(true); } } -void SubkeyGenerateDialog::slotSigningBoxChanged(int state) { +void SubkeyGenerateDialog::slot_signing_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowSigning(false); + gen_key_info_->SetAllowSigning(false); } else { - gen_key_info_->setAllowSigning(true); + gen_key_info_->SetAllowSigning(true); } } -void SubkeyGenerateDialog::slotCertificationBoxChanged(int state) { +void SubkeyGenerateDialog::slot_certification_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowCertification(false); + gen_key_info_->SetAllowCertification(false); } else { - gen_key_info_->setAllowCertification(true); + gen_key_info_->SetAllowCertification(true); } } -void SubkeyGenerateDialog::slotAuthenticationBoxChanged(int state) { +void SubkeyGenerateDialog::slot_authentication_box_changed(int state) { if (state == 0) { - gen_key_info_->setAllowAuthentication(false); + gen_key_info_->SetAllowAuthentication(false); } else { - gen_key_info_->setAllowAuthentication(true); + gen_key_info_->SetAllowAuthentication(true); } } -void SubkeyGenerateDialog::slotActivatedKeyType(int index) { +void SubkeyGenerateDialog::slot_activated_key_type(int index) { qDebug() << "key type index changed " << index; - gen_key_info_->setAlgo(this->keyTypeComboBox->itemText(index).toStdString()); + gen_key_info_->SetAlgo( + this->key_type_combo_box_->itemText(index).toStdString()); refresh_widgets_state(); } diff --git a/src/ui/key_generate/SubkeyGenerateDialog.h b/src/ui/key_generate/SubkeyGenerateDialog.h new file mode 100644 index 00000000..4ab90ad4 --- /dev/null +++ b/src/ui/key_generate/SubkeyGenerateDialog.h @@ -0,0 +1,151 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SUBKEYGENERATEDIALOG_H +#define GPGFRONTEND_SUBKEYGENERATEDIALOG_H + +#include "core/GpgContext.h" +#include "core/GpgGenKeyInfo.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { +/** + * @brief + * + */ +class SubkeyGenerateDialog : public QDialog { + Q_OBJECT + + public: + /** + * @brief Construct a new Subkey Generate Dialog object + * + * @param key_id + * @param parent + */ + explicit SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent); + + signals: + /** + * @brief + * + */ + void SignalSubKeyGenerated(); + + private: + GpgKey key_; ///< + + std::unique_ptr<GenKeyInfo> gen_key_info_ = + std::make_unique<GenKeyInfo>(true); ///< + + QGroupBox* key_usage_group_box_{}; + QDialogButtonBox* button_box_; ///< Box for standard buttons + QLabel* error_label_{}; ///< Label containing error message + QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit) + QComboBox* key_type_combo_box_{}; ///< Combobox for Key tpe + QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date + QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire + + std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH + QDateTime max_date_time_; ///< + + /** + * @brief Create a key usage group box object + * + * @return QGroupBox* + */ + QGroupBox* create_key_usage_group_box(); + + /** + * @brief Create a basic info group box object + * + * @return QGroupBox* + */ + QGroupBox* create_basic_info_group_box(); + /** + * @brief Set the signal slot object + * + */ + void set_signal_slot(); + + /** + * @details Refresh widgets state by GenKeyInfo + */ + void refresh_widgets_state(); + + private slots: + + /** + * @details when expire box was checked/unchecked, enable/disable the + * expiration date box + */ + void slot_expire_box_changed(); + + /** + * @details check all line edits for false entries. Show error, when there is + * one, otherwise generate the key + */ + void slot_key_gen_accept(); + + /** + * @brief + * + * @param state + */ + void slot_encryption_box_changed(int state); + + /** + * @brief + * + * @param state + */ + void slot_signing_box_changed(int state); + + /** + * @brief + * + * @param state + */ + void slot_certification_box_changed(int state); + + /** + * @brief + * + * @param state + */ + void slot_authentication_box_changed(int state); + + /** + * @brief + * + * @param index + */ + void slot_activated_key_type(int index); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SUBKEYGENERATEDIALOG_H diff --git a/src/ui/keygen/KeygenDialog.h b/src/ui/keygen/KeygenDialog.h deleted file mode 100644 index 1b9fdb2a..00000000 --- a/src/ui/keygen/KeygenDialog.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __KEYGENDIALOG_H__ -#define __KEYGENDIALOG_H__ - -#include "gpg/GpgContext.h" -#include "gpg/GpgGenKeyInfo.h" -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { - -class KeyGenDialog : public QDialog { - Q_OBJECT - - public: - /** - * @details Constructor of this class - * - * @param ctx The current GpgME context - * @param key The key to show details of - * @param parent The parent of this widget - */ - explicit KeyGenDialog(QWidget* parent = nullptr); - - signals: - void KeyGenerated(); - - private: - QGroupBox* create_key_usage_group_box(); - - QGroupBox* create_basic_info_group_box(); - - QRegularExpression re_email{ - R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; - - QStringList error_messages_; /** List of errors occuring when checking entries - of lineedits */ - std::unique_ptr<GenKeyInfo> gen_key_info_ = std::make_unique<GenKeyInfo>(); - - QDialogButtonBox* buttonBox; /** Box for standard buttons */ - QLabel* errorLabel{}; /** Label containing error message */ - QLineEdit* nameEdit{}; /** Line edit for the keys name */ - QLineEdit* emailEdit{}; /** Line edit for the keys email */ - QLineEdit* commentEdit{}; /** Line edit for the keys comment */ - QSpinBox* keySizeSpinBox{}; /** Spinbox for the keys size (in bit) */ - QComboBox* keyTypeComboBox{}; /** Combobox for Key type */ - QDateTimeEdit* dateEdit{}; /** Date edit for expiration date */ - QCheckBox* expireCheckBox{}; /** Checkbox, if key should expire */ - QCheckBox* noPassPhraseCheckBox{}; - - QGroupBox* keyUsageGroupBox{}; /** Group of Widgets detecting the usage of the - Key **/ - QDateTime max_date_time_; - - // ENCR, SIGN, CERT, AUTH - std::vector<QCheckBox*> key_usage_check_boxes_; - - void generateKeyDialog(); - - /** - * @details Refresh widgets state by GenKeyInfo - */ - void refresh_widgets_state(); - - void set_signal_slot(); - - bool check_email_address(const QString& str); - - private slots: - - /** - * @details when expirebox was checked/unchecked, enable/disable the - * expiration date box - */ - void slotExpireBoxChanged(); - - /** - * @details check all lineedits for false entries. Show error, when there is - * one, otherwise generate the key - */ - void slotKeyGenAccept(); - - void slotEncryptionBoxChanged(int state); - - void slotSigningBoxChanged(int state); - - void slotCertificationBoxChanged(int state); - - void slotAuthenticationBoxChanged(int state); - - void slotActivatedKeyType(int index); -}; - -} // namespace GpgFrontend::UI - -#endif // __KEYGENDIALOG_H__ diff --git a/src/ui/keygen/SubkeyGenerateDialog.h b/src/ui/keygen/SubkeyGenerateDialog.h deleted file mode 100644 index 78f3ac92..00000000 --- a/src/ui/keygen/SubkeyGenerateDialog.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_SUBKEYGENERATEDIALOG_H -#define GPGFRONTEND_SUBKEYGENERATEDIALOG_H - -#include "gpg/GpgContext.h" -#include "gpg/GpgGenKeyInfo.h" -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { - -class SubkeyGenerateDialog : public QDialog { - Q_OBJECT - - public: - explicit SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent); - - signals: - void SubKeyGenerated(); - - private: - GpgKey key_; - - std::unique_ptr<GenKeyInfo> gen_key_info_ = - std::make_unique<GenKeyInfo>(true); - - QGroupBox* keyUsageGroupBox{}; - QDialogButtonBox* buttonBox; /** Box for standardbuttons */ - QLabel* errorLabel{}; /** Label containing error message */ - QSpinBox* keySizeSpinBox{}; /** Spinbox for the keys size (in bit) */ - QComboBox* keyTypeComboBox{}; /** Combobox for Keytpe */ - QDateTimeEdit* dateEdit{}; /** Dateedit for expiration date */ - QCheckBox* expireCheckBox{}; /** Checkbox, if key should expire */ - - // ENCR, SIGN, CERT, AUTH - std::vector<QCheckBox*> key_usage_check_boxes_; - QDateTime max_date_time_; - - QGroupBox* create_key_usage_group_box(); - QGroupBox* create_basic_info_group_box(); - void set_signal_slot(); - - /** - * @details Refresh widgets state by GenKeyInfo - */ - void refresh_widgets_state(); - - private slots: - - /** - * @details when expirebox was checked/unchecked, enable/disable the - * expiration date box - */ - void slotExpireBoxChanged(); - - /** - * @details check all lineedits for false entries. Show error, when there is - * one, otherwise generate the key - */ - void slotKeyGenAccept(); - - void slotEncryptionBoxChanged(int state); - - void slotSigningBoxChanged(int state); - - void slotCertificationBoxChanged(int state); - - void slotAuthenticationBoxChanged(int state); - - void slotActivatedKeyType(int index); -}; - -} // namespace GpgFrontend::UI - -#endif // GPGFRONTEND_SUBKEYGENERATEDIALOG_H diff --git a/src/ui/keypair_details/EditSubKeyDialog.cpp b/src/ui/keypair_details/EditSubKeyDialog.cpp deleted file mode 100644 index 6c2e0ce1..00000000 --- a/src/ui/keypair_details/EditSubKeyDialog.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "ui/keypair_details/EditSubKeyDialog.h" diff --git a/src/ui/keypair_details/EditSubKeyDialog.h b/src/ui/keypair_details/EditSubKeyDialog.h deleted file mode 100644 index 51842405..00000000 --- a/src/ui/keypair_details/EditSubKeyDialog.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_EDITSUBKEY_H -#define GPGFRONTEND_EDITSUBKEY_H - -class EditSubKeyDialog {}; - -#endif // GPGFRONTEND_EDITSUBKEY_H diff --git a/src/ui/keypair_details/KeyDetailsDialog.cpp b/src/ui/keypair_details/KeyDetailsDialog.cpp index 83be8af0..3b3e8818 100644 --- a/src/ui/keypair_details/KeyDetailsDialog.cpp +++ b/src/ui/keypair_details/KeyDetailsDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -32,14 +36,17 @@ namespace GpgFrontend::UI { KeyDetailsDialog::KeyDetailsDialog(const GpgKey& key, QWidget* parent) : QDialog(parent) { - tabWidget = new QTabWidget(); - tabWidget->addTab(new KeyPairDetailTab(key.id(), tabWidget), _("KeyPair")); - tabWidget->addTab(new KeyPairUIDTab(key.id(), tabWidget), _("UIDs")); - tabWidget->addTab(new KeyPairSubkeyTab(key.id(), tabWidget), _("Subkeys")); - tabWidget->addTab(new KeyPairOperaTab(key.id(), tabWidget), _("Operations")); + tab_widget_ = new QTabWidget(); + tab_widget_->addTab(new KeyPairDetailTab(key.GetId(), tab_widget_), + _("KeyPair")); + tab_widget_->addTab(new KeyPairUIDTab(key.GetId(), tab_widget_), _("UIDs")); + tab_widget_->addTab(new KeyPairSubkeyTab(key.GetId(), tab_widget_), + _("Subkeys")); + tab_widget_->addTab(new KeyPairOperaTab(key.GetId(), tab_widget_), + _("Operations")); auto* mainLayout = new QVBoxLayout; - mainLayout->addWidget(tabWidget); + mainLayout->addWidget(tab_widget_); #ifdef MACOS setAttribute(Qt::WA_LayoutUsesWidgetRect); diff --git a/src/ui/keypair_details/KeyDetailsDialog.h b/src/ui/keypair_details/KeyDetailsDialog.h index 72ae3f57..e6f4472c 100644 --- a/src/ui/keypair_details/KeyDetailsDialog.h +++ b/src/ui/keypair_details/KeyDetailsDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,26 +8,28 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef __KEYDETAILSDIALOG_H__ #define __KEYDETAILSDIALOG_H__ -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { @@ -37,7 +41,7 @@ class KeyDetailsDialog : public QDialog { explicit KeyDetailsDialog(const GpgKey& key, QWidget* parent = nullptr); private: - QTabWidget* tabWidget{}; + QTabWidget* tab_widget_{}; }; } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyNewUIDDialog.cpp b/src/ui/keypair_details/KeyNewUIDDialog.cpp index 809a05f8..9ff73f9e 100644 --- a/src/ui/keypair_details/KeyNewUIDDialog.cpp +++ b/src/ui/keypair_details/KeyNewUIDDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -24,68 +26,69 @@ #include "ui/keypair_details/KeyNewUIDDialog.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/UidOperator.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgUIDOperator.h" #include "ui/SignalStation.h" namespace GpgFrontend::UI { KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent) - : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { - name = new QLineEdit(); - name->setMinimumWidth(240); - email = new QLineEdit(); - email->setMinimumWidth(240); - comment = new QLineEdit(); - comment->setMinimumWidth(240); - createButton = new QPushButton("Create"); - errorLabel = new QLabel(); + : QDialog(parent), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { + name_ = new QLineEdit(); + name_->setMinimumWidth(240); + email_ = new QLineEdit(); + email_->setMinimumWidth(240); + comment_ = new QLineEdit(); + comment_->setMinimumWidth(240); + create_button_ = new QPushButton("Create"); + error_label_ = new QLabel(); auto gridLayout = new QGridLayout(); gridLayout->addWidget(new QLabel(_("Name")), 0, 0); gridLayout->addWidget(new QLabel(_("Email")), 1, 0); gridLayout->addWidget(new QLabel(_("Comment")), 2, 0); - gridLayout->addWidget(name, 0, 1); - gridLayout->addWidget(email, 1, 1); - gridLayout->addWidget(comment, 2, 1); + gridLayout->addWidget(name_, 0, 1); + gridLayout->addWidget(email_, 1, 1); + gridLayout->addWidget(comment_, 2, 1); - gridLayout->addWidget(createButton, 3, 0, 1, 2); + gridLayout->addWidget(create_button_, 3, 0, 1, 2); gridLayout->addWidget( new QLabel(_("Notice: The New UID Created will be set as Primary.")), 4, 0, 1, 2); - gridLayout->addWidget(errorLabel, 5, 0, 1, 2); + gridLayout->addWidget(error_label_, 5, 0, 1, 2); - connect(createButton, SIGNAL(clicked(bool)), this, SLOT(slotCreateNewUID())); + connect(create_button_, &QPushButton::clicked, this, + &KeyNewUIDDialog::slot_create_new_uid); this->setLayout(gridLayout); this->setWindowTitle(_("Create New UID")); this->setAttribute(Qt::WA_DeleteOnClose, true); this->setModal(true); - connect(this, SIGNAL(signalUIDCreated()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); + connect(this, &KeyNewUIDDialog::SignalUIDCreated, SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); } -void KeyNewUIDDialog::slotCreateNewUID() { +void KeyNewUIDDialog::slot_create_new_uid() { std::stringstream error_stream; /** * check for errors in keygen dialog input */ - if ((name->text()).size() < 5) { + if ((name_->text()).size() < 5) { error_stream << " " << _("Name must contain at least five characters.") << std::endl; } - if (email->text().isEmpty() || !check_email_address(email->text())) { + if (email_->text().isEmpty() || !check_email_address(email_->text())) { error_stream << " " << _("Please give a email address.") << std::endl; } auto error_string = error_stream.str(); if (error_string.empty()) { - if (UidOperator::GetInstance().addUID(mKey, name->text().toStdString(), - comment->text().toStdString(), - email->text().toStdString())) { + if (GpgUIDOperator::GetInstance().AddUID(m_key_, name_->text().toStdString(), + comment_->text().toStdString(), + email_->text().toStdString())) { emit finished(1); - emit signalUIDCreated(); + emit SignalUIDCreated(); } else emit finished(-1); @@ -93,17 +96,17 @@ void KeyNewUIDDialog::slotCreateNewUID() { /** * create error message */ - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); + error_label_->setAutoFillBackground(true); + QPalette error = error_label_->palette(); error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(error_string.c_str()); + error_label_->setPalette(error); + error_label_->setText(error_string.c_str()); this->show(); } } bool KeyNewUIDDialog::check_email_address(const QString& str) { - return re_email.match(str).hasMatch(); + return re_email_.match(str).hasMatch(); } } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyNewUIDDialog.h b/src/ui/keypair_details/KeyNewUIDDialog.h index 2e38a7f4..24f2c6b1 100644 --- a/src/ui/keypair_details/KeyNewUIDDialog.h +++ b/src/ui/keypair_details/KeyNewUIDDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -25,7 +27,7 @@ #ifndef GPGFRONTEND_KEYNEWUIDDIALOG_H #define GPGFRONTEND_KEYNEWUIDDIALOG_H -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { @@ -33,30 +35,51 @@ class KeyNewUIDDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Key New U I D Dialog object + * + * @param key + * @param parent + */ KeyNewUIDDialog(const KeyId& key, QWidget* parent = nullptr); signals: - void signalUIDCreated(); + /** + * @brief + * + */ + void SignalUIDCreated(); private slots: - void slotCreateNewUID(); + /** + * @brief + * + */ + void slot_create_new_uid(); private: - GpgKey mKey; + GpgKey m_key_; ///< - QLineEdit* name{}; - QLineEdit* email{}; - QLineEdit* comment{}; + QLineEdit* name_{}; ///< + QLineEdit* email_{}; ///< + QLineEdit* comment_{}; ///< - QPushButton* createButton{}; + QPushButton* create_button_{}; ///< - QStringList errorMessages; - QLabel* errorLabel{}; + QStringList error_messages_; ///< + QLabel* error_label_{}; ///< - QRegularExpression re_email{ + QRegularExpression re_email_{ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + /** + * @brief + * + * @param str + * @return true + * @return false + */ bool check_email_address(const QString& str); }; } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp index 49593d01..6174e67b 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/keypair_details/KeyPairDetailTab.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -24,41 +26,41 @@ #include "ui/keypair_details/KeyPairDetailTab.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExporter.h" +#include "dialog/WaitingDialog.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyImportExporter.h" #include "ui/SignalStation.h" -#include "ui/WaitingDialog.h" namespace GpgFrontend::UI { KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) : QWidget(parent), key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { - - LOG(INFO) << key_.email() <<key_.is_private_key() << key_.has_master_key() << key_.subKeys()->front().is_private_key(); - - ownerBox = new QGroupBox(_("Owner")); - keyBox = new QGroupBox(_("Primary Key")); - fingerprintBox = new QGroupBox(_("Fingerprint")); - additionalUidBox = new QGroupBox(_("Additional UIDs")); - - nameVarLabel = new QLabel(); - nameVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - emailVarLabel = new QLabel(); - emailVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - - commentVarLabel = new QLabel(); - commentVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - keyidVarLabel = new QLabel(); - keyidVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - - usageVarLabel = new QLabel(); - actualUsageVarLabel = new QLabel(); - - keySizeVarLabel = new QLabel(); - expireVarLabel = new QLabel(); - createdVarLabel = new QLabel(); - lastUpdateVarLabel = new QLabel(); - algorithmVarLabel = new QLabel(); - masterKeyExistVarLabel = new QLabel(); + LOG(INFO) << key_.GetEmail() << key_.IsPrivateKey() << key_.IsHasMasterKey() + << key_.GetSubKeys()->front().IsPrivateKey(); + + owner_box_ = new QGroupBox(_("Owner")); + key_box_ = new QGroupBox(_("Primary Key")); + fingerprint_box_ = new QGroupBox(_("Fingerprint")); + additional_uid_box_ = new QGroupBox(_("Additional UIDs")); + + name_var_label_ = new QLabel(); + name_var_label_->setTextInteractionFlags(Qt::TextSelectableByMouse); + email_var_label_ = new QLabel(); + email_var_label_->setTextInteractionFlags(Qt::TextSelectableByMouse); + + comment_var_label_ = new QLabel(); + comment_var_label_->setTextInteractionFlags(Qt::TextSelectableByMouse); + key_id_var_label = new QLabel(); + key_id_var_label->setTextInteractionFlags(Qt::TextSelectableByMouse); + + usage_var_label_ = new QLabel(); + actual_usage_var_label_ = new QLabel(); + + key_size_var_label_ = new QLabel(); + expire_var_label_ = new QLabel(); + created_var_label_ = new QLabel(); + last_update_var_label_ = new QLabel(); + algorithm_var_label_ = new QLabel(); + primary_key_exist_var_label_ = new QLabel(); auto* mvbox = new QVBoxLayout(); auto* vboxKD = new QGridLayout(); @@ -67,9 +69,9 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) vboxOD->addWidget(new QLabel(QString(_("Name")) + ": "), 0, 0); vboxOD->addWidget(new QLabel(QString(_("Email Address")) + ": "), 1, 0); vboxOD->addWidget(new QLabel(QString(_("Comment")) + ": "), 2, 0); - vboxOD->addWidget(nameVarLabel, 0, 1); - vboxOD->addWidget(emailVarLabel, 1, 1); - vboxOD->addWidget(commentVarLabel, 2, 1); + vboxOD->addWidget(name_var_label_, 0, 1); + vboxOD->addWidget(email_var_label_, 1, 1); + vboxOD->addWidget(comment_var_label_, 2, 1); vboxKD->addWidget(new QLabel(QString(_("Key ID")) + ": "), 0, 0); vboxKD->addWidget(new QLabel(QString(_("Algorithm")) + ": "), 1, 0); @@ -85,181 +87,188 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) vboxKD->addWidget(new QLabel(QString(_("Primary Key Existence")) + ": "), 8, 0); - keyidVarLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - vboxKD->addWidget(keyidVarLabel, 0, 1, 1, 1); - vboxKD->addWidget(algorithmVarLabel, 1, 1, 1, 2); - vboxKD->addWidget(keySizeVarLabel, 2, 1, 1, 2); - vboxKD->addWidget(usageVarLabel, 3, 1, 1, 2); - vboxKD->addWidget(actualUsageVarLabel, 4, 1, 1, 2); - vboxKD->addWidget(createdVarLabel, 5, 1, 1, 2); - vboxKD->addWidget(expireVarLabel, 6, 1, 1, 2); - vboxKD->addWidget(lastUpdateVarLabel, 7, 1, 1, 2); - vboxKD->addWidget(masterKeyExistVarLabel, 8, 1, 1, 2); + key_id_var_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + vboxKD->addWidget(key_id_var_label, 0, 1, 1, 1); + vboxKD->addWidget(algorithm_var_label_, 1, 1, 1, 2); + vboxKD->addWidget(key_size_var_label_, 2, 1, 1, 2); + vboxKD->addWidget(usage_var_label_, 3, 1, 1, 2); + vboxKD->addWidget(actual_usage_var_label_, 4, 1, 1, 2); + vboxKD->addWidget(created_var_label_, 5, 1, 1, 2); + vboxKD->addWidget(expire_var_label_, 6, 1, 1, 2); + vboxKD->addWidget(last_update_var_label_, 7, 1, 1, 2); + vboxKD->addWidget(primary_key_exist_var_label_, 8, 1, 1, 2); auto* copyKeyIdButton = new QPushButton(_("Copy")); copyKeyIdButton->setFlat(true); copyKeyIdButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); vboxKD->addWidget(copyKeyIdButton, 0, 2); connect(copyKeyIdButton, &QPushButton::clicked, this, [=]() { - QString fpr = keyidVarLabel->text().trimmed(); + QString fpr = key_id_var_label->text().trimmed(); QClipboard* cb = QApplication::clipboard(); cb->setText(fpr); }); - ownerBox->setLayout(vboxOD); - mvbox->addWidget(ownerBox); - keyBox->setLayout(vboxKD); - mvbox->addWidget(keyBox); + owner_box_->setLayout(vboxOD); + mvbox->addWidget(owner_box_); + key_box_->setLayout(vboxKD); + mvbox->addWidget(key_box_); - fingerPrintVarLabel = new QLabel(); - fingerPrintVarLabel->setWordWrap(false); - fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;"); - fingerPrintVarLabel->setAlignment(Qt::AlignCenter); + fingerprint_var_label_ = new QLabel(); + fingerprint_var_label_->setWordWrap(false); + fingerprint_var_label_->setTextInteractionFlags(Qt::TextSelectableByMouse); + fingerprint_var_label_->setStyleSheet("margin-left: 0; margin-right: 5;"); + fingerprint_var_label_->setAlignment(Qt::AlignCenter); auto* hboxFP = new QHBoxLayout(); hboxFP->addStretch(); - hboxFP->addWidget(fingerPrintVarLabel); + hboxFP->addWidget(fingerprint_var_label_); auto* copyFingerprintButton = new QPushButton(_("Copy")); copyFingerprintButton->setFlat(true); copyFingerprintButton->setToolTip(_("copy fingerprint to clipboard")); - connect(copyFingerprintButton, SIGNAL(clicked()), this, - SLOT(slotCopyFingerprint())); + connect(copyFingerprintButton, &QPushButton::clicked, this, + &KeyPairDetailTab::slot_copy_fingerprint); hboxFP->addWidget(copyFingerprintButton); hboxFP->addStretch(); - fingerprintBox->setLayout(hboxFP); - mvbox->addWidget(fingerprintBox); + fingerprint_box_->setLayout(hboxFP); + mvbox->addWidget(fingerprint_box_); mvbox->addStretch(); auto* expBox = new QHBoxLayout(); QPixmap pixmap(":warning.png"); - expLabel = new QLabel(); - iconLabel = new QLabel(); + exp_label_ = new QLabel(); + icon_label_ = new QLabel(); - iconLabel->setPixmap(pixmap.scaled(24, 24, Qt::KeepAspectRatio)); - expLabel->setAlignment(Qt::AlignCenter); + icon_label_->setPixmap(pixmap.scaled(24, 24, Qt::KeepAspectRatio)); + exp_label_->setAlignment(Qt::AlignCenter); expBox->addStretch(); - expBox->addWidget(iconLabel); - expBox->addWidget(expLabel); + expBox->addWidget(icon_label_); + expBox->addWidget(exp_label_); expBox->addStretch(); mvbox->addLayout(expBox); mvbox->setContentsMargins(0, 0, 0, 0); // when key database updated - connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, - SLOT(slotRefreshKey())); + connect(SignalStation::GetInstance(), &SignalStation::SignalKeyDatabaseRefresh, this, + &KeyPairDetailTab::slot_refresh_key); - slotRefreshKeyInfo(); + slot_refresh_key_info(); setAttribute(Qt::WA_DeleteOnClose, true); setLayout(mvbox); } -void KeyPairDetailTab::slotCopyFingerprint() { - QString fpr = fingerPrintVarLabel->text().trimmed().replace(" ", QString()); +void KeyPairDetailTab::slot_copy_fingerprint() { + QString fpr = + fingerprint_var_label_->text().trimmed().replace(" ", QString()); QClipboard* cb = QApplication::clipboard(); cb->setText(fpr); } -void KeyPairDetailTab::slotRefreshKeyInfo() { +void KeyPairDetailTab::slot_refresh_key_info() { // Show the situation that primary key not exists. - masterKeyExistVarLabel->setText(key_.has_master_key() ? _("Exists") + primary_key_exist_var_label_->setText(key_.IsHasMasterKey() ? _("Exists") : _("Not Exists")); - if (!key_.has_master_key()) { - auto palette_expired = masterKeyExistVarLabel->palette(); - palette_expired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red); - masterKeyExistVarLabel->setPalette(palette_expired); + if (!key_.IsHasMasterKey()) { + auto palette_expired = primary_key_exist_var_label_->palette(); + palette_expired.setColor(primary_key_exist_var_label_->foregroundRole(), Qt::red); + primary_key_exist_var_label_->setPalette(palette_expired); } else { - auto palette_valid = masterKeyExistVarLabel->palette(); - palette_valid.setColor(masterKeyExistVarLabel->foregroundRole(), + auto palette_valid = primary_key_exist_var_label_->palette(); + palette_valid.setColor(primary_key_exist_var_label_->foregroundRole(), Qt::darkGreen); - masterKeyExistVarLabel->setPalette(palette_valid); + primary_key_exist_var_label_->setPalette(palette_valid); } - if (key_.expired()) { - auto paletteExpired = expireVarLabel->palette(); - paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red); - expireVarLabel->setPalette(paletteExpired); + if (key_.IsExpired()) { + auto paletteExpired = expire_var_label_->palette(); + paletteExpired.setColor(expire_var_label_->foregroundRole(), Qt::red); + expire_var_label_->setPalette(paletteExpired); } else { - auto paletteValid = expireVarLabel->palette(); - paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen); - expireVarLabel->setPalette(paletteValid); + auto paletteValid = expire_var_label_->palette(); + paletteValid.setColor(expire_var_label_->foregroundRole(), Qt::darkGreen); + expire_var_label_->setPalette(paletteValid); } - nameVarLabel->setText(QString::fromStdString(key_.name())); - emailVarLabel->setText(QString::fromStdString(key_.email())); + name_var_label_->setText(QString::fromStdString(key_.GetName())); + email_var_label_->setText(QString::fromStdString(key_.GetEmail())); - commentVarLabel->setText(QString::fromStdString(key_.comment())); - keyidVarLabel->setText(QString::fromStdString(key_.id())); + comment_var_label_->setText(QString::fromStdString(key_.GetComment())); + key_id_var_label->setText(QString::fromStdString(key_.GetId())); std::stringstream usage_steam; - if (key_.can_certify()) usage_steam << _("Certificate") << " "; - if (key_.can_encrypt()) usage_steam << _("Encrypt") << " "; - if (key_.can_sign()) usage_steam << _("Sign") << " "; - if (key_.can_authenticate()) usage_steam << _("Auth") << " "; + if (key_.IsHasCertificationCapability()) + usage_steam << _("Certificate") << " "; + if (key_.IsHasEncryptionCapability()) usage_steam << _("Encrypt") << " "; + if (key_.IsHasSigningCapability()) usage_steam << _("Sign") << " "; + if (key_.IsHasAuthenticationCapability()) usage_steam << _("Auth") << " "; - usageVarLabel->setText(usage_steam.str().c_str()); + usage_var_label_->setText(usage_steam.str().c_str()); std::stringstream actual_usage_steam; - if (key_.CanCertActual()) actual_usage_steam << _("Certificate") << " "; - if (key_.CanEncrActual()) actual_usage_steam << _("Encrypt") << " "; - if (key_.CanSignActual()) actual_usage_steam << _("Sign") << " "; - if (key_.CanAuthActual()) actual_usage_steam << _("Auth") << " "; + if (key_.IsHasActualCertificationCapability()) + actual_usage_steam << _("Certificate") << " "; + if (key_.IsHasActualEncryptionCapability()) + actual_usage_steam << _("Encrypt") << " "; + if (key_.IsHasActualSigningCapability()) + actual_usage_steam << _("Sign") << " "; + if (key_.IsHasActualAuthenticationCapability()) + actual_usage_steam << _("Auth") << " "; - actualUsageVarLabel->setText(actual_usage_steam.str().c_str()); + actual_usage_var_label_->setText(actual_usage_steam.str().c_str()); std::string key_size_val, key_expire_val, key_create_time_val, key_algo_val, key_last_update_val; - key_size_val = std::to_string(key_.length()); + key_size_val = std::to_string(key_.GetPrimaryKeyLength()); - if (to_time_t(boost::posix_time::ptime(key_.expires())) == 0) { - expireVarLabel->setText(_("Never Expire")); + if (to_time_t(boost::posix_time::ptime(key_.GetExpireTime())) == 0) { + expire_var_label_->setText(_("Never Expire")); } else { - expireVarLabel->setText(QLocale::system().toString( - QDateTime::fromTime_t(to_time_t(key_.expires())))); + expire_var_label_->setText(QLocale::system().toString( + QDateTime::fromTime_t(to_time_t(key_.GetExpireTime())))); } - key_algo_val = key_.pubkey_algo(); + key_algo_val = key_.GetPublicKeyAlgo(); - createdVarLabel->setText(QLocale::system().toString( - QDateTime::fromTime_t(to_time_t(key_.create_time())))); + created_var_label_->setText(QLocale::system().toString( + QDateTime::fromTime_t(to_time_t(key_.GetCreateTime())))); - if (to_time_t(boost::posix_time::ptime(key_.last_update())) == 0) { - lastUpdateVarLabel->setText(_("No Data")); + if (to_time_t(boost::posix_time::ptime(key_.GetLastUpdateTime())) == 0) { + last_update_var_label_->setText(_("No Data")); } else { - lastUpdateVarLabel->setText(QLocale::system().toString( - QDateTime::fromTime_t(to_time_t(key_.last_update())))); + last_update_var_label_->setText(QLocale::system().toString( + QDateTime::fromTime_t(to_time_t(key_.GetLastUpdateTime())))); } - keySizeVarLabel->setText(key_size_val.c_str()); - algorithmVarLabel->setText(key_algo_val.c_str()); - fingerPrintVarLabel->setText(beautify_fingerprint(key_.fpr()).c_str()); + key_size_var_label_->setText(key_size_val.c_str()); + algorithm_var_label_->setText(key_algo_val.c_str()); + fingerprint_var_label_->setText( + beautify_fingerprint(key_.GetFingerprint()).c_str()); - iconLabel->hide(); - expLabel->hide(); + icon_label_->hide(); + exp_label_->hide(); - if (key_.expired()) { - iconLabel->show(); - expLabel->show(); - expLabel->setText(_("Warning: The primary key has expired.")); + if (key_.IsExpired()) { + icon_label_->show(); + exp_label_->show(); + exp_label_->setText(_("Warning: The primary key has expired.")); } - if (key_.revoked()) { - iconLabel->show(); - expLabel->show(); - expLabel->setText(_("Warning: The primary key has been revoked.")); + if (key_.IsRevoked()) { + icon_label_->show(); + exp_label_->show(); + exp_label_->setText(_("Warning: The primary key has been revoked.")); } } -void KeyPairDetailTab::slotRefreshKey() { +void KeyPairDetailTab::slot_refresh_key() { LOG(INFO) << _("Called"); - this->key_ = GpgKeyGetter::GetInstance().GetKey(key_.id()); - this->slotRefreshKeyInfo(); + this->key_ = GpgKeyGetter::GetInstance().GetKey(key_.GetId()); + this->slot_refresh_key_info(); } } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairDetailTab.h b/src/ui/keypair_details/KeyPairDetailTab.h index 151d8fc7..9d0d6560 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.h +++ b/src/ui/keypair_details/KeyPairDetailTab.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -26,10 +28,10 @@ #define GPGFRONTEND_KEYPAIRDETAILTAB_H #include "KeySetExpireDateDialog.h" -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" +#include "import_export/KeyServerImportDialog.h" +#include "import_export/KeyUploadDialog.h" #include "ui/GpgFrontendUI.h" -#include "ui/KeyServerImportDialog.h" -#include "ui/KeyUploadDialog.h" namespace GpgFrontend::UI { @@ -41,42 +43,53 @@ class KeyPairDetailTab : public QWidget { /** * @details Copy the fingerprint to clipboard */ - void slotCopyFingerprint(); + void slot_copy_fingerprint(); - void slotRefreshKeyInfo(); + /** + * @brief + * + */ + void slot_refresh_key_info(); - void slotRefreshKey(); + /** + * @brief + * + */ + void slot_refresh_key(); private: - GpgKey key_; - - QGroupBox* ownerBox; /** Groupbox containing owner information */ - QGroupBox* keyBox; /** Groupbox containing key information */ - QGroupBox* fingerprintBox; /** Groupbox containing fingerprint information */ - QGroupBox* additionalUidBox; /** Groupbox containing information about - additional uids */ - - QLabel* nameVarLabel; /** Label containng the keys name */ - QLabel* emailVarLabel; /** Label containng the keys email */ - QLabel* commentVarLabel; /** Label containng the keys commment */ - QLabel* keySizeVarLabel; /** Label containng the keys keysize */ - QLabel* expireVarLabel; /** Label containng the keys expiration date */ - QLabel* createdVarLabel; /** Label containng the keys creation date */ - QLabel* lastUpdateVarLabel; - QLabel* algorithmVarLabel; /** Label containng the keys algorithm */ - QLabel* keyidVarLabel; /** Label containng the keys keyid */ - QLabel* fingerPrintVarLabel; /** Label containng the keys fingerprint */ - QLabel* usageVarLabel; - QLabel* actualUsageVarLabel; - QLabel* masterKeyExistVarLabel; - - QLabel* iconLabel; - QLabel* expLabel; - - QMenu* keyServerOperaMenu{}; - QMenu* secretKeyExportOperaMenu{}; + GpgKey key_; ///< + + QGroupBox* owner_box_; ///< Groupbox containing owner information + QGroupBox* key_box_; ///< Groupbox containing key information + QGroupBox* fingerprint_box_; ///< Groupbox containing fingerprint information + QGroupBox* additional_uid_box_; ///< Groupbox containing information about + ///< additional uids + + QLabel* name_var_label_; ///< Label containing the keys name + QLabel* email_var_label_; ///< Label containing the keys email + QLabel* comment_var_label_; ///< Label containing the keys comment + QLabel* key_size_var_label_; ///< Label containing the keys key size + QLabel* expire_var_label_; ///< Label containing the keys expiration date + QLabel* created_var_label_; ///< Label containing the keys creation date + QLabel* last_update_var_label_; ///< + QLabel* algorithm_var_label_; ///< Label containing the keys algorithm + QLabel* key_id_var_label; ///< Label containing the keys keyid + QLabel* fingerprint_var_label_; ///< Label containing the keys fingerprint + QLabel* usage_var_label_; + QLabel* actual_usage_var_label_; + QLabel* primary_key_exist_var_label_; + + QLabel* icon_label_; ///< + QLabel* exp_label_; ///< public: + /** + * @brief Construct a new Key Pair Detail Tab object + * + * @param key_id + * @param parent + */ explicit KeyPairDetailTab(const std::string& key_id, QWidget* parent = nullptr); }; diff --git a/src/ui/keypair_details/KeyPairOperaTab.cpp b/src/ui/keypair_details/KeyPairOperaTab.cpp index 57eb8164..988ce527 100644 --- a/src/ui/keypair_details/KeyPairOperaTab.cpp +++ b/src/ui/keypair_details/KeyPairOperaTab.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -24,9 +26,9 @@ #include "KeyPairOperaTab.h" -#include "gpg/function/GpgKeyImportExporter.h" -#include "gpg/function/GpgKeyOpera.h" -#include "ui/KeyUploadDialog.h" +#include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/function/gpg/GpgKeyOpera.h" +#include "import_export/KeyUploadDialog.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" #include "ui/keypair_details/KeySetExpireDateDialog.h" @@ -36,7 +38,7 @@ namespace GpgFrontend::UI { KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent) : QWidget(parent), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { // Set Menu - createOperaMenu(); + CreateOperaMenu(); auto m_vbox = new QVBoxLayout(this); auto* opera_key_box = new QGroupBox(_("General Operations")); @@ -47,24 +49,24 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent) auto* export_public_button = new QPushButton(_("Export Public Key")); export_h_box_layout->addWidget(export_public_button); - connect(export_public_button, SIGNAL(clicked()), this, - SLOT(slotExportPublicKey())); + connect(export_public_button, &QPushButton::clicked, this, + &KeyPairOperaTab::slot_export_public_key); - if (m_key_.is_private_key()) { + if (m_key_.IsPrivateKey()) { auto* export_private_button = new QPushButton(_("Export Private Key")); export_private_button->setStyleSheet("text-align:center;"); - export_private_button->setMenu(secretKeyExportOperaMenu); + export_private_button->setMenu(secret_key_export_opera_menu_); export_h_box_layout->addWidget(export_private_button); - if (m_key_.has_master_key()) { + if (m_key_.IsHasMasterKey()) { auto* edit_expires_button = new QPushButton(_("Modify Expiration Datetime (Primary Key)")); - connect(edit_expires_button, SIGNAL(clicked()), this, - SLOT(slotModifyEditDatetime())); + connect(edit_expires_button, &QPushButton::clicked, this, + &KeyPairOperaTab::slot_modify_edit_datetime); auto* edit_password_button = new QPushButton(_("Modify Password")); - connect(edit_password_button, SIGNAL(clicked()), this, - SLOT(slotModifyPassword())); - + connect(edit_password_button, &QPushButton::clicked, this, + &KeyPairOperaTab::slot_modify_password); + vbox_p_k->addWidget(edit_expires_button); vbox_p_k->addWidget(edit_password_button); } @@ -74,20 +76,20 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent) auto* key_server_opera_button = new QPushButton(_("Key Server Operation (Pubkey)")); key_server_opera_button->setStyleSheet("text-align:center;"); - key_server_opera_button->setMenu(keyServerOperaMenu); + key_server_opera_button->setMenu(key_server_opera_menu_); advance_h_box_layout->addWidget(key_server_opera_button); - if (m_key_.is_private_key() && m_key_.has_master_key()) { + if (m_key_.IsPrivateKey() && m_key_.IsHasMasterKey()) { auto* revoke_cert_gen_button = new QPushButton(_("Generate Revoke Certificate")); - connect(revoke_cert_gen_button, SIGNAL(clicked()), this, - SLOT(slotGenRevokeCert())); + connect(revoke_cert_gen_button, &QPushButton::clicked, this, + &KeyPairOperaTab::slot_gen_revoke_cert); advance_h_box_layout->addWidget(revoke_cert_gen_button); } auto* modify_tofu_button = new QPushButton(_("Modify TOFU Policy")); - connect(modify_tofu_button, SIGNAL(clicked()), this, - SLOT(slotModifyTOFUPolicy())); + connect(modify_tofu_button, &QPushButton::clicked, this, + &KeyPairOperaTab::slot_modify_tofu_policy); vbox_p_k->addLayout(advance_h_box_layout); opera_key_box->setLayout(vbox_p_k); @@ -98,44 +100,44 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent) setLayout(m_vbox); } -void KeyPairOperaTab::createOperaMenu() { - keyServerOperaMenu = new QMenu(this); +void KeyPairOperaTab::CreateOperaMenu() { + key_server_opera_menu_ = new QMenu(this); auto* uploadKeyPair = new QAction(_("Upload Key Pair to Key Server"), this); - connect(uploadKeyPair, SIGNAL(triggered()), this, - SLOT(slotUploadKeyToServer())); - if (!(m_key_.is_private_key() && m_key_.has_master_key())) + connect(uploadKeyPair, &QAction::triggered, this, + &KeyPairOperaTab::slot_upload_key_to_server); + if (!(m_key_.IsPrivateKey() && m_key_.IsHasMasterKey())) uploadKeyPair->setDisabled(true); auto* updateKeyPair = new QAction(_("Sync Key Pair From Key Server"), this); - connect(updateKeyPair, SIGNAL(triggered()), this, - SLOT(slotUpdateKeyFromServer())); + connect(updateKeyPair, &QAction::triggered, this, + &KeyPairOperaTab::slot_update_key_from_server); // when a key has primary key, it should always upload to keyserver. - if (m_key_.has_master_key()) { + if (m_key_.IsHasMasterKey()) { updateKeyPair->setDisabled(true); } - keyServerOperaMenu->addAction(uploadKeyPair); - keyServerOperaMenu->addAction(updateKeyPair); + key_server_opera_menu_->addAction(uploadKeyPair); + key_server_opera_menu_->addAction(updateKeyPair); - secretKeyExportOperaMenu = new QMenu(this); + secret_key_export_opera_menu_ = new QMenu(this); auto* exportFullSecretKey = new QAction(_("Export Full Secret Key"), this); - connect(exportFullSecretKey, SIGNAL(triggered()), this, - SLOT(slotExportPrivateKey())); - if (!m_key_.is_private_key()) exportFullSecretKey->setDisabled(true); + connect(exportFullSecretKey, &QAction::triggered, this, + &KeyPairOperaTab::slot_export_private_key); + if (!m_key_.IsPrivateKey()) exportFullSecretKey->setDisabled(true); auto* exportShortestSecretKey = new QAction(_("Export Shortest Secret Key"), this); - connect(exportShortestSecretKey, SIGNAL(triggered()), this, - SLOT(slotExportShortPrivateKey())); + connect(exportShortestSecretKey, &QAction::triggered, this, + &KeyPairOperaTab::slot_export_short_private_key); - secretKeyExportOperaMenu->addAction(exportFullSecretKey); - secretKeyExportOperaMenu->addAction(exportShortestSecretKey); + secret_key_export_opera_menu_->addAction(exportFullSecretKey); + secret_key_export_opera_menu_->addAction(exportShortestSecretKey); } -void KeyPairOperaTab::slotExportPublicKey() { +void KeyPairOperaTab::slot_export_public_key() { ByteArrayPtr keyArray = nullptr; if (!GpgKeyImportExporter::GetInstance().ExportKey(m_key_, keyArray)) { @@ -143,8 +145,8 @@ void KeyPairOperaTab::slotExportPublicKey() { _("An error occurred during the export operation.")); return; } - auto file_string = - m_key_.name() + " " + m_key_.email() + "(" + m_key_.id() + ")_pub.asc"; + auto file_string = m_key_.GetName() + " " + m_key_.GetEmail() + "(" + + m_key_.GetId() + ")_pub.asc"; auto file_name = QFileDialog::getSaveFileName( this, _("Export Key To File"), QString::fromStdString(file_string), @@ -161,7 +163,7 @@ void KeyPairOperaTab::slotExportPublicKey() { } } -void KeyPairOperaTab::slotExportShortPrivateKey() { +void KeyPairOperaTab::slot_export_short_private_key() { // Show a information box with explanation about private key int ret = QMessageBox::information( this, _("Exporting short private Key"), @@ -186,8 +188,8 @@ void KeyPairOperaTab::slotExportShortPrivateKey() { _("An error occurred during the export operation.")); return; } - auto file_string = m_key_.name() + " " + m_key_.email() + "(" + - m_key_.id() + ")_short_secret.asc"; + auto file_string = m_key_.GetName() + " " + m_key_.GetEmail() + "(" + + m_key_.GetId() + ")_short_secret.asc"; auto file_name = QFileDialog::getSaveFileName( this, _("Export Key To File"), QString::fromStdString(file_string), @@ -205,7 +207,7 @@ void KeyPairOperaTab::slotExportShortPrivateKey() { } } -void KeyPairOperaTab::slotExportPrivateKey() { +void KeyPairOperaTab::slot_export_private_key() { // Show a information box with explanation about private key int ret = QMessageBox::information( this, _("Exporting private Key"), @@ -226,8 +228,8 @@ void KeyPairOperaTab::slotExportPrivateKey() { _("An error occurred during the export operation.")); return; } - auto file_string = m_key_.name() + " " + m_key_.email() + "(" + - m_key_.id() + ")_full_secret.asc"; + auto file_string = m_key_.GetName() + " " + m_key_.GetEmail() + "(" + + m_key_.GetId() + ")_full_secret.asc"; auto file_name = QFileDialog::getSaveFileName( this, _("Export Key To File"), QString::fromStdString(file_string), @@ -245,28 +247,28 @@ void KeyPairOperaTab::slotExportPrivateKey() { } } -void KeyPairOperaTab::slotModifyEditDatetime() { - auto dialog = new KeySetExpireDateDialog(m_key_.id(), this); +void KeyPairOperaTab::slot_modify_edit_datetime() { + auto dialog = new KeySetExpireDateDialog(m_key_.GetId(), this); dialog->show(); } -void KeyPairOperaTab::slotUploadKeyToServer() { +void KeyPairOperaTab::slot_upload_key_to_server() { auto keys = std::make_unique<KeyIdArgsList>(); - keys->push_back(m_key_.id()); + keys->push_back(m_key_.GetId()); auto* dialog = new KeyUploadDialog(keys, this); dialog->show(); - dialog->slotUpload(); + dialog->SlotUpload(); } -void KeyPairOperaTab::slotUpdateKeyFromServer() { +void KeyPairOperaTab::slot_update_key_from_server() { auto keys = std::make_unique<KeyIdArgsList>(); - keys->push_back(m_key_.id()); + keys->push_back(m_key_.GetId()); auto* dialog = new KeyServerImportDialog(this); dialog->show(); - dialog->slotImport(keys); + dialog->SlotImport(keys); } -void KeyPairOperaTab::slotGenRevokeCert() { +void KeyPairOperaTab::slot_gen_revoke_cert() { auto literal = QString("%1 (*.rev)").arg(_("Revocation Certificates")); QString m_output_file_name; @@ -278,9 +280,9 @@ void KeyPairOperaTab::slotGenRevokeCert() { if (dialog.exec()) m_output_file_name = dialog.selectedFiles().front(); if (!m_output_file_name.isEmpty()) - CommonUtils::GetInstance()->slotExecuteGpgCommand( + CommonUtils::GetInstance()->SlotExecuteGpgCommand( {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o", - m_output_file_name, "--gen-revoke", m_key_.fpr().c_str()}, + m_output_file_name, "--gen-revoke", m_key_.GetFingerprint().c_str()}, [](QProcess* proc) -> void { // Code From Gpg4Win while (proc->canReadLine()) { @@ -307,7 +309,7 @@ void KeyPairOperaTab::slotGenRevokeCert() { }); } -void KeyPairOperaTab::slotModifyPassword() { +void KeyPairOperaTab::slot_modify_password() { auto err = GpgKeyOpera::GetInstance().ModifyPassword(m_key_); if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) { QMessageBox::critical(this, _("Not Successful"), @@ -315,7 +317,7 @@ void KeyPairOperaTab::slotModifyPassword() { } } -void KeyPairOperaTab::slotModifyTOFUPolicy() { +void KeyPairOperaTab::slot_modify_tofu_policy() { QStringList items; items << _("Policy Auto") << _("Policy Good") << _("Policy Bad") << _("Policy Ask") << _("Policy Unknown"); diff --git a/src/ui/keypair_details/KeyPairOperaTab.h b/src/ui/keypair_details/KeyPairOperaTab.h index f8a5ded9..af6b1eee 100644 --- a/src/ui/keypair_details/KeyPairOperaTab.h +++ b/src/ui/keypair_details/KeyPairOperaTab.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -25,44 +27,86 @@ #ifndef GPGFRONTEND_KEYPAIROPERATAB_H #define GPGFRONTEND_KEYPAIROPERATAB_H -#include "gpg/function/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyGetter.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { class KeyPairOperaTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Key Pair Opera Tab object + * + * @param key_id + * @param parent + */ KeyPairOperaTab(const std::string& key_id, QWidget* parent); - void createOperaMenu(); + /** + * @brief Create a Opera Menu object + * + */ + void CreateOperaMenu(); private slots: /** * @details Export the key to a file, which is chosen in a file dialog */ - void slotExportPrivateKey(); + void slot_export_private_key(); - void slotExportShortPrivateKey(); + /** + * @brief + * + */ + void slot_export_short_private_key(); - void slotExportPublicKey(); + /** + * @brief + * + */ + void slot_export_public_key(); - void slotModifyEditDatetime(); + /** + * @brief + * + */ + void slot_modify_edit_datetime(); - void slotModifyPassword(); + /** + * @brief + * + */ + void slot_modify_password(); - void slotUploadKeyToServer(); + /** + * @brief + * + */ + void slot_upload_key_to_server(); - void slotUpdateKeyFromServer(); + /** + * @brief + * + */ + void slot_update_key_from_server(); - void slotGenRevokeCert(); + /** + * @brief + * + */ + void slot_gen_revoke_cert(); - void slotModifyTOFUPolicy(); + /** + * @brief + * + */ + void slot_modify_tofu_policy(); private: - GpgKey m_key_; - QMenu* keyServerOperaMenu{}; - QMenu* secretKeyExportOperaMenu{}; + GpgKey m_key_; ///< + QMenu* key_server_opera_menu_{}; ///< + QMenu* secret_key_export_opera_menu_{}; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/keypair_details/KeyPairSubkeyTab.cpp index a80eb5e4..067ce110 100644 --- a/src/ui/keypair_details/KeyPairSubkeyTab.cpp +++ b/src/ui/keypair_details/KeyPairSubkeyTab.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,44 +8,46 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "ui/keypair_details/KeyPairSubkeyTab.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyGetter.h" #include "ui/SignalStation.h" namespace GpgFrontend::UI { KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent) : QWidget(parent), key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { + LOG(INFO) << key_.GetEmail() << key_.IsPrivateKey() << key_.IsHasMasterKey() + << key_.GetSubKeys()->front().IsPrivateKey(); - LOG(INFO) << key_.email() <<key_.is_private_key() << key_.has_master_key() << key_.subKeys()->front().is_private_key(); - - createSubkeyList(); - createSubkeyOperaMenu(); + create_subkey_list(); + create_subkey_opera_menu(); - listBox = new QGroupBox(_("Subkey List")); - detailBox = new QGroupBox(_("Detail of Selected Subkey")); + list_box_ = new QGroupBox(_("Subkey List")); + detail_box_ = new QGroupBox(_("Detail of Selected Subkey")); auto uidButtonsLayout = new QGridLayout(); auto addSubkeyButton = new QPushButton(_("Generate A New Subkey")); - if (!key_.is_private_key() || !key_.has_master_key()) { + if (!key_.IsPrivateKey() || !key_.IsHasMasterKey()) { addSubkeyButton->setDisabled(true); setHidden(addSubkeyButton); } @@ -53,7 +57,7 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent) auto* baseLayout = new QVBoxLayout(); auto subkeyListLayout = new QGridLayout(); - subkeyListLayout->addWidget(subkeyList, 0, 0); + subkeyListLayout->addWidget(subkey_list_, 0, 0); subkeyListLayout->addLayout(uidButtonsLayout, 1, 0); subkeyListLayout->setContentsMargins(0, 10, 0, 0); @@ -76,254 +80,259 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent) subkeyDetailLayout->addWidget(new QLabel(QString(_("Fingerprint")) + ": "), 8, 0); - keyidVarLabel = new QLabel(this); - keySizeVarLabel = new QLabel(this); - expireVarLabel = new QLabel(this); - algorithmVarLabel = new QLabel(this); - createdVarLabel = new QLabel(this); - usageVarLabel = new QLabel(this); - masterKeyExistVarLabel = new QLabel(this); - fingerPrintVarLabel = new QLabel(this); - cardKeyLabel = new QLabel(this); - - subkeyDetailLayout->addWidget(keyidVarLabel, 0, 1, 1, 1); - subkeyDetailLayout->addWidget(keySizeVarLabel, 2, 1, 1, 2); - subkeyDetailLayout->addWidget(expireVarLabel, 4, 1, 1, 2); - subkeyDetailLayout->addWidget(algorithmVarLabel, 1, 1, 1, 2); - subkeyDetailLayout->addWidget(createdVarLabel, 5, 1, 1, 2); - subkeyDetailLayout->addWidget(usageVarLabel, 3, 1, 1, 2); - subkeyDetailLayout->addWidget(masterKeyExistVarLabel, 6, 1, 1, 2); - subkeyDetailLayout->addWidget(cardKeyLabel, 7, 1, 1, 2); - subkeyDetailLayout->addWidget(fingerPrintVarLabel, 8, 1, 1, 2); + key_id_var_label_ = new QLabel(this); + key_size_var_label_ = new QLabel(this); + expire_var_label_ = new QLabel(this); + algorithm_var_label_ = new QLabel(this); + created_var_label_ = new QLabel(this); + usage_var_label_ = new QLabel(this); + master_key_exist_var_label_ = new QLabel(this); + fingerprint_var_label_ = new QLabel(this); + card_key_label_ = new QLabel(this); + + subkeyDetailLayout->addWidget(key_id_var_label_, 0, 1, 1, 1); + subkeyDetailLayout->addWidget(key_size_var_label_, 2, 1, 1, 2); + subkeyDetailLayout->addWidget(expire_var_label_, 4, 1, 1, 2); + subkeyDetailLayout->addWidget(algorithm_var_label_, 1, 1, 1, 2); + subkeyDetailLayout->addWidget(created_var_label_, 5, 1, 1, 2); + subkeyDetailLayout->addWidget(usage_var_label_, 3, 1, 1, 2); + subkeyDetailLayout->addWidget(master_key_exist_var_label_, 6, 1, 1, 2); + subkeyDetailLayout->addWidget(card_key_label_, 7, 1, 1, 2); + subkeyDetailLayout->addWidget(fingerprint_var_label_, 8, 1, 1, 2); auto* copyKeyIdButton = new QPushButton(_("Copy")); copyKeyIdButton->setFlat(true); subkeyDetailLayout->addWidget(copyKeyIdButton, 0, 2); connect(copyKeyIdButton, &QPushButton::clicked, this, [=]() { - QString fpr = keyidVarLabel->text().trimmed(); + QString fpr = key_id_var_label_->text().trimmed(); QClipboard* cb = QApplication::clipboard(); cb->setText(fpr); }); - listBox->setLayout(subkeyListLayout); - listBox->setContentsMargins(0, 12, 0, 0); - detailBox->setLayout(subkeyDetailLayout); + list_box_->setLayout(subkeyListLayout); + list_box_->setContentsMargins(0, 12, 0, 0); + detail_box_->setLayout(subkeyDetailLayout); - baseLayout->addWidget(listBox); - baseLayout->addWidget(detailBox); + baseLayout->addWidget(list_box_); + baseLayout->addWidget(detail_box_); baseLayout->addStretch(); - connect(addSubkeyButton, SIGNAL(clicked(bool)), this, SLOT(slotAddSubkey())); - connect(subkeyList, SIGNAL(itemSelectionChanged()), this, - SLOT(slotRefreshSubkeyDetail())); + connect(addSubkeyButton, &QPushButton::clicked, this, + &KeyPairSubkeyTab::slot_add_subkey); + connect(subkey_list_, &QTableWidget::itemSelectionChanged, this, + &KeyPairSubkeyTab::slot_refresh_subkey_detail); // key database refresh signal - connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, - SLOT(slotRefreshKeyInfo())); - connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, - SLOT(slotRefreshSubkeyList())); + connect(SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh, this, + &KeyPairSubkeyTab::slot_refresh_key_info); + connect(SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh, this, + &KeyPairSubkeyTab::slot_refresh_subkey_list); baseLayout->setContentsMargins(0, 0, 0, 0); setLayout(baseLayout); setAttribute(Qt::WA_DeleteOnClose, true); - slotRefreshSubkeyList(); + slot_refresh_subkey_list(); } -void KeyPairSubkeyTab::createSubkeyList() { - subkeyList = new QTableWidget(this); +void KeyPairSubkeyTab::create_subkey_list() { + subkey_list_ = new QTableWidget(this); - subkeyList->setColumnCount(5); - subkeyList->horizontalHeader()->setSectionResizeMode( + subkey_list_->setColumnCount(5); + subkey_list_->horizontalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents); - subkeyList->verticalHeader()->hide(); - subkeyList->setShowGrid(false); - subkeyList->setSelectionBehavior(QAbstractItemView::SelectRows); + subkey_list_->verticalHeader()->hide(); + subkey_list_->setShowGrid(false); + subkey_list_->setSelectionBehavior(QAbstractItemView::SelectRows); // tableitems not editable - subkeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); + subkey_list_->setEditTriggers(QAbstractItemView::NoEditTriggers); // no focus (rectangle around tableitems) // may be it should focus on whole row - subkeyList->setFocusPolicy(Qt::NoFocus); - subkeyList->setAlternatingRowColors(true); + subkey_list_->setFocusPolicy(Qt::NoFocus); + subkey_list_->setAlternatingRowColors(true); QStringList labels; labels << _("Subkey ID") << _("Key Size") << _("Algo") << _("Create Date (UTC)") << _("Expire Date (UTC)"); - subkeyList->setHorizontalHeaderLabels(labels); - subkeyList->horizontalHeader()->setStretchLastSection(false); + subkey_list_->setHorizontalHeaderLabels(labels); + subkey_list_->horizontalHeader()->setStretchLastSection(false); } -void KeyPairSubkeyTab::slotRefreshSubkeyList() { +void KeyPairSubkeyTab::slot_refresh_subkey_list() { LOG(INFO) << "Called"; int row = 0; - subkeyList->setSelectionMode(QAbstractItemView::SingleSelection); + subkey_list_->setSelectionMode(QAbstractItemView::SingleSelection); - this->buffered_subkeys.clear(); - auto sub_keys = key_.subKeys(); + this->buffered_subkeys_.clear(); + auto sub_keys = key_.GetSubKeys(); for (auto& sub_key : *sub_keys) { - if (sub_key.disabled() || sub_key.revoked()) continue; - this->buffered_subkeys.push_back(std::move(sub_key)); + if (sub_key.IsDisabled() || sub_key.IsRevoked()) continue; + this->buffered_subkeys_.push_back(std::move(sub_key)); } - subkeyList->setRowCount(buffered_subkeys.size()); + subkey_list_->setRowCount(buffered_subkeys_.size()); - for (const auto& subkeys : buffered_subkeys) { - auto* tmp0 = new QTableWidgetItem(QString::fromStdString(subkeys.id())); + for (const auto& subkeys : buffered_subkeys_) { + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(subkeys.GetID())); tmp0->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 0, tmp0); + subkey_list_->setItem(row, 0, tmp0); - auto* tmp1 = new QTableWidgetItem(QString::number(subkeys.length())); + auto* tmp1 = new QTableWidgetItem(QString::number(subkeys.GetKeyLength())); tmp1->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 1, tmp1); + subkey_list_->setItem(row, 1, tmp1); auto* tmp2 = - new QTableWidgetItem(QString::fromStdString(subkeys.pubkey_algo())); + new QTableWidgetItem(QString::fromStdString(subkeys.GetPubkeyAlgo())); tmp2->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 2, tmp2); + subkey_list_->setItem(row, 2, tmp2); auto* tmp3 = new QTableWidgetItem( - QString::fromStdString(to_iso_string(subkeys.timestamp()))); + QString::fromStdString(to_iso_string(subkeys.GetCreateTime()))); tmp3->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 3, tmp3); + subkey_list_->setItem(row, 3, tmp3); auto* tmp4 = new QTableWidgetItem( boost::posix_time::to_time_t( - boost::posix_time::ptime(subkeys.expires())) == 0 + boost::posix_time::ptime(subkeys.GetExpireTime())) == 0 ? _("Never Expire") - : QString::fromStdString(to_iso_string(subkeys.expires()))); + : QString::fromStdString(to_iso_string(subkeys.GetExpireTime()))); tmp4->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 4, tmp4); + subkey_list_->setItem(row, 4, tmp4); if (!row) { - for (auto i = 0; i < subkeyList->columnCount(); i++) { - subkeyList->item(row, i)->setForeground(QColor(65, 105, 255)); + for (auto i = 0; i < subkey_list_->columnCount(); i++) { + subkey_list_->item(row, i)->setForeground(QColor(65, 105, 255)); } } row++; } - if (subkeyList->rowCount() > 0) { - subkeyList->selectRow(0); + if (subkey_list_->rowCount() > 0) { + subkey_list_->selectRow(0); } } -void KeyPairSubkeyTab::slotAddSubkey() { - auto dialog = new SubkeyGenerateDialog(key_.id(), this); +void KeyPairSubkeyTab::slot_add_subkey() { + auto dialog = new SubkeyGenerateDialog(key_.GetId(), this); dialog->show(); } -void KeyPairSubkeyTab::slotRefreshSubkeyDetail() { - auto& subkey = getSelectedSubkey(); +void KeyPairSubkeyTab::slot_refresh_subkey_detail() { + auto& subkey = get_selected_subkey(); - keyidVarLabel->setText(QString::fromStdString(subkey.id())); - keySizeVarLabel->setText(QString::number(subkey.length())); + key_id_var_label_->setText(QString::fromStdString(subkey.GetID())); + key_size_var_label_->setText(QString::number(subkey.GetKeyLength())); - time_t subkey_time_t = - boost::posix_time::to_time_t(boost::posix_time::ptime(subkey.expires())); + time_t subkey_time_t = boost::posix_time::to_time_t( + boost::posix_time::ptime(subkey.GetExpireTime())); - expireVarLabel->setText( + expire_var_label_->setText( subkey_time_t == 0 ? _("Never Expires") : QLocale::system().toString(QDateTime::fromTime_t( - to_time_t(subkey.expires())))); + to_time_t(subkey.GetExpireTime())))); if (subkey_time_t != 0 && - subkey.expires() < boost::posix_time::second_clock::local_time()) { - auto paletteExpired = expireVarLabel->palette(); - paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red); - expireVarLabel->setPalette(paletteExpired); + subkey.GetExpireTime() < boost::posix_time::second_clock::local_time()) { + auto paletteExpired = expire_var_label_->palette(); + paletteExpired.setColor(expire_var_label_->foregroundRole(), Qt::red); + expire_var_label_->setPalette(paletteExpired); } else { - auto paletteValid = expireVarLabel->palette(); - paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen); - expireVarLabel->setPalette(paletteValid); + auto paletteValid = expire_var_label_->palette(); + paletteValid.setColor(expire_var_label_->foregroundRole(), Qt::darkGreen); + expire_var_label_->setPalette(paletteValid); } - algorithmVarLabel->setText(QString::fromStdString(subkey.pubkey_algo())); - createdVarLabel->setText(QLocale::system().toString( - QDateTime::fromTime_t(to_time_t(subkey.timestamp())))); + algorithm_var_label_->setText(QString::fromStdString(subkey.GetPubkeyAlgo())); + created_var_label_->setText(QLocale::system().toString( + QDateTime::fromTime_t(to_time_t(subkey.GetCreateTime())))); std::stringstream usage_steam; - if (subkey.can_certify()) usage_steam << _("Certificate") << " "; - if (subkey.can_encrypt()) usage_steam << _("Encrypt") << " "; - if (subkey.can_sign()) usage_steam << _("Sign") << " "; - if (subkey.can_authenticate()) usage_steam << _("Auth") << " "; + if (subkey.IsHasCertificationCapability()) + usage_steam << _("Certificate") << " "; + if (subkey.IsHasEncryptionCapability()) usage_steam << _("Encrypt") << " "; + if (subkey.IsHasSigningCapability()) usage_steam << _("Sign") << " "; + if (subkey.IsHasAuthenticationCapability()) usage_steam << _("Auth") << " "; - usageVarLabel->setText(usage_steam.str().c_str()); + usage_var_label_->setText(usage_steam.str().c_str()); // Show the situation that secret key not exists. - masterKeyExistVarLabel->setText(subkey.secret() ? _("Exists") - : _("Not Exists")); + master_key_exist_var_label_->setText(subkey.IsSecretKey() ? _("Exists") + : _("Not Exists")); // Show the situation if key in a smart card. - cardKeyLabel->setText(subkey.is_cardkey() ? _("Yes") : _("No")); + card_key_label_->setText(subkey.IsCardKey() ? _("Yes") : _("No")); - if (!subkey.secret()) { - auto palette_expired = masterKeyExistVarLabel->palette(); - palette_expired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red); - masterKeyExistVarLabel->setPalette(palette_expired); + if (!subkey.IsSecretKey()) { + auto palette_expired = master_key_exist_var_label_->palette(); + palette_expired.setColor(master_key_exist_var_label_->foregroundRole(), + Qt::red); + master_key_exist_var_label_->setPalette(palette_expired); } else { - auto palette_valid = masterKeyExistVarLabel->palette(); - palette_valid.setColor(masterKeyExistVarLabel->foregroundRole(), + auto palette_valid = master_key_exist_var_label_->palette(); + palette_valid.setColor(master_key_exist_var_label_->foregroundRole(), Qt::darkGreen); - masterKeyExistVarLabel->setPalette(palette_valid); + master_key_exist_var_label_->setPalette(palette_valid); } - if (!subkey.is_cardkey()) { - auto palette_expired = cardKeyLabel->palette(); - palette_expired.setColor(cardKeyLabel->foregroundRole(), Qt::red); - cardKeyLabel->setPalette(palette_expired); + if (!subkey.IsCardKey()) { + auto palette_expired = card_key_label_->palette(); + palette_expired.setColor(card_key_label_->foregroundRole(), Qt::red); + card_key_label_->setPalette(palette_expired); } else { - auto palette_valid = cardKeyLabel->palette(); - palette_valid.setColor(cardKeyLabel->foregroundRole(), Qt::darkGreen); - cardKeyLabel->setPalette(palette_valid); + auto palette_valid = card_key_label_->palette(); + palette_valid.setColor(card_key_label_->foregroundRole(), Qt::darkGreen); + card_key_label_->setPalette(palette_valid); } - fingerPrintVarLabel->setText(QString::fromStdString(subkey.fpr())); + fingerprint_var_label_->setText( + QString::fromStdString(subkey.GetFingerprint())); } -void KeyPairSubkeyTab::createSubkeyOperaMenu() { - subkeyOperaMenu = new QMenu(this); - // auto *revokeSubkeyAct = new QAction(_("Revoke Subkey")); +void KeyPairSubkeyTab::create_subkey_opera_menu() { + subkey_opera_menu_ = new QMenu(this); auto* editSubkeyAct = new QAction(_("Edit Expire Date")); - connect(editSubkeyAct, SIGNAL(triggered(bool)), this, SLOT(slotEditSubkey())); + connect(editSubkeyAct, &QAction::triggered, this, + &KeyPairSubkeyTab::slot_edit_subkey); - // subkeyOperaMenu->addAction(revokeSubkeyAct); - subkeyOperaMenu->addAction(editSubkeyAct); + subkey_opera_menu_->addAction(editSubkeyAct); } -void KeyPairSubkeyTab::slotEditSubkey() { - LOG(INFO) << "Fpr" << getSelectedSubkey().fpr(); +void KeyPairSubkeyTab::slot_edit_subkey() { + LOG(INFO) << "Fpr" << get_selected_subkey().GetFingerprint(); - auto dialog = - new KeySetExpireDateDialog(key_.id(), getSelectedSubkey().fpr(), this); + auto dialog = new KeySetExpireDateDialog( + key_.GetId(), get_selected_subkey().GetFingerprint(), this); dialog->show(); } -void KeyPairSubkeyTab::slotRevokeSubkey() {} +void KeyPairSubkeyTab::slot_revoke_subkey() {} void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent* event) { - if (!subkeyList->selectedItems().isEmpty()) { - subkeyOperaMenu->exec(event->globalPos()); + if (!subkey_list_->selectedItems().isEmpty()) { + subkey_opera_menu_->exec(event->globalPos()); } } -const GpgSubKey& KeyPairSubkeyTab::getSelectedSubkey() { +const GpgSubKey& KeyPairSubkeyTab::get_selected_subkey() { int row = 0; - for (int i = 0; i < subkeyList->rowCount(); i++) { - if (subkeyList->item(row, 0)->isSelected()) break; + for (int i = 0; i < subkey_list_->rowCount(); i++) { + if (subkey_list_->item(row, 0)->isSelected()) break; row++; } - return buffered_subkeys[row]; + return buffered_subkeys_[row]; } -void KeyPairSubkeyTab::slotRefreshKeyInfo() { - key_ = GpgKeyGetter::GetInstance().GetKey(key_.id()); +void KeyPairSubkeyTab::slot_refresh_key_info() { + key_ = GpgKeyGetter::GetInstance().GetKey(key_.GetId()); } } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.h b/src/ui/keypair_details/KeyPairSubkeyTab.h index f254fed0..a64d143c 100644 --- a/src/ui/keypair_details/KeyPairSubkeyTab.h +++ b/src/ui/keypair_details/KeyPairSubkeyTab.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,9 +30,9 @@ #define GPGFRONTEND_KEYPAIRSUBKEYTAB_H #include "KeySetExpireDateDialog.h" -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" -#include "ui/keygen/SubkeyGenerateDialog.h" +#include "ui/key_generate/SubkeyGenerateDialog.h" namespace GpgFrontend::UI { @@ -36,49 +40,97 @@ class KeyPairSubkeyTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Key Pair Subkey Tab object + * + * @param key + * @param parent + */ KeyPairSubkeyTab(const std::string& key, QWidget* parent); private: - void createSubkeyList(); - - void createSubkeyOperaMenu(); - - const GpgSubKey& getSelectedSubkey(); - - GpgKey key_; - QTableWidget* subkeyList{}; - std::vector<GpgSubKey> buffered_subkeys; - - QGroupBox* listBox; - QGroupBox* detailBox; - - QMenu* subkeyOperaMenu{}; - - QLabel* keySizeVarLabel; /** Label containing the keys key size */ - QLabel* expireVarLabel; /** Label containing the keys expiration date */ - QLabel* createdVarLabel; /** Label containing the keys creation date */ - QLabel* algorithmVarLabel; /** Label containing the keys algorithm */ - QLabel* keyidVarLabel; /** Label containing the keys keyid */ - QLabel* fingerPrintVarLabel; /** Label containing the keys fingerprint */ - QLabel* usageVarLabel; - QLabel* masterKeyExistVarLabel; - QLabel* cardKeyLabel; + /** + * @brief Create a subkey list object + * + */ + void create_subkey_list(); + + /** + * @brief Create a subkey opera menu object + * + */ + void create_subkey_opera_menu(); + + /** + * @brief Get the selected subkey object + * + * @return const GpgSubKey& + */ + const GpgSubKey& get_selected_subkey(); + + GpgKey key_; ///< + QTableWidget* subkey_list_{}; ///< + std::vector<GpgSubKey> buffered_subkeys_; ///< + + QGroupBox* list_box_; ///< + QGroupBox* detail_box_; ///< + + QMenu* subkey_opera_menu_{}; ///< + + QLabel* key_size_var_label_; ///< Label containing the keys key size + QLabel* expire_var_label_; ///< Label containing the keys expiration date + QLabel* created_var_label_; ///< Label containing the keys creation date + QLabel* algorithm_var_label_; ///< Label containing the keys algorithm + QLabel* key_id_var_label_; ///< Label containing the keys keyid + QLabel* fingerprint_var_label_; ///< Label containing the keys fingerprint + QLabel* usage_var_label_; ///< + QLabel* master_key_exist_var_label_; ///< + QLabel* card_key_label_; ///< private slots: - void slotAddSubkey(); - - void slotRefreshSubkeyList(); - - void slotRefreshSubkeyDetail(); - - void slotEditSubkey(); - - void slotRevokeSubkey(); - - void slotRefreshKeyInfo(); + /** + * @brief + * + */ + void slot_add_subkey(); + + /** + * @brief + * + */ + void slot_refresh_subkey_list(); + + /** + * @brief + * + */ + void slot_refresh_subkey_detail(); + + /** + * @brief + * + */ + void slot_edit_subkey(); + + /** + * @brief + * + */ + void slot_revoke_subkey(); + + /** + * @brief + * + */ + void slot_refresh_key_info(); protected: + /** + * @brief + * + * @param event + */ void contextMenuEvent(QContextMenuEvent* event) override; }; diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp index 92a3c3ea..81d34684 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/keypair_details/KeyPairUIDTab.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -24,29 +26,29 @@ #include "ui/keypair_details/KeyPairUIDTab.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyManager.h" -#include "gpg/function/UidOperator.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyManager.h" +#include "core/function/gpg/GpgUIDOperator.h" #include "ui/SignalStation.h" #include "ui/widgets/TOFUInfoPage.h" namespace GpgFrontend::UI { KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent) - : QWidget(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { - createUIDList(); - createSignList(); - createManageUIDMenu(); - createUIDPopupMenu(); - createSignPopupMenu(); + : QWidget(parent), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { + create_uid_list(); + create_sign_list(); + create_manage_uid_menu(); + create_uid_popup_menu(); + create_sign_popup_menu(); auto uidButtonsLayout = new QGridLayout(); auto addUIDButton = new QPushButton(_("New UID")); auto manageUIDButton = new QPushButton(_("UID Management")); - if (mKey.has_master_key()) { - manageUIDButton->setMenu(manageSelectedUIDMenu); + if (m_key_.IsHasMasterKey()) { + manageUIDButton->setMenu(manage_selected_uid_menu_); } else { manageUIDButton->setDisabled(true); } @@ -56,7 +58,7 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent) auto grid_layout = new QGridLayout(); - grid_layout->addWidget(uidList, 0, 0); + grid_layout->addWidget(uid_list_, 0, 0); grid_layout->addLayout(uidButtonsLayout, 1, 0); grid_layout->setContentsMargins(0, 10, 0, 0); @@ -69,12 +71,12 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent) tofu_group_box->setLayout(tofu_vbox_layout); tofu_group_box->setTitle(_("TOFU")); #if !defined(RELEASE) - tofuTabs = new QTabWidget(this); - tofu_vbox_layout->addWidget(tofuTabs); + tofu_tabs_ = new QTabWidget(this); + tofu_vbox_layout->addWidget(tofu_tabs_); #endif auto sign_grid_layout = new QGridLayout(); - sign_grid_layout->addWidget(sigList, 0, 0); + sign_grid_layout->addWidget(sig_list_, 0, 0); sign_grid_layout->setContentsMargins(0, 10, 0, 0); auto sign_group_box = new QGroupBox(); @@ -91,198 +93,203 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent) vboxLayout->setContentsMargins(0, 0, 0, 0); - connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID())); - connect(uidList, SIGNAL(itemSelectionChanged()), this, - SLOT(slotRefreshTOFUInfo())); - connect(uidList, SIGNAL(itemSelectionChanged()), this, - SLOT(slotRefreshSigList())); + connect(addUIDButton, &QPushButton::clicked, this, + &KeyPairUIDTab::slot_add_uid); + connect(uid_list_, &QTableWidget::itemSelectionChanged, this, + &KeyPairUIDTab::slot_refresh_tofu_info); + connect(uid_list_, &QTableWidget::itemSelectionChanged, this, + &KeyPairUIDTab::slot_refresh_sig_list); // Key Database Refresh - connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, - SLOT(slotRefreshKey())); + connect(SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh, this, + &KeyPairUIDTab::slot_refresh_key); - connect(this, SIGNAL(signalUpdateUIDInfo()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); + connect(this, &KeyPairUIDTab::SignalUpdateUIDInfo, + SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); setLayout(vboxLayout); setAttribute(Qt::WA_DeleteOnClose, true); - slotRefreshUIDList(); + slot_refresh_uid_list(); } -void KeyPairUIDTab::createUIDList() { - uidList = new QTableWidget(this); - uidList->setColumnCount(4); - uidList->horizontalHeader()->setSectionResizeMode( +void KeyPairUIDTab::create_uid_list() { + uid_list_ = new QTableWidget(this); + uid_list_->setColumnCount(4); + uid_list_->horizontalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents); - uidList->verticalHeader()->hide(); - uidList->setShowGrid(false); - uidList->setSelectionBehavior(QAbstractItemView::SelectRows); - uidList->setSelectionMode(QAbstractItemView::SingleSelection); + uid_list_->verticalHeader()->hide(); + uid_list_->setShowGrid(false); + uid_list_->setSelectionBehavior(QAbstractItemView::SelectRows); + uid_list_->setSelectionMode(QAbstractItemView::SingleSelection); // tableitems not editable - uidList->setEditTriggers(QAbstractItemView::NoEditTriggers); + uid_list_->setEditTriggers(QAbstractItemView::NoEditTriggers); // no focus (rectangle around tableitems) // may be it should focus on whole row - uidList->setFocusPolicy(Qt::NoFocus); - uidList->setAlternatingRowColors(true); + uid_list_->setFocusPolicy(Qt::NoFocus); + uid_list_->setAlternatingRowColors(true); QStringList labels; labels << _("Select") << _("Name") << _("Email") << _("Comment"); - uidList->setHorizontalHeaderLabels(labels); - uidList->horizontalHeader()->setStretchLastSection(true); + uid_list_->setHorizontalHeaderLabels(labels); + uid_list_->horizontalHeader()->setStretchLastSection(true); } -void KeyPairUIDTab::createSignList() { - sigList = new QTableWidget(this); - sigList->setColumnCount(5); - sigList->horizontalHeader()->setSectionResizeMode( +void KeyPairUIDTab::create_sign_list() { + sig_list_ = new QTableWidget(this); + sig_list_->setColumnCount(5); + sig_list_->horizontalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents); - sigList->verticalHeader()->hide(); - sigList->setShowGrid(false); - sigList->setSelectionBehavior(QAbstractItemView::SelectRows); + sig_list_->verticalHeader()->hide(); + sig_list_->setShowGrid(false); + sig_list_->setSelectionBehavior(QAbstractItemView::SelectRows); // table items not editable - sigList->setEditTriggers(QAbstractItemView::NoEditTriggers); + sig_list_->setEditTriggers(QAbstractItemView::NoEditTriggers); // no focus (rectangle around table items) // may be it should focus on whole row - sigList->setFocusPolicy(Qt::NoFocus); - sigList->setAlternatingRowColors(true); + sig_list_->setFocusPolicy(Qt::NoFocus); + sig_list_->setAlternatingRowColors(true); QStringList labels; labels << _("Key ID") << _("Name") << _("Email") << _("Create Date (UTC)") << _("Expired Date (UTC)"); - sigList->setHorizontalHeaderLabels(labels); - sigList->horizontalHeader()->setStretchLastSection(false); + sig_list_->setHorizontalHeaderLabels(labels); + sig_list_->horizontalHeader()->setStretchLastSection(false); } -void KeyPairUIDTab::slotRefreshUIDList() { +void KeyPairUIDTab::slot_refresh_uid_list() { int row = 0; - uidList->setSelectionMode(QAbstractItemView::SingleSelection); + uid_list_->setSelectionMode(QAbstractItemView::SingleSelection); - this->buffered_uids.clear(); + this->buffered_uids_.clear(); - auto uids = mKey.uids(); + auto uids = m_key_.GetUIDs(); for (auto& uid : *uids) { - if (uid.invalid() || uid.revoked()) { + if (uid.GetInvalid() || uid.GetRevoked()) { continue; } - this->buffered_uids.push_back(std::move(uid)); + this->buffered_uids_.push_back(std::move(uid)); } - uidList->setRowCount(buffered_uids.size()); + uid_list_->setRowCount(buffered_uids_.size()); - for (const auto& uid : buffered_uids) { - auto* tmp0 = new QTableWidgetItem(QString::fromStdString(uid.name())); - uidList->setItem(row, 1, tmp0); + for (const auto& uid : buffered_uids_) { + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(uid.GetUID())); + uid_list_->setItem(row, 1, tmp0); - auto* tmp1 = new QTableWidgetItem(QString::fromStdString(uid.email())); - uidList->setItem(row, 2, tmp1); + auto* tmp1 = new QTableWidgetItem(QString::fromStdString(uid.GetUID())); + uid_list_->setItem(row, 2, tmp1); - auto* tmp2 = new QTableWidgetItem(QString::fromStdString(uid.comment())); - uidList->setItem(row, 3, tmp2); + auto* tmp2 = new QTableWidgetItem(QString::fromStdString(uid.GetUID())); + uid_list_->setItem(row, 3, tmp2); auto* tmp3 = new QTableWidgetItem(QString::number(row)); tmp3->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); tmp3->setTextAlignment(Qt::AlignCenter); tmp3->setCheckState(Qt::Unchecked); - uidList->setItem(row, 0, tmp3); + uid_list_->setItem(row, 0, tmp3); if (!row) { - for (auto i = 0; i < uidList->columnCount(); i++) { - uidList->item(row, i)->setForeground(QColor(65, 105, 255)); + for (auto i = 0; i < uid_list_->columnCount(); i++) { + uid_list_->item(row, i)->setForeground(QColor(65, 105, 255)); } } row++; } - if (uidList->rowCount() > 0) { - uidList->selectRow(0); + if (uid_list_->rowCount() > 0) { + uid_list_->selectRow(0); } - slotRefreshSigList(); - slotRefreshTOFUInfo(); + slot_refresh_sig_list(); + slot_refresh_tofu_info(); } -void KeyPairUIDTab::slotRefreshTOFUInfo() { - if (this->tofuTabs == nullptr) return; +void KeyPairUIDTab::slot_refresh_tofu_info() { + if (this->tofu_tabs_ == nullptr) return; int uidRow = 0; - tofuTabs->clear(); - for (const auto& uid : buffered_uids) { + tofu_tabs_->clear(); + for (const auto& uid : buffered_uids_) { // Only Show Selected UID Signatures - if (!uidList->item(uidRow++, 0)->isSelected()) { + if (!uid_list_->item(uidRow++, 0)->isSelected()) { continue; } - auto tofu_infos = uid.tofu_infos(); + auto tofu_infos = uid.GetTofuInfos(); LOG(INFO) << "tofu info size" << tofu_infos->size(); if (tofu_infos->empty()) { - tofuTabs->hide(); + tofu_tabs_->hide(); } else { - tofuTabs->show(); + tofu_tabs_->show(); } int index = 1; for (const auto& tofu_info : *tofu_infos) { - tofuTabs->addTab(new TOFUInfoPage(tofu_info, this), - QString(_("TOFU %1")).arg(index++)); + tofu_tabs_->addTab(new TOFUInfoPage(tofu_info, this), + QString(_("TOFU %1")).arg(index++)); } } } -void KeyPairUIDTab::slotRefreshSigList() { +void KeyPairUIDTab::slot_refresh_sig_list() { int uidRow = 0, sigRow = 0; - for (const auto& uid : buffered_uids) { + for (const auto& uid : buffered_uids_) { // Only Show Selected UID Signatures - if (!uidList->item(uidRow++, 0)->isSelected()) { + if (!uid_list_->item(uidRow++, 0)->isSelected()) { continue; } - buffered_signatures.clear(); - auto signatures = uid.signatures(); + buffered_signatures_.clear(); + auto signatures = uid.GetSignatures(); for (auto& sig : *signatures) { - if (sig.invalid() || sig.revoked()) { + if (sig.IsInvalid() || sig.IsRevoked()) { continue; } - buffered_signatures.push_back(std::move(sig)); + buffered_signatures_.push_back(std::move(sig)); } - sigList->setRowCount(buffered_signatures.size()); + sig_list_->setRowCount(buffered_signatures_.size()); - for (const auto& sig : buffered_signatures) { - auto* tmp0 = new QTableWidgetItem(QString::fromStdString(sig.keyid())); - sigList->setItem(sigRow, 0, tmp0); + for (const auto& sig : buffered_signatures_) { + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(sig.GetKeyID())); + sig_list_->setItem(sigRow, 0, tmp0); - if (gpgme_err_code(sig.status()) == GPG_ERR_NO_PUBKEY) { + if (gpgme_err_code(sig.GetStatus()) == GPG_ERR_NO_PUBKEY) { auto* tmp2 = new QTableWidgetItem("<Unknown>"); - sigList->setItem(sigRow, 1, tmp2); + sig_list_->setItem(sigRow, 1, tmp2); auto* tmp3 = new QTableWidgetItem("<Unknown>"); - sigList->setItem(sigRow, 2, tmp3); + sig_list_->setItem(sigRow, 2, tmp3); } else { - auto* tmp2 = new QTableWidgetItem(QString::fromStdString(sig.name())); - sigList->setItem(sigRow, 1, tmp2); + auto* tmp2 = + new QTableWidgetItem(QString::fromStdString(sig.GetName())); + sig_list_->setItem(sigRow, 1, tmp2); - auto* tmp3 = new QTableWidgetItem(QString::fromStdString(sig.email())); - sigList->setItem(sigRow, 2, tmp3); + auto* tmp3 = + new QTableWidgetItem(QString::fromStdString(sig.GetEmail())); + sig_list_->setItem(sigRow, 2, tmp3); } auto* tmp4 = new QTableWidgetItem(QLocale::system().toString( - QDateTime::fromTime_t(to_time_t(sig.create_time())))); - sigList->setItem(sigRow, 3, tmp4); + QDateTime::fromTime_t(to_time_t(sig.GetCreateTime())))); + sig_list_->setItem(sigRow, 3, tmp4); auto* tmp5 = new QTableWidgetItem( boost::posix_time::to_time_t( - boost::posix_time::ptime(sig.expire_time())) == 0 + boost::posix_time::ptime(sig.GetExpireTime())) == 0 ? _("Never Expires") : QLocale::system().toString( - QDateTime::fromTime_t(to_time_t(sig.expire_time())))); + QDateTime::fromTime_t(to_time_t(sig.GetExpireTime())))); tmp5->setTextAlignment(Qt::AlignCenter); - sigList->setItem(sigRow, 4, tmp5); + sig_list_->setItem(sigRow, 4, tmp5); sigRow++; } @@ -291,8 +298,8 @@ void KeyPairUIDTab::slotRefreshSigList() { } } -void KeyPairUIDTab::slotAddSign() { - auto selected_uids = getUIDChecked(); +void KeyPairUIDTab::slot_add_sign() { + auto selected_uids = get_uid_checked(); if (selected_uids->empty()) { QMessageBox::information( @@ -302,43 +309,43 @@ void KeyPairUIDTab::slotAddSign() { } auto keySignDialog = - new KeyUIDSignDialog(mKey, std::move(selected_uids), this); + new KeyUIDSignDialog(m_key_, std::move(selected_uids), this); keySignDialog->show(); } -UIDArgsListPtr KeyPairUIDTab::getUIDChecked() { +UIDArgsListPtr KeyPairUIDTab::get_uid_checked() { auto selected_uids = std::make_unique<UIDArgsList>(); - for (int i = 0; i < uidList->rowCount(); i++) { - if (uidList->item(i, 0)->checkState() == Qt::Checked) - selected_uids->push_back(buffered_uids[i].uid()); + for (int i = 0; i < uid_list_->rowCount(); i++) { + if (uid_list_->item(i, 0)->checkState() == Qt::Checked) + selected_uids->push_back(buffered_uids_[i].GetUID()); } return selected_uids; } -void KeyPairUIDTab::createManageUIDMenu() { - manageSelectedUIDMenu = new QMenu(this); +void KeyPairUIDTab::create_manage_uid_menu() { + manage_selected_uid_menu_ = new QMenu(this); auto* signUIDAct = new QAction(_("Sign Selected UID(s)"), this); - connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSign())); + connect(signUIDAct, &QAction::triggered, this, &KeyPairUIDTab::slot_add_sign); auto* delUIDAct = new QAction(_("Delete Selected UID(s)"), this); - connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUID())); + connect(delUIDAct, &QAction::triggered, this, &KeyPairUIDTab::slot_del_uid); - if (mKey.has_master_key()) { - manageSelectedUIDMenu->addAction(signUIDAct); - manageSelectedUIDMenu->addAction(delUIDAct); + if (m_key_.IsHasMasterKey()) { + manage_selected_uid_menu_->addAction(signUIDAct); + manage_selected_uid_menu_->addAction(delUIDAct); } } -void KeyPairUIDTab::slotAddUID() { - auto keyNewUIDDialog = new KeyNewUIDDialog(mKey.id(), this); - connect(keyNewUIDDialog, SIGNAL(finished(int)), this, - SLOT(slotAddUIDResult(int))); - connect(keyNewUIDDialog, SIGNAL(finished(int)), keyNewUIDDialog, - SLOT(deleteLater())); +void KeyPairUIDTab::slot_add_uid() { + auto keyNewUIDDialog = new KeyNewUIDDialog(m_key_.GetId(), this); + connect(keyNewUIDDialog, &KeyNewUIDDialog::finished, this, + &KeyPairUIDTab::slot_add_uid_result); + connect(keyNewUIDDialog, &KeyNewUIDDialog::finished, keyNewUIDDialog, + &KeyPairUIDTab::deleteLater); keyNewUIDDialog->show(); } -void KeyPairUIDTab::slotAddUIDResult(int result) { +void KeyPairUIDTab::slot_add_uid_result(int result) { if (result == 1) { QMessageBox::information(nullptr, _("Successful Operation"), _("Successfully added a new UID.")); @@ -348,8 +355,8 @@ void KeyPairUIDTab::slotAddUIDResult(int result) { } } -void KeyPairUIDTab::slotDelUID() { - auto selected_uids = getUIDChecked(); +void KeyPairUIDTab::slot_del_uid() { + auto selected_uids = get_uid_checked(); if (selected_uids->empty()) { QMessageBox::information( @@ -375,20 +382,20 @@ void KeyPairUIDTab::slotDelUID() { if (ret == QMessageBox::Yes) { for (const auto& uid : *selected_uids) { - LOG(INFO) << "KeyPairUIDTab::slotDelUID UID" << uid; - if (!UidOperator::GetInstance().revUID(mKey, uid)) { + LOG(INFO) << "KeyPairUIDTab::slot_del_uid UID" << uid; + if (!GpgUIDOperator::GetInstance().RevUID(m_key_, uid)) { QMessageBox::critical( nullptr, _("Operation Failed"), QString(_("An error occurred during the delete %1 operation.")) .arg(uid.c_str())); } } - emit signalUpdateUIDInfo(); + emit SignalUpdateUIDInfo(); } } -void KeyPairUIDTab::slotSetPrimaryUID() { - auto selected_uids = getUIDSelected(); +void KeyPairUIDTab::slot_set_primary_uid() { + auto selected_uids = get_uid_selected(); if (selected_uids->empty()) { auto emptyUIDMsg = new QMessageBox(); @@ -411,68 +418,66 @@ void KeyPairUIDTab::slotSetPrimaryUID() { QMessageBox::No | QMessageBox::Yes); if (ret == QMessageBox::Yes) { - if (!UidOperator::GetInstance().setPrimaryUID(mKey, + if (!GpgUIDOperator::GetInstance().SetPrimaryUID(m_key_, selected_uids->front())) { QMessageBox::critical(nullptr, _("Operation Failed"), _("An error occurred during the operation.")); } else { - emit signalUpdateUIDInfo(); + emit SignalUpdateUIDInfo(); } } } -UIDArgsListPtr KeyPairUIDTab::getUIDSelected() { +UIDArgsListPtr KeyPairUIDTab::get_uid_selected() { auto uids = std::make_unique<UIDArgsList>(); - for (int i = 0; i < uidList->rowCount(); i++) { - if (uidList->item(i, 0)->isSelected()) { - uids->push_back(buffered_uids[i].uid()); + for (int i = 0; i < uid_list_->rowCount(); i++) { + if (uid_list_->item(i, 0)->isSelected()) { + uids->push_back(buffered_uids_[i].GetUID()); } } return uids; } -SignIdArgsListPtr KeyPairUIDTab::getSignSelected() { +SignIdArgsListPtr KeyPairUIDTab::get_sign_selected() { auto signatures = std::make_unique<SignIdArgsList>(); - for (int i = 0; i < sigList->rowCount(); i++) { - if (sigList->item(i, 0)->isSelected()) { - auto& sign = buffered_signatures[i]; - signatures->push_back({sign.keyid(), sign.uid()}); + for (int i = 0; i < sig_list_->rowCount(); i++) { + if (sig_list_->item(i, 0)->isSelected()) { + auto& sign = buffered_signatures_[i]; + signatures->push_back({sign.GetKeyID(), sign.GetUID()}); } } return signatures; } -void KeyPairUIDTab::createUIDPopupMenu() { - uidPopupMenu = new QMenu(this); +void KeyPairUIDTab::create_uid_popup_menu() { + uid_popup_menu_ = new QMenu(this); auto* serPrimaryUIDAct = new QAction(_("Set As Primary"), this); - connect(serPrimaryUIDAct, SIGNAL(triggered()), this, - SLOT(slotSetPrimaryUID())); + connect(serPrimaryUIDAct, &QAction::triggered, this, + &KeyPairUIDTab::slot_set_primary_uid); auto* signUIDAct = new QAction(_("Sign UID"), this); - connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSignSingle())); + connect(signUIDAct, &QAction::triggered, this, + &KeyPairUIDTab::slot_add_sign_single); auto* delUIDAct = new QAction(_("Delete UID"), this); - connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUIDSingle())); + connect(delUIDAct, &QAction::triggered, this, + &KeyPairUIDTab::slot_del_uid_single); - if (mKey.has_master_key()) { - uidPopupMenu->addAction(serPrimaryUIDAct); - uidPopupMenu->addAction(signUIDAct); - uidPopupMenu->addAction(delUIDAct); + if (m_key_.IsHasMasterKey()) { + uid_popup_menu_->addAction(serPrimaryUIDAct); + uid_popup_menu_->addAction(signUIDAct); + uid_popup_menu_->addAction(delUIDAct); } } void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent* event) { - if (uidList->selectedItems().length() > 0 && - sigList->selectedItems().isEmpty()) { - uidPopupMenu->exec(event->globalPos()); + if (uid_list_->selectedItems().length() > 0 && + sig_list_->selectedItems().isEmpty()) { + uid_popup_menu_->exec(event->globalPos()); } - - // if (!sigList->selectedItems().isEmpty()) { - // signPopupMenu->exec(event->globalPos()); - // } } -void KeyPairUIDTab::slotAddSignSingle() { - auto selected_uids = getUIDSelected(); +void KeyPairUIDTab::slot_add_sign_single() { + auto selected_uids = get_uid_selected(); if (selected_uids->empty()) { QMessageBox::information( @@ -482,12 +487,12 @@ void KeyPairUIDTab::slotAddSignSingle() { } auto keySignDialog = - new KeyUIDSignDialog(mKey, std::move(selected_uids), this); + new KeyUIDSignDialog(m_key_, std::move(selected_uids), this); keySignDialog->show(); } -void KeyPairUIDTab::slotDelUIDSingle() { - auto selected_uids = getUIDSelected(); +void KeyPairUIDTab::slot_del_uid_single() { + auto selected_uids = get_uid_selected(); if (selected_uids->empty()) { QMessageBox::information( nullptr, _("Invalid Operation"), @@ -510,26 +515,26 @@ void KeyPairUIDTab::slotDelUIDSingle() { QMessageBox::No | QMessageBox::Yes); if (ret == QMessageBox::Yes) { - if (!UidOperator::GetInstance().revUID(mKey, selected_uids->front())) { + if (!GpgUIDOperator::GetInstance().RevUID(m_key_, selected_uids->front())) { QMessageBox::critical(nullptr, _("Operation Failed"), _("An error occurred during the operation.")); } else { - emit signalUpdateUIDInfo(); + emit SignalUpdateUIDInfo(); } } } -void KeyPairUIDTab::createSignPopupMenu() { - signPopupMenu = new QMenu(this); +void KeyPairUIDTab::create_sign_popup_menu() { + sign_popup_menu_ = new QMenu(this); auto* delSignAct = new QAction(_("Delete(Revoke) Key Signature"), this); - connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign())); + connect(delSignAct, &QAction::triggered, this, &KeyPairUIDTab::slot_del_sign); - signPopupMenu->addAction(delSignAct); + sign_popup_menu_->addAction(delSignAct); } -void KeyPairUIDTab::slotDelSign() { - auto selected_signs = getSignSelected(); +void KeyPairUIDTab::slot_del_sign() { + auto selected_signs = get_sign_selected(); if (selected_signs->empty()) { QMessageBox::information( nullptr, _("Invalid Operation"), @@ -539,7 +544,7 @@ void KeyPairUIDTab::slotDelSign() { if (!GpgKeyGetter::GetInstance() .GetKey(selected_signs->front().first) - .good()) { + .IsGood()) { QMessageBox::critical( nullptr, _("Invalid Operation"), _("To delete the signature, you need to have its corresponding public " @@ -562,17 +567,17 @@ void KeyPairUIDTab::slotDelSign() { QMessageBox::No | QMessageBox::Yes); if (ret == QMessageBox::Yes) { - if (!GpgKeyManager::GetInstance().revSign(mKey, selected_signs)) { + if (!GpgKeyManager::GetInstance().RevSign(m_key_, selected_signs)) { QMessageBox::critical(nullptr, _("Operation Failed"), _("An error occurred during the operation.")); } } } -void KeyPairUIDTab::slotRefreshKey() { - this->mKey = GpgKeyGetter::GetInstance().GetKey(this->mKey.id()); - this->slotRefreshUIDList(); - this->slotRefreshTOFUInfo(); - this->slotRefreshSigList(); +void KeyPairUIDTab::slot_refresh_key() { + this->m_key_ = GpgKeyGetter::GetInstance().GetKey(this->m_key_.GetId()); + this->slot_refresh_uid_list(); + this->slot_refresh_tofu_info(); + this->slot_refresh_sig_list(); } } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairUIDTab.h b/src/ui/keypair_details/KeyPairUIDTab.h index 823935d4..fae8f9f2 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.h +++ b/src/ui/keypair_details/KeyPairUIDTab.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -27,7 +31,7 @@ #include "KeyNewUIDDialog.h" #include "KeyUIDSignDialog.h" -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { @@ -36,65 +40,165 @@ class KeyPairUIDTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Key Pair U I D Tab object + * + * @param key_id + * @param parent + */ KeyPairUIDTab(const std::string& key_id, QWidget* parent); signals: - void signalUpdateUIDInfo(); - - private: - GpgKey mKey; - QTableWidget* uidList{}; - QTableWidget* sigList{}; - QTabWidget* tofuTabs{}; - QMenu* manageSelectedUIDMenu{}; - QMenu* uidPopupMenu{}; - QMenu* signPopupMenu{}; - std::vector<GpgUID> buffered_uids; - std::vector<GpgKeySignature> buffered_signatures; - - void createUIDList(); - - void createSignList(); - void createManageUIDMenu(); + /** + * @brief + * + */ + void SignalUpdateUIDInfo(); - void createUIDPopupMenu(); - - void createSignPopupMenu(); - - UIDArgsListPtr getUIDChecked(); - - UIDArgsListPtr getUIDSelected(); - - SignIdArgsListPtr getSignSelected(); + private: + GpgKey m_key_; + QTableWidget* uid_list_{}; ///< + QTableWidget* sig_list_{}; ///< + QTabWidget* tofu_tabs_{}; ///< + QMenu* manage_selected_uid_menu_{}; ///< + QMenu* uid_popup_menu_{}; ///< + QMenu* sign_popup_menu_{}; ///< + std::vector<GpgUID> buffered_uids_; ///< + std::vector<GpgKeySignature> buffered_signatures_; ///< + + /** + * @brief Create a uid list object + * + */ + void create_uid_list(); + + /** + * @brief Create a sign list object + * + */ + void create_sign_list(); + + /** + * @brief Create a manage uid menu object + * + */ + void create_manage_uid_menu(); + + /** + * @brief Create a uid popup menu object + * + */ + void create_uid_popup_menu(); + + /** + * @brief Create a sign popup menu object + * + */ + void create_sign_popup_menu(); + + /** + * @brief Get the uid checked object + * + * @return UIDArgsListPtr + */ + UIDArgsListPtr get_uid_checked(); + + /** + * @brief Get the uid selected object + * + * @return UIDArgsListPtr + */ + UIDArgsListPtr get_uid_selected(); + + /** + * @brief Get the sign selected object + * + * @return SignIdArgsListPtr + */ + SignIdArgsListPtr get_sign_selected(); private slots: - void slotRefreshUIDList(); - - void slotRefreshTOFUInfo(); - - void slotRefreshSigList(); - - void slotAddSign(); - - void slotAddSignSingle(); - - void slotAddUID(); - - void slotDelUID(); - - void slotDelUIDSingle(); - - void slotSetPrimaryUID(); - - void slotDelSign(); - - void slotRefreshKey(); - - static void slotAddUIDResult(int result); + /** + * @brief + * + */ + void slot_refresh_uid_list(); + + /** + * @brief + * + */ + void slot_refresh_tofu_info(); + + /** + * @brief + * + */ + void slot_refresh_sig_list(); + + /** + * @brief + * + */ + void slot_add_sign(); + + /** + * @brief + * + */ + void slot_add_sign_single(); + + /** + * @brief + * + */ + void slot_add_uid(); + + /** + * @brief + * + */ + void slot_del_uid(); + + /** + * @brief + * + */ + void slot_del_uid_single(); + + /** + * @brief + * + */ + void slot_set_primary_uid(); + + /** + * @brief + * + */ + void slot_del_sign(); + + /** + * @brief + * + */ + void slot_refresh_key(); + + /** + * @brief + * + * @param result + */ + static void slot_add_uid_result(int result); protected: + /** + * @brief + * + * @param event + */ void contextMenuEvent(QContextMenuEvent* event) override; }; diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/keypair_details/KeySetExpireDateDialog.cpp index 5b592cf6..79325e8b 100644 --- a/src/ui/keypair_details/KeySetExpireDateDialog.cpp +++ b/src/ui/keypair_details/KeySetExpireDateDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,10 +30,10 @@ #include <utility> -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyOpera.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyOpera.h" #include "ui/SignalStation.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" #include "ui_ModifiedExpirationDateTime.h" namespace GpgFrontend::UI { @@ -37,8 +41,8 @@ namespace GpgFrontend::UI { KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id, QWidget* parent) : QDialog(parent), - ui(std::make_shared<Ui_ModifiedExpirationDateTime>()), - mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { + ui_(std::make_shared<Ui_ModifiedExpirationDateTime>()), + m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) { init(); } @@ -46,26 +50,26 @@ KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id, std::string subkey_fpr, QWidget* parent) : QDialog(parent), - ui(std::make_shared<Ui_ModifiedExpirationDateTime>()), - mKey(GpgKeyGetter::GetInstance().GetKey(key_id)), - mSubkey(std::move(subkey_fpr)) { + ui_(std::make_shared<Ui_ModifiedExpirationDateTime>()), + m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)), + m_subkey_(std::move(subkey_fpr)) { init(); } -void KeySetExpireDateDialog::slotConfirm() { - LOG(INFO) << "Called" << ui->dateEdit->date().toString().toStdString() - << ui->timeEdit->time().toString().toStdString(); - auto datetime = QDateTime(ui->dateEdit->date(), ui->timeEdit->time()); +void KeySetExpireDateDialog::slot_confirm() { + LOG(INFO) << "Called" << ui_->dateEdit->date().toString().toStdString() + << ui_->timeEdit->time().toString().toStdString(); + auto datetime = QDateTime(ui_->dateEdit->date(), ui_->timeEdit->time()); std::unique_ptr<boost::posix_time::ptime> expires = nullptr; - if (ui->noExpirationCheckBox->checkState() == Qt::Unchecked) { + if (ui_->noExpirationCheckBox->checkState() == Qt::Unchecked) { expires = std::make_unique<boost::posix_time::ptime>( boost::posix_time::from_time_t(datetime.toLocalTime().toTime_t())); - LOG(INFO) << "keyid" << mKey.id() << mSubkey << *expires; + LOG(INFO) << "keyid" << m_key_.GetId() << m_subkey_ << *expires; } else { - LOG(INFO) << "keyid" << mKey.id() << mSubkey << "Non Expired"; + LOG(INFO) << "keyid" << m_key_.GetId() << m_subkey_ << "Non Expired"; } - auto err = GpgKeyOpera::GetInstance().SetExpire(mKey, mSubkey, expires); + auto err = GpgKeyOpera::GetInstance().SetExpire(m_key_, m_subkey_, expires); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) { auto* msg_box = new QMessageBox(nullptr); @@ -76,7 +80,7 @@ void KeySetExpireDateDialog::slotConfirm() { msg_box->setModal(false); msg_box->open(); - emit signalKeyExpireDateUpdated(); + emit SignalKeyExpireDateUpdated(); } else { QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(err))); @@ -86,7 +90,7 @@ void KeySetExpireDateDialog::slotConfirm() { } void KeySetExpireDateDialog::init() { - ui->setupUi(this); + ui_->setupUi(this); auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); @@ -106,31 +110,32 @@ void KeySetExpireDateDialog::init() { auto min_date_time = QDateTime::currentDateTime().addDays(7); - ui->dateEdit->setMaximumDateTime(max_date_time); - ui->dateEdit->setMinimumDateTime(min_date_time); + ui_->dateEdit->setMaximumDateTime(max_date_time); + ui_->dateEdit->setMinimumDateTime(min_date_time); - ui->dateEdit->setDateTime(max_date_time); - ui->timeEdit->setDateTime(max_date_time); + ui_->dateEdit->setDateTime(max_date_time); + ui_->timeEdit->setDateTime(max_date_time); - connect(ui->noExpirationCheckBox, SIGNAL(stateChanged(int)), this, - SLOT(slotNonExpiredChecked(int))); - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, - &KeySetExpireDateDialog::slotConfirm); - connect(this, SIGNAL(signalKeyExpireDateUpdated()), - SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh())); + connect(ui_->noExpirationCheckBox, &QCheckBox::stateChanged, this, + &KeySetExpireDateDialog::slot_non_expired_checked); + connect(ui_->button_box_, &QDialogButtonBox::accepted, this, + &KeySetExpireDateDialog::slot_confirm); + connect(this, &KeySetExpireDateDialog::SignalKeyExpireDateUpdated, + SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); - ui->titleLabel->setText(_("Modified Expiration Date (Local Time)")); - ui->label->setText( + ui_->titleLabel->setText(_("Modified Expiration Date (Local Time)")); + ui_->label->setText( _("Tips: For the sake of security, the key is valid for up to two years. " "If you are an expert user, please unlock it for a longer time in the " "settings.")); - ui->noExpirationCheckBox->setText(_("No Expiration")); + ui_->noExpirationCheckBox->setText(_("No Expiration")); this->setWindowTitle(_("Modified Expiration Date")); } -void KeySetExpireDateDialog::slotNonExpiredChecked(int state) { - ui->dateEdit->setDisabled(state == Qt::Checked); - ui->timeEdit->setDisabled(state == Qt::Checked); +void KeySetExpireDateDialog::slot_non_expired_checked(int state) { + ui_->dateEdit->setDisabled(state == Qt::Checked); + ui_->timeEdit->setDisabled(state == Qt::Checked); } } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.h b/src/ui/keypair_details/KeySetExpireDateDialog.h index d4386e43..3c0b62f7 100644 --- a/src/ui/keypair_details/KeySetExpireDateDialog.h +++ b/src/ui/keypair_details/KeySetExpireDateDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,28 +8,30 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H #define GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H -#include "gpg/GpgContext.h" -#include "gpg/model/GpgKey.h" -#include "gpg/model/GpgSubKey.h" +#include "core/GpgContext.h" +#include "core/model/GpgKey.h" +#include "core/model/GpgSubKey.h" #include "ui/GpgFrontendUI.h" class Ui_ModifiedExpirationDateTime; @@ -37,25 +41,56 @@ namespace GpgFrontend::UI { class KeySetExpireDateDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Key Set Expire Date Dialog object + * + * @param key_id + * @param parent + */ explicit KeySetExpireDateDialog(const KeyId& key_id, QWidget* parent = nullptr); + /** + * @brief Construct a new Key Set Expire Date Dialog object + * + * @param key_id + * @param subkey_fpr + * @param parent + */ explicit KeySetExpireDateDialog(const KeyId& key_id, std::string subkey_fpr, QWidget* parent = nullptr); signals: - void signalKeyExpireDateUpdated(); + /** + * @brief + * + */ + void SignalKeyExpireDateUpdated(); private: + /** + * @brief + * + */ void init(); - std::shared_ptr<Ui_ModifiedExpirationDateTime> ui; - const GpgKey mKey; - const SubkeyId mSubkey; + std::shared_ptr<Ui_ModifiedExpirationDateTime> ui_; ///< + const GpgKey m_key_; ///< + const SubkeyId m_subkey_; ///< private slots: - void slotConfirm(); - void slotNonExpiredChecked(int state); + /** + * @brief + * + */ + void slot_confirm(); + + /** + * @brief + * + * @param state + */ + void slot_non_expired_checked(int state); }; } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyUIDSignDialog.cpp b/src/ui/keypair_details/KeyUIDSignDialog.cpp index b43a119e..2ed45512 100644 --- a/src/ui/keypair_details/KeyUIDSignDialog.cpp +++ b/src/ui/keypair_details/KeyUIDSignDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -24,66 +26,68 @@ #include "ui/keypair_details/KeyUIDSignDialog.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyManager.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyManager.h" #include "ui/SignalStation.h" namespace GpgFrontend::UI { KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid, QWidget* parent) - : QDialog(parent), mUids(std::move(uid)), mKey(key) { - const auto key_id = mKey.id(); - mKeyList = new KeyList(KeyMenuAbility::NONE, this); - mKeyList->addListGroupTab(_("Signers"), KeyListRow::ONLY_SECRET_KEY, - KeyListColumn::NAME | KeyListColumn::EmailAddress, - [key_id](const GpgKey& key) -> bool { - if (key.disabled() || !key.can_certify() || - !key.has_master_key() || key.expired() || - key.revoked() || key_id == key.id()) - return false; - else - return true; - }); - mKeyList->slotRefresh(); - - signKeyButton = new QPushButton("Sign"); + : QDialog(parent), m_uids_(std::move(uid)), m_key_(key) { + const auto key_id = m_key_.GetId(); + m_key_list_ = new KeyList(KeyMenuAbility::NONE, this); + m_key_list_->AddListGroupTab( + _("Signers"), KeyListRow::ONLY_SECRET_KEY, + KeyListColumn::NAME | KeyListColumn::EmailAddress, + [key_id](const GpgKey& key) -> bool { + if (key.IsDisabled() || !key.IsHasCertificationCapability() || + !key.IsHasMasterKey() || key.IsExpired() || key.IsRevoked() || + key_id == key.GetId()) + return false; + else + return true; + }); + m_key_list_->SlotRefresh(); + + sign_key_button_ = new QPushButton("Sign"); /** * A DateTime after 5 Years is recommend. */ - expiresEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5)); - expiresEdit->setMinimumDateTime(QDateTime::currentDateTime()); + expires_edit_ = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5)); + expires_edit_->setMinimumDateTime(QDateTime::currentDateTime()); /** * Note further that the OpenPGP protocol uses 32 bit values for timestamps * and thus can only encode dates up to the year 2106. */ - expiresEdit->setMaximumDate(QDate(2106, 1, 1)); + expires_edit_->setMaximumDate(QDate(2106, 1, 1)); - nonExpireCheck = new QCheckBox("Non Expired"); - nonExpireCheck->setTristate(false); + non_expire_check_ = new QCheckBox("Non Expired"); + non_expire_check_->setTristate(false); - connect(nonExpireCheck, &QCheckBox::stateChanged, this, + connect(non_expire_check_, &QCheckBox::stateChanged, this, [this](int state) -> void { if (state == 0) - expiresEdit->setDisabled(false); + expires_edit_->setDisabled(false); else - expiresEdit->setDisabled(true); + expires_edit_->setDisabled(true); }); auto layout = new QGridLayout(); auto timeLayout = new QGridLayout(); - layout->addWidget(mKeyList, 0, 0); - layout->addWidget(signKeyButton, 2, 0, Qt::AlignRight); + layout->addWidget(m_key_list_, 0, 0); + layout->addWidget(sign_key_button_, 2, 0, Qt::AlignRight); timeLayout->addWidget(new QLabel(_("Expire Date")), 0, 0); - timeLayout->addWidget(expiresEdit, 0, 1); - timeLayout->addWidget(nonExpireCheck, 0, 2); + timeLayout->addWidget(expires_edit_, 0, 1); + timeLayout->addWidget(non_expire_check_, 0, 2); layout->addLayout(timeLayout, 1, 0); - connect(signKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotSignKey(bool))); + connect(sign_key_button_, &QPushButton::clicked, this, + &KeyUIDSignDialog::slot_sign_key); this->setLayout(layout); this->setModal(true); @@ -92,26 +96,27 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid, setAttribute(Qt::WA_DeleteOnClose, true); - connect(this, SIGNAL(signalKeyUIDSignUpdate()), SignalStation::GetInstance(), - SIGNAL(KeyDatabaseRefresh())); + connect(this, &KeyUIDSignDialog::SignalKeyUIDSignUpdate, + SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); } -void KeyUIDSignDialog::slotSignKey(bool clicked) { +void KeyUIDSignDialog::slot_sign_key(bool clicked) { LOG(INFO) << "Called"; // Set Signers - auto key_ids = mKeyList->getChecked(); + auto key_ids = m_key_list_->GetChecked(); auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); LOG(INFO) << "Key Info Got"; auto expires = std::make_unique<boost::posix_time::ptime>( - boost::posix_time::from_time_t(expiresEdit->dateTime().toTime_t())); + boost::posix_time::from_time_t(expires_edit_->dateTime().toTime_t())); LOG(INFO) << "Sign Start"; - for (const auto& uid : *mUids) { + for (const auto& uid : *m_uids_) { LOG(INFO) << "Sign UID" << uid; // Sign For mKey - if (!GpgKeyManager::GetInstance().signKey(mKey, *keys, uid, expires)) { + if (!GpgKeyManager::GetInstance().SignKey(m_key_, *keys, uid, expires)) { QMessageBox::critical( nullptr, _("Unsuccessful Operation"), QString(_("Signature operation failed for UID %1")).arg(uid.c_str())); @@ -121,7 +126,7 @@ void KeyUIDSignDialog::slotSignKey(bool clicked) { QMessageBox::information(nullptr, _("Operation Complete"), _("The signature operation of the UID is complete")); this->close(); - emit signalKeyUIDSignUpdate(); + emit SignalKeyUIDSignUpdate(); } } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyUIDSignDialog.h b/src/ui/keypair_details/KeyUIDSignDialog.h index 8a83977a..7c1cb58c 100644 --- a/src/ui/keypair_details/KeyUIDSignDialog.h +++ b/src/ui/keypair_details/KeyUIDSignDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -25,7 +27,7 @@ #ifndef GPGFRONTEND_KEYUIDSIGNDIALOG_H #define GPGFRONTEND_KEYUIDSIGNDIALOG_H -#include "gpg/GpgContext.h" +#include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" #include "ui/widgets/KeyList.h" @@ -35,28 +37,39 @@ class KeyUIDSignDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Key U I D Sign Dialog object + * + * @param key + * @param uid + * @param parent + */ explicit KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid, QWidget* parent = nullptr); signals: - void signalKeyUIDSignUpdate(); + /** + * @brief + * + */ + void SignalKeyUIDSignUpdate(); private: - KeyList* mKeyList; - - QPushButton* signKeyButton; - - QDateTimeEdit* expiresEdit; + KeyList* m_key_list_; ///< + QPushButton* sign_key_button_; ///< + QDateTimeEdit* expires_edit_; ///< + QCheckBox* non_expire_check_; ///< + UIDArgsListPtr m_uids_; ///< - QCheckBox* nonExpireCheck; - - UIDArgsListPtr mUids; - - const GpgKey& mKey; + const GpgKey& m_key_; ///< private slots: - - void slotSignKey(bool clicked); + /** + * @brief + * + * @param clicked + */ + void slot_sign_key(bool clicked); }; } // namespace GpgFrontend::UI diff --git a/src/ui/smtp/EmailListEditor.cpp b/src/ui/mail/EmailListEditor.cpp index 49399f11..b5147115 100644 --- a/src/ui/smtp/EmailListEditor.cpp +++ b/src/ui/mail/EmailListEditor.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -28,8 +32,8 @@ GpgFrontend::UI::EmailListEditor::EmailListEditor(const QString& email_list, QWidget* parent) - : QDialog(parent), ui(std::make_shared<Ui_EmailListEditorDialog>()) { - ui->setupUi(this); + : QDialog(parent), ui_(std::make_shared<Ui_EmailListEditorDialog>()) { + ui_->setupUi(this); QStringList email_string_list = email_list.split(';'); @@ -38,53 +42,53 @@ GpgFrontend::UI::EmailListEditor::EmailListEditor(const QString& email_list, auto _recipient = recipient.trimmed(); if (check_email_address(_recipient)) { auto item = new QListWidgetItem(_recipient); - ui->emaillistWidget->addItem(item); + ui_->emaillistWidget->addItem(item); item->setFlags(item->flags() | Qt::ItemIsEditable); } } } - connect(ui->addEmailAddressButton, &QPushButton::clicked, this, [=]() { + connect(ui_->addEmailAddressButton, &QPushButton::clicked, this, [=]() { auto item = new QListWidgetItem("new email address"); - ui->emaillistWidget->addItem(item); + ui_->emaillistWidget->addItem(item); item->setFlags(item->flags() | Qt::ItemIsEditable); }); - connect( - ui->actionDelete_Selected_Email_Address, &QAction::triggered, this, - [=]() { - const auto row_size = ui->emaillistWidget->count(); - for (int i = 0; i < row_size; i++) { - auto item = ui->emaillistWidget->item(i); - if (!item->isSelected()) continue; - delete ui->emaillistWidget->takeItem(ui->emaillistWidget->row(item)); - break; - } - }); + connect(ui_->actionDelete_Selected_Email_Address, &QAction::triggered, this, + [=]() { + const auto row_size = ui_->emaillistWidget->count(); + for (int i = 0; i < row_size; i++) { + auto item = ui_->emaillistWidget->item(i); + if (!item->isSelected()) continue; + delete ui_->emaillistWidget->takeItem( + ui_->emaillistWidget->row(item)); + break; + } + }); - ui->titleLabel->setText(_("Email List:")); - ui->tipsLabel->setText( + ui_->titleLabel->setText(_("Email List:")); + ui_->tipsLabel->setText( _("Tips: You can double-click the email address in the edit list, or " "click the email to pop up the option menu.")); - ui->addEmailAddressButton->setText(_("Add An Email Address")); + ui_->addEmailAddressButton->setText(_("Add An Email Address")); this->setWindowTitle(_("Email List Editor")); - ui->actionDelete_Selected_Email_Address->setText(_("Delete")); + ui_->actionDelete_Selected_Email_Address->setText(_("Delete")); - popupMenu = new QMenu(this); - popupMenu->addAction(ui->actionDelete_Selected_Email_Address); + popup_menu_ = new QMenu(this); + popup_menu_->addAction(ui_->actionDelete_Selected_Email_Address); this->exec(); } bool GpgFrontend::UI::EmailListEditor::check_email_address( const QString& email_address) { - return re_email.match(email_address).hasMatch(); + return re_email_.match(email_address).hasMatch(); } -QString GpgFrontend::UI::EmailListEditor::getEmailList() { +QString GpgFrontend::UI::EmailListEditor::GetEmailList() { QString email_list; - for (int i = 0; i < ui->emaillistWidget->count(); ++i) { - QListWidgetItem* item = ui->emaillistWidget->item(i); + for (int i = 0; i < ui_->emaillistWidget->count(); ++i) { + QListWidgetItem* item = ui_->emaillistWidget->item(i); if (check_email_address(item->text())) { email_list.append(item->text()); email_list.append("; "); @@ -96,7 +100,7 @@ QString GpgFrontend::UI::EmailListEditor::getEmailList() { void GpgFrontend::UI::EmailListEditor::contextMenuEvent( QContextMenuEvent* event) { QWidget::contextMenuEvent(event); - if (ui->emaillistWidget->selectedItems().length() > 0) { - popupMenu->exec(event->globalPos()); + if (ui_->emaillistWidget->selectedItems().length() > 0) { + popup_menu_->exec(event->globalPos()); } } diff --git a/src/ui/smtp/EmailListEditor.h b/src/ui/mail/EmailListEditor.h index d4e476a4..b716ff66 100644 --- a/src/ui/smtp/EmailListEditor.h +++ b/src/ui/mail/EmailListEditor.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,23 +34,50 @@ class Ui_EmailListEditorDialog; namespace GpgFrontend::UI { +/** + * @brief + * + */ class EmailListEditor : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Email List Editor object + * + * @param email_list + * @param parent + */ explicit EmailListEditor(const QString& email_list, QWidget* parent); - QString getEmailList(); - private: - std::shared_ptr<Ui_EmailListEditorDialog> ui; - QMenu* popupMenu{}; + /** + * @brief Get the Email List object + * + * @return QString + */ + QString GetEmailList(); - QRegularExpression re_email{ + private: + std::shared_ptr<Ui_EmailListEditorDialog> ui_; ///< + QMenu* popup_menu_{}; ///< + QRegularExpression re_email_{ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + /** + * @brief + * + * @param email_address + * @return true + * @return false + */ bool check_email_address(const QString& email_address); protected: + /** + * @brief + * + * @param event + */ void contextMenuEvent(QContextMenuEvent* event) override; }; } // namespace GpgFrontend::UI diff --git a/src/ui/mail/IMAPFolder.cpp b/src/ui/mail/IMAPFolder.cpp new file mode 100644 index 00000000..68a894f7 --- /dev/null +++ b/src/ui/mail/IMAPFolder.cpp @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "IMAPFolder.h" + +#include <utility> +#include <vmime/vmime.hpp> + +GpgFrontend::UI::IMAPFolder::IMAPFolder( + std::shared_ptr<vmime::net::folder> folder) + : folder_(std::move(folder)), + tree_node_(new QTreeWidgetItem(static_cast<QTreeWidget *>(nullptr), + {"server"})) { + const std::string folder_name = folder_->getName().getBuffer(); + LOG(INFO) << "folder" << folder_name; + + const vmime::net::folderAttributes attr = folder_->getAttributes(); + std::ostringstream attrStr; + + tree_node_->setIcon(0, QIcon(":folder.png")); + if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL) { + LOG(INFO) << "use:All"; + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_ARCHIVE) { + tree_node_->setIcon(0, QIcon(":archive.png")); + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_DRAFTS) { + tree_node_->setIcon(0, QIcon(":drafts.png")); + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_FLAGGED) { + tree_node_->setIcon(0, QIcon(":flag.png")); + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_JUNK) { + tree_node_->setIcon(0, QIcon(":junk.png")); + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_SENT) { + tree_node_->setIcon(0, QIcon(":sent.png")); + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_TRASH) { + tree_node_->setIcon(0, QIcon(":trash.png")); + } else if (attr.getSpecialUse() == + vmime::net::folderAttributes::SPECIALUSE_IMPORTANT) { + tree_node_->setIcon(0, QIcon(":importance.png")); + } + + if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) { + LOG(INFO) << " flag:HasChildren"; + } + if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) { + LOG(INFO) << " flag:NoOpen"; + // tree_node_->setDisabled(true); + } + + if (!folder_name.empty()) + tree_node_->setText(0, folder_name.c_str()); + else + tree_node_->setIcon(0, QIcon(":server.png")); +} + +void GpgFrontend::UI::IMAPFolder::SetParentFolder(IMAPFolder *parent_folder) { + parent_folder->GetTreeWidgetItem()->addChild(tree_node_); +} + +QTreeWidgetItem *GpgFrontend::UI::IMAPFolder::GetTreeWidgetItem() { + return tree_node_; +} + +vmime::net::folder *GpgFrontend::UI::IMAPFolder::GetVmimeFolder() { + return folder_.get(); +} diff --git a/src/ui/mail/IMAPFolder.h b/src/ui/mail/IMAPFolder.h new file mode 100644 index 00000000..8d09eb94 --- /dev/null +++ b/src/ui/mail/IMAPFolder.h @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef GPGFRONTEND_IMAPFOLDER_H +#define GPGFRONTEND_IMAPFOLDER_H + +#include "GpgFrontendUI.h" + +namespace vmime::net { +class folder; +}; + +namespace GpgFrontend::UI { +/** + * @brief + * + */ +class IMAPFolder { + public: + /** + * @brief Construct a new IMAPFolder object + * + * @param folder + */ + explicit IMAPFolder(std::shared_ptr<vmime::net::folder> folder); + + /** + * @brief Set the Parent Folder object + * + * @param parent_node + */ + void SetParentFolder(IMAPFolder* parent_node); + + /** + * @brief Get the Tree Widget Item object + * + * @return QTreeWidgetItem* + */ + QTreeWidgetItem* GetTreeWidgetItem(); + + /** + * @brief Get the Vmime Folder object + * + * @return vmime::net::folder* + */ + vmime::net::folder* GetVmimeFolder(); + + private: + std::shared_ptr<vmime::net::folder> folder_; ///< + QTreeWidgetItem* tree_node_; ///< +}; +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_IMAPFOLDER_H diff --git a/src/ui/mail/ReceiveMailDialog.cpp b/src/ui/mail/ReceiveMailDialog.cpp new file mode 100644 index 00000000..765e8baa --- /dev/null +++ b/src/ui/mail/ReceiveMailDialog.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "ReceiveMailDialog.h" + +#include "ui_ReceiveMailDialog.h" + +GpgFrontend::UI::ReceiveMailDialog::ReceiveMailDialog(QWidget *parent) + : QDialog(parent), ui_(std::make_shared<Ui_ReceiveMailDialog>()) { + ui_->setupUi(this); +} + +void GpgFrontend::UI::ReceiveMailDialog::slot_refresh_data() {} + +void GpgFrontend::UI::ReceiveMailDialog::list_sub_folders( + GpgFrontend::UI::IMAPFolder *parent_folder, + const std::shared_ptr<vmime::net::folder> &) {} diff --git a/src/ui/mail/ReceiveMailDialog.h b/src/ui/mail/ReceiveMailDialog.h new file mode 100644 index 00000000..2ccb2664 --- /dev/null +++ b/src/ui/mail/ReceiveMailDialog.h @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_RECEIVEMAILDIALOG_H +#define GPGFRONTEND_RECEIVEMAILDIALOG_H + +#include "ui/GpgFrontendUI.h" + +class Ui_ReceiveMailDialog; + +namespace vmime::net { +class folder; +}; + +namespace GpgFrontend::UI { + +class IMAPFolder; + +/** + * @brief + * + */ +class ReceiveMailDialog : public QDialog { + Q_OBJECT + public: + /** + * @brief Construct a new Receive Mail Dialog object + * + * @param parent + */ + explicit ReceiveMailDialog(QWidget* parent); + + private slots: + /** + * @brief + * + */ + void slot_refresh_data(); + + private: + std::shared_ptr<Ui_ReceiveMailDialog> ui_; ///< + std::vector<std::shared_ptr<IMAPFolder>> folders_; ///< + + /** + * @brief + * + * @param parent_folder + */ + void list_sub_folders(IMAPFolder* parent_folder, + const std::shared_ptr<vmime::net::folder>&); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_RECEIVEMAILDIALOG_H diff --git a/src/ui/smtp/RecipientsPicker.cpp b/src/ui/mail/RecipientsPicker.cpp index eaaa683a..d6b8bcc5 100644 --- a/src/ui/smtp/RecipientsPicker.cpp +++ b/src/ui/mail/RecipientsPicker.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,23 +34,23 @@ GpgFrontend::UI::RecipientsPicker::RecipientsPicker( const GpgFrontend::KeyIdArgsListPtr& current_key_ids, QWidget* parent) : QDialog(parent) { auto confirm_button = new QPushButton(_("Confirm")); - connect(confirm_button, SIGNAL(clicked(bool)), this, SLOT(accept())); + connect(confirm_button,&QPushButton::clicked, this, &RecipientsPicker::accept); // Setup KeyList key_list_ = new KeyList(KeyMenuAbility::NONE, this); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("Recipient(s)"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::NAME | KeyListColumn::EmailAddress, [](const GpgKey& key) -> bool { - return !key.is_private_key() && key.CanEncrActual(); + return !key.IsPrivateKey() && key.IsHasActualEncryptionCapability(); }); - key_list_->slotRefresh(); + key_list_->SlotRefresh(); auto key_ids = std::make_unique<GpgFrontend::KeyIdArgsList>(); for (const auto& key_id : *current_key_ids) { key_ids->push_back(key_id); } - key_list_->setChecked(std::move(key_ids)); + key_list_->SetChecked(std::move(key_ids)); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(new QLabel(QString(_("Select Recipient(s)")) + ": ")); @@ -71,6 +75,6 @@ GpgFrontend::UI::RecipientsPicker::RecipientsPicker( } GpgFrontend::KeyIdArgsListPtr -GpgFrontend::UI::RecipientsPicker::getCheckedRecipients() { - return key_list_->getChecked(); +GpgFrontend::UI::RecipientsPicker::GetCheckedRecipients() { + return key_list_->GetChecked(); } diff --git a/src/ui/smtp/RecipientsPicker.h b/src/ui/mail/RecipientsPicker.h index bf128149..252bbd58 100644 --- a/src/ui/smtp/RecipientsPicker.h +++ b/src/ui/mail/RecipientsPicker.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -31,18 +35,33 @@ namespace GpgFrontend::UI { class KeyList; +/** + * @brief + * + */ class RecipientsPicker : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Recipients Picker object + * + * @param current_key_ids + * @param parent + */ explicit RecipientsPicker( const GpgFrontend::KeyIdArgsListPtr& current_key_ids, QWidget* parent = nullptr); - GpgFrontend::KeyIdArgsListPtr getCheckedRecipients(); + /** + * @brief Get the Checked Recipients object + * + * @return GpgFrontend::KeyIdArgsListPtr + */ + GpgFrontend::KeyIdArgsListPtr GetCheckedRecipients(); private: - KeyList* key_list_; + KeyList* key_list_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/smtp/SendMailDialog.cpp b/src/ui/mail/SendMailDialog.cpp index 3f0b87cd..137c941f 100644 --- a/src/ui/smtp/SendMailDialog.cpp +++ b/src/ui/mail/SendMailDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,42 +8,43 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SendMailDialog.h" -#include "gpg/function/GpgKeyGetter.h" -#include "ui/smtp/EmailListEditor.h" -#include "ui/smtp/RecipientsPicker.h" -#include "ui/smtp/SenderPicker.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "ui/mail/EmailListEditor.h" +#include "ui/mail/RecipientsPicker.h" +#include "ui/mail/SenderPicker.h" #include "ui_SendMailDialog.h" #ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#include "ui/function/SMTPSendMailThread.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" +#include "ui/thread/SMTPSendMailThread.h" #endif namespace GpgFrontend::UI { SendMailDialog::SendMailDialog(const QString& text, QWidget* parent) - : QDialog(parent), ui(std::make_shared<Ui_SendMailDialog>()) { + : QDialog(parent), ui_(std::make_shared<Ui_SendMailDialog>()) { // read from settings - initSettings(); + init_settings(); if (smtp_address_.isEmpty()) { QMessageBox::critical( @@ -53,87 +56,88 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent) return; } - ui->setupUi(this); + ui_->setupUi(this); - ui->ccInputWidget->setHidden(true); - ui->bccInputWidget->setHidden(true); - ui->textEdit->setText(text); - ui->errorLabel->setHidden(true); + ui_->ccInputWidget->setHidden(true); + ui_->bccInputWidget->setHidden(true); + ui_->textEdit->setText(text); + ui_->errorLabel->setHidden(true); - ui->senderEdit->setText(default_sender_); + ui_->senderEdit->setText(default_sender_); - if (!default_sender_gpg_key_id.isEmpty()) { + if (!default_sender_gpg_key_id_.isEmpty()) { auto key = GpgKeyGetter::GetInstance().GetKey( - default_sender_gpg_key_id.toStdString()); - if (key.good() && key.is_private_key() && key.CanSignActual()) { - sender_key_id_ = key.id(); + default_sender_gpg_key_id_.toStdString()); + if (key.IsGood() && key.IsPrivateKey() && + key.IsHasActualSigningCapability()) { + sender_key_id_ = key.GetId(); set_sender_value_label(); } } - connect(ui->ccButton, &QPushButton::clicked, [=]() { - ui->ccInputWidget->setHidden(!ui->ccInputWidget->isHidden()); - ui->ccEdit->clear(); + connect(ui_->ccButton, &QPushButton::clicked, [=]() { + ui_->ccInputWidget->setHidden(!ui_->ccInputWidget->isHidden()); + ui_->ccEdit->clear(); }); - connect(ui->bccButton, &QPushButton::clicked, [=]() { - ui->bccInputWidget->setHidden(!ui->bccInputWidget->isHidden()); - ui->bccEdit->clear(); + connect(ui_->bccButton, &QPushButton::clicked, [=]() { + ui_->bccInputWidget->setHidden(!ui_->bccInputWidget->isHidden()); + ui_->bccEdit->clear(); }); #ifdef SMTP_SUPPORT - connect(ui->sendMailButton, &QPushButton::clicked, this, - &SendMailDialog::slotConfirm); + connect(ui_->sendMailButton, &QPushButton::clicked, this, + &SendMailDialog::slot_confirm); #endif - connect(ui->senderKeySelectButton, &QPushButton::clicked, this, [=]() { + connect(ui_->senderKeySelectButton, &QPushButton::clicked, this, [=]() { auto picker = new SenderPicker(sender_key_id_, this); - sender_key_id_ = picker->getCheckedSender(); + sender_key_id_ = picker->GetCheckedSender(); set_sender_value_label(); }); - connect(ui->recipientKeySelectButton, &QPushButton::clicked, this, [=]() { + connect(ui_->recipientKeySelectButton, &QPushButton::clicked, this, [=]() { auto picker = new RecipientsPicker(recipients_key_ids_, this); - recipients_key_ids_ = picker->getCheckedRecipients(); + recipients_key_ids_ = picker->GetCheckedRecipients(); set_recipients_value_label(); }); - connect(ui->recipientsEditButton, &QPushButton::clicked, this, [=]() { - auto editor = new EmailListEditor(ui->recipientEdit->text(), this); - ui->recipientEdit->setText(editor->getEmailList()); + connect(ui_->recipientsEditButton, &QPushButton::clicked, this, [=]() { + auto editor = new EmailListEditor(ui_->recipientEdit->text(), this); + ui_->recipientEdit->setText(editor->GetEmailList()); }); - connect(ui->ccEditButton, &QPushButton::clicked, this, [=]() { - auto editor = new EmailListEditor(ui->ccEdit->text(), this); - ui->ccEdit->setText(editor->getEmailList()); + connect(ui_->ccEditButton, &QPushButton::clicked, this, [=]() { + auto editor = new EmailListEditor(ui_->ccEdit->text(), this); + ui_->ccEdit->setText(editor->GetEmailList()); }); - connect(ui->bccEditButton, &QPushButton::clicked, this, [=]() { - auto editor = new EmailListEditor(ui->bccEdit->text(), this); - ui->bccEdit->setText(editor->getEmailList()); + connect(ui_->bccEditButton, &QPushButton::clicked, this, [=]() { + auto editor = new EmailListEditor(ui_->bccEdit->text(), this); + ui_->bccEdit->setText(editor->GetEmailList()); }); - ui->ccButton->setText(_("CC")); - ui->bccButton->setText(_("BCC")); - ui->senderLabel->setText(_("Sender")); - ui->recipientLabel->setText(_("Recipient")); - ui->subjectLabel->setText(_("Mail Subject")); - ui->bccLabel->setText(_("BCC")); - ui->ccLabel->setText(_("CC")); - ui->tipsLabel->setText( + ui_->ccButton->setText(_("CC")); + ui_->bccButton->setText(_("BCC")); + ui_->senderLabel->setText(_("Sender")); + ui_->recipientLabel->setText(_("Recipient")); + ui_->subjectLabel->setText(_("Mail Subject")); + ui_->bccLabel->setText(_("BCC")); + ui_->ccLabel->setText(_("CC")); + ui_->tipsLabel->setText( _("Tips: You can fill in multiple email addresses, please separate them " "with \";\".")); - ui->sendMailButton->setText(_("Send Message")); - ui->senderKeySelectButton->setText(_("Select Sender GPG Key")); - ui->recipientKeySelectButton->setText(_("Select Recipient(s) GPG Key")); - ui->gpgOperaLabel->setText(_("GPG Operations")); - ui->attacSignatureCheckBox->setText(_("Attach signature")); - ui->attachSenderPublickeyCheckBox->setText(_("Attach sender's public key")); - ui->contentEncryptCheckBox->setText(_("Encrypt content")); - ui->recipientsEditButton->setText(_("Edit Recipients(s)")); - ui->ccEditButton->setText(_("Edit CC(s)")); - ui->bccEditButton->setText(_("Edit BCC(s)")); - ui->senderKeyLabel->setText(_("Sender GPG Key: ")); - ui->recipientKeysLabel->setText(_("Recipient(s) GPG Key: ")); + ui_->sendMailButton->setText(_("Send Message")); + ui_->senderKeySelectButton->setText(_("Select Sender GPG Key")); + ui_->recipientKeySelectButton->setText(_("Select Recipient(s) GPG Key")); + ui_->gpgOperaLabel->setText(_("GPG Operations")); + ui_->attacSignatureCheckBox->setText(_("Attach signature")); + ui_->attachSenderPublickeyCheckBox->setText(_("Attach sender's public key")); + ui_->contentEncryptCheckBox->setText(_("Encrypt content")); + ui_->recipientsEditButton->setText(_("Edit Recipients(s)")); + ui_->ccEditButton->setText(_("Edit CC(s)")); + ui_->bccEditButton->setText(_("Edit BCC(s)")); + ui_->senderKeyLabel->setText(_("Sender GPG Key: ")); + ui_->recipientKeysLabel->setText(_("Recipient(s) GPG Key: ")); auto pos = QPoint(100, 100); LOG(INFO) << "parent" << parent; @@ -147,18 +151,18 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent) } bool SendMailDialog::check_email_address(const QString& str) { - return re_email.match(str).hasMatch(); + return re_email_.match(str).hasMatch(); } #ifdef SMTP_SUPPORT -void SendMailDialog::slotConfirm() { +void SendMailDialog::slot_confirm() { QString errString; - ui->errorLabel->clear(); - ui->errorLabel->setHidden(true); - QStringList rcpt_string_list = ui->recipientEdit->text().split(';'); - QStringList cc_string_list = ui->ccEdit->text().split(';'); - QStringList bcc_string_list = ui->bccEdit->text().split(';'); + ui_->errorLabel->clear(); + ui_->errorLabel->setHidden(true); + QStringList rcpt_string_list = ui_->recipientEdit->text().split(';'); + QStringList cc_string_list = ui_->ccEdit->text().split(';'); + QStringList bcc_string_list = ui_->bccEdit->text().split(';'); if (rcpt_string_list.isEmpty()) { errString.append(QString(" ") + _("Recipient cannot be empty") + " \n"); @@ -173,17 +177,17 @@ void SendMailDialog::slotConfirm() { } } } - if (ui->senderEdit->text().isEmpty()) { + if (ui_->senderEdit->text().isEmpty()) { errString.append(QString(" ") + _("Sender cannot be empty") + " \n"); - } else if (!check_email_address(ui->senderEdit->text())) { + } else if (!check_email_address(ui_->senderEdit->text())) { errString.append(QString(" ") + _("Sender's email is invalid") + " \n"); } - if (ui->subjectEdit->text().isEmpty()) { + if (ui_->subjectEdit->text().isEmpty()) { errString.append(QString(" ") + _("Subject cannot be empty") + " \n"); } - if (!ui->ccEdit->text().isEmpty()) + if (!ui_->ccEdit->text().isEmpty()) for (const auto& cc : cc_string_list) { LOG(INFO) << "cc" << cc.trimmed().toStdString(); if (!check_email_address(cc.trimmed())) { @@ -193,7 +197,7 @@ void SendMailDialog::slotConfirm() { } } - if (!ui->bccEdit->text().isEmpty()) + if (!ui_->bccEdit->text().isEmpty()) for (const auto& bcc : bcc_string_list) { LOG(INFO) << "bcc" << bcc.trimmed().toStdString(); if (!check_email_address(bcc.trimmed())) { @@ -204,12 +208,12 @@ void SendMailDialog::slotConfirm() { } if (!errString.isEmpty()) { - ui->errorLabel->setAutoFillBackground(true); - QPalette error = ui->errorLabel->palette(); + ui_->errorLabel->setAutoFillBackground(true); + QPalette error = ui_->errorLabel->palette(); error.setColor(QPalette::Window, "#ff8080"); - ui->errorLabel->setPalette(error); - ui->errorLabel->setText(errString); - ui->errorLabel->setHidden(false); + ui_->errorLabel->setPalette(error); + ui_->errorLabel->setText(errString); + ui_->errorLabel->setHidden(false); return; } @@ -232,19 +236,19 @@ void SendMailDialog::slotConfirm() { bool identity_needed = identity_enable_; auto username = username_.toStdString(); auto password = password_.toStdString(); - auto sender_address = ui->senderEdit->text().toStdString(); + auto sender_address = ui_->senderEdit->text().toStdString(); auto thread = new SMTPSendMailThread( host, port, connection_type, identity_needed, username, password, this); - thread->setSender(ui->senderEdit->text()); - thread->setRecipient(ui->recipientEdit->text()); - thread->setCC(ui->ccEdit->text()); - thread->setBCC(ui->bccEdit->text()); - thread->setSubject(ui->subjectEdit->text()); - thread->addTextContent(ui->textEdit->toPlainText()); + thread->SetSender(ui_->senderEdit->text()); + thread->SetRecipient(ui_->recipientEdit->text()); + thread->SetCC(ui_->ccEdit->text()); + thread->SetBCC(ui_->bccEdit->text()); + thread->SetSubject(ui_->subjectEdit->text()); + thread->AddTextContent(ui_->textEdit->toPlainText()); - if (ui->contentEncryptCheckBox->checkState() == Qt::Checked) { + if (ui_->contentEncryptCheckBox->checkState() == Qt::Checked) { if (recipients_key_ids_ == nullptr || recipients_key_ids_->empty()) { QMessageBox::critical( this, _("Forbidden"), @@ -256,11 +260,11 @@ void SendMailDialog::slotConfirm() { auto key_ids = std::make_unique<KeyIdArgsList>(); for (const auto& key_id : *recipients_key_ids_) key_ids->push_back(key_id); - thread->setEncryptContent(true, std::move(key_ids)); + thread->SetEncryptContent(true, std::move(key_ids)); } } - if (ui->attacSignatureCheckBox->checkState() == Qt::Checked) { + if (ui_->attacSignatureCheckBox->checkState() == Qt::Checked) { if (sender_key_id_.empty()) { QMessageBox::critical( this, _("Forbidden"), @@ -270,11 +274,11 @@ void SendMailDialog::slotConfirm() { "operation is prohibited.")); return; } else { - thread->setAttachSignatureFile(true, sender_key_id_); + thread->SetAttachSignatureFile(true, sender_key_id_); } } - if (ui->attachSenderPublickeyCheckBox->checkState() == Qt::Checked) { + if (ui_->attachSenderPublickeyCheckBox->checkState() == Qt::Checked) { if (sender_key_id_.empty()) { QMessageBox::critical( this, _("Forbidden"), @@ -285,7 +289,7 @@ void SendMailDialog::slotConfirm() { "with your expectations, so the operation is prohibited.")); return; } else { - thread->setAttachPublicKey(true, sender_key_id_); + thread->SetAttachPublicKey(true, sender_key_id_); } } @@ -300,8 +304,8 @@ void SendMailDialog::slotConfirm() { waiting_dialog_label->setWordWrap(true); waiting_dialog->setLabel(waiting_dialog_label); waiting_dialog->resize(420, 120); - connect(thread, &SMTPSendMailThread::signalSMTPResult, this, - &SendMailDialog::slotTestSMTPConnectionResult); + connect(thread, &SMTPSendMailThread::SignalSMTPResult, this, + &SendMailDialog::slot_test_smtp_connection_result); connect(thread, &QThread::finished, [=]() { waiting_dialog->finished(0); waiting_dialog->deleteLater(); @@ -321,7 +325,7 @@ void SendMailDialog::slotConfirm() { loop.exec(); } -void SendMailDialog::initSettings() { +void SendMailDialog::init_settings() { auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); try { @@ -373,7 +377,7 @@ void SendMailDialog::initSettings() { } try { - default_sender_gpg_key_id = + default_sender_gpg_key_id_ = settings.lookup("smtp.default_sender_gpg_key_id").c_str(); } catch (...) { LOG(ERROR) << _("Setting Operation Error") @@ -384,8 +388,8 @@ void SendMailDialog::initSettings() { void SendMailDialog::set_sender_value_label() { auto key = GpgKeyGetter::GetInstance().GetKey(sender_key_id_); - if (key.good()) { - ui->senderKeyValueLabel->setText(key.uids()->front().uid().c_str()); + if (key.IsGood()) { + ui_->senderKeyValueLabel->setText(key.GetUIDs()->front().GetUID().c_str()); } } @@ -393,14 +397,14 @@ void SendMailDialog::set_recipients_value_label() { auto keys = GpgKeyGetter::GetInstance().GetKeys(recipients_key_ids_); std::stringstream ss; for (const auto& key : *keys) { - if (key.good()) { - ss << key.uids()->front().uid().c_str() << ";"; + if (key.IsGood()) { + ss << key.GetUIDs()->front().GetUID().c_str() << ";"; } } - ui->recipientsKeyValueLabel->setText(ss.str().c_str()); + ui_->recipientsKeyValueLabel->setText(ss.str().c_str()); } -void SendMailDialog::slotTestSMTPConnectionResult(const QString& result) { +void SendMailDialog::slot_test_smtp_connection_result(const QString& result) { if (result == "Fail to connect SMTP server") { QMessageBox::critical(this, _("Fail"), _("Fail to Connect SMTP Server.")); } else if (result == "Fail to login") { @@ -424,12 +428,12 @@ void SendMailDialog::slotTestSMTPConnectionResult(const QString& result) { QMessageBox::critical(this, _("Fail"), _("Unknown error.")); } } -void SendMailDialog::setContentEncryption(bool on) { - ui->contentEncryptCheckBox->setCheckState(on ? Qt::Checked : Qt::Unchecked); +void SendMailDialog::SetContentEncryption(bool on) { + ui_->contentEncryptCheckBox->setCheckState(on ? Qt::Checked : Qt::Unchecked); } -void SendMailDialog::setAttachSignature(bool on) { - ui->attacSignatureCheckBox->setCheckState(on ? Qt::Checked : Qt::Unchecked); +void SendMailDialog::SetAttachSignature(bool on) { + ui_->attacSignatureCheckBox->setCheckState(on ? Qt::Checked : Qt::Unchecked); } } // namespace GpgFrontend::UI diff --git a/src/ui/mail/SendMailDialog.h b/src/ui/mail/SendMailDialog.h new file mode 100644 index 00000000..3d745e11 --- /dev/null +++ b/src/ui/mail/SendMailDialog.h @@ -0,0 +1,132 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_SENDMAILDIALOG_H +#define GPGFRONTEND_SENDMAILDIALOG_H + +#include "ui/GpgFrontendUI.h" + +class Ui_SendMailDialog; + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +class SendMailDialog : public QDialog { + Q_OBJECT + public: + /** + * @brief Construct a new Send Mail Dialog object + * + * @param text + * @param parent + */ + explicit SendMailDialog(const QString& text, QWidget* parent = nullptr); + + /** + * @brief Set the Content Encryption object + * + * @param on + */ + void SetContentEncryption(bool on); + + /** + * @brief Set the Attach Signature object + * + * @param on + */ + void SetAttachSignature(bool on); + + private slots: + + /** + * @brief + * + */ + void slot_confirm(); + + /** + * @brief + * + * @param result + */ + void slot_test_smtp_connection_result(const QString& result); + + private: + /** + * @brief + * + */ + void init_settings(); + + std::shared_ptr<Ui_SendMailDialog> ui_; ///< + + bool ability_enable_ = false; ///< + bool identity_enable_ = false; ///< + QString smtp_address_; ///< + QString username_; ///< + QString password_; ///< + QString default_sender_; ///< + QString connection_type_settings_ = "None"; ///< + QString default_sender_gpg_key_id_ = {}; ///< + int port_ = 25; ///< + + GpgFrontend::KeyId sender_key_id_; ///< + GpgFrontend::KeyIdArgsListPtr recipients_key_ids_ = + std::make_unique<GpgFrontend::KeyIdArgsList>(); ///< + + QRegularExpression re_email_{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + + /** + * @brief + * + * @param str + * @return true + * @return false + */ + bool check_email_address(const QString& str); + + /** + * @brief Set the sender value label object + * + */ + void set_sender_value_label(); + + /** + * @brief Set the recipients value label object + * + */ + void set_recipients_value_label(); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SENDMAILDIALOG_H diff --git a/src/ui/smtp/SenderPicker.cpp b/src/ui/mail/SenderPicker.cpp index fcd3ba61..e3563480 100644 --- a/src/ui/smtp/SenderPicker.cpp +++ b/src/ui/mail/SenderPicker.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,19 +34,20 @@ GpgFrontend::UI::SenderPicker::SenderPicker(const KeyId& current_key_id, QWidget* parent) : QDialog(parent) { auto confirm_button = new QPushButton(_("Confirm")); - connect(confirm_button, SIGNAL(clicked(bool)), this, SLOT(accept())); + connect(confirm_button, &QPushButton::clicked, this, &SenderPicker::accept); // Setup KeyList key_list_ = new KeyList(KeyMenuAbility::NONE, this); - key_list_->addListGroupTab( - _("Sender"), KeyListRow::ONLY_SECRET_KEY, - KeyListColumn::NAME | KeyListColumn::EmailAddress, - [](const GpgKey& key) -> bool { return key.CanSignActual(); }); - key_list_->slotRefresh(); + key_list_->AddListGroupTab(_("Sender"), KeyListRow::ONLY_SECRET_KEY, + KeyListColumn::NAME | KeyListColumn::EmailAddress, + [](const GpgKey& key) -> bool { + return key.IsHasActualSigningCapability(); + }); + key_list_->SlotRefresh(); auto key_ids = std::make_unique<GpgFrontend::KeyIdArgsList>(); key_ids->push_back(current_key_id); - key_list_->setChecked(std::move(key_ids)); + key_list_->SetChecked(std::move(key_ids)); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(new QLabel(QString(_("Select Sender")) + ": ")); @@ -66,10 +71,10 @@ GpgFrontend::UI::SenderPicker::SenderPicker(const KeyId& current_key_id, this->exec(); } -GpgFrontend::KeyId GpgFrontend::UI::SenderPicker::getCheckedSender() { - auto checked_keys = key_list_->getChecked(); +GpgFrontend::KeyId GpgFrontend::UI::SenderPicker::GetCheckedSender() { + auto checked_keys = key_list_->GetChecked(); if (!checked_keys->empty()) { - return key_list_->getChecked()->front(); + return key_list_->GetChecked()->front(); } else { return {}; } diff --git a/src/ui/smtp/SenderPicker.h b/src/ui/mail/SenderPicker.h index 3745bb34..ce8cd8e6 100644 --- a/src/ui/smtp/SenderPicker.h +++ b/src/ui/mail/SenderPicker.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -31,16 +35,31 @@ namespace GpgFrontend::UI { class KeyList; +/** + * @brief + * + */ class SenderPicker : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Sender Picker object + * + * @param current_key_id + * @param parent + */ explicit SenderPicker(const KeyId& current_key_id, QWidget* parent = nullptr); - GpgFrontend::KeyId getCheckedSender(); + /** + * @brief Get the Checked Sender object + * + * @return GpgFrontend::KeyId + */ + GpgFrontend::KeyId GetCheckedSender(); private: - KeyList* key_list_; + KeyList* key_list_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp new file mode 100644 index 00000000..368c5630 --- /dev/null +++ b/src/ui/main_window/MainWindow.cpp @@ -0,0 +1,332 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "MainWindow.h" + +#include "ui/UserInterfaceUtils.h" +#ifdef RELEASE +#include "ui/thread/VersionCheckThread.h" +#endif +#include "core/function/GlobalSettingStation.h" +#include "ui/SignalStation.h" +#include "ui/struct/SettingsObject.h" + +namespace GpgFrontend::UI { + +MainWindow::MainWindow() { + this->setMinimumSize(1200, 700); + this->setWindowTitle(qApp->applicationName()); +} + +void MainWindow::Init() noexcept { + try { + /* get path where app was started */ + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + + edit_ = new TextEdit(this); + setCentralWidget(edit_); + + /* the list of Keys available*/ + m_key_list_ = new KeyList( + KeyMenuAbility::REFRESH | KeyMenuAbility::UNCHECK_ALL, this); + + info_board_ = new InfoBoardWidget(this); + + /* List of binary Attachments */ + attachment_dock_created_ = false; + + /* Variable containing if restart is needed */ + this->SlotSetRestartNeeded(false); + + create_actions(); + create_menus(); + create_tool_bars(); + create_status_bar(); + create_dock_windows(); + + connect(edit_->tab_widget_, &QTabWidget::currentChanged, this, + &MainWindow::slot_disable_tab_actions); + connect(SignalStation::GetInstance(), + &SignalStation::SignalRefreshStatusBar, this, + [=](const QString &message, int timeout) { + statusBar()->showMessage(message, timeout); + }); + + m_key_list_->AddMenuAction(append_selected_keys_act_); + m_key_list_->AddMenuAction(copy_mail_address_to_clipboard_act_); + m_key_list_->AddSeparator(); + m_key_list_->AddMenuAction(show_key_details_act_); + + restore_settings(); + + // open filename if provided as first command line parameter + QStringList args = qApp->arguments(); + if (args.size() > 1) { + if (!args[1].startsWith("-")) { + if (QFile::exists(args[1])) + edit_->LoadFile(args[1]); + } + } + edit_->CurTextPage()->setFocus(); + + auto &settings = GlobalSettingStation::GetInstance().GetUISettings(); + + if (!settings.exists("wizard") || + settings.lookup("wizard").getType() != libconfig::Setting::TypeGroup) + settings.add("wizard", libconfig::Setting::TypeGroup); + + auto &wizard = settings["wizard"]; + + // Show wizard, if the don't show wizard message box wasn't checked + // and keylist doesn't contain a private key + + if (!wizard.exists("show_wizard")) + wizard.add("show_wizard", libconfig::Setting::TypeBoolean) = true; + + bool show_wizard = true; + wizard.lookupValue("show_wizard", show_wizard); + + LOG(INFO) << "wizard show_wizard" << show_wizard; + + if (show_wizard) { + slot_start_wizard(); + } + + emit SignalLoaded(); + + // if not prohibit update checking + if (!prohibit_update_checking_) { +#ifdef RELEASE + auto version_thread = new VersionCheckThread(); + + connect(version_thread, &VersionCheckThread::finished, version_thread, + &VersionCheckThread::deleteLater); + connect(version_thread, &VersionCheckThread::SignalUpgradeVersion, this, + &MainWindow::slot_version_upgrade); + + version_thread->start(); +#endif + } + + } catch (...) { + LOG(FATAL) << _("Critical error occur while loading GpgFrontend."); + QMessageBox::critical(nullptr, _("Loading Failed"), + _("Critical error occur while loading GpgFrontend.")); + QCoreApplication::quit(); + exit(0); + } +} + +void MainWindow::restore_settings() { + LOG(INFO) << _("Called"); + + try { + + LOG(INFO) << "restore settings main_windows_state"; + + SettingsObject main_windows_state("main_windows_state"); + + std::string window_state = main_windows_state.Check( + "window_state", saveState().toBase64().toStdString()); + // state sets pos & size of dock-widgets + this->restoreState( + QByteArray::fromBase64(QByteArray::fromStdString(window_state))); + + bool window_save = main_windows_state.Check("window_save", true); + + // Restore window size & location + if (window_save) { + int x = main_windows_state.Check("window_pos").Check("x", 100), + y = main_windows_state.Check("window_pos").Check("y", 100); + + auto pos = QPoint(x, y); + + int width = main_windows_state.Check("window_size").Check("width", 800), + height = main_windows_state.Check("window_size").Check("height", 450); + + auto size = QSize(width, height); + this->resize(size); + this->move(pos); + } else { + this->resize(QSize(800, 450)); + this->move(QPoint(100, 100)); + } + + int width = main_windows_state.Check("icon_size").Check("width", 24), + height = main_windows_state.Check("icon_size").Check("height", 24); + LOG(INFO) << "icon_size" << width << height; + + main_windows_state.Check("info_font_size", 10); + + // icon_style + int s_icon_style = + main_windows_state.Check("icon_style", Qt::ToolButtonTextUnderIcon); + auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); + this->setToolButtonStyle(icon_style); + import_button_->setToolButtonStyle(icon_style); + + // icons ize + this->setIconSize(QSize(width, height)); + import_button_->setIconSize(QSize(width, height)); + + LOG(INFO) << "restore settings key_server"; + + SettingsObject key_server_json("key_server"); + + if (!key_server_json.contains("server_list")) { + key_server_json["server_list"] = {"https://keyserver.ubuntu.com", + "http://keys.gnupg.net", + "http://pool.sks-keyservers.net"}; + } + + if (!key_server_json.contains("default_server")) { + key_server_json["default_server"] = 0; + } + + auto &settings = GlobalSettingStation::GetInstance().GetUISettings(); + + if (!settings.exists("general") || + settings.lookup("general").getType() != libconfig::Setting::TypeGroup) + settings.add("general", libconfig::Setting::TypeGroup); + + auto &general = settings["general"]; + + if (!general.exists("save_key_checked")) { + general.add("save_key_checked", libconfig::Setting::TypeBoolean) = true; + } + + if (!general.exists("non_ascii_when_export")) { + general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) = + true; + } + + bool save_key_checked = true; + general.lookupValue("save_key_checked", save_key_checked); + + try { + + LOG(INFO) << "restore settings default_key_checked"; + + // Checked Keys + SettingsObject default_key_checked("default_key_checked"); + if (save_key_checked) { + auto key_ids_ptr = std::make_unique<KeyIdArgsList>(); + for (auto &it : default_key_checked) { + std::string key_id = it; + LOG(INFO) << "get checked key id" << key_id; + key_ids_ptr->push_back(key_id); + } + m_key_list_->SetChecked(std::move(key_ids_ptr)); + } + } catch (...) { + LOG(ERROR) << "restore default_key_checked failed"; + } + + LOG(INFO) << "restore settings smtp_passport"; + + SettingsObject smtp_passport("smtp_passport"); + smtp_passport.Check("enable", false); + + prohibit_update_checking_ = false; + try { + prohibit_update_checking_ = + settings.lookup("network.prohibit_update_checking"); + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") + << _("prohibit_update_checking"); + } + + } catch (...) { + LOG(ERROR) << "cannot resolve settings"; + } + + GlobalSettingStation::GetInstance().SyncSettings(); +} + +void MainWindow::save_settings() { + auto &settings = GlobalSettingStation::GetInstance().GetUISettings(); + + try { + SettingsObject main_windows_state("main_windows_state"); + + // window position and size + main_windows_state["window_state"] = saveState().toBase64().toStdString(); + main_windows_state["window_pos"]["x"] = pos().x(); + main_windows_state["window_pos"]["y"] = pos().y(); + + main_windows_state["window_size"]["width"] = size().width(); + main_windows_state["window_size"]["height"] = size().height(); + + bool save_key_checked = settings.lookup("general.save_key_checked"); + + // keyid-list of private checked keys + if (save_key_checked) { + auto key_ids_need_to_store = m_key_list_->GetChecked(); + + SettingsObject default_key_checked("default_key_checked"); + default_key_checked.clear(); + + for (const auto &key_id : *key_ids_need_to_store) + default_key_checked.push_back(key_id); + } else { + settings["general"].remove("save_key_checked"); + } + } catch (...) { + LOG(ERROR) << "cannot save settings"; + }; + + GlobalSettingStation::GetInstance().SyncSettings(); +} + +void MainWindow::close_attachment_dock() { + if (!attachment_dock_created_) { + return; + } + attachment_dock_->close(); + attachment_dock_->deleteLater(); + attachment_dock_created_ = false; +} + +void MainWindow::closeEvent(QCloseEvent *event) { + /* + * ask to save changes, if there are + * modified documents in any tab + */ + if (edit_->MaybeSaveAnyTab()) { + save_settings(); + event->accept(); + } else { + event->ignore(); + } + + // clear password from memory + // GpgContext::GetInstance().clearPasswordCache(); +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h new file mode 100644 index 00000000..5cc9a15a --- /dev/null +++ b/src/ui/main_window/MainWindow.h @@ -0,0 +1,416 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef __GPGWIN_H__ +#define __GPGWIN_H__ + +#include "core/GpgConstants.h" +#include "core/function/result_analyse/GpgDecryptResultAnalyse.h" +#include "core/function/result_analyse/GpgEncryptResultAnalyse.h" +#include "core/function/result_analyse/GpgSignResultAnalyse.h" +#include "ui/GpgFrontendUI.h" +#include "ui/KeyMgmt.h" +#include "ui/dialog/WaitingDialog.h" +#include "ui/dialog/Wizard.h" +#include "ui/help/AboutDialog.h" +#include "ui/import_export/KeyUploadDialog.h" +#include "ui/settings/SettingsDialog.h" +#include "ui/widgets/FindWidget.h" +#include "ui/widgets/InfoBoardWidget.h" +#include "ui/widgets/TextEdit.h" + +namespace GpgFrontend::UI { +/** + * @brief + * + */ +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + + struct CryptoMenu{ + using OperationType = unsigned int; + + static constexpr OperationType None = 0; + static constexpr OperationType Encrypt = 1 << 0; + static constexpr OperationType Sign = 1 << 1; + static constexpr OperationType Decrypt = 1 << 2; + static constexpr OperationType Verify = 1 << 3; + static constexpr OperationType EncryptAndSign = 1 << 4; + static constexpr OperationType DecryptAndVerify = 1 << 5; + }; + + /** + * @brief + * + */ + MainWindow(); + + /** + * @details ONLY Called from main() + */ + void Init() noexcept; + + /** + * @details refresh and enable specify crypto-menu actions. + */ + void SetCryptoMenuStatus(CryptoMenu::OperationType type); + + signals: + + /** + * @brief + */ + void SignalLoaded(); + + + public slots: + + /** + * @brief + */ + void SlotSetStatusBarText(const QString& text); + + protected: + /** + * @details Close event shows a save dialog, if there are unsaved documents on + * exit. + * @param event + */ + void closeEvent(QCloseEvent* event) override; + + public slots: + + /** + * @details Open a new tab for path + */ + void SlotOpenFile(QString& path); + + /** + * @details Open dialog for encrypting file. + */ + void SlotFileEncrypt(); + + /** + * @details Open dialog for decrypting file. + */ + void SlotFileDecrypt(); + + /** + * @details Open dialog for signing file. + */ + void SlotFileSign(); + + /** + * @details Open dialog for verifying file. + */ + void SlotFileVerify(); + + /** + * @details Open dialog for signing file. + */ + void SlotFileEncryptSign(); + + /** + * @details Open dialog for verifying file. + */ + void SlotFileDecryptVerify(); + + /** + * @details get value of member restartNeeded to needed. + * @param needed true, if application has to be restarted + */ + void SlotSetRestartNeeded(bool needed); + + private slots: + + /** + * @details encrypt the text of currently active textedit-page + * with the currently checked keys + */ + void slot_encrypt(); + + /** + * @details encrypt and sign the text of currently active textedit-page + * with the currently checked keys + */ + void slot_encrypt_sign(); + + /** + * @details Show a passphrase dialog and decrypt the text of currently active + * tab. + */ + void slot_decrypt(); + + /** + * @details Sign the text of currently active tab with the checked private + * keys + */ + void slot_sign(); + + /** + * @details Verify the text of currently active tab and show verify + * information. If document is signed with a key, which is not in keylist, + * show import missing key from keyserver in Menu of verifynotification. + */ + void slot_verify(); + + /** + * @details decrypt and verify the text of currently active textedit-page + * with the currently checked keys + */ + void slot_decrypt_verify(); + + /** + * @details Show the details of the first of the first of selected keys + */ + void slot_show_key_details(); + + /** + * @details Refresh key information of selected keys from default keyserver + */ + void refresh_keys_from_key_server(); + + /** + * @details upload the selected key to the keyserver + */ + void upload_key_to_server(); + + /** + * @details Open find widget. + */ + void slot_find(); + + /** + * @details start the wizard + */ + void slot_start_wizard(); + + /** + * @details Import keys from currently active tab to keylist if possible. + */ + void slot_import_key_from_edit(); + + /** + * @details Append the selected keys to currently active textedit. + */ + void slot_append_selected_keys(); + + /** + * @details Copy the mailaddress of selected key to clipboard. + * Method for keylists contextmenu. + */ + void slot_copy_mail_address_to_clipboard(); + + /** + * @details Open key management dialog. + */ + void slot_open_key_management(); + + /** + * @details Open File Opera Tab + */ + void slot_open_file_tab(); + + /** + * @details Open settings-dialog. + */ + void slot_open_settings_dialog(); + + /** + * @details Replace double linebreaks by single linebreaks in currently active + * tab. + */ + void slot_clean_double_line_breaks(); + + /** + * @details Cut the existing PGP header and footer from current tab. + */ + void slot_cut_pgp_header(); + + /** + * @details Add PGP header and footer to current tab. + */ + void slot_add_pgp_header(); + + /** + * @details Disable tab related actions, if number of tabs is 0. + * @param number number of the opened tabs and -1, if no tab is opened + */ + void slot_disable_tab_actions(int number); + + /** + * @details called when need to upgrade. + */ + void slot_version_upgrade(const SoftwareVersion& version); + + private: + /** + * @details Create actions for the main-menu and the context-menu of the + * keylist. + */ + void create_actions(); + + /** + * @details create the menu of the main-window. + */ + void create_menus(); + + /** + * @details Create edit-, crypt- and key-toolbars. + */ + void create_tool_bars(); + + /** + * @details Create statusbar of mainwindow. + */ + void create_status_bar(); + + /** + * @details Create keylist- and attachment-dockwindows. + */ + void create_dock_windows(); + + /** + * @details Create attachment dock window. + */ + void create_attachment_dock(); + + /** + * @details close attachment-dockwindow. + */ + void close_attachment_dock(); + + /** + * @details Load settings from ini-file. + */ + void restore_settings(); + + /** + * @details Save settings to ini-file. + */ + void save_settings(); + + /** + * @brief return true, if restart is needed + */ + [[nodiscard]] bool get_restart_needed() const; + + TextEdit* edit_{}; ///< Tabwidget holding the edit-windows + QMenu* file_menu_{}; ///< Submenu for file-operations + QMenu* edit_menu_{}; ///< Submenu for text-operations + QMenu* crypt_menu_{}; ///< Submenu for crypt-operations + QMenu* help_menu_{}; ///< Submenu for help-operations + QMenu* key_menu_{}; ///< Submenu for key-operations + QMenu* view_menu_{}; ///< Submenu for view operations + QMenu* import_key_menu_{}; ///< Submenu for import operations +#ifdef SMTP_SUPPORT + QMenu* email_menu_{}; ///< Submenu for email operations +#endif + + QMenu* steganography_menu_{}; ///< Submenu for steganography operations + QToolBar* crypt_tool_bar_{}; ///< Toolbar holding crypt actions + QToolBar* file_tool_bar_{}; ///< Toolbar holding file actions + QToolBar* edit_tool_bar_{}; ///< Toolbar holding edit actions + QToolBar* + special_edit_tool_bar_{}; ///< Toolbar holding special edit actions + QToolBar* key_tool_bar_{}; ///< Toolbar holding key operations + QToolBar* email_tool_bar_{}; ///< Toolbar holding key operations + QToolButton* + import_button_{}; ///< Tool button for import dropdown menu in toolbar + QDockWidget* key_list_dock_{}; ///< Encrypt Dock + QDockWidget* attachment_dock_{}; ///< Attachment Dock + QDockWidget* info_board_dock_{}; + + QAction* new_tab_act_{}; ///< Action to create new tab + QAction* switch_tab_up_act_{}; ///< Action to switch tab up + QAction* switch_tab_down_act_{}; ///< Action to switch tab down + QAction* open_act_{}; ///< Action to open file + QAction* browser_act_{}; ///< Action to open file browser + QAction* save_act_{}; ///< Action to save file + QAction* save_as_act_{}; ///< Action to save file as + QAction* print_act_{}; ///< Action to print + QAction* close_tab_act_{}; ///< Action to print + QAction* quit_act_{}; ///< Action to quit application + QAction* encrypt_act_{}; ///< Action to encrypt text + QAction* encrypt_sign_act_{}; ///< Action to encrypt and sign text + QAction* decrypt_verify_act_{}; ///< Action to encrypt and sign text + QAction* decrypt_act_{}; ///< Action to decrypt text + QAction* sign_act_{}; ///< Action to sign text + QAction* verify_act_{}; ///< Action to verify text + QAction* import_key_from_edit_act_{}; ///< Action to import key from edit + QAction* clean_double_line_breaks_act_{}; ///< Action to remove double line + ///< breaks + + QAction* + append_selected_keys_act_{}; ///< Action to append selected keys to edit + QAction* copy_mail_address_to_clipboard_act_{}; ///< Action to copy mail to + ///< clipboard + QAction* open_key_management_act_{}; ///< Action to open key management + QAction* copy_act_{}; ///< Action to copy text + QAction* quote_act_{}; ///< Action to quote text + QAction* cut_act_{}; ///< Action to cut text + QAction* paste_act_{}; ///< Action to paste text + QAction* select_all_act_{}; ///< Action to select whole text + QAction* find_act_{}; ///< Action to find text + QAction* undo_act_{}; ///< Action to undo last action + QAction* redo_act_{}; ///< Action to redo last action + QAction* zoom_in_act_{}; ///< Action to zoom in + QAction* zoom_out_act_{}; ///< Action to zoom out + QAction* about_act_{}; ///< Action to open about dialog + QAction* check_update_act_{}; ///< Action to open about dialog + QAction* translate_act_{}; ///< Action to open about dialog + QAction* open_settings_act_{}; ///< Action to open settings dialog + QAction* show_key_details_act_{}; ///< Action to open key-details dialog + QAction* start_wizard_act_{}; ///< Action to open the wizard + QAction* cut_pgp_header_act_{}; ///< Action for cutting the PGP header + QAction* add_pgp_header_act_{}; ///< Action for adding the PGP header + +#ifdef SMTP_SUPPORT + QAction* send_mail_act_{}; ///< Action for sending a email + QAction* receive_mail_act_{}; ///< Action for receive emails +#endif + + QAction* import_key_from_file_act_{}; ///< + QAction* import_key_from_clipboard_act_{}; ///< + QAction* import_key_from_key_server_act_{}; ///< + + QLabel* status_bar_icon_{}; ///< + + KeyList* m_key_list_{}; ///< + InfoBoardWidget* info_board_{}; ///< + + bool attachment_dock_created_{}; ///< + bool restart_needed_{}; ///< + bool prohibit_update_checking_ = false; ///< +}; + +} // namespace GpgFrontend::UI + +#endif // __GPGWIN_H__ diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp index 286cef3a..d1288a1b 100644 --- a/src/ui/main_window/MainWindowFileSlotFunction.cpp +++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,37 +8,40 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "MainWindow.h" -#include "gpg/function/GpgFileOpera.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/function/ArchiveFileOperator.h" +#include "core/function/GlobalSettingStation.h" +#include "core/function/gpg/GpgFileOpera.h" +#include "core/function/gpg/GpgKeyGetter.h" #include "ui/UserInterfaceUtils.h" -#include "ui/settings/GlobalSettingStation.h" #include "ui/widgets/SignersPicker.h" namespace GpgFrontend::UI { -bool file_pre_check(QWidget* parent, const QString& path) { +bool path_pre_check(QWidget* parent, const QString& path) { QFileInfo file_info(path); QFileInfo path_info(file_info.absolutePath()); - if (!file_info.isFile()) { + if (!path_info.exists()) { QMessageBox::critical(parent, _("Error"), - _("Select a file before doing it.")); + QString(_("The path %1 does not exist.")).arg(path)); return false; } if (!file_info.isReadable()) { @@ -52,14 +57,108 @@ bool file_pre_check(QWidget* parent, const QString& path) { return true; } -void MainWindow::slotFileEncrypt() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); +/** + * @brief convert directory into tarball + * + * @param parent parent widget + * @param path the directory to be converted + * @return + */ +bool process_tarball_into_directory(QWidget* parent, + std::filesystem::path& path) { + + LOG(INFO) << "Converting directory into tarball" << path; + auto selected_dir_path = std::filesystem::path(path); + + if (selected_dir_path.extension() != ".tar") { + QMessageBox::critical(parent, _("Error"), _("The file is not a tarball.")); + return false; + } + + try { + auto base_path = selected_dir_path.parent_path(); + + auto target_path = selected_dir_path; + target_path.replace_extension(".tar"); + + LOG(INFO) << "base path" << base_path.u8string() << "target archive path" + << target_path.u8string(); + + bool if_error = false; + process_operation(parent, _("Extracting Tarball"), [&]() { + try { + GpgFrontend::ArchiveFileOperator::ExtractArchive(target_path, + base_path); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (if_error || !exists(target_path)) { + throw std::runtime_error("Decompress Failed"); + } + path = target_path.u8string().c_str(); + } catch (...) { + LOG(ERROR) << "decompress error"; + return false; + } + return true; +} + +/** + * @brief convert tarball into directory + * + * @param parent parent widget + * @param path the tarball to be converted + */ +bool process_directory_into_tarball(QWidget* parent, QString& path) { + +#ifdef WINDOWS + std::filesystem::path selected_dir_path = path.toStdU16String(); +#else + std::filesystem::path selected_dir_path = path.toStdString(); +#endif + + try { + auto base_path = selected_dir_path.parent_path(); + auto target_path = selected_dir_path; + selected_dir_path.replace_extension(""); + + LOG(INFO) << "base path" << base_path << "target archive path" + << target_path << "selected_dir_path" << selected_dir_path; + + bool if_error = false; + process_operation(parent, _("Making Tarball"), [&]() { + try { + GpgFrontend::ArchiveFileOperator::CreateArchive(base_path, target_path, + 0, {selected_dir_path}); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (if_error || !exists(target_path)) { + throw std::runtime_error("Compress Failed"); + } + path = target_path.u8string().c_str(); + } catch (...) { + LOG(ERROR) << "compress error"; + return false; + } + return true; +} + +void MainWindow::SlotFileEncrypt() { + auto fileTreeView = edit_->SlotCurPageFileTreeView(); + auto path = fileTreeView->GetSelected(); - if (!file_pre_check(this, path)) return; + if (!path_pre_check(this, path)) { + LOG(ERROR) << "path pre check failed"; + return; + } // check selected keys - auto key_ids = mKeyList->getChecked(); + auto key_ids = m_key_list_->GetChecked(); GpgEncrResult result = nullptr; GpgError error; bool if_error = false; @@ -73,9 +172,16 @@ void MainWindow::slotFileEncrypt() { LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export"); } + // get file info + QFileInfo file_info(path); + + if (file_info.isDir()) { + path = path + (file_info.isDir() ? ".tar" : ""); + } + auto _channel = GPGFRONTEND_DEFAULT_CHANNEL; auto _extension = ".asc"; - if (non_ascii_when_export) { + if (non_ascii_when_export || file_info.isDir()) { _channel = GPGFRONTEND_NON_ASCII_CHANNEL; _extension = ".gpg"; } @@ -83,7 +189,11 @@ void MainWindow::slotFileEncrypt() { auto out_path = path + _extension; if (QFile::exists(out_path)) { - boost::filesystem::path _out_path = out_path.toStdString(); +#ifdef WINDOWS + std::filesystem::path _out_path = out_path.toStdU16String(); +#else + std::filesystem::path _out_path = out_path.toStdString(); +#endif auto out_file_name = boost::format(_("The target file %1% already exists, " "do you need to overwrite it?")) % _out_path.filename(); @@ -94,6 +204,15 @@ void MainWindow::slotFileEncrypt() { if (ret == QMessageBox::Cancel) return; } + if (file_info.isDir()) { + // stop if the process making tarball failed + if (!process_directory_into_tarball(this, path)) { + QMessageBox::critical(this, _("Error"), + _("Unable to convert the folder into tarball.")); + return; + } + } + if (key_ids->empty()) { // Symmetric Encrypt auto ret = QMessageBox::information( @@ -117,14 +236,14 @@ void MainWindow::slotFileEncrypt() { // check key abilities for (const auto& key : *p_keys) { - bool key_can_encrypt = key.CanEncrActual(); + bool key_can_encrypt = key.IsHasActualEncryptionCapability(); if (!key_can_encrypt) { QMessageBox::critical( nullptr, _("Invalid KeyPair"), QString(_("The selected keypair cannot be used for encryption.")) + "<br/><br/>" + _("For example the Following Key:") + " <br/>" + - QString::fromStdString(key.uids()->front().uid())); + QString::fromStdString(key.GetUIDs()->front().GetUID())); return; } } @@ -140,10 +259,19 @@ void MainWindow::slotFileEncrypt() { }); } + // remove xxx.tar and only left xxx.tar.gpg + if (file_info.isDir()) { + auto selected_dir_path = std::filesystem::path(path.toStdString()); + auto target_path = selected_dir_path.replace_extension(".tar"); + if (exists(target_path)) { + std::filesystem::remove(target_path); + } + } + if (!if_error) { - auto resultAnalyse = EncryptResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); + auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result)); + resultAnalyse.Analyse(); + process_result_analyse(edit_, info_board_, resultAnalyse); fileTreeView->update(); } else { QMessageBox::critical(this, _("Error"), @@ -152,13 +280,17 @@ void MainWindow::slotFileEncrypt() { } } -void MainWindow::slotFileDecrypt() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); +void MainWindow::SlotFileDecrypt() { + auto fileTreeView = edit_->SlotCurPageFileTreeView(); + auto path = fileTreeView->GetSelected(); - if (!file_pre_check(this, path)) return; + if (!path_pre_check(this, path)) return; - boost::filesystem::path out_path = path.toStdString(); +#ifdef WINDOWS + std::filesystem::path out_path = path.toStdU16String(); +#else + std::filesystem::path out_path = path.toStdString(); +#endif if (out_path.extension() == ".asc" || out_path.extension() == ".gpg") { out_path = out_path.parent_path() / out_path.stem(); @@ -180,7 +312,7 @@ void MainWindow::slotFileDecrypt() { bool if_error = false; process_operation(this, _("Decrypting"), [&]() { try { - error = GpgFileOpera::DecryptFile(path.toStdString(), out_path.string(), + error = GpgFileOpera::DecryptFile(path.toStdString(), out_path.u8string(), result); } catch (const std::runtime_error& e) { if_error = true; @@ -188,9 +320,9 @@ void MainWindow::slotFileDecrypt() { }); if (!if_error) { - auto resultAnalyse = DecryptResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); + auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result)); + resultAnalyse.Analyse(); + process_result_analyse(edit_, info_board_, resultAnalyse); fileTreeView->update(); } else { @@ -198,32 +330,52 @@ void MainWindow::slotFileDecrypt() { _("An error occurred during operation.")); return; } + + // extract the tarball + if (out_path.extension() == ".tar" && exists(out_path)) { + bool ret = QMessageBox::information( + this, _("Decrypting"), + _("Do you want to extract and delete the decrypted tarball?"), + QMessageBox::Ok | QMessageBox::Cancel); + if (ret) { + if (process_tarball_into_directory(this, out_path)) { + QMessageBox::information(this, _("Decrypting"), + _("Extracting tarball succeeded.")); + // remove tarball + std::filesystem::remove(out_path); + } else { + QMessageBox::critical(this, _("Decrypting"), + _("Extracting tarball failed.")); + } + } + } + } -void MainWindow::slotFileSign() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); +void MainWindow::SlotFileSign() { + auto fileTreeView = edit_->SlotCurPageFileTreeView(); + auto path = fileTreeView->GetSelected(); - if (!file_pre_check(this, path)) return; + if (!path_pre_check(this, path)) return; - auto key_ids = mKeyList->getChecked(); + auto key_ids = m_key_list_->GetChecked(); auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); if (keys->empty()) { QMessageBox::critical( - this, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check the key in the key toolbox on the right.")); return; } for (const auto& key : *keys) { - if (!key.CanSignActual()) { + if (!key.IsHasActualSigningCapability()) { QMessageBox::information( this, _("Invalid Operation"), QString(_("The selected key contains a key that does not actually " "have a sign usage.")) + "<br/><br/>" + _("for example the Following Key:") + " <br/>" + - QString::fromStdString(key.uids()->front().uid())); + QString::fromStdString(key.GetUIDs()->front().GetUID())); return; } } @@ -244,7 +396,12 @@ void MainWindow::slotFileSign() { _extension = ".sig"; } - boost::filesystem::path in_path = path.toStdString(); +#ifdef WINDOWS + std::filesystem::path in_path = path.toStdU16String(); +#else + std::filesystem::path in_path = path.toStdString(); +#endif + auto sig_file_path = in_path; sig_file_path += _extension; if (exists(sig_file_path)) { @@ -252,7 +409,7 @@ void MainWindow::slotFileSign() { this, _("Warning"), QString(_("The signature file \"%1\" exists, " "do you need to overwrite it?")) - .arg(sig_file_path.filename().string().c_str()), + .arg(sig_file_path.filename().u8string().c_str()), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Cancel) return; @@ -264,17 +421,17 @@ void MainWindow::slotFileSign() { process_operation(this, _("Signing"), [&]() { try { - error = GpgFileOpera::SignFile(std::move(keys), in_path.string(), - sig_file_path.string(), result, _channel); + error = GpgFileOpera::SignFile(std::move(keys), in_path.u8string(), + sig_file_path.u8string(), result, _channel); } catch (const std::runtime_error& e) { if_error = true; } }); if (!if_error) { - auto resultAnalyse = SignResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); + auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result)); + resultAnalyse.Analyse(); + process_result_analyse(edit_, info_board_, resultAnalyse); fileTreeView->update(); @@ -287,12 +444,17 @@ void MainWindow::slotFileSign() { fileTreeView->update(); } -void MainWindow::slotFileVerify() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); +void MainWindow::SlotFileVerify() { + auto fileTreeView = edit_->SlotCurPageFileTreeView(); + auto path = fileTreeView->GetSelected(); + +#ifdef WINDOWS + std::filesystem::path in_path = path.toStdU16String(); +#else + std::filesystem::path in_path = path.toStdString(); +#endif - boost::filesystem::path in_path = path.toStdString(); - boost::filesystem::path sign_file_path = in_path, data_file_path; + std::filesystem::path sign_file_path = in_path, data_file_path; // Detect ascii mode auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); @@ -320,7 +482,7 @@ void MainWindow::slotFileVerify() { bool ok; QString text = QInputDialog::getText(this, _("Origin file to verify"), _("Filepath"), QLineEdit::Normal, - data_file_path.string().c_str(), &ok); + data_file_path.u8string().c_str(), &ok); if (ok && !text.isEmpty()) { data_file_path = text.toStdString(); } else { @@ -346,22 +508,22 @@ void MainWindow::slotFileVerify() { process_operation(this, _("Verifying"), [&]() { try { error = GpgFileOpera::VerifyFile( - data_file_path.string(), sign_file_path.string(), result, _channel); + data_file_path.u8string(), sign_file_path.u8string(), result, _channel); } catch (const std::runtime_error& e) { if_error = true; } }); if (!if_error) { - auto result_analyse = VerifyResultAnalyse(error, result); - result_analyse.analyse(); - process_result_analyse(edit, infoBoard, result_analyse); + auto result_analyse = GpgVerifyResultAnalyse(error, result); + result_analyse.Analyse(); + process_result_analyse(edit_, info_board_, result_analyse); - if (result_analyse.getStatus() == -2) + if (result_analyse.GetStatus() == -2) import_unknown_key_from_keyserver(this, result_analyse); - if (result_analyse.getStatus() >= 0) - show_verify_details(this, infoBoard, error, result); + if (result_analyse.GetStatus() >= 0) + show_verify_details(this, info_board_, error, result); fileTreeView->update(); } else { @@ -371,38 +533,38 @@ void MainWindow::slotFileVerify() { } } -void MainWindow::slotFileEncryptSign() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); +void MainWindow::SlotFileEncryptSign() { + auto fileTreeView = edit_->SlotCurPageFileTreeView(); + auto path = fileTreeView->GetSelected(); - if (!file_pre_check(this, path)) return; + if (!path_pre_check(this, path)) return; // check selected keys - auto key_ids = mKeyList->getChecked(); + auto key_ids = m_key_list_->GetChecked(); auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); if (p_keys->empty()) { QMessageBox::critical( - this, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check the key in the key toolbox on the right.")); return; } // check key abilities for (const auto& key : *p_keys) { - bool key_can_encrypt = key.CanEncrActual(); + bool key_can_encrypt = key.IsHasActualEncryptionCapability(); if (!key_can_encrypt) { QMessageBox::critical( nullptr, _("Invalid KeyPair"), QString(_("The selected keypair cannot be used for encryption.")) + "<br/><br/>" + _("For example the Following Key:") + " <br/>" + - QString::fromStdString(key.uids()->front().uid())); + QString::fromStdString(key.GetUIDs()->front().GetUID())); return; } } - // Detect ascii mode + // detect ascii mode auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); bool non_ascii_when_export = true; try { @@ -411,16 +573,23 @@ void MainWindow::slotFileEncryptSign() { LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export"); } + // get file info + QFileInfo file_info(path); + + if (file_info.isDir()) { + path = path + (file_info.isDir() ? ".tar" : ""); + } + auto _channel = GPGFRONTEND_DEFAULT_CHANNEL; auto _extension = ".asc"; - if (non_ascii_when_export) { + if (non_ascii_when_export || file_info.isDir()) { _channel = GPGFRONTEND_NON_ASCII_CHANNEL; _extension = ".gpg"; } - boost::filesystem::path out_path = path.toStdString() + _extension; + auto out_path = path + _extension; - if (exists(out_path)) { + if (QFile::exists(out_path)) { auto ret = QMessageBox::warning( this, _("Warning"), _("The target file already exists, do you need to overwrite it?"), @@ -431,12 +600,22 @@ void MainWindow::slotFileEncryptSign() { auto signersPicker = new SignersPicker(this); QEventLoop loop; - connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit())); + connect(signersPicker, &SignersPicker::finished, &loop, &QEventLoop::quit); loop.exec(); - auto signer_key_ids = signersPicker->getCheckedSigners(); + auto signer_key_ids = signersPicker->GetCheckedSigners(); auto p_signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids); + // convert directory into tarball + if (file_info.isDir()) { + // stop if the process making tarball failed + if (!process_directory_into_tarball(this, path)) { + QMessageBox::critical(this, _("Error"), + _("Unable to convert the folder into tarball.")); + return; + } + } + GpgEncrResult encr_result = nullptr; GpgSignResult sign_result = nullptr; @@ -447,18 +626,19 @@ void MainWindow::slotFileEncryptSign() { try { error = GpgFileOpera::EncryptSignFile( std::move(p_keys), std::move(p_signer_keys), path.toStdString(), - out_path.string(), encr_result, sign_result, _channel); + out_path.toStdString(), encr_result, sign_result, _channel); } catch (const std::runtime_error& e) { if_error = true; } }); if (!if_error) { - auto encrypt_result = EncryptResultAnalyse(error, std::move(encr_result)); - auto sign_res = SignResultAnalyse(error, std::move(sign_result)); - encrypt_result.analyse(); - sign_res.analyse(); - process_result_analyse(edit, infoBoard, encrypt_result, sign_res); + auto encrypt_result = + GpgEncryptResultAnalyse(error, std::move(encr_result)); + auto sign_res = GpgSignResultAnalyse(error, std::move(sign_result)); + encrypt_result.Analyse(); + sign_res.Analyse(); + process_result_analyse(edit_, info_board_, encrypt_result, sign_res); fileTreeView->update(); @@ -467,16 +647,31 @@ void MainWindow::slotFileEncryptSign() { _("An error occurred during operation.")); return; } + + // remove xxx.tar and only left xxx.tar.gpg + if (file_info.isDir()) { + auto selected_dir_path = std::filesystem::path(path.toStdString()); + auto target_path = selected_dir_path.replace_extension(".tar"); + if (exists(target_path)) { + std::filesystem::remove(target_path); + } + } + } -void MainWindow::slotFileDecryptVerify() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); +void MainWindow::SlotFileDecryptVerify() { + auto fileTreeView = edit_->SlotCurPageFileTreeView(); + auto path = fileTreeView->GetSelected(); + + if (!path_pre_check(this, path)) return; - if (!file_pre_check(this, path)) return; +#ifdef WINDOWS + std::filesystem::path in_path = path.toStdU16String(); +#else + std::filesystem::path in_path = path.toStdString(); +#endif - boost::filesystem::path in_path(path.toStdString()); - boost::filesystem::path out_path = in_path; + std::filesystem::path out_path = in_path; if (in_path.extension() == ".asc" || in_path.extension() == ".gpg") { out_path = in_path.parent_path() / out_path.stem(); } else { @@ -484,12 +679,12 @@ void MainWindow::slotFileDecryptVerify() { } LOG(INFO) << "out path" << out_path; - if (QFile::exists(out_path.string().c_str())) { + if (QFile::exists(out_path.u8string().c_str())) { auto ret = QMessageBox::warning(this, _("Warning"), QString(_("The output file %1 already exists, do " "you need to overwrite it?")) - .arg(out_path.filename().string().c_str()), + .arg(out_path.filename().u8string().c_str()), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Cancel) return; @@ -502,24 +697,24 @@ void MainWindow::slotFileDecryptVerify() { process_operation(this, _("Decrypting and Verifying"), [&]() { try { error = GpgFileOpera::DecryptVerifyFile( - path.toStdString(), out_path.string(), d_result, v_result); + path.toStdString(), out_path.u8string(), d_result, v_result); } catch (const std::runtime_error& e) { if_error = true; } }); if (!if_error) { - auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result)); - auto verify_res = VerifyResultAnalyse(error, v_result); - decrypt_res.analyse(); - verify_res.analyse(); - process_result_analyse(edit, infoBoard, decrypt_res, verify_res); + auto decrypt_res = GpgDecryptResultAnalyse(error, std::move(d_result)); + auto verify_res = GpgVerifyResultAnalyse(error, v_result); + decrypt_res.Analyse(); + verify_res.Analyse(); + process_result_analyse(edit_, info_board_, decrypt_res, verify_res); - if (verify_res.getStatus() == -2) + if (verify_res.GetStatus() == -2) import_unknown_key_from_keyserver(this, verify_res); - if (verify_res.getStatus() >= 0) - show_verify_details(this, infoBoard, error, v_result); + if (verify_res.GetStatus() >= 0) + show_verify_details(this, info_board_, error, v_result); fileTreeView->update(); } else { @@ -527,6 +722,26 @@ void MainWindow::slotFileDecryptVerify() { _("An error occurred during operation.")); return; } + + // extract the tarball + if (out_path.extension() == ".tar" && exists(out_path)) { + bool ret = QMessageBox::information( + this, _("Decrypting"), + _("Do you want to extract and delete the decrypted tarball?"), + QMessageBox::Ok | QMessageBox::Cancel); + if (ret) { + if (process_tarball_into_directory(this, out_path)) { + QMessageBox::information(this, _("Decrypting"), + _("Extracting tarball succeeded.")); + // remove tarball + std::filesystem::remove(out_path); + } else { + QMessageBox::critical(this, _("Decrypting"), + _("Extracting tarball failed.")); + } + } + } + } } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowServerSlotFunction.cpp b/src/ui/main_window/MainWindowServerSlotFunction.cpp deleted file mode 100644 index 17491db7..00000000 --- a/src/ui/main_window/MainWindowServerSlotFunction.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "MainWindow.h" - -#ifdef SERVER_SUPPORT -#include "rapidjson/document.h" -#include "rapidjson/prettywriter.h" -#include "server/ComUtils.h" -#endif -#include "ui/ShowCopyDialog.h" - -namespace GpgFrontend::UI { - -#ifdef SERVER_SUPPORT - -/** - * get full size crypt text from server using short crypto text - * @param shortenCryptoText short crypto text([GpgFrontend_ShortCrypto]://) - * @return - */ -QString MainWindow::getCryptText(const QString& shortenCryptoText) { - QString ownKeyId = settings.value("general/ownKeyId").toString(); - - GpgKey key = mCtx->getKeyRefById(ownKeyId); - if (!key.good) { - QMessageBox::critical(this, _("Invalid Own Key"), - _("Own Key can not be use to do any operation. " - "Please go to the setting interface to select an " - "OwnKey and get a ServiceToken.")); - return {}; - } - - auto utils = new ComUtils(this); - - QString serviceToken = settings.value("general/serviceToken").toString(); - if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) { - QMessageBox::critical( - this, _("Error"), - _("Please obtain a Service Token from the server in the settings.")); - return {}; - } - - QUrl reqUrl(utils->getUrl(ComUtils::GetFullCryptText)); - QNetworkRequest request(reqUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - // Sign Shorten Text - auto outSignTextBase64 = - ComUtils::getSignStringBase64(mCtx, shortenCryptoText, key); - - rapidjson::Document doc; - doc.SetObject(); - - rapidjson::Value s, t; - - // Signature - s.SetString(outSignTextBase64.constData(), outSignTextBase64.count()); - // Service Token - const auto t_byte_array = serviceToken.toUtf8(); - t.SetString(t_byte_array.constData(), t_byte_array.count()); - - rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); - - doc.AddMember("signature", s, allocator); - doc.AddMember("serviceToken", t, allocator); - - rapidjson::StringBuffer sb; - rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); - doc.Accept(writer); - - QByteArray postData(sb.GetString()); - qDebug() << "postData" << QString::fromUtf8(postData); - - QNetworkReply* reply = utils->getNetworkManager().post(request, postData); - - auto dialog = new WaitingDialog(_("Getting Cpt From Server"), this); - dialog->show(); - - while (reply->isRunning()) QApplication::processEvents(); - - dialog->close(); - - QByteArray replyData = reply->readAll().constData(); - if (utils->checkServerReply(replyData)) { - /** - * { - * "cryptoText" : ... - * "sha": ... - * "serviceToken": ... - * "date": ... - * } - */ - - if (!utils->checkDataValueStr("cryptoText") || - !utils->checkDataValueStr("sha") || - !utils->checkDataValueStr("serviceToken")) { - QMessageBox::critical(this, _("Error"), - _("The communication content with the server does " - "not meet the requirements")); - return {}; - } - - auto cryptoText = utils->getDataValueStr("cryptoText"); - auto sha = utils->getDataValueStr("sha"); - auto serviceTokenFromServer = utils->getDataValueStr("serviceToken"); - - QCryptographicHash sha_generator(QCryptographicHash::Sha256); - sha_generator.addData(cryptoText.toUtf8()); - - if (sha_generator.result().toHex() == sha && - serviceToken == serviceTokenFromServer) { - return cryptoText; - } else - QMessageBox::critical(this, _("Error"), _("Invalid short ciphertext")); - - return {}; - } - - return {}; -} - -#endif - -#ifdef SERVER_SUPPORT - -void MainWindow::shortenCryptText() { - // gather information - QString serviceToken = settings.value("general/serviceToken").toString(); - QString ownKeyId = settings.value("general/ownKeyId").toString(); - QByteArray cryptoText = edit->curTextPage()->toPlainText().toUtf8(); - - auto utils = new ComUtils(this); - - if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) { - QMessageBox::critical( - this, _("Invalid Service Token"), - _("Please go to the setting interface to get a ServiceToken.")); - return; - } - - QUrl reqUrl(utils->getUrl(ComUtils::ShortenCryptText)); - QNetworkRequest request(reqUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - GpgKey key = mCtx->getKeyRefById(ownKeyId); - if (!key.good) { - QMessageBox::critical(this, _("Invalid Own Key"), - _("Own Key can not be use to do any operation.")); - return; - } - - QCryptographicHash ch(QCryptographicHash::Md5); - ch.addData(cryptoText); - QString md5 = ch.result().toHex(); - - qDebug() << "md5" << md5; - - QByteArray signText = QString("[%1][%2]").arg(serviceToken, md5).toUtf8(); - - QCryptographicHash sha(QCryptographicHash::Sha256); - sha.addData(signText); - QString shaText = sha.result().toHex(); - - qDebug() << "shaText" << shaText; - - QByteArray outSignTextBase64 = - ComUtils::getSignStringBase64(mCtx, signText, key); - - rapidjson::Value c, s, m, t; - - rapidjson::Document doc; - doc.SetObject(); - - c.SetString(cryptoText.constData(), cryptoText.count()); - auto m_byte_array = shaText.toUtf8(); - m.SetString(m_byte_array.constData(), m_byte_array.count()); - s.SetString(outSignTextBase64.constData(), outSignTextBase64.count()); - auto t_byte_array = serviceToken.toUtf8(); - t.SetString(t_byte_array.constData(), t_byte_array.count()); - - rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); - - doc.AddMember("cryptoText", c, allocator); - doc.AddMember("sha", m, allocator); - doc.AddMember("sign", s, allocator); - doc.AddMember("serviceToken", t, allocator); - - rapidjson::StringBuffer sb; - rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); - doc.Accept(writer); - - QByteArray postData(sb.GetString()); - qDebug() << "postData" << QString::fromUtf8(postData); - - QNetworkReply* reply = networkAccessManager->post(request, postData); - - auto* dialog = new WaitingDialog(_("Getting Scpt From Server"), this); - dialog->show(); - while (reply->isRunning()) QApplication::processEvents(); - dialog->close(); - - if (utils->checkServerReply(reply->readAll().constData())) { - /** - * { - * "shortenText" : ... - * "md5": ... - * } - */ - - if (!utils->checkDataValueStr("shortenText") || - !utils->checkDataValueStr("md5")) { - QMessageBox::critical(this, _("Error"), - _("The communication content with the server does " - "not meet the requirements")); - return; - } - - QString shortenText = utils->getDataValueStr("shortenText"); - - QCryptographicHash md5_generator(QCryptographicHash::Md5); - md5_generator.addData(shortenText.toUtf8()); - if (md5_generator.result().toHex() == utils->getDataValueStr("md5")) { - auto* dialog = - new ShowCopyDialog(shortenText, - _("Notice: Use Decrypt & Verify operation to " - "decrypt this short crypto text."), - this); - dialog->show(); - } else { - QMessageBox::critical( - this, _("Error"), - _("There is a problem with the communication with the server")); - return; - } - } -} - -#endif - -} // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 57fb5bae..f25d696a 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -32,25 +36,28 @@ #endif #ifdef SMTP_SUPPORT -#include "ui/smtp/SendMailDialog.h" +#include "ui/mail/SendMailDialog.h" #endif -#include "gpg/function/BasicOperator.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExporter.h" +#include "core/function/GlobalSettingStation.h" +#include "core/function/gpg/GpgBasicOperator.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyImportExporter.h" #include "ui/UserInterfaceUtils.h" #include "ui/help/AboutDialog.h" -#include "ui/settings/GlobalSettingStation.h" #include "ui/widgets/SignersPicker.h" namespace GpgFrontend::UI { /** * Encrypt Entry(Text & File) */ -void MainWindow::slotEncrypt() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; +void MainWindow::slot_encrypt() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { + if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileEncrypt(); + return; + } - auto key_ids = mKeyList->getChecked(); + auto key_ids = m_key_list_->GetChecked(); GpgEncrResult result = nullptr; GpgError error; @@ -61,7 +68,7 @@ void MainWindow::slotEncrypt() { // Symmetric Encrypt auto ret = QMessageBox::information( this, _("Symmetric Encryption"), - _("No Key Selected. Do you want to encrypt with a " + _("No Key Checked. Do you want to encrypt with a " "symmetric cipher using a passphrase?"), QMessageBox::Ok | QMessageBox::Cancel); @@ -69,8 +76,9 @@ void MainWindow::slotEncrypt() { process_operation(this, _("Symmetrically Encrypting"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); - error = GpgFrontend::BasicOperator::GetInstance().EncryptSymmetric( + auto buffer = + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); + error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric( buffer, tmp, result); } catch (const std::runtime_error& e) { if_error = true; @@ -80,22 +88,23 @@ void MainWindow::slotEncrypt() { auto key_getter = GpgFrontend::GpgKeyGetter::GetInstance(); auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); for (const auto& key : *keys) { - if (!key.CanEncrActual()) { + if (!key.IsHasActualEncryptionCapability()) { QMessageBox::information( - nullptr, _("Invalid Operation"), + this, _("Invalid Operation"), QString(_( "The selected key contains a key that does not actually have a " "encrypt usage.")) + "<br/><br/>" + _("For example the Following Key:") + " <br/>" + - QString::fromStdString(key.uids()->front().uid())); + QString::fromStdString(key.GetUIDs()->front().GetUID())); return; } } process_operation(this, _("Encrypting"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); - error = GpgFrontend::BasicOperator::GetInstance().Encrypt( + auto buffer = + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); + error = GpgFrontend::GpgBasicOperator::GetInstance().Encrypt( std::move(keys), buffer, tmp, result); } catch (const std::runtime_error& e) { if_error = true; @@ -105,16 +114,17 @@ void MainWindow::slotEncrypt() { if (!if_error) { LOG(INFO) << "result" << result.get(); - auto resultAnalyse = EncryptResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); + auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result)); + resultAnalyse.Analyse(); + process_result_analyse(edit_, info_board_, resultAnalyse); if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromStdString(*tmp)); - infoBoard->resetOptionActionsMenu(); + edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp)); + info_board_->ResetOptionActionsMenu(); #ifdef SMTP_SUPPORT if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - send_an_email(this, infoBoard, edit->curTextPage()->toPlainText()); + send_an_email(this, info_board_, + edit_->CurTextPage()->GetTextPage()->toPlainText()); #endif } else { QMessageBox::critical(this, _("Error"), @@ -123,28 +133,31 @@ void MainWindow::slotEncrypt() { } } -void MainWindow::slotSign() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; +void MainWindow::slot_sign() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { + if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileSign(); + return; + } - auto key_ids = mKeyList->getPrivateChecked(); + auto key_ids = m_key_list_->GetPrivateChecked(); if (key_ids->empty()) { QMessageBox::critical( - this, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check the key in the key toolbox on the right.")); return; } auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); for (const auto& key : *keys) { - if (!key.CanSignActual()) { + if (!key.IsHasActualSigningCapability()) { QMessageBox::information( this, _("Invalid Operation"), QString( _("The selected key contains a key that does not actually have a " "signature usage.")) + "<br/><br/>" + _("For example the Following Key:") + "<br/>" + - key.uids()->front().uid().c_str()); + key.GetUIDs()->front().GetUID().c_str()); return; } } @@ -157,8 +170,12 @@ void MainWindow::slotSign() { process_operation(this, _("Signing"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); - error = GpgFrontend::BasicOperator::GetInstance().Sign( + auto buffer = edit_->CurTextPage() + ->GetTextPage() + ->toPlainText() + .toUtf8() + .toStdString(); + error = GpgFrontend::GpgBasicOperator::GetInstance().Sign( std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result); } catch (const std::runtime_error& e) { if_error = true; @@ -166,12 +183,12 @@ void MainWindow::slotSign() { }); if (!if_error) { - auto resultAnalyse = SignResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); + auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result)); + resultAnalyse.Analyse(); + process_result_analyse(edit_, info_board_, resultAnalyse); if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromStdString(*tmp)); + edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp)); } else { QMessageBox::critical(this, _("Error"), _("An error occurred during operation.")); @@ -179,11 +196,14 @@ void MainWindow::slotSign() { } } -void MainWindow::slotDecrypt() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; +void MainWindow::slot_decrypt() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { + if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileDecrypt(); + return; + } auto decrypted = std::make_unique<ByteArray>(); - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + QByteArray text = edit_->CurTextPage()->GetTextPage()->toPlainText().toUtf8(); if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { QMessageBox::critical( @@ -198,7 +218,7 @@ void MainWindow::slotDecrypt() { process_operation(this, _("Decrypting"), [&]() { try { auto buffer = text.toStdString(); - error = GpgFrontend::BasicOperator::GetInstance().Decrypt( + error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt( buffer, decrypted, result); } catch (const std::runtime_error& e) { if_error = true; @@ -206,12 +226,12 @@ void MainWindow::slotDecrypt() { }); if (!if_error) { - auto resultAnalyse = DecryptResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); + auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result)); + resultAnalyse.Analyse(); + process_result_analyse(edit_, info_board_, resultAnalyse); if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromStdString(*decrypted)); + edit_->SlotFillTextEditWithText(QString::fromStdString(*decrypted)); } else { QMessageBox::critical(this, _("Error"), _("An error occurred during operation.")); @@ -219,22 +239,25 @@ void MainWindow::slotDecrypt() { } } -void MainWindow::slotFind() { - if (edit->tabCount() == 0 || edit->curTextPage() == nullptr) { +void MainWindow::slot_find() { + if (edit_->TabCount() == 0 || edit_->CurTextPage() == nullptr) { return; } // At first close verifynotification, if existing - edit->slotCurPageTextEdit()->closeNoteByClass("findwidget"); + edit_->SlotCurPageTextEdit()->CloseNoteByClass("findwidget"); - auto* fw = new FindWidget(this, edit->curTextPage()); - edit->slotCurPageTextEdit()->showNotificationWidget(fw, "findWidget"); + auto* fw = new FindWidget(this, edit_->CurTextPage()); + edit_->SlotCurPageTextEdit()->ShowNotificationWidget(fw, "findWidget"); } -void MainWindow::slotVerify() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; +void MainWindow::slot_verify() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { + if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileVerify(); + return; + } - auto text = edit->curTextPage()->toPlainText().toUtf8(); + auto text = edit_->CurTextPage()->GetTextPage()->toPlainText().toUtf8(); // TODO(Saturneric) PreventNoDataErr auto sig_buffer = std::make_unique<ByteArray>(); @@ -246,7 +269,7 @@ void MainWindow::slotVerify() { process_operation(this, _("Verifying"), [&]() { try { auto buffer = text.toStdString(); - error = GpgFrontend::BasicOperator::GetInstance().Verify( + error = GpgFrontend::GpgBasicOperator::GetInstance().Verify( buffer, sig_buffer, result); } catch (const std::runtime_error& e) { if_error = true; @@ -254,59 +277,63 @@ void MainWindow::slotVerify() { }); if (!if_error) { - auto result_analyse = VerifyResultAnalyse(error, result); - result_analyse.analyse(); - process_result_analyse(edit, infoBoard, result_analyse); + auto result_analyse = GpgVerifyResultAnalyse(error, result); + result_analyse.Analyse(); + process_result_analyse(edit_, info_board_, result_analyse); - if (result_analyse.getStatus() == -2) + if (result_analyse.GetStatus() == -2) import_unknown_key_from_keyserver(this, result_analyse); - if (result_analyse.getStatus() >= 0) - show_verify_details(this, infoBoard, error, result); + if (result_analyse.GetStatus() >= 0) + show_verify_details(this, info_board_, error, result); } } -void MainWindow::slotEncryptSign() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; +void MainWindow::slot_encrypt_sign() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { + if (edit_->SlotCurPageFileTreeView() != nullptr) + this->SlotFileEncryptSign(); + return; + } - auto key_ids = mKeyList->getChecked(); + auto key_ids = m_key_list_->GetChecked(); if (key_ids->empty()) { QMessageBox::critical( - nullptr, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check some key in the key toolbox on the right.")); return; } auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); for (const auto& key : *keys) { - bool key_can_encrypt = key.CanEncrActual(); + bool key_can_encrypt = key.IsHasActualEncryptionCapability(); if (!key_can_encrypt) { QMessageBox::critical( - nullptr, _("Invalid KeyPair"), + this, _("Invalid KeyPair"), QString(_("The selected keypair cannot be used for encryption.")) + "<br/><br/>" + _("For example the Following Key:") + " <br/>" + - QString::fromStdString(key.uids()->front().uid())); + QString::fromStdString(key.GetUIDs()->front().GetUID())); return; } } auto signersPicker = new SignersPicker(this); QEventLoop loop; - connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit())); + connect(signersPicker, &SignersPicker::finished, &loop, &QEventLoop::quit); loop.exec(); - auto signer_key_ids = signersPicker->getCheckedSigners(); + auto signer_key_ids = signersPicker->GetCheckedSigners(); auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids); for (const auto& key : *keys) { - LOG(INFO) << "Keys " << key.email(); + LOG(INFO) << "Keys " << key.GetEmail(); } for (const auto& signer : *signer_keys) { - LOG(INFO) << "Signers " << signer.email(); + LOG(INFO) << "Signers " << signer.GetEmail(); } GpgEncrResult encr_result = nullptr; @@ -317,8 +344,12 @@ void MainWindow::slotEncryptSign() { auto tmp = std::make_unique<ByteArray>(); process_operation(this, _("Encrypting and Signing"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); - error = GpgFrontend::BasicOperator::GetInstance().EncryptSign( + auto buffer = edit_->CurTextPage() + ->GetTextPage() + ->toPlainText() + .toUtf8() + .toStdString(); + error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign( std::move(keys), std::move(signer_keys), buffer, tmp, encr_result, sign_result); } catch (const std::runtime_error& e) { @@ -340,19 +371,20 @@ void MainWindow::slotEncryptSign() { } } #endif - LOG(INFO) << "ResultAnalyse Started"; - auto encrypt_res = EncryptResultAnalyse(error, std::move(encr_result)); - auto sign_res = SignResultAnalyse(error, std::move(sign_result)); - encrypt_res.analyse(); - sign_res.analyse(); - process_result_analyse(edit, infoBoard, encrypt_res, sign_res); + LOG(INFO) << "GpgResultAnalyse Started"; + auto encrypt_res = GpgEncryptResultAnalyse(error, std::move(encr_result)); + auto sign_res = GpgSignResultAnalyse(error, std::move(sign_result)); + encrypt_res.Analyse(); + sign_res.Analyse(); + process_result_analyse(edit_, info_board_, encrypt_res, sign_res); if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromStdString(*tmp)); + edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp)); - infoBoard->resetOptionActionsMenu(); + info_board_->ResetOptionActionsMenu(); #ifdef SMTP_SUPPORT if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - send_an_email(this, infoBoard, edit->curTextPage()->toPlainText(), false); + send_an_email(this, info_board_, + edit_->CurTextPage()->GetTextPage()->toPlainText(), false); #endif #ifdef ADVANCE_SUPPORT @@ -373,10 +405,14 @@ void MainWindow::slotEncryptSign() { } } -void MainWindow::slotDecryptVerify() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; +void MainWindow::slot_decrypt_verify() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { + if (edit_->SlotCurPageFileTreeView() != nullptr) + this->SlotFileDecryptVerify(); + return; + } - QString plainText = edit->curTextPage()->toPlainText(); + QString plainText = edit_->CurTextPage()->GetTextPage()->toPlainText(); #ifdef ADVANCE_SUPPORT if (plainText.trimmed().startsWith( @@ -412,27 +448,27 @@ void MainWindow::slotDecryptVerify() { process_operation(this, _("Decrypting and Verifying"), [&]() { try { auto buffer = text.toStdString(); - error = BasicOperator::GetInstance().DecryptVerify(buffer, decrypted, - d_result, v_result); + error = GpgBasicOperator::GetInstance().DecryptVerify(buffer, decrypted, + d_result, v_result); } catch (const std::runtime_error& e) { if_error = true; } }); if (!if_error) { - auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result)); - auto verify_res = VerifyResultAnalyse(error, v_result); - decrypt_res.analyse(); - verify_res.analyse(); - process_result_analyse(edit, infoBoard, decrypt_res, verify_res); + auto decrypt_res = GpgDecryptResultAnalyse(error, std::move(d_result)); + auto verify_res = GpgVerifyResultAnalyse(error, v_result); + decrypt_res.Analyse(); + verify_res.Analyse(); + process_result_analyse(edit_, info_board_, decrypt_res, verify_res); if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromStdString(*decrypted)); + edit_->SlotFillTextEditWithText(QString::fromStdString(*decrypted)); - if (verify_res.getStatus() == -2) + if (verify_res.GetStatus() == -2) import_unknown_key_from_keyserver(this, verify_res); - if (verify_res.getStatus() >= 0) - show_verify_details(this, infoBoard, error, v_result); + if (verify_res.GetStatus() >= 0) + show_verify_details(this, info_board_, error, v_result); } else { QMessageBox::critical(this, _("Error"), @@ -444,62 +480,63 @@ void MainWindow::slotDecryptVerify() { /* * Append the selected (not checked!) Key(s) To Textedit */ -void MainWindow::slotAppendSelectedKeys() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { +void MainWindow::slot_append_selected_keys() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { return; } auto exported = std::make_unique<ByteArray>(); - auto key_ids = mKeyList->getSelected(); + auto key_ids = m_key_list_->GetSelected(); GpgKeyImportExporter::GetInstance().ExportKeys(key_ids, exported); - edit->curTextPage()->append(QString::fromStdString(*exported)); + edit_->CurTextPage()->GetTextPage()->appendPlainText( + QString::fromStdString(*exported)); } -void MainWindow::slotCopyMailAddressToClipboard() { - auto key_ids = mKeyList->getSelected(); +void MainWindow::slot_copy_mail_address_to_clipboard() { + auto key_ids = m_key_list_->GetSelected(); if (key_ids->empty()) return; auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front()); - if (!key.good()) { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + if (!key.IsGood()) { + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } QClipboard* cb = QApplication::clipboard(); - cb->setText(QString::fromStdString(key.email())); + cb->setText(QString::fromStdString(key.GetEmail())); } -void MainWindow::slotShowKeyDetails() { - auto key_ids = mKeyList->getSelected(); +void MainWindow::slot_show_key_details() { + auto key_ids = m_key_list_->GetSelected(); if (key_ids->empty()) return; auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front()); - if (key.good()) { + if (key.IsGood()) { new KeyDetailsDialog(key, this); } else { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); } } -void MainWindow::refreshKeysFromKeyserver() { - auto key_ids = mKeyList->getSelected(); +void MainWindow::refresh_keys_from_key_server() { + auto key_ids = m_key_list_->GetSelected(); if (key_ids->empty()) return; auto* dialog = new KeyServerImportDialog(this); dialog->show(); - dialog->slotImport(key_ids); + dialog->SlotImport(key_ids); } -void MainWindow::uploadKeyToServer() { - auto key_ids = mKeyList->getSelected(); +void MainWindow::upload_key_to_server() { + auto key_ids = m_key_list_->GetSelected(); auto* dialog = new KeyUploadDialog(key_ids, this); dialog->show(); - dialog->slotUpload(); + dialog->SlotUpload(); } -void MainWindow::slotOpenFile(QString& path) { edit->slotOpenFile(path); } +void MainWindow::SlotOpenFile(QString& path) { edit_->SlotOpenFile(path); } -void MainWindow::slotVersionUpgrade(const SoftwareVersion& version) { +void MainWindow::slot_version_upgrade(const SoftwareVersion& version) { LOG(INFO) << _("called"); if (version.NeedUpgrade()) { statusBar()->showMessage( diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 0c0204f4..9d81b11c 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,53 +8,56 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "MainWindow.h" +#include "core/function/GlobalSettingStation.h" #include "ui/UserInterfaceUtils.h" -#include "ui/settings/GlobalSettingStation.h" +#include "ui/struct/SettingsObject.h" namespace GpgFrontend::UI { -void MainWindow::slotSetStatusBarText(const QString& text) { +void MainWindow::SlotSetStatusBarText(const QString& text) { statusBar()->showMessage(text, 20000); } -void MainWindow::slotStartWizard() { +void MainWindow::slot_start_wizard() { auto* wizard = new Wizard(this); wizard->show(); wizard->setModal(true); } -void MainWindow::slotImportKeyFromEdit() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; - CommonUtils::GetInstance()->slotImportKeys( - this, edit->curTextPage()->toPlainText().toStdString()); +void MainWindow::slot_import_key_from_edit() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) return; + CommonUtils::GetInstance()->SlotImportKeys( + this, edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString()); } -void MainWindow::slotOpenKeyManagement() { +void MainWindow::slot_open_key_management() { auto* dialog = new KeyMgmt(this); dialog->show(); dialog->raise(); } -void MainWindow::slotOpenFileTab() { edit->slotNewFileTab(); } +void MainWindow::slot_open_file_tab() { edit_->SlotNewFileTab(); } -void MainWindow::slotDisableTabActions(int number) { +void MainWindow::slot_disable_tab_actions(int number) { bool disable; if (number == -1) @@ -60,109 +65,105 @@ void MainWindow::slotDisableTabActions(int number) { else disable = false; - if (edit->curFilePage() != nullptr) { + if (edit_->CurFilePage() != nullptr) { disable = true; } - printAct->setDisabled(disable); - saveAct->setDisabled(disable); - saveAsAct->setDisabled(disable); - quoteAct->setDisabled(disable); - cutAct->setDisabled(disable); - copyAct->setDisabled(disable); - pasteAct->setDisabled(disable); - closeTabAct->setDisabled(disable); - selectAllAct->setDisabled(disable); - findAct->setDisabled(disable); - verifyAct->setDisabled(disable); - signAct->setDisabled(disable); - encryptAct->setDisabled(disable); - encryptSignAct->setDisabled(disable); - decryptAct->setDisabled(disable); - decryptVerifyAct->setDisabled(disable); - - redoAct->setDisabled(disable); - undoAct->setDisabled(disable); - zoomOutAct->setDisabled(disable); - zoomInAct->setDisabled(disable); - cleanDoubleLinebreaksAct->setDisabled(disable); - quoteAct->setDisabled(disable); - appendSelectedKeysAct->setDisabled(disable); - importKeyFromEditAct->setDisabled(disable); - - cutPgpHeaderAct->setDisabled(disable); - addPgpHeaderAct->setDisabled(disable); + print_act_->setDisabled(disable); + save_act_->setDisabled(disable); + save_as_act_->setDisabled(disable); + quote_act_->setDisabled(disable); + cut_act_->setDisabled(disable); + copy_act_->setDisabled(disable); + paste_act_->setDisabled(disable); + close_tab_act_->setDisabled(disable); + select_all_act_->setDisabled(disable); + find_act_->setDisabled(disable); + verify_act_->setDisabled(disable); + sign_act_->setDisabled(disable); + encrypt_act_->setDisabled(disable); + encrypt_sign_act_->setDisabled(disable); + decrypt_act_->setDisabled(disable); + decrypt_verify_act_->setDisabled(disable); + + redo_act_->setDisabled(disable); + undo_act_->setDisabled(disable); + zoom_out_act_->setDisabled(disable); + zoom_in_act_->setDisabled(disable); + clean_double_line_breaks_act_->setDisabled(disable); + quote_act_->setDisabled(disable); + append_selected_keys_act_->setDisabled(disable); + import_key_from_edit_act_->setDisabled(disable); + + cut_pgp_header_act_->setDisabled(disable); + add_pgp_header_act_->setDisabled(disable); } -void MainWindow::slotOpenSettingsDialog() { +void MainWindow::slot_open_settings_dialog() { auto dialog = new SettingsDialog(this); connect(dialog, &SettingsDialog::finished, this, [&]() -> void { LOG(INFO) << "Setting Dialog Finished"; - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + SettingsObject main_windows_state("main_windows_state"); - int icon_width = settings["window"]["icon_size"]["width"]; - int icon_height = settings["window"]["icon_size"]["height"]; + int width = main_windows_state.Check("icon_size").Check("width", 24), + height = main_windows_state.Check("icon_size").Check("height", 24); + LOG(INFO) << "icon_size" << width << height; - this->setIconSize(QSize(icon_width, icon_height)); - importButton->setIconSize(QSize(icon_width, icon_height)); + main_windows_state.Check("info_font_size", 10); - // Iconstyle + // icon_style + int s_icon_style = + main_windows_state.Check("icon_style", Qt::ToolButtonTextUnderIcon); + auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); + this->setToolButtonStyle(icon_style); + import_button_->setToolButtonStyle(icon_style); - int icon_style = settings["window"]["icon_style"]; - auto button_style = static_cast<Qt::ToolButtonStyle>(icon_style); - this->setToolButtonStyle(button_style); - importButton->setToolButtonStyle(button_style); + // icons ize + this->setIconSize(QSize(width, height)); + import_button_->setIconSize(QSize(width, height)); // restart mainwindow if necessary - if (getRestartNeeded()) { - if (edit->maybeSaveAnyTab()) { - saveSettings(); + if (get_restart_needed()) { + if (edit_->MaybeSaveAnyTab()) { + save_settings(); qApp->exit(RESTART_CODE); } } -#ifdef ADVANCED_SUPPORT - // steganography hide/show - if (!settings.value("advanced/steganography").toBool()) { - this->menuBar()->removeAction(steganoMenu->menuAction()); - } else { - this->menuBar()->insertAction(viewMenu->menuAction(), - steganoMenu->menuAction()); - } -#endif }); } -void MainWindow::slotCleanDoubleLinebreaks() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { +void MainWindow::slot_clean_double_line_breaks() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { return; } - QString content = edit->curTextPage()->toPlainText(); + QString content = edit_->CurTextPage()->GetTextPage()->toPlainText(); content.replace("\n\n", "\n"); - edit->slotFillTextEditWithText(content); + edit_->SlotFillTextEditWithText(content); } -void MainWindow::slotAddPgpHeader() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { +void MainWindow::slot_add_pgp_header() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { return; } - QString content = edit->curTextPage()->toPlainText().trimmed(); + QString content = + edit_->CurTextPage()->GetTextPage()->toPlainText().trimmed(); content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN); content.append("\n").append(GpgConstants::PGP_CRYPT_END); - edit->slotFillTextEditWithText(content); + edit_->SlotFillTextEditWithText(content); } -void MainWindow::slotCutPgpHeader() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { +void MainWindow::slot_cut_pgp_header() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) { return; } - QString content = edit->curTextPage()->toPlainText(); + QString content = edit_->CurTextPage()->GetTextPage()->toPlainText(); int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN); int end = content.indexOf(GpgConstants::PGP_CRYPT_END); @@ -178,13 +179,46 @@ void MainWindow::slotCutPgpHeader() { end = content.indexOf(GpgConstants::PGP_CRYPT_END); content.remove(end, QString(GpgConstants::PGP_CRYPT_END).size()); - edit->slotFillTextEditWithText(content.trimmed()); + edit_->SlotFillTextEditWithText(content.trimmed()); } -void MainWindow::slotSetRestartNeeded(bool needed) { - this->restartNeeded = needed; +void MainWindow::SlotSetRestartNeeded(bool needed) { + this->restart_needed_ = needed; } -bool MainWindow::getRestartNeeded() const { return this->restartNeeded; } +bool MainWindow::get_restart_needed() const { return this->restart_needed_; } + +void MainWindow::SetCryptoMenuStatus( + MainWindow::CryptoMenu::OperationType type) { + LOG(INFO) << "SetCryptoMenuStatus" << type; + + // refresh status to disable all + verify_act_->setDisabled(true); + sign_act_->setDisabled(true); + encrypt_act_->setDisabled(true); + encrypt_sign_act_->setDisabled(true); + decrypt_act_->setDisabled(true); + decrypt_verify_act_->setDisabled(true); + + // enable according to type + if (type & MainWindow::CryptoMenu::Verify) { + verify_act_->setDisabled(false); + } + if (type & MainWindow::CryptoMenu::Sign) { + sign_act_->setDisabled(false); + } + if (type & MainWindow::CryptoMenu::Encrypt) { + encrypt_act_->setDisabled(false); + } + if (type & MainWindow::CryptoMenu::EncryptAndSign) { + encrypt_sign_act_->setDisabled(false); + } + if (type & MainWindow::CryptoMenu::Decrypt) { + decrypt_act_->setDisabled(false); + } + if (type & MainWindow::CryptoMenu::DecryptAndVerify) { + decrypt_verify_act_->setDisabled(false); + } +} } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index cb7962f7..01c4bbc9 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,437 +8,457 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "MainWindow.h" #include "ui/UserInterfaceUtils.h" -#include "ui/smtp/SendMailDialog.h" +#ifdef SMTP_SUPPORT +#include "ui/mail/ReceiveMailDialog.h" +#include "ui/mail/SendMailDialog.h" +#endif namespace GpgFrontend::UI { -void MainWindow::createActions() { +void MainWindow::create_actions() { /* Main Menu */ - newTabAct = new QAction(_("New"), this); - newTabAct->setIcon(QIcon(":misc_doc.png")); + new_tab_act_ = new QAction(_("New"), this); + new_tab_act_->setIcon(QIcon(":misc_doc.png")); QList<QKeySequence> newTabActShortcutList; newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N)); newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T)); - newTabAct->setShortcuts(newTabActShortcutList); - newTabAct->setToolTip(_("Open a new file")); - connect(newTabAct, SIGNAL(triggered()), edit, SLOT(slotNewTab())); - - openAct = new QAction(_("Open..."), this); - openAct->setIcon(QIcon(":fileopen.png")); - openAct->setShortcut(QKeySequence::Open); - openAct->setToolTip(_("Open an existing file")); - connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen())); - - browserAct = new QAction(_("File Browser"), this); - browserAct->setIcon(QIcon(":file-browser.png")); - browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); - browserAct->setToolTip(_("Open a file browser")); - connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab())); - - saveAct = new QAction(_("Save File"), this); - saveAct->setIcon(QIcon(":filesave.png")); - saveAct->setShortcut(QKeySequence::Save); - saveAct->setToolTip(_("Save the current File")); - connect(saveAct, SIGNAL(triggered()), edit, SLOT(slotSave())); - - saveAsAct = new QAction(QString(_("Save As")) + "...", this); - saveAsAct->setIcon(QIcon(":filesaveas.png")); - saveAsAct->setShortcut(QKeySequence::SaveAs); - saveAsAct->setToolTip(_("Save the current File as...")); - connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(slotSaveAs())); - - printAct = new QAction(_("Print"), this); - printAct->setIcon(QIcon(":fileprint.png")); - printAct->setShortcut(QKeySequence::Print); - printAct->setToolTip(_("Print Document")); - connect(printAct, SIGNAL(triggered()), edit, SLOT(slotPrint())); - - closeTabAct = new QAction(_("Close"), this); - closeTabAct->setShortcut(QKeySequence::Close); - closeTabAct->setToolTip(_("Close file")); - connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(slotCloseTab())); - - quitAct = new QAction(_("Quit"), this); - quitAct->setShortcut(QKeySequence::Quit); - quitAct->setIcon(QIcon(":exit.png")); - quitAct->setToolTip(_("Quit Program")); - connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); + new_tab_act_->setShortcuts(newTabActShortcutList); + new_tab_act_->setToolTip(_("Open a new file")); + connect(new_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotNewTab); + + open_act_ = new QAction(_("Open..."), this); + open_act_->setIcon(QIcon(":fileopen.png")); + open_act_->setShortcut(QKeySequence::Open); + open_act_->setToolTip(_("Open an existing file")); + connect(open_act_, &QAction::triggered, edit_, &TextEdit::SlotOpen); + + browser_act_ = new QAction(_("File Browser"), this); + browser_act_->setIcon(QIcon(":file-browser.png")); + browser_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); + browser_act_->setToolTip(_("Open a file browser")); + connect(browser_act_, &QAction::triggered, this, &MainWindow::slot_open_file_tab); + + save_act_ = new QAction(_("Save File"), this); + save_act_->setIcon(QIcon(":filesave.png")); + save_act_->setShortcut(QKeySequence::Save); + save_act_->setToolTip(_("Save the current File")); + connect(save_act_, &QAction::triggered, edit_, &TextEdit::SlotSave); + + save_as_act_ = new QAction(QString(_("Save As")) + "...", this); + save_as_act_->setIcon(QIcon(":filesaveas.png")); + save_as_act_->setShortcut(QKeySequence::SaveAs); + save_as_act_->setToolTip(_("Save the current File as...")); + connect(save_as_act_, &QAction::triggered, edit_, &TextEdit::SlotSaveAs); + + print_act_ = new QAction(_("Print"), this); + print_act_->setIcon(QIcon(":fileprint.png")); + print_act_->setShortcut(QKeySequence::Print); + print_act_->setToolTip(_("Print Document")); + connect(print_act_, &QAction::triggered, edit_, &TextEdit::SlotPrint); + + close_tab_act_ = new QAction(_("Close"), this); + close_tab_act_->setShortcut(QKeySequence::Close); + close_tab_act_->setToolTip(_("Close file")); + connect(close_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotCloseTab); + + quit_act_ = new QAction(_("Quit"), this); + quit_act_->setShortcut(QKeySequence::Quit); + quit_act_->setIcon(QIcon(":exit.png")); + quit_act_->setToolTip(_("Quit Program")); + connect(quit_act_, &QAction::triggered, this, &MainWindow::close); /* Edit Menu */ - undoAct = new QAction(_("Undo"), this); - undoAct->setShortcut(QKeySequence::Undo); - undoAct->setToolTip(_("Undo Last Edit Action")); - connect(undoAct, SIGNAL(triggered()), edit, SLOT(slotUndo())); - - redoAct = new QAction(_("Redo"), this); - redoAct->setShortcut(QKeySequence::Redo); - redoAct->setToolTip(_("Redo Last Edit Action")); - connect(redoAct, SIGNAL(triggered()), edit, SLOT(slotRedo())); - - zoomInAct = new QAction(_("Zoom In"), this); - zoomInAct->setShortcut(QKeySequence::ZoomIn); - connect(zoomInAct, SIGNAL(triggered()), edit, SLOT(slotZoomIn())); - - zoomOutAct = new QAction(_("Zoom Out"), this); - zoomOutAct->setShortcut(QKeySequence::ZoomOut); - connect(zoomOutAct, SIGNAL(triggered()), edit, SLOT(slotZoomOut())); - - pasteAct = new QAction(_("Paste"), this); - pasteAct->setIcon(QIcon(":button_paste.png")); - pasteAct->setShortcut(QKeySequence::Paste); - pasteAct->setToolTip(_("Paste Text From Clipboard")); - connect(pasteAct, SIGNAL(triggered()), edit, SLOT(slotPaste())); - - cutAct = new QAction(_("Cut"), this); - cutAct->setIcon(QIcon(":button_cut.png")); - cutAct->setShortcut(QKeySequence::Cut); - cutAct->setToolTip( + undo_act_ = new QAction(_("Undo"), this); + undo_act_->setShortcut(QKeySequence::Undo); + undo_act_->setToolTip(_("Undo Last Edit Action")); + connect(undo_act_, &QAction::triggered, edit_, &TextEdit::SlotUndo); + + redo_act_ = new QAction(_("Redo"), this); + redo_act_->setShortcut(QKeySequence::Redo); + redo_act_->setToolTip(_("Redo Last Edit Action")); + connect(redo_act_, &QAction::triggered, edit_, &TextEdit::SlotRedo); + + zoom_in_act_ = new QAction(_("Zoom In"), this); + zoom_in_act_->setShortcut(QKeySequence::ZoomIn); + connect(zoom_in_act_, &QAction::triggered, edit_, &TextEdit::SlotZoomIn); + + zoom_out_act_ = new QAction(_("Zoom Out"), this); + zoom_out_act_->setShortcut(QKeySequence::ZoomOut); + connect(zoom_out_act_, &QAction::triggered, edit_, &TextEdit::SlotZoomOut); + + paste_act_ = new QAction(_("Paste"), this); + paste_act_->setIcon(QIcon(":button_paste.png")); + paste_act_->setShortcut(QKeySequence::Paste); + paste_act_->setToolTip(_("Paste Text From Clipboard")); + connect(paste_act_, &QAction::triggered, edit_, &TextEdit::SlotPaste); + + cut_act_ = new QAction(_("Cut"), this); + cut_act_->setIcon(QIcon(":button_cut.png")); + cut_act_->setShortcut(QKeySequence::Cut); + cut_act_->setToolTip( _("Cut the current selection's contents to the " "clipboard")); - connect(cutAct, SIGNAL(triggered()), edit, SLOT(slotCut())); + connect(cut_act_, &QAction::triggered, edit_, &TextEdit::SlotCut); - copyAct = new QAction(_("Copy"), this); - copyAct->setIcon(QIcon(":button_copy.png")); - copyAct->setShortcut(QKeySequence::Copy); - copyAct->setToolTip( + copy_act_ = new QAction(_("Copy"), this); + copy_act_->setIcon(QIcon(":button_copy.png")); + copy_act_->setShortcut(QKeySequence::Copy); + copy_act_->setToolTip( _("Copy the current selection's contents to the " "clipboard")); - connect(copyAct, SIGNAL(triggered()), edit, SLOT(slotCopy())); - - quoteAct = new QAction(_("Quote"), this); - quoteAct->setIcon(QIcon(":quote.png")); - quoteAct->setToolTip(_("Quote whole text")); - connect(quoteAct, SIGNAL(triggered()), edit, SLOT(slotQuote())); - - selectAllAct = new QAction(_("Select All"), this); - selectAllAct->setIcon(QIcon(":edit.png")); - selectAllAct->setShortcut(QKeySequence::SelectAll); - selectAllAct->setToolTip(_("Select the whole text")); - connect(selectAllAct, SIGNAL(triggered()), edit, SLOT(slotSelectAll())); - - findAct = new QAction(_("Find"), this); - findAct->setShortcut(QKeySequence::Find); - findAct->setToolTip(_("Find a word")); - connect(findAct, SIGNAL(triggered()), this, SLOT(slotFind())); - - cleanDoubleLinebreaksAct = new QAction(_("Remove spacing"), this); - cleanDoubleLinebreaksAct->setIcon(QIcon(":format-line-spacing-triple.png")); + connect(copy_act_, &QAction::triggered, edit_, &TextEdit::SlotCopy); + + quote_act_ = new QAction(_("Quote"), this); + quote_act_->setIcon(QIcon(":quote.png")); + quote_act_->setToolTip(_("Quote whole text")); + connect(quote_act_, &QAction::triggered, edit_, &TextEdit::SlotQuote); + + select_all_act_ = new QAction(_("Select All"), this); + select_all_act_->setIcon(QIcon(":edit.png")); + select_all_act_->setShortcut(QKeySequence::SelectAll); + select_all_act_->setToolTip(_("Select the whole text")); + connect(select_all_act_, &QAction::triggered, edit_, &TextEdit::SlotSelectAll); + + find_act_ = new QAction(_("Find"), this); + find_act_->setShortcut(QKeySequence::Find); + find_act_->setToolTip(_("Find a word")); + connect(find_act_, &QAction::triggered, this, &MainWindow::slot_find); + + clean_double_line_breaks_act_ = new QAction(_("Remove spacing"), this); + clean_double_line_breaks_act_->setIcon( + QIcon(":format-line-spacing-triple.png")); // cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll); - cleanDoubleLinebreaksAct->setToolTip( + clean_double_line_breaks_act_->setToolTip( _("Remove double linebreaks, e.g. in pasted text from Web Mailer")); - connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this, - SLOT(slotCleanDoubleLinebreaks())); + connect(clean_double_line_breaks_act_, &QAction::triggered, this, + &MainWindow::slot_clean_double_line_breaks); - openSettingsAct = new QAction(_("Settings"), this); - openSettingsAct->setToolTip(_("Open settings dialog")); - openSettingsAct->setShortcut(QKeySequence::Preferences); - connect(openSettingsAct, SIGNAL(triggered()), this, - SLOT(slotOpenSettingsDialog())); + open_settings_act_ = new QAction(_("Settings"), this); + open_settings_act_->setToolTip(_("Open settings dialog")); + open_settings_act_->setShortcut(QKeySequence::Preferences); + connect(open_settings_act_, &QAction::triggered, this, + &MainWindow::slot_open_settings_dialog); /* Crypt Menu */ - encryptAct = new QAction(_("Encrypt"), this); - encryptAct->setIcon(QIcon(":encrypted.png")); - encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); - encryptAct->setToolTip(_("Encrypt Message")); - connect(encryptAct, SIGNAL(triggered()), this, SLOT(slotEncrypt())); - - encryptSignAct = new QAction(_("Encrypt Sign"), this); - encryptSignAct->setIcon(QIcon(":encrypted_signed.png")); - encryptSignAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E)); - encryptSignAct->setToolTip(_("Encrypt and Sign Message")); - connect(encryptSignAct, SIGNAL(triggered()), this, SLOT(slotEncryptSign())); - - decryptAct = new QAction(_("Decrypt"), this); - decryptAct->setIcon(QIcon(":decrypted.png")); - decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); - decryptAct->setToolTip(_("Decrypt Message")); - connect(decryptAct, SIGNAL(triggered()), this, SLOT(slotDecrypt())); - - decryptVerifyAct = new QAction(_("Decrypt Verify"), this); - decryptVerifyAct->setIcon(QIcon(":decrypted_verified.png")); - decryptVerifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D)); - decryptVerifyAct->setToolTip(_("Decrypt and Verify Message")); - connect(decryptVerifyAct, SIGNAL(triggered()), this, - SLOT(slotDecryptVerify())); - - signAct = new QAction(_("Sign"), this); - signAct->setIcon(QIcon(":signature.png")); - signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I)); - signAct->setToolTip(_("Sign Message")); - connect(signAct, SIGNAL(triggered()), this, SLOT(slotSign())); - - verifyAct = new QAction(_("Verify"), this); - verifyAct->setIcon(QIcon(":verify.png")); - verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); - verifyAct->setToolTip(_("Verify Message")); - connect(verifyAct, SIGNAL(triggered()), this, SLOT(slotVerify())); + encrypt_act_ = new QAction(_("Encrypt"), this); + encrypt_act_->setIcon(QIcon(":encrypted.png")); + encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); + encrypt_act_->setToolTip(_("Encrypt Message")); + connect(encrypt_act_, &QAction::triggered, this, &MainWindow::slot_encrypt); + + encrypt_sign_act_ = new QAction(_("Encrypt Sign"), this); + encrypt_sign_act_->setIcon(QIcon(":encrypted_signed.png")); + encrypt_sign_act_->setShortcut( + QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E)); + encrypt_sign_act_->setToolTip(_("Encrypt and Sign Message")); + connect(encrypt_sign_act_, &QAction::triggered, this, + &MainWindow::slot_encrypt_sign); + + decrypt_act_ = new QAction(_("Decrypt"), this); + decrypt_act_->setIcon(QIcon(":decrypted.png")); + decrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); + decrypt_act_->setToolTip(_("Decrypt Message")); + connect(decrypt_act_, &QAction::triggered, this, &MainWindow::slot_decrypt); + + decrypt_verify_act_ = new QAction(_("Decrypt Verify"), this); + decrypt_verify_act_->setIcon(QIcon(":decrypted_verified.png")); + decrypt_verify_act_->setShortcut( + QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D)); + decrypt_verify_act_->setToolTip(_("Decrypt and Verify Message")); + connect(decrypt_verify_act_, &QAction::triggered, this, + &MainWindow::slot_decrypt_verify); + + sign_act_ = new QAction(_("Sign"), this); + sign_act_->setIcon(QIcon(":signature.png")); + sign_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I)); + sign_act_->setToolTip(_("Sign Message")); + connect(sign_act_, &QAction::triggered, this, &MainWindow::slot_sign); + + verify_act_ = new QAction(_("Verify"), this); + verify_act_->setIcon(QIcon(":verify.png")); + verify_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); + verify_act_->setToolTip(_("Verify Message")); + connect(verify_act_, &QAction::triggered, this, &MainWindow::slot_verify); /* Key Menu */ - importKeyFromFileAct = new QAction(_("File"), this); - importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png")); - importKeyFromFileAct->setToolTip(_("Import New Key From File")); - connect(importKeyFromFileAct, &QAction::triggered, this, - [&]() { CommonUtils::GetInstance()->slotImportKeyFromFile(this); }); - - importKeyFromClipboardAct = new QAction(_("Clipboard"), this); - importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png")); - importKeyFromClipboardAct->setToolTip(_("Import New Key From Clipboard")); - connect(importKeyFromClipboardAct, &QAction::triggered, this, [&]() { - CommonUtils::GetInstance()->slotImportKeyFromClipboard(this); + import_key_from_file_act_ = new QAction(_("File"), this); + import_key_from_file_act_->setIcon(QIcon(":import_key_from_file.png")); + import_key_from_file_act_->setToolTip(_("Import New Key From File")); + connect(import_key_from_file_act_, &QAction::triggered, this, + [&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); }); + + import_key_from_clipboard_act_ = new QAction(_("Clipboard"), this); + import_key_from_clipboard_act_->setIcon( + QIcon(":import_key_from_clipboard.png")); + import_key_from_clipboard_act_->setToolTip( + _("Import New Key From Clipboard")); + connect(import_key_from_clipboard_act_, &QAction::triggered, this, [&]() { + CommonUtils::GetInstance()->SlotImportKeyFromClipboard(this); }); - importKeyFromKeyServerAct = new QAction(_("Keyserver"), this); - importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png")); - importKeyFromKeyServerAct->setToolTip(_("Import New Key From Keyserver")); - connect(importKeyFromKeyServerAct, &QAction::triggered, this, [&]() { - CommonUtils::GetInstance()->slotImportKeyFromKeyServer(this); + import_key_from_key_server_act_ = new QAction(_("Keyserver"), this); + import_key_from_key_server_act_->setIcon( + QIcon(":import_key_from_server.png")); + import_key_from_key_server_act_->setToolTip( + _("Import New Key From Keyserver")); + connect(import_key_from_key_server_act_, &QAction::triggered, this, [&]() { + CommonUtils::GetInstance()->SlotImportKeyFromKeyServer(this); }); - importKeyFromEditAct = new QAction(_("Editor"), this); - importKeyFromEditAct->setIcon(QIcon(":txt.png")); - importKeyFromEditAct->setToolTip(_("Import New Key From Editor")); - connect(importKeyFromEditAct, SIGNAL(triggered()), this, - SLOT(slotImportKeyFromEdit())); + import_key_from_edit_act_ = new QAction(_("Editor"), this); + import_key_from_edit_act_->setIcon(QIcon(":txt.png")); + import_key_from_edit_act_->setToolTip(_("Import New Key From Editor")); + connect(import_key_from_edit_act_, &QAction::triggered, this, + &MainWindow::slot_import_key_from_edit); - openKeyManagementAct = new QAction(_("Manage Keys"), this); - openKeyManagementAct->setIcon(QIcon(":keymgmt.png")); - openKeyManagementAct->setToolTip(_("Open Key Management")); - connect(openKeyManagementAct, SIGNAL(triggered()), this, - SLOT(slotOpenKeyManagement())); + open_key_management_act_ = new QAction(_("Manage Keys"), this); + open_key_management_act_->setIcon(QIcon(":keymgmt.png")); + open_key_management_act_->setToolTip(_("Open Key Management")); + connect(open_key_management_act_, &QAction::triggered, this, + &MainWindow::slot_open_key_management); /* * About Menu */ - aboutAct = new QAction(_("About"), this); - aboutAct->setIcon(QIcon(":help.png")); - aboutAct->setToolTip(_("Show the application's About box")); - connect(aboutAct, &QAction::triggered, this, + about_act_ = new QAction(_("About"), this); + about_act_->setIcon(QIcon(":help.png")); + about_act_->setToolTip(_("Show the application's About box")); + connect(about_act_, &QAction::triggered, this, [=]() { new AboutDialog(0, this); }); - translateAct = new QAction(_("Translate"), this); - translateAct->setIcon(QIcon(":help.png")); - translateAct->setToolTip(_("Information about translation")); - connect(translateAct, &QAction::triggered, this, + translate_act_ = new QAction(_("Translate"), this); + translate_act_->setIcon(QIcon(":help.png")); + translate_act_->setToolTip(_("Information about translation")); + connect(translate_act_, &QAction::triggered, this, [=]() { new AboutDialog(1, this); }); /* * Check Update Menu */ - checkUpdateAct = new QAction(_("Check for Updates"), this); - checkUpdateAct->setIcon(QIcon(":help.png")); - checkUpdateAct->setToolTip(_("Check for updates")); - connect(checkUpdateAct, &QAction::triggered, this, + check_update_act_ = new QAction(_("Check for Updates"), this); + check_update_act_->setIcon(QIcon(":help.png")); + check_update_act_->setToolTip(_("Check for updates")); + connect(check_update_act_, &QAction::triggered, this, [=]() { new AboutDialog(2, this); }); - startWizardAct = new QAction(_("Open Wizard"), this); - startWizardAct->setToolTip(_("Open the wizard")); - connect(startWizardAct, SIGNAL(triggered()), this, SLOT(slotStartWizard())); + start_wizard_act_ = new QAction(_("Open Wizard"), this); + start_wizard_act_->setToolTip(_("Open the wizard")); + connect(start_wizard_act_, &QAction::triggered, this, + &MainWindow::slot_start_wizard); /* Popup-Menu-Action for KeyList */ - appendSelectedKeysAct = - new QAction(_("Append Public Key To Text Editor"), this); - appendSelectedKeysAct->setToolTip( - _("Append The Selected Keys To Text in Editor")); - connect(appendSelectedKeysAct, SIGNAL(triggered()), this, - SLOT(slotAppendSelectedKeys())); - - copyMailAddressToClipboardAct = new QAction(_("Copy Email"), this); - copyMailAddressToClipboardAct->setToolTip( + append_selected_keys_act_ = + new QAction(_("Append To Text Editor"), this); + append_selected_keys_act_->setToolTip( + _("Append The Selected Public Key To Text in Editor")); + connect(append_selected_keys_act_, &QAction::triggered, this, + &MainWindow::slot_append_selected_keys); + + copy_mail_address_to_clipboard_act_ = new QAction(_("Copy Email"), this); + copy_mail_address_to_clipboard_act_->setToolTip( _("Copy selected Email to clipboard")); - connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this, - SLOT(slotCopyMailAddressToClipboard())); + connect(copy_mail_address_to_clipboard_act_, &QAction::triggered, this, + &MainWindow::slot_copy_mail_address_to_clipboard); // TODO: find central place for shared actions, to avoid code-duplication with // keymgmt.cpp - showKeyDetailsAct = new QAction(_("Show Key Details"), this); - showKeyDetailsAct->setToolTip(_("Show Details for this Key")); - connect(showKeyDetailsAct, SIGNAL(triggered()), this, - SLOT(slotShowKeyDetails())); + show_key_details_act_ = new QAction(_("Show Key Details"), this); + show_key_details_act_->setToolTip(_("Show Details for this Key")); + connect(show_key_details_act_, &QAction::triggered, this, + &MainWindow::slot_show_key_details); /* Key-Shortcuts for Tab-Switchung-Action */ - switchTabUpAct = new QAction(this); - switchTabUpAct->setShortcut(QKeySequence::NextChild); - connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabUp())); - this->addAction(switchTabUpAct); - - switchTabDownAct = new QAction(this); - switchTabDownAct->setShortcut(QKeySequence::PreviousChild); - connect(switchTabDownAct, SIGNAL(triggered()), edit, - SLOT(slotSwitchTabDown())); - this->addAction(switchTabDownAct); - - cutPgpHeaderAct = new QAction(_("Remove PGP Header"), this); - connect(cutPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotCutPgpHeader())); - - addPgpHeaderAct = new QAction(_("Add PGP Header"), this); - connect(addPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotAddPgpHeader())); + switch_tab_up_act_ = new QAction(this); + switch_tab_up_act_->setShortcut(QKeySequence::NextChild); + connect(switch_tab_up_act_, &QAction::triggered, edit_, + &TextEdit::SlotSwitchTabUp); + this->addAction(switch_tab_up_act_); + + switch_tab_down_act_ = new QAction(this); + switch_tab_down_act_->setShortcut(QKeySequence::PreviousChild); + connect(switch_tab_down_act_, &QAction::triggered, edit_, + &TextEdit::SlotSwitchTabDown); + this->addAction(switch_tab_down_act_); + + cut_pgp_header_act_ = new QAction(_("Remove PGP Header"), this); + connect(cut_pgp_header_act_, &QAction::triggered, this, + &MainWindow::slot_cut_pgp_header); + + add_pgp_header_act_ = new QAction(_("Add PGP Header"), this); + connect(add_pgp_header_act_, &QAction::triggered, this, + &MainWindow::slot_add_pgp_header); #ifdef SMTP_SUPPORT - sendMailAct = new QAction(_("New Message"), this); - sendMailAct->setIcon(QIcon(":email.png")); - connect(sendMailAct, &QAction::triggered, this, [=]() { + send_mail_act_ = new QAction(_("New Message"), this); + send_mail_act_->setIcon(QIcon(":email.png")); + connect(send_mail_act_, &QAction::triggered, this, [=]() { auto* dialog = new SendMailDialog({}, this); dialog->show(); }); + + receive_mail_act_ = new QAction(_("Message Inbox"), this); + receive_mail_act_->setVisible(false); + receive_mail_act_->setIcon(QIcon(":receive_email.png")); + connect(receive_mail_act_, &QAction::triggered, this, [=]() { + auto* dialog = new ReceiveMailDialog(this); + dialog->show(); + }); #endif } -void MainWindow::createMenus() { - fileMenu = menuBar()->addMenu(_("File")); - fileMenu->addAction(newTabAct); - fileMenu->addAction(browserAct); - fileMenu->addAction(openAct); - fileMenu->addSeparator(); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(printAct); - fileMenu->addSeparator(); - fileMenu->addAction(closeTabAct); - fileMenu->addAction(quitAct); - - editMenu = menuBar()->addMenu(_("Edit")); - editMenu->addAction(undoAct); - editMenu->addAction(redoAct); - editMenu->addSeparator(); - editMenu->addAction(zoomInAct); - editMenu->addAction(zoomOutAct); - editMenu->addSeparator(); - editMenu->addAction(copyAct); - editMenu->addAction(cutAct); - editMenu->addAction(pasteAct); - editMenu->addAction(selectAllAct); - editMenu->addAction(findAct); - editMenu->addSeparator(); - editMenu->addAction(quoteAct); - editMenu->addAction(cleanDoubleLinebreaksAct); - editMenu->addSeparator(); - editMenu->addAction(openSettingsAct); - - cryptMenu = menuBar()->addMenu(_("Crypt")); - cryptMenu->addAction(encryptAct); - cryptMenu->addAction(encryptSignAct); - cryptMenu->addAction(decryptAct); - cryptMenu->addAction(decryptVerifyAct); - cryptMenu->addSeparator(); - cryptMenu->addAction(signAct); - cryptMenu->addAction(verifyAct); - cryptMenu->addSeparator(); - - keyMenu = menuBar()->addMenu(_("Keys")); - importKeyMenu = keyMenu->addMenu(_("Import Key")); - importKeyMenu->setIcon(QIcon(":key_import.png")); - importKeyMenu->addAction(importKeyFromFileAct); - importKeyMenu->addAction(importKeyFromEditAct); - importKeyMenu->addAction(importKeyFromClipboardAct); - importKeyMenu->addAction(importKeyFromKeyServerAct); - keyMenu->addAction(openKeyManagementAct); - - steganoMenu = menuBar()->addMenu(_("Steganography")); - steganoMenu->addAction(cutPgpHeaderAct); - steganoMenu->addAction(addPgpHeaderAct); +void MainWindow::create_menus() { + file_menu_ = menuBar()->addMenu(_("File")); + file_menu_->addAction(new_tab_act_); + file_menu_->addAction(browser_act_); + file_menu_->addAction(open_act_); + file_menu_->addSeparator(); + file_menu_->addAction(save_act_); + file_menu_->addAction(save_as_act_); + file_menu_->addSeparator(); + file_menu_->addAction(print_act_); + file_menu_->addSeparator(); + file_menu_->addAction(close_tab_act_); + file_menu_->addAction(quit_act_); + + edit_menu_ = menuBar()->addMenu(_("Edit")); + edit_menu_->addAction(undo_act_); + edit_menu_->addAction(redo_act_); + edit_menu_->addSeparator(); + edit_menu_->addAction(zoom_in_act_); + edit_menu_->addAction(zoom_out_act_); + edit_menu_->addSeparator(); + edit_menu_->addAction(copy_act_); + edit_menu_->addAction(cut_act_); + edit_menu_->addAction(paste_act_); + edit_menu_->addAction(select_all_act_); + edit_menu_->addAction(find_act_); + edit_menu_->addSeparator(); + edit_menu_->addAction(quote_act_); + edit_menu_->addAction(clean_double_line_breaks_act_); + edit_menu_->addSeparator(); + edit_menu_->addAction(open_settings_act_); + + crypt_menu_ = menuBar()->addMenu(_("Crypt")); + crypt_menu_->addAction(encrypt_act_); + crypt_menu_->addAction(encrypt_sign_act_); + crypt_menu_->addAction(decrypt_act_); + crypt_menu_->addAction(decrypt_verify_act_); + crypt_menu_->addSeparator(); + crypt_menu_->addAction(sign_act_); + crypt_menu_->addAction(verify_act_); + crypt_menu_->addSeparator(); + + key_menu_ = menuBar()->addMenu(_("Keys")); + import_key_menu_ = key_menu_->addMenu(_("Import Key")); + import_key_menu_->setIcon(QIcon(":key_import.png")); + import_key_menu_->addAction(import_key_from_file_act_); + import_key_menu_->addAction(import_key_from_edit_act_); + import_key_menu_->addAction(import_key_from_clipboard_act_); + import_key_menu_->addAction(import_key_from_key_server_act_); + key_menu_->addAction(open_key_management_act_); + + steganography_menu_ = menuBar()->addMenu(_("Steganography")); + steganography_menu_->addAction(cut_pgp_header_act_); + steganography_menu_->addAction(add_pgp_header_act_); #ifdef SMTP_SUPPORT - emailMenu = menuBar()->addMenu(_("Email")); - emailMenu->addAction(sendMailAct); -#endif - -#ifdef ADVANCED_SUPPORT - // Hide menu, when steganography menu is disabled in settings - if (!settings.value("advanced/steganography").toBool()) { - this->menuBar()->removeAction(steganoMenu->menuAction()); - } + email_menu_ = menuBar()->addMenu(_("Email")); + email_menu_->addAction(send_mail_act_); + email_menu_->addAction(receive_mail_act_); #endif - viewMenu = menuBar()->addMenu(_("View")); + view_menu_ = menuBar()->addMenu(_("View")); - helpMenu = menuBar()->addMenu(_("Help")); - helpMenu->addAction(startWizardAct); - helpMenu->addSeparator(); - helpMenu->addAction(checkUpdateAct); - helpMenu->addAction(translateAct); - helpMenu->addAction(aboutAct); + help_menu_ = menuBar()->addMenu(_("Help")); + help_menu_->addAction(start_wizard_act_); + help_menu_->addSeparator(); + help_menu_->addAction(check_update_act_); + help_menu_->addAction(translate_act_); + help_menu_->addAction(about_act_); } -void MainWindow::createToolBars() { - fileToolBar = addToolBar(_("File")); - fileToolBar->setObjectName("fileToolBar"); - fileToolBar->addAction(newTabAct); - fileToolBar->addAction(openAct); - fileToolBar->addAction(saveAct); - fileToolBar->addAction(browserAct); - viewMenu->addAction(fileToolBar->toggleViewAction()); - - cryptToolBar = addToolBar(_("Operations")); - cryptToolBar->setObjectName("cryptToolBar"); - cryptToolBar->addAction(encryptAct); - cryptToolBar->addAction(encryptSignAct); - cryptToolBar->addAction(decryptAct); - cryptToolBar->addAction(decryptVerifyAct); - cryptToolBar->addAction(signAct); - cryptToolBar->addAction(verifyAct); - viewMenu->addAction(cryptToolBar->toggleViewAction()); - - keyToolBar = addToolBar(_("Key")); - keyToolBar->setObjectName("keyToolBar"); - keyToolBar->addAction(openKeyManagementAct); - viewMenu->addAction(keyToolBar->toggleViewAction()); - - editToolBar = addToolBar(_("Edit")); - editToolBar->setObjectName("editToolBar"); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); - editToolBar->addAction(selectAllAct); - editToolBar->hide(); - viewMenu->addAction(editToolBar->toggleViewAction()); - - specialEditToolBar = addToolBar(_("Special Edit")); - specialEditToolBar->setObjectName("specialEditToolBar"); - specialEditToolBar->addAction(quoteAct); - specialEditToolBar->addAction(cleanDoubleLinebreaksAct); - specialEditToolBar->hide(); - viewMenu->addAction(specialEditToolBar->toggleViewAction()); - - emailToolBar = addToolBar(_("Email")); - emailToolBar->setObjectName("emailToolBar"); - emailToolBar->addAction(sendMailAct); - viewMenu->addAction(emailToolBar->toggleViewAction()); +void MainWindow::create_tool_bars() { + file_tool_bar_ = addToolBar(_("File")); + file_tool_bar_->setObjectName("fileToolBar"); + file_tool_bar_->addAction(new_tab_act_); + file_tool_bar_->addAction(open_act_); + file_tool_bar_->addAction(save_act_); + file_tool_bar_->addAction(browser_act_); + view_menu_->addAction(file_tool_bar_->toggleViewAction()); + + crypt_tool_bar_ = addToolBar(_("Operations")); + crypt_tool_bar_->setObjectName("cryptToolBar"); + crypt_tool_bar_->addAction(encrypt_act_); + crypt_tool_bar_->addAction(encrypt_sign_act_); + crypt_tool_bar_->addAction(decrypt_act_); + crypt_tool_bar_->addAction(decrypt_verify_act_); + crypt_tool_bar_->addAction(sign_act_); + crypt_tool_bar_->addAction(verify_act_); + view_menu_->addAction(crypt_tool_bar_->toggleViewAction()); + + key_tool_bar_ = addToolBar(_("Key")); + key_tool_bar_->setObjectName("keyToolBar"); + key_tool_bar_->addAction(open_key_management_act_); + view_menu_->addAction(key_tool_bar_->toggleViewAction()); + + edit_tool_bar_ = addToolBar(_("Edit")); + edit_tool_bar_->setObjectName("editToolBar"); + edit_tool_bar_->addAction(copy_act_); + edit_tool_bar_->addAction(paste_act_); + edit_tool_bar_->addAction(select_all_act_); + edit_tool_bar_->hide(); + view_menu_->addAction(edit_tool_bar_->toggleViewAction()); + + special_edit_tool_bar_ = addToolBar(_("Special Edit")); + special_edit_tool_bar_->setObjectName("specialEditToolBar"); + special_edit_tool_bar_->addAction(quote_act_); + special_edit_tool_bar_->addAction(clean_double_line_breaks_act_); + special_edit_tool_bar_->hide(); + view_menu_->addAction(special_edit_tool_bar_->toggleViewAction()); + + email_tool_bar_ = addToolBar(_("Email")); + email_tool_bar_->setObjectName("emailToolBar"); + email_tool_bar_->addAction(send_mail_act_); + email_tool_bar_->addAction(receive_mail_act_); + view_menu_->addAction(email_tool_bar_->toggleViewAction()); // Add dropdown menu for key import to keytoolbar - importButton = new QToolButton(); - importButton->setMenu(importKeyMenu); - importButton->setPopupMode(QToolButton::InstantPopup); - importButton->setIcon(QIcon(":key_import.png")); - importButton->setToolTip(_("Import key from...")); - importButton->setText(_("Import key")); - keyToolBar->addWidget(importButton); + import_button_ = new QToolButton(); + import_button_->setMenu(import_key_menu_); + import_button_->setPopupMode(QToolButton::InstantPopup); + import_button_->setIcon(QIcon(":key_import.png")); + import_button_->setToolTip(_("Import key from...")); + import_button_->setText(_("Import key")); + key_tool_bar_->addWidget(import_button_); } -void MainWindow::createStatusBar() { +void MainWindow::create_status_bar() { auto* statusBarBox = new QWidget(); auto* statusBarBoxLayout = new QHBoxLayout(); // QPixmap* pixmap; @@ -452,54 +474,54 @@ void MainWindow::createStatusBar() { statusBarBox->setLayout(statusBarBoxLayout); } -void MainWindow::createDockWindows() { +void MainWindow::create_dock_windows() { /* KeyList-Dock window */ - keyListDock = new QDockWidget(_("Key ToolBox"), this); - keyListDock->setObjectName("EncryptDock"); - keyListDock->setAllowedAreas(Qt::LeftDockWidgetArea | - Qt::RightDockWidgetArea); - keyListDock->setMinimumWidth(460); - addDockWidget(Qt::RightDockWidgetArea, keyListDock); - - mKeyList->addListGroupTab( + key_list_dock_ = new QDockWidget(_("Key ToolBox"), this); + key_list_dock_->setObjectName("EncryptDock"); + key_list_dock_->setAllowedAreas(Qt::LeftDockWidgetArea | + Qt::RightDockWidgetArea); + key_list_dock_->setMinimumWidth(460); + addDockWidget(Qt::RightDockWidgetArea, key_list_dock_); + + m_key_list_->AddListGroupTab( _("Default"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, [](const GpgKey& key) -> bool { - return !(key.revoked() || key.disabled() || key.expired()); + return !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); - mKeyList->addListGroupTab( + m_key_list_->AddListGroupTab( _("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, [](const GpgKey& key) -> bool { - return !key.is_private_key() && - !(key.revoked() || key.disabled() || key.expired()); + return !key.IsPrivateKey() && + !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); - mKeyList->addListGroupTab( + m_key_list_->AddListGroupTab( _("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage | KeyListColumn::Validity, [](const GpgKey& key) -> bool { - return key.is_private_key() && - !(key.revoked() || key.disabled() || key.expired()); + return key.IsPrivateKey() && + !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); - mKeyList->slotRefresh(); + m_key_list_->SlotRefresh(); - keyListDock->setWidget(mKeyList); - viewMenu->addAction(keyListDock->toggleViewAction()); + key_list_dock_->setWidget(m_key_list_); + view_menu_->addAction(key_list_dock_->toggleViewAction()); - infoBoardDock = new QDockWidget(_("Information Board"), this); - infoBoardDock->setObjectName("Information Board"); - infoBoardDock->setAllowedAreas(Qt::BottomDockWidgetArea); - addDockWidget(Qt::BottomDockWidgetArea, infoBoardDock); - infoBoardDock->setWidget(infoBoard); - infoBoardDock->widget()->layout()->setContentsMargins(0, 0, 0, 0); - viewMenu->addAction(infoBoardDock->toggleViewAction()); + info_board_dock_ = new QDockWidget(_("Information Board"), this); + info_board_dock_->setObjectName("Information Board"); + info_board_dock_->setAllowedAreas(Qt::BottomDockWidgetArea); + addDockWidget(Qt::BottomDockWidgetArea, info_board_dock_); + info_board_dock_->setWidget(info_board_); + info_board_dock_->widget()->layout()->setContentsMargins(0, 0, 0, 0); + view_menu_->addAction(info_board_dock_->toggleViewAction()); } } // namespace GpgFrontend::UI diff --git a/src/ui/settings/GlobalSettingStation.cpp b/src/ui/settings/GlobalSettingStation.cpp deleted file mode 100644 index e88de93b..00000000 --- a/src/ui/settings/GlobalSettingStation.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "GlobalSettingStation.h" - -std::unique_ptr<GpgFrontend::UI::GlobalSettingStation> - GpgFrontend::UI::GlobalSettingStation::_instance = nullptr; - -GpgFrontend::UI::GlobalSettingStation& -GpgFrontend::UI::GlobalSettingStation::GetInstance() { - if (_instance == nullptr) { - _instance = std::make_unique<GlobalSettingStation>(); - } - return *_instance; -} - -void GpgFrontend::UI::GlobalSettingStation::Sync() noexcept { - using namespace libconfig; - try { - ui_cfg.writeFile(ui_config_path.string().c_str()); - LOG(INFO) << _("Updated ui configuration successfully written to") - << ui_config_path; - - } catch (const FileIOException& fioex) { - LOG(ERROR) << _("I/O error while writing ui configuration file") - << ui_config_path; - } -} - -GpgFrontend::UI::GlobalSettingStation::GlobalSettingStation() noexcept { - using namespace boost::filesystem; - using namespace libconfig; - - el::Loggers::addFlag(el::LoggingFlag::AutoSpacing); - - LOG(INFO) << _("App Path") << app_path; - LOG(INFO) << _("App Configure Path") << app_configure_path; - LOG(INFO) << _("App Data Path") << app_data_path; - LOG(INFO) << _("App Log Path") << app_log_path; - LOG(INFO) << _("App Locale Path") << app_locale_path; - - if (!is_directory(app_configure_path)) create_directory(app_configure_path); - - if (!is_directory(app_data_path)) create_directory(app_data_path); - - if (!is_directory(app_log_path)) create_directory(app_log_path); - - if (!is_directory(ui_config_dir_path)) create_directory(ui_config_dir_path); - - if (!exists(ui_config_path)) { - try { - this->ui_cfg.writeFile(ui_config_path.string().c_str()); - LOG(INFO) << _("UserInterface configuration successfully written to") - << ui_config_path; - - } catch (const FileIOException& fioex) { - LOG(ERROR) - << _("I/O error while writing UserInterface configuration file") - << ui_config_path; - } - } else { - try { - this->ui_cfg.readFile(ui_config_path.string().c_str()); - LOG(INFO) << _("UserInterface configuration successfully read from") - << ui_config_path; - } catch (const FileIOException& fioex) { - LOG(ERROR) << _("I/O error while reading UserInterface configure file"); - } catch (const ParseException& pex) { - LOG(ERROR) << _("Parse error at ") << pex.getFile() << ":" - << pex.getLine() << " - " << pex.getError(); - } - } -} diff --git a/src/ui/settings/GlobalSettingStation.h b/src/ui/settings/GlobalSettingStation.h deleted file mode 100644 index a89bf32d..00000000 --- a/src/ui/settings/GlobalSettingStation.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H -#define GPGFRONTEND_GLOBALSETTINGSTATION_H - -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem/path.hpp> - -#include "GpgFrontendBuildInstallInfo.h" -#include "ui/GpgFrontendUI.h" - -namespace GpgFrontend::UI { - -class GlobalSettingStation : public QObject { - Q_OBJECT - public: - static GlobalSettingStation& GetInstance(); - - GlobalSettingStation() noexcept; - - libconfig::Setting& GetUISettings() noexcept { return ui_cfg.getRoot(); } - - [[nodiscard]] boost::filesystem::path GetAppDir() const { return app_path; } - - [[nodiscard]] boost::filesystem::path GetLogDir() const { - return app_log_path; - } - - [[nodiscard]] boost::filesystem::path GetStandaloneDatabaseDir() const { - auto db_path = app_configure_path / "db"; - if (!boost::filesystem::exists(db_path)) { - boost::filesystem::create_directory(db_path); - } - return db_path; - } - - [[nodiscard]] boost::filesystem::path GetStandaloneGpgBinDir() const { - return app_resource_path / "gpg1.4" / "gpg"; - } - - [[nodiscard]] boost::filesystem::path GetLocaleDir() const { - return app_locale_path; - } - - [[nodiscard]] boost::filesystem::path GetResourceDir() const { - return app_resource_path; - } - - void Sync() noexcept; - - private: - // Program Location - boost::filesystem::path app_path = qApp->applicationDirPath().toStdString(); - - // Program Data Location - boost::filesystem::path app_data_path = - QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) - .toStdString(); - - // Program Data Location - boost::filesystem::path app_log_path = app_data_path / "logs"; - -#ifdef LINUX_INSTALL_BUILD - // Program Data Location - boost::filesystem::path app_resource_path = - boost::filesystem::path(APP_LOCALSTATE_PATH) / "gpgfrontend"; -#else - // Program Data Location - boost::filesystem::path app_resource_path = RESOURCE_DIR_BOOST_PATH(app_path); -#endif - -#ifdef LINUX_INSTALL_BUILD - // Program Data Location - boost::filesystem::path app_locale_path = std::string(APP_LOCALE_PATH); -#else - // Program Data Location - boost::filesystem::path app_locale_path = app_resource_path / "locales"; -#endif - - // Program Configure Location - boost::filesystem::path app_configure_path = - QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) - .toStdString(); - - // Configure File Directory Location - boost::filesystem::path ui_config_dir_path = - app_configure_path / "UserInterface"; - - // UI Configure File Location - boost::filesystem::path ui_config_path = ui_config_dir_path / "ui.cfg"; - - libconfig::Config ui_cfg; - - static std::unique_ptr<GlobalSettingStation> _instance; -}; -} // namespace GpgFrontend::UI - -#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H diff --git a/src/ui/settings/SettingsAdvanced.cpp b/src/ui/settings/SettingsAdvanced.cpp index b64ec8e9..516d4d02 100644 --- a/src/ui/settings/SettingsAdvanced.cpp +++ b/src/ui/settings/SettingsAdvanced.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,67 +8,97 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SettingsAdvanced.h" +#include "core/function/GlobalSettingStation.h" + namespace GpgFrontend::UI { -AdvancedTab::AdvancedTab(QWidget* parent) - : QWidget(parent), - appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - /***************************************** - * Steganography Box - *****************************************/ - auto* steganoBox = new QGroupBox(_("Show Steganography Options")); - auto* steganoBoxLayout = new QHBoxLayout(); - steganoCheckBox = new QCheckBox(_("Show Steganographic Options."), this); - steganoBoxLayout->addWidget(steganoCheckBox); - steganoBox->setLayout(steganoBoxLayout); +AdvancedTab::AdvancedTab(QWidget* parent) : QWidget(parent) { + auto* stegano_box = new QGroupBox(_("Show Steganography Options")); + auto* stegano_box_layout = new QHBoxLayout(); + stegano_check_box_ = new QCheckBox(_("Show Steganography Options."), this); + stegano_box_layout->addWidget(stegano_check_box_); + stegano_box->setLayout(stegano_box_layout); - auto* pubkeyExchangeBox = new QGroupBox(_("Pubkey Exchange")); - auto* pubkeyExchangeBoxLayout = new QHBoxLayout(); - autoPubkeyExchangeCheckBox = new QCheckBox(_("Auto Pubkey Exchange"), this); - pubkeyExchangeBoxLayout->addWidget(autoPubkeyExchangeCheckBox); - pubkeyExchangeBox->setLayout(pubkeyExchangeBoxLayout); + auto* pubkey_exchange_box = new QGroupBox(_("Pubkey Exchange")); + auto* pubkey_exchange_box_layout = new QHBoxLayout(); + auto_pubkey_exchange_check_box_ = + new QCheckBox(_("Auto Pubkey Exchange"), this); + pubkey_exchange_box_layout->addWidget(auto_pubkey_exchange_check_box_); + pubkey_exchange_box->setLayout(pubkey_exchange_box_layout); - auto* mainLayout = new QVBoxLayout; - mainLayout->addWidget(steganoBox); - mainLayout->addWidget(pubkeyExchangeBox); - setSettings(); - mainLayout->addStretch(1); - setLayout(mainLayout); + auto* main_layout = new QVBoxLayout; + main_layout->addWidget(stegano_box); + main_layout->addWidget(pubkey_exchange_box); + SetSettings(); + main_layout->addStretch(1); + setLayout(main_layout); } -void AdvancedTab::setSettings() { - if (settings.value("advanced/steganography").toBool()) { - steganoCheckBox->setCheckState(Qt::Checked); +void AdvancedTab::SetSettings() { + auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + try { + bool stegano_checked = settings.lookup("advanced.stegano_checked"); + if (stegano_checked) stegano_check_box_->setCheckState(Qt::Checked); + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") << _("stegano_checked"); } - if (settings.value("advanced/autoPubkeyExchange").toBool()) { - autoPubkeyExchangeCheckBox->setCheckState(Qt::Checked); + + try { + bool auto_pubkey_exchange_checked = + settings.lookup("advanced.auto_pubkey_exchange_checked"); + if (auto_pubkey_exchange_checked) + auto_pubkey_exchange_check_box_->setCheckState(Qt::Checked); + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") + << _("auto_pubkey_exchange_checked"); } } -void AdvancedTab::applySettings() { - settings.setValue("advanced/steganography", steganoCheckBox->isChecked()); - settings.setValue("advanced/autoPubkeyExchange", - autoPubkeyExchangeCheckBox->isChecked()); +void AdvancedTab::ApplySettings() { + auto& settings = + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); + + if (!settings.exists("advanced") || + settings.lookup("advanced").getType() != libconfig::Setting::TypeGroup) + settings.add("advanced", libconfig::Setting::TypeGroup); + + auto& advanced = settings["advanced"]; + + if (!advanced.exists("stegano_checked")) + advanced.add("stegano_checked", libconfig::Setting::TypeBoolean) = + stegano_check_box_->isChecked(); + else { + advanced["stegano_checked"] = stegano_check_box_->isChecked(); + } + + if (!advanced.exists("auto_pubkey_exchange_checked")) + advanced.add("auto_pubkey_exchange_checked", + libconfig::Setting::TypeBoolean) = + auto_pubkey_exchange_check_box_->isChecked(); + else { + advanced["auto_pubkey_exchange_checked"] = + auto_pubkey_exchange_check_box_->isChecked(); + } } } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsAdvanced.h b/src/ui/settings/SettingsAdvanced.h index d8ec8089..c1a3d5a6 100644 --- a/src/ui/settings/SettingsAdvanced.h +++ b/src/ui/settings/SettingsAdvanced.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -34,20 +38,17 @@ class AdvancedTab : public QWidget { public: explicit AdvancedTab(QWidget* parent = nullptr); - void setSettings(); + void SetSettings(); - void applySettings(); + void ApplySettings(); private: - QString appPath; - QSettings settings; - - QCheckBox* steganoCheckBox; - QCheckBox* autoPubkeyExchangeCheckBox; + QCheckBox* stegano_check_box_; + QCheckBox* auto_pubkey_exchange_check_box_; signals: - void signalRestartNeeded(bool needed); + void SignalRestartNeeded(bool needed); }; } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsAppearance.cpp b/src/ui/settings/SettingsAppearance.cpp index 49dc349c..7e54c9f8 100644 --- a/src/ui/settings/SettingsAppearance.cpp +++ b/src/ui/settings/SettingsAppearance.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,25 +8,28 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SettingsAppearance.h" -#include "GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" +#include "ui/struct/SettingsObject.h" namespace GpgFrontend::UI { @@ -33,19 +38,19 @@ AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { * Icon-Size-Box *****************************************/ auto* iconSizeBox = new QGroupBox(_("Icon Size")); - iconSizeGroup = new QButtonGroup(); - iconSizeSmall = new QRadioButton(_("small")); - iconSizeMedium = new QRadioButton(_("medium")); - iconSizeLarge = new QRadioButton(_("large")); + icon_size_group_ = new QButtonGroup(); + icon_size_small_ = new QRadioButton(_("small")); + icon_size_medium_ = new QRadioButton(_("medium")); + icon_size_large_ = new QRadioButton(_("large")); - iconSizeGroup->addButton(iconSizeSmall, 1); - iconSizeGroup->addButton(iconSizeMedium, 2); - iconSizeGroup->addButton(iconSizeLarge, 3); + icon_size_group_->addButton(icon_size_small_, 1); + icon_size_group_->addButton(icon_size_medium_, 2); + icon_size_group_->addButton(icon_size_large_, 3); auto* iconSizeBoxLayout = new QHBoxLayout(); - iconSizeBoxLayout->addWidget(iconSizeSmall); - iconSizeBoxLayout->addWidget(iconSizeMedium); - iconSizeBoxLayout->addWidget(iconSizeLarge); + iconSizeBoxLayout->addWidget(icon_size_small_); + iconSizeBoxLayout->addWidget(icon_size_medium_); + iconSizeBoxLayout->addWidget(icon_size_large_); iconSizeBox->setLayout(iconSizeBoxLayout); @@ -53,19 +58,19 @@ AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { * Icon-Style-Box *****************************************/ auto* iconStyleBox = new QGroupBox(_("Icon Style")); - iconStyleGroup = new QButtonGroup(); - iconTextButton = new QRadioButton(_("just text")); - iconIconsButton = new QRadioButton(_("just icons")); - iconAllButton = new QRadioButton(_("text and icons")); + icon_style_group_ = new QButtonGroup(); + icon_text_button_ = new QRadioButton(_("just text")); + icon_icons_button_ = new QRadioButton(_("just icons")); + icon_all_button_ = new QRadioButton(_("text and icons")); - iconStyleGroup->addButton(iconTextButton, 1); - iconStyleGroup->addButton(iconIconsButton, 2); - iconStyleGroup->addButton(iconAllButton, 3); + icon_style_group_->addButton(icon_text_button_, 1); + icon_style_group_->addButton(icon_icons_button_, 2); + icon_style_group_->addButton(icon_all_button_, 3); auto* iconStyleBoxLayout = new QHBoxLayout(); - iconStyleBoxLayout->addWidget(iconTextButton); - iconStyleBoxLayout->addWidget(iconIconsButton); - iconStyleBoxLayout->addWidget(iconAllButton); + iconStyleBoxLayout->addWidget(icon_text_button_); + iconStyleBoxLayout->addWidget(icon_icons_button_); + iconStyleBoxLayout->addWidget(icon_all_button_); iconStyleBox->setLayout(iconStyleBoxLayout); @@ -74,9 +79,9 @@ AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { *****************************************/ auto* windowSizeBox = new QGroupBox(_("Window State")); auto* windowSizeBoxLayout = new QHBoxLayout(); - windowSizeCheckBox = + window_size_check_box_ = new QCheckBox(_("Save window size and position on exit."), this); - windowSizeBoxLayout->addWidget(windowSizeCheckBox); + windowSizeBoxLayout->addWidget(window_size_check_box_); windowSizeBox->setLayout(windowSizeBoxLayout); /***************************************** @@ -85,12 +90,12 @@ AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { auto* infoBoardBox = new QGroupBox(_("Information Board")); auto* infoBoardLayout = new QHBoxLayout(); - infoBoardFontSizeSpin = new QSpinBox(); - infoBoardFontSizeSpin->setRange(9, 18); - infoBoardFontSizeSpin->setValue(10); - infoBoardFontSizeSpin->setSingleStep(1); + info_board_font_size_spin_ = new QSpinBox(); + info_board_font_size_spin_->setRange(9, 18); + info_board_font_size_spin_->setValue(10); + info_board_font_size_spin_->setSingleStep(1); infoBoardLayout->addWidget(new QLabel(_("Font Size in Information Board"))); - infoBoardLayout->addWidget(infoBoardFontSizeSpin); + infoBoardLayout->addWidget(info_board_font_size_spin_); infoBoardBox->setLayout(infoBoardLayout); auto* mainLayout = new QVBoxLayout; @@ -99,7 +104,7 @@ AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { mainLayout->addWidget(windowSizeBox); mainLayout->addWidget(infoBoardBox); mainLayout->addStretch(1); - setSettings(); + SetSettings(); setLayout(mainLayout); } @@ -108,89 +113,64 @@ AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { * and set the buttons and checkboxes * appropriately **********************************/ -void AppearanceTab::setSettings() { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - try { - int width = settings.lookup("window.icon_size.width"); - int height = settings.lookup("window.icon_size.height"); - - auto icon_size = QSize(width, height); - - switch (icon_size.height()) { - case 12: - iconSizeSmall->setChecked(true); - break; - case 24: - iconSizeMedium->setChecked(true); - break; - case 32: - iconSizeLarge->setChecked(true); - break; - } - - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("icon_size"); - } +void AppearanceTab::SetSettings() { - // icon_style - try { - int s_icon_style = settings.lookup("window.icon_style"); - auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); - - switch (icon_style) { - case Qt::ToolButtonTextOnly: - iconTextButton->setChecked(true); - break; - case Qt::ToolButtonIconOnly: - iconIconsButton->setChecked(true); - break; - case Qt::ToolButtonTextUnderIcon: - iconAllButton->setChecked(true); - break; - default: - break; - } - - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("icon_style"); - } + SettingsObject main_windows_state("main_windows_state"); + + int width = main_windows_state.Check("icon_size").Check("width", 24), + height = main_windows_state.Check("icon_size").Check("height", 24); - // Window Save and Position - try { - bool window_save = settings.lookup("window.window_save"); - if (window_save) windowSizeCheckBox->setCheckState(Qt::Checked); + auto icon_size = QSize(width, height); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("window_save"); + switch (icon_size.width()) { + case 12: + icon_size_small_->setChecked(true); + break; + case 24: + icon_size_medium_->setChecked(true); + break; + case 32: + icon_size_large_->setChecked(true); + break; } - // info board font size - try { - int info_font_size = settings.lookup("window.info_font_size"); - if (info_font_size < 9 || info_font_size > 18) info_font_size = 10; - infoBoardFontSizeSpin->setValue(info_font_size); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("info_font_size"); + // icon_style + int s_icon_style = + main_windows_state.Check("icon_style", Qt::ToolButtonTextUnderIcon); + auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); + + switch (icon_style) { + case Qt::ToolButtonTextOnly: + icon_text_button_->setChecked(true); + break; + case Qt::ToolButtonIconOnly: + icon_icons_button_->setChecked(true); + break; + case Qt::ToolButtonTextUnderIcon: + icon_all_button_->setChecked(true); + break; + default: + break; } + + bool window_save = main_windows_state.Check("window_save", true); + if (window_save) window_size_check_box_->setCheckState(Qt::Checked); + + auto info_font_size = main_windows_state.Check("info_font_size", 10); + if (info_font_size < 9 || info_font_size > 18) info_font_size = 10; + info_board_font_size_spin_->setValue(info_font_size); } /*********************************** * get the values of the buttons and * write them to settings-file *************************************/ -void AppearanceTab::applySettings() { - auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); - - if (!settings.exists("window") || - settings.lookup("window").getType() != libconfig::Setting::TypeGroup) - settings.add("window", libconfig::Setting::TypeGroup); +void AppearanceTab::ApplySettings() { - auto& window = settings["window"]; + SettingsObject main_windows_state("main_windows_state"); int icon_size = 24; - switch (iconSizeGroup->checkedId()) { + switch (icon_size_group_->checkedId()) { case 1: icon_size = 12; break; @@ -202,18 +182,11 @@ void AppearanceTab::applySettings() { break; } - if (!window.exists("icon_size")) { - auto& icon_size_settings = - window.add("icon_size", libconfig::Setting::TypeGroup); - icon_size_settings.add("width", libconfig::Setting::TypeInt) = icon_size; - icon_size_settings.add("height", libconfig::Setting::TypeInt) = icon_size; - } else { - window["icon_size"]["width"] = icon_size; - window["icon_size"]["height"] = icon_size; - } + main_windows_state["icon_size"]["width"] = icon_size; + main_windows_state["icon_size"]["height"] = icon_size; auto icon_style = Qt::ToolButtonTextUnderIcon; - switch (iconStyleGroup->checkedId()) { + switch (icon_style_group_->checkedId()) { case 1: icon_style = Qt::ToolButtonTextOnly; break; @@ -225,25 +198,12 @@ void AppearanceTab::applySettings() { break; } - if (!window.exists("icon_style")) { - window.add("icon_style", libconfig::Setting::TypeInt) = icon_style; - } else { - window["icon_style"] = icon_style; - } + main_windows_state["icon_style"] = icon_style; - if (!window.exists("window_save")) { - window.add("window_save", libconfig::Setting::TypeBoolean) = - windowSizeCheckBox->isChecked(); - } else { - window["window_save"] = windowSizeCheckBox->isChecked(); - } + main_windows_state["window_save"] = window_size_check_box_->isChecked(); + + main_windows_state["info_font_size"] = info_board_font_size_spin_->value(); - if (!window.exists("info_font_size")) { - window.add("info_font_size", libconfig::Setting::TypeBoolean) = - infoBoardFontSizeSpin->value(); - } else { - window["info_font_size"] = infoBoardFontSizeSpin->value(); - } } } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsAppearance.h b/src/ui/settings/SettingsAppearance.h index c0a0247b..7110d992 100644 --- a/src/ui/settings/SettingsAppearance.h +++ b/src/ui/settings/SettingsAppearance.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -33,26 +37,44 @@ class AppearanceTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Appearance Tab object + * + * @param parent + */ explicit AppearanceTab(QWidget* parent = nullptr); - void setSettings(); + /** + * @brief Set the Settings object + * + */ + void SetSettings(); - void applySettings(); + /** + * @brief + * + */ + void ApplySettings(); private: - QButtonGroup* iconStyleGroup; - QRadioButton* iconSizeSmall; - QRadioButton* iconSizeMedium; - QRadioButton* iconSizeLarge; - QButtonGroup* iconSizeGroup; - QRadioButton* iconTextButton; - QRadioButton* iconIconsButton; - QRadioButton* iconAllButton; - QSpinBox* infoBoardFontSizeSpin; - QCheckBox* windowSizeCheckBox; + QButtonGroup* icon_style_group_; ///< + QRadioButton* icon_size_small_; ///< + QRadioButton* icon_size_medium_; ///< + QRadioButton* icon_size_large_; ///< + QButtonGroup* icon_size_group_; ///< + QRadioButton* icon_text_button_; ///< + QRadioButton* icon_icons_button_; ///< + QRadioButton* icon_all_button_; ///< + QSpinBox* info_board_font_size_spin_; ///< + QCheckBox* window_size_check_box_; ///< signals: + /** + * @brief + * + * @param needed + */ void signalRestartNeeded(bool needed); }; diff --git a/src/ui/settings/SettingsDialog.cpp b/src/ui/settings/SettingsDialog.cpp index 01e4094f..2c23858f 100644 --- a/src/ui/settings/SettingsDialog.cpp +++ b/src/ui/settings/SettingsDialog.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,119 +8,109 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SettingsDialog.h" -#include "GlobalSettingStation.h" -#include "SettingsAdvanced.h" -#include "SettingsAppearance.h" -#include "SettingsGeneral.h" -#include "SettingsKeyServer.h" -#include "SettingsNetwork.h" +#include "core/function/GlobalSettingStation.h" +#include "ui/settings/SettingsAdvanced.h" +#include "ui/settings/SettingsAppearance.h" +#include "ui/settings/SettingsGeneral.h" +#include "ui/settings/SettingsKeyServer.h" +#include "ui/settings/SettingsNetwork.h" +#include "ui/main_window/MainWindow.h" #ifdef SMTP_SUPPORT -#include "SettingsSendMail.h" +#include "ui/settings/SettingsSendMail.h" #endif namespace GpgFrontend::UI { SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent) { - - tabWidget = new QTabWidget(); - generalTab = new GeneralTab(); - appearanceTab = new AppearanceTab(); + tab_widget_ = new QTabWidget(); + general_tab_ = new GeneralTab(); + appearance_tab_ = new AppearanceTab(); #ifdef SMTP_SUPPORT - sendMailTab = new SendMailTab(); + send_mail_tab_ = new SendMailTab(); #endif - keyserverTab = new KeyserverTab(); - networkTab = new NetworkTab(); + key_server_tab_ = new KeyserverTab(); + network_tab_ = new NetworkTab(); #ifdef ADVANCED_SUPPORT advancedTab = new AdvancedTab; #endif - tabWidget->addTab(generalTab, _("General")); - tabWidget->addTab(appearanceTab, _("Appearance")); + tab_widget_->addTab(general_tab_, _("General")); + tab_widget_->addTab(appearance_tab_, _("Appearance")); #ifdef SMTP_SUPPORT - tabWidget->addTab(sendMailTab, _("Send Mail")); + tab_widget_->addTab(send_mail_tab_, _("Send Mail")); #endif - tabWidget->addTab(keyserverTab, _("Key Server")); + tab_widget_->addTab(key_server_tab_, _("Key Server")); // tabWidget->addTab(gpgPathsTab, _("Gpg paths")); - tabWidget->addTab(networkTab, _("Network")); + tab_widget_->addTab(network_tab_, _("Network")); #ifdef ADVANCED_SUPPORT tabWidget->addTab(advancedTab, _("Advanced")); #endif - buttonBox = + button_box_ = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotAccept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(button_box_, &QDialogButtonBox::accepted, this, &SettingsDialog::SlotAccept); + connect(button_box_, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); auto* mainLayout = new QVBoxLayout; - mainLayout->addWidget(tabWidget); + mainLayout->addWidget(tab_widget_); mainLayout->stretch(0); - mainLayout->addWidget(buttonBox); + mainLayout->addWidget(button_box_); mainLayout->stretch(0); setLayout(mainLayout); setWindowTitle(_("Settings")); - // slots for handling the restartneeded member - this->slotSetRestartNeeded(false); - connect(generalTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); - connect(appearanceTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); -#ifdef SMTP_SUPPORT - connect(sendMailTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); -#endif - connect(keyserverTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); -#ifdef ADVANCED_SUPPORT - connect(advancedTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); -#endif - - connect(this, SIGNAL(signalRestartNeeded(bool)), parent, - SLOT(slotSetRestartNeeded(bool))); + // slots for handling the restart needed member + this->slot_set_restart_needed(false); + connect(general_tab_, &GeneralTab::SignalRestartNeeded, this, + &SettingsDialog::slot_set_restart_needed); + connect(this, &SettingsDialog::SignalRestartNeeded, qobject_cast<MainWindow *>(parent), &MainWindow::SlotSetRestartNeeded); this->setMinimumSize(480, 680); this->adjustSize(); this->show(); } -bool SettingsDialog::getRestartNeeded() const { return this->restartNeeded; } +bool SettingsDialog::get_restart_needed() const { + return this->restart_needed_; +} -void SettingsDialog::slotSetRestartNeeded(bool needed) { - this->restartNeeded = needed; +void SettingsDialog::slot_set_restart_needed(bool needed) { + this->restart_needed_ = needed; } -void SettingsDialog::slotAccept() { +void SettingsDialog::SlotAccept() { LOG(INFO) << "Called"; - generalTab->applySettings(); + general_tab_->ApplySettings(); #ifdef SMTP_SUPPORT - sendMailTab->applySettings(); + send_mail_tab_->ApplySettings(); #endif - appearanceTab->applySettings(); - keyserverTab->applySettings(); - networkTab->applySettings(); + appearance_tab_->ApplySettings(); + key_server_tab_->ApplySettings(); + network_tab_->ApplySettings(); #ifdef ADVANCED_SUPPORT advancedTab->applySettings(); #endif @@ -126,16 +118,16 @@ void SettingsDialog::slotAccept() { LOG(INFO) << "apply done"; // write settings to filesystem - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); - LOG(INFO) << "restart needed" << getRestartNeeded(); - if (getRestartNeeded()) { - emit signalRestartNeeded(true); + LOG(INFO) << "restart needed" << get_restart_needed(); + if (get_restart_needed()) { + emit SignalRestartNeeded(true); } close(); } -QHash<QString, QString> SettingsDialog::listLanguages() { +QHash<QString, QString> SettingsDialog::ListLanguages() { QHash<QString, QString> languages; languages.insert(QString(), _("System Default")); diff --git a/src/ui/settings/SettingsDialog.h b/src/ui/settings/SettingsDialog.h index da3bdba3..000e6599 100755 --- a/src/ui/settings/SettingsDialog.h +++ b/src/ui/settings/SettingsDialog.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -44,43 +48,77 @@ class NetworkTab; class AdvancedTab; #endif +/** + * @brief + * + */ class SettingsDialog : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Settings Dialog object + * + * @param parent + */ explicit SettingsDialog(QWidget* parent = nullptr); - GeneralTab* generalTab; + GeneralTab* general_tab_; ///< #ifdef SMTP_SUPPORT - SendMailTab* sendMailTab; + SendMailTab* send_mail_tab_; ///< #endif - AppearanceTab* appearanceTab; - KeyserverTab* keyserverTab; - NetworkTab* networkTab; + AppearanceTab* appearance_tab_; ///< + KeyserverTab* key_server_tab_; ///< + NetworkTab* network_tab_; ///< #ifdef ADVANCED_SUPPORT - AdvancedTab* advancedTab; + AdvancedTab* advanced_tab_; ///< #endif - static QHash<QString, QString> listLanguages(); + /** + * @brief + * + * @return QHash<QString, QString> + */ + static QHash<QString, QString> ListLanguages(); public slots: - void slotAccept(); + /** + * @brief + * + */ + void SlotAccept(); signals: - void signalRestartNeeded(bool needed); + /** + * @brief + * + * @param needed + */ + void SignalRestartNeeded(bool needed); private: - QTabWidget* tabWidget; - QDialogButtonBox* buttonBox; - bool restartNeeded{}; - - bool getRestartNeeded() const; + QTabWidget* tab_widget_; ///< + QDialogButtonBox* button_box_; ///< + bool restart_needed_{}; ///< + + /** + * @brief Get the Restart Needed object + * + * @return true + * @return false + */ + bool get_restart_needed() const; private slots: - void slotSetRestartNeeded(bool needed); + /** + * @brief + * + * @param needed + */ + void slot_set_restart_needed(bool needed); }; } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsGeneral.cpp b/src/ui/settings/SettingsGeneral.cpp index 4f8ef544..3c7bca32 100644 --- a/src/ui/settings/SettingsGeneral.cpp +++ b/src/ui/settings/SettingsGeneral.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -28,45 +32,45 @@ #include "SettingsDialog.h" #endif -#include "GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" #include "ui_GeneralSettings.h" namespace GpgFrontend::UI { GeneralTab::GeneralTab(QWidget* parent) - : QWidget(parent), ui(std::make_shared<Ui_GeneralSettings>()) { - ui->setupUi(this); + : QWidget(parent), ui_(std::make_shared<Ui_GeneralSettings>()) { + ui_->setupUi(this); - ui->saveCheckedKeysBox->setTitle(_("Save Checked Keys")); - ui->saveCheckedKeysCheckBox->setText( + ui_->saveCheckedKeysBox->setTitle(_("Save Checked Keys")); + ui_->saveCheckedKeysCheckBox->setText( _("Save checked private keys on exit and restore them on next start.")); - ui->longerKeyExpirationDateBox->setTitle(_("Longer Key Expiration Date")); - ui->longerKeyExpirationDateCheckBox->setText( + ui_->longerKeyExpirationDateBox->setTitle(_("Longer Key Expiration Date")); + ui_->longerKeyExpirationDateCheckBox->setText( _("Unlock key expiration date setting up to 30 years.")); - ui->importConfirmationBox->setTitle(_("Confirm drag'n'drop key import")); - ui->importConfirmationCheckBox->setText( + ui_->importConfirmationBox->setTitle(_("Confirm drag'n'drop key import")); + ui_->importConfirmationCheckBox->setText( _("Import files dropped on the Key List without confirmation.")); - ui->asciiModeBox->setTitle(_("ASCII Mode")); - ui->asciiModeCheckBox->setText( + ui_->asciiModeBox->setTitle(_("ASCII Mode")); + ui_->asciiModeCheckBox->setText( _("ASCII encoding is not used when file encrypting and " "signing.")); - ui->langBox->setTitle(_("Language")); - ui->langNoteLabel->setText( + ui_->langBox->setTitle(_("Language")); + ui_->langNoteLabel->setText( "<b>" + QString(_("NOTE")) + _(": ") + "</b>" + _("GpgFrontend will restart automatically if you change the language!")); #ifdef MULTI_LANG_SUPPORT - lang = SettingsDialog::listLanguages(); - for (const auto& l : lang) { - ui->langSelectBox->addItem(l); + lang_ = SettingsDialog::ListLanguages(); + for (const auto& l : lang_) { + ui_->langSelectBox->addItem(l); } - connect(ui->langSelectBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(slotLanguageChanged())); + connect(ui_->langSelectBox, qOverload<int>(&QComboBox::currentIndexChanged), + this, &GeneralTab::slot_language_changed); #endif - setSettings(); + SetSettings(); } /********************************** @@ -74,12 +78,12 @@ GeneralTab::GeneralTab(QWidget* parent) * and set the buttons and checkboxes * appropriately **********************************/ -void GeneralTab::setSettings() { +void GeneralTab::SetSettings() { auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); try { bool save_key_checked = settings.lookup("general.save_key_checked"); if (save_key_checked) - ui->saveCheckedKeysCheckBox->setCheckState(Qt::Checked); + ui_->saveCheckedKeysCheckBox->setCheckState(Qt::Checked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked"); } @@ -89,7 +93,7 @@ void GeneralTab::setSettings() { settings.lookup("general.longer_expiration_date"); LOG(INFO) << "longer_expiration_date" << longer_expiration_date; if (longer_expiration_date) - ui->longerKeyExpirationDateCheckBox->setCheckState(Qt::Checked); + ui_->longerKeyExpirationDateCheckBox->setCheckState(Qt::Checked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date"); } @@ -97,13 +101,13 @@ void GeneralTab::setSettings() { #ifdef MULTI_LANG_SUPPORT try { std::string lang_key = settings.lookup("general.lang"); - QString lang_value = lang.value(lang_key.c_str()); + QString lang_value = lang_.value(lang_key.c_str()); LOG(INFO) << "lang settings current" << lang_value.toStdString(); - if (!lang.empty()) { - ui->langSelectBox->setCurrentIndex( - ui->langSelectBox->findText(lang_value)); + if (!lang_.empty()) { + ui_->langSelectBox->setCurrentIndex( + ui_->langSelectBox->findText(lang_value)); } else { - ui->langSelectBox->setCurrentIndex(0); + ui_->langSelectBox->setCurrentIndex(0); } } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("lang"); @@ -114,7 +118,7 @@ void GeneralTab::setSettings() { bool confirm_import_keys = settings.lookup("general.confirm_import_keys"); LOG(INFO) << "confirm_import_keys" << confirm_import_keys; if (confirm_import_keys) - ui->importConfirmationCheckBox->setCheckState(Qt::Checked); + ui_->importConfirmationCheckBox->setCheckState(Qt::Checked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("confirm_import_keys"); } @@ -124,7 +128,7 @@ void GeneralTab::setSettings() { settings.lookup("general.non_ascii_when_export"); LOG(INFO) << "non_ascii_when_export" << non_ascii_when_export; if (non_ascii_when_export) - ui->asciiModeCheckBox->setCheckState(Qt::Checked); + ui_->asciiModeCheckBox->setCheckState(Qt::Checked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export"); } @@ -134,9 +138,9 @@ void GeneralTab::setSettings() { * get the values of the buttons and * write them to settings-file *************************************/ -void GeneralTab::applySettings() { +void GeneralTab::ApplySettings() { auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); if (!settings.exists("general") || settings.lookup("general").getType() != libconfig::Setting::TypeGroup) @@ -146,46 +150,47 @@ void GeneralTab::applySettings() { if (!general.exists("longer_expiration_date")) general.add("longer_expiration_date", libconfig::Setting::TypeBoolean) = - ui->longerKeyExpirationDateCheckBox->isChecked(); + ui_->longerKeyExpirationDateCheckBox->isChecked(); else { general["longer_expiration_date"] = - ui->longerKeyExpirationDateCheckBox->isChecked(); + ui_->longerKeyExpirationDateCheckBox->isChecked(); } if (!general.exists("save_key_checked")) general.add("save_key_checked", libconfig::Setting::TypeBoolean) = - ui->saveCheckedKeysCheckBox->isChecked(); + ui_->saveCheckedKeysCheckBox->isChecked(); else { - general["save_key_checked"] = ui->saveCheckedKeysCheckBox->isChecked(); + general["save_key_checked"] = ui_->saveCheckedKeysCheckBox->isChecked(); } if (!general.exists("non_ascii_when_export")) general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) = - ui->asciiModeCheckBox->isChecked(); + ui_->asciiModeCheckBox->isChecked(); else { - general["non_ascii_when_export"] = ui->asciiModeCheckBox->isChecked(); + general["non_ascii_when_export"] = ui_->asciiModeCheckBox->isChecked(); } #ifdef MULTI_LANG_SUPPORT if (!general.exists("lang")) general.add("lang", libconfig::Setting::TypeBoolean) = - lang.key(ui->langSelectBox->currentText()).toStdString(); + lang_.key(ui_->langSelectBox->currentText()).toStdString(); else { - general["lang"] = lang.key(ui->langSelectBox->currentText()).toStdString(); + general["lang"] = + lang_.key(ui_->langSelectBox->currentText()).toStdString(); } #endif if (!general.exists("confirm_import_keys")) general.add("confirm_import_keys", libconfig::Setting::TypeBoolean) = - ui->importConfirmationCheckBox->isChecked(); + ui_->importConfirmationCheckBox->isChecked(); else { general["confirm_import_keys"] = - ui->importConfirmationCheckBox->isChecked(); + ui_->importConfirmationCheckBox->isChecked(); } } #ifdef MULTI_LANG_SUPPORT -void GeneralTab::slotLanguageChanged() { emit signalRestartNeeded(true); } +void GeneralTab::slot_language_changed() { emit SignalRestartNeeded(true); } #endif } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsGeneral.h b/src/ui/settings/SettingsGeneral.h index a5e2b8d0..b3e7d904 100644 --- a/src/ui/settings/SettingsGeneral.h +++ b/src/ui/settings/SettingsGeneral.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -32,37 +36,63 @@ class Ui_GeneralSettings; namespace GpgFrontend::UI { class KeyList; +/** + * @brief + * + */ class GeneralTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new General Tab object + * + * @param parent + */ explicit GeneralTab(QWidget* parent = nullptr); - void setSettings(); + /** + * @brief Set the Settings object + * + */ + void SetSettings(); - void applySettings(); + /** + * @brief + * + */ + void ApplySettings(); + + signals: + + /** + * @brief + * + * @param needed + */ + void SignalRestartNeeded(bool needed); private: - std::shared_ptr<Ui_GeneralSettings> ui; + std::shared_ptr<Ui_GeneralSettings> ui_; ///< #ifdef MULTI_LANG_SUPPORT - QHash<QString, QString> lang; + QHash<QString, QString> lang_; ///< #endif - std::vector<std::string> keyIdsList; + std::vector<std::string> key_ids_list_; ///< - KeyList* mKeyList{}; + KeyList* m_key_list_{}; ///< private slots: #ifdef MULTI_LANG_SUPPORT - - void slotLanguageChanged(); + /** + * @brief + * + */ + void slot_language_changed(); #endif - signals: - - void signalRestartNeeded(bool needed); }; } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsKeyServer.cpp b/src/ui/settings/SettingsKeyServer.cpp index 0cba7b51..f2eaf9a9 100644 --- a/src/ui/settings/SettingsKeyServer.cpp +++ b/src/ui/settings/SettingsKeyServer.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,104 +8,108 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SettingsKeyServer.h" -#include "GlobalSettingStation.h" -#include "ui/function/TestListedKeyServerThread.h" +#include "core/function/GlobalSettingStation.h" +#include "ui/struct/SettingsObject.h" +#include "ui/thread/ListedKeyServerTestThread.h" #include "ui_KeyServerSettings.h" namespace GpgFrontend::UI { KeyserverTab::KeyserverTab(QWidget* parent) - : QWidget(parent), ui(std::make_shared<Ui_KeyServerSettings>()) { - ui->setupUi(this); - ui->keyServerListTable->setSizeAdjustPolicy( + : QWidget(parent), ui_(std::make_shared<Ui_KeyServerSettings>()) { + ui_->setupUi(this); + ui_->keyServerListTable->setSizeAdjustPolicy( QAbstractScrollArea::AdjustToContents); - connect(ui->addKeyServerPushButton, &QPushButton::clicked, this, - &KeyserverTab::addKeyServer); - connect(ui->testKeyServerButton, &QPushButton::clicked, this, - &KeyserverTab::slotTestListedKeyServer); + connect(ui_->addKeyServerPushButton, &QPushButton::clicked, this, + &KeyserverTab::slot_add_key_server); + connect(ui_->testKeyServerButton, &QPushButton::clicked, this, + &KeyserverTab::slot_test_listed_key_server); - ui->keyServerListGroupBox->setTitle(_("Keyserver List")); - ui->operationsGroupBox->setTitle(_("Operations")); + ui_->keyServerListGroupBox->setTitle(_("Keyserver List")); + ui_->operationsGroupBox->setTitle(_("Operations")); - ui->keyServerListTable->horizontalHeaderItem(0)->setText(_("Default")); - ui->keyServerListTable->horizontalHeaderItem(1)->setText( + ui_->keyServerListTable->horizontalHeaderItem(0)->setText(_("Default")); + ui_->keyServerListTable->horizontalHeaderItem(1)->setText( _("Keyserver Address")); - ui->keyServerListTable->horizontalHeaderItem(2)->setText(_("Security")); - ui->keyServerListTable->horizontalHeaderItem(3)->setText(_("Available")); + ui_->keyServerListTable->horizontalHeaderItem(2)->setText(_("Security")); + ui_->keyServerListTable->horizontalHeaderItem(3)->setText(_("Available")); - ui->addKeyServerPushButton->setText(_("Add")); - ui->testKeyServerButton->setText(_("Test Listed Keyserver")); + ui_->addKeyServerPushButton->setText(_("Add")); + ui_->testKeyServerButton->setText(_("Test Listed Keyserver")); - ui->tipsLabel->setText(_("Tips: Please Double-click table item to edit it.")); - ui->actionDelete_Selected_Key_Server->setText(_("Delete Selected")); - ui->actionDelete_Selected_Key_Server->setToolTip( + ui_->tipsLabel->setText( + _("Tips: Please Double-click table item to edit it.")); + ui_->actionDelete_Selected_Key_Server->setText(_("Delete Selected")); + ui_->actionDelete_Selected_Key_Server->setToolTip( _("Delete Selected Key Server")); - ui->actionSet_As_Default->setText(_("Set As Default")); - ui->actionSet_As_Default->setToolTip(_("Set As Default")); + ui_->actionSet_As_Default->setText(_("Set As Default")); + ui_->actionSet_As_Default->setToolTip(_("Set As Default")); - popupMenu = new QMenu(this); - popupMenu->addAction(ui->actionSet_As_Default); - popupMenu->addAction(ui->actionDelete_Selected_Key_Server); + popup_menu_ = new QMenu(this); + popup_menu_->addAction(ui_->actionSet_As_Default); + popup_menu_->addAction(ui_->actionDelete_Selected_Key_Server); - connect(ui->keyServerListTable, &QTableWidget::itemChanged, + connect(ui_->keyServerListTable, &QTableWidget::itemChanged, [=](QTableWidgetItem* item) { LOG(INFO) << "item edited" << item->column(); if (item->column() != 1) return; - const auto row_size = ui->keyServerListTable->rowCount(); + const auto row_size = ui_->keyServerListTable->rowCount(); // Update Actions if (row_size > 0) { - keyServerStrList.clear(); + key_server_str_list_.clear(); for (int i = 0; i < row_size; i++) { const auto key_server = - ui->keyServerListTable->item(i, 1)->text(); - keyServerStrList.append(key_server); + ui_->keyServerListTable->item(i, 1)->text(); + key_server_str_list_.append(key_server); } } }); - connect(ui->actionSet_As_Default, &QAction::triggered, [=]() { - const auto row_size = ui->keyServerListTable->rowCount(); + connect(ui_->actionSet_As_Default, &QAction::triggered, [=]() { + const auto row_size = ui_->keyServerListTable->rowCount(); for (int i = 0; i < row_size; i++) { - const auto item = ui->keyServerListTable->item(i, 1); + const auto item = ui_->keyServerListTable->item(i, 1); if (!item->isSelected()) continue; - this->defaultKeyServer = item->text(); + this->default_key_server_ = item->text(); } - this->refreshTable(); + this->slot_refresh_table(); }); - connect(ui->actionDelete_Selected_Key_Server, &QAction::triggered, [=]() { - const auto row_size = ui->keyServerListTable->rowCount(); + connect(ui_->actionDelete_Selected_Key_Server, &QAction::triggered, [=]() { + const auto row_size = ui_->keyServerListTable->rowCount(); for (int i = 0; i < row_size; i++) { - const auto item = ui->keyServerListTable->item(i, 1); + const auto item = ui_->keyServerListTable->item(i, 1); if (!item->isSelected()) continue; - this->keyServerStrList.removeAt(i); + this->key_server_str_list_.removeAt(i); break; } - this->refreshTable(); + this->slot_refresh_table(); }); // Read key-list from ini-file and fill it into combobox - setSettings(); - refreshTable(); + SetSettings(); + slot_refresh_table(); } /********************************** @@ -111,33 +117,31 @@ KeyserverTab::KeyserverTab(QWidget* parent) * and set the buttons and checkboxes * appropriately **********************************/ -void KeyserverTab::setSettings() { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); +void KeyserverTab::SetSettings() { + SettingsObject key_server_json("key_server"); - try { - auto& server_list = settings.lookup("keyserver.server_list"); - const auto server_list_size = server_list.getLength(); - for (int i = 0; i < server_list_size; i++) { - std::string server_url = server_list[i]; - keyServerStrList.append(server_url.c_str()); - } - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("server_list"); - } + const auto key_server_list = + key_server_json.Check("server_list", nlohmann::json::array()); - try { - std::string default_server = settings.lookup("keyserver.default_server"); - if (!keyServerStrList.contains(default_server.c_str())) - keyServerStrList.append(default_server.c_str()); - defaultKeyServer = QString::fromStdString(default_server); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("default_server"); + for (const auto& key_server : key_server_list) { + const auto key_server_str = key_server.get<std::string>(); + this->key_server_str_list_.append(key_server_str.c_str()); } + + auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + + int default_key_server_index = key_server_json.Check("default_server", 0); + std::string default_key_server = + key_server_list[default_key_server_index].get<std::string>(); + + if (!key_server_str_list_.contains(default_key_server.c_str())) + key_server_str_list_.append(default_key_server.c_str()); + default_key_server_ = QString::fromStdString(default_key_server); } -void KeyserverTab::addKeyServer() { - auto target_url = ui->addKeyServerEdit->text(); - if (url_reg.match(target_url).hasMatch()) { +void KeyserverTab::slot_add_key_server() { + auto target_url = ui_->addKeyServerEdit->text(); + if (url_reg_.match(target_url).hasMatch()) { if (target_url.startsWith("https://")) { ; } else if (target_url.startsWith("http://")) { @@ -148,7 +152,7 @@ void KeyserverTab::addKeyServer() { "the key server is not recommended. It is recommended to use " "HTTPS.")); } - keyServerStrList.append(ui->addKeyServerEdit->text()); + key_server_str_list_.append(ui_->addKeyServerEdit->text()); } else { auto ret = QMessageBox::warning( this, _("Warning"), @@ -162,99 +166,85 @@ void KeyserverTab::addKeyServer() { if (ret == QMessageBox::Cancel) return; else - keyServerStrList.append(ui->addKeyServerEdit->text()); + key_server_str_list_.append(ui_->addKeyServerEdit->text()); } - refreshTable(); + slot_refresh_table(); } -void KeyserverTab::applySettings() { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - if (!settings.exists("keyserver") || - settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup) - settings.add("keyserver", libconfig::Setting::TypeGroup); - - auto& keyserver = settings["keyserver"]; - - if (keyserver.exists("server_list")) keyserver.remove("server_list"); - - keyserver.add("server_list", libconfig::Setting::TypeList); - - const auto row_size = ui->keyServerListTable->rowCount(); - auto& server_list = keyserver["server_list"]; - for (int i = 0; i < row_size; i++) { - const auto key_server = ui->keyServerListTable->item(i, 1)->text(); - server_list.add(libconfig::Setting::TypeString) = key_server.toStdString(); - } - - if (!keyserver.exists("default_server")) { - keyserver.add("default_server", libconfig::Setting::TypeString) = - defaultKeyServer.toStdString(); - } else { - keyserver["default_server"] = defaultKeyServer.toStdString(); +void KeyserverTab::ApplySettings() { + SettingsObject key_server_json("key_server"); + key_server_json["server_list"] = nlohmann::json::array(); + auto& key_server_list = key_server_json["server_list"]; + + const auto list_size = key_server_str_list_.size(); + for (int i = 0; i < list_size; i++) { + const auto key_server = key_server_str_list_[i]; + if (default_key_server_ == key_server) + key_server_json["default_server"] = i; + key_server_list.insert(key_server_list.end(), key_server.toStdString()); } } -void KeyserverTab::refreshTable() { +void KeyserverTab::slot_refresh_table() { LOG(INFO) << "Start Refreshing Key Server Table"; - ui->keyServerListTable->blockSignals(true); - ui->keyServerListTable->setRowCount(keyServerStrList.size()); + ui_->keyServerListTable->blockSignals(true); + ui_->keyServerListTable->setRowCount(key_server_str_list_.size()); int index = 0; - for (const auto& server : keyServerStrList) { + for (const auto& server : key_server_str_list_) { auto* tmp1 = - new QTableWidgetItem(server == defaultKeyServer ? "*" : QString{}); + new QTableWidgetItem(server == default_key_server_ ? "*" : QString{}); tmp1->setTextAlignment(Qt::AlignCenter); - ui->keyServerListTable->setItem(index, 0, tmp1); + ui_->keyServerListTable->setItem(index, 0, tmp1); tmp1->setFlags(tmp1->flags() ^ Qt::ItemIsEditable); auto* tmp2 = new QTableWidgetItem(server); tmp2->setTextAlignment(Qt::AlignCenter); - ui->keyServerListTable->setItem(index, 1, tmp2); + ui_->keyServerListTable->setItem(index, 1, tmp2); auto* tmp3 = new QTableWidgetItem(server.startsWith("https") ? _("true") : _("false")); tmp3->setTextAlignment(Qt::AlignCenter); - ui->keyServerListTable->setItem(index, 2, tmp3); + ui_->keyServerListTable->setItem(index, 2, tmp3); tmp3->setFlags(tmp3->flags() ^ Qt::ItemIsEditable); auto* tmp4 = new QTableWidgetItem(_("unknown")); tmp4->setTextAlignment(Qt::AlignCenter); - ui->keyServerListTable->setItem(index, 3, tmp4); + ui_->keyServerListTable->setItem(index, 3, tmp4); tmp4->setFlags(tmp3->flags() ^ Qt::ItemIsEditable); index++; } - const auto column_count = ui->keyServerListTable->columnCount(); + const auto column_count = ui_->keyServerListTable->columnCount(); for (int i = 0; i < column_count; i++) { - ui->keyServerListTable->resizeColumnToContents(i); + ui_->keyServerListTable->resizeColumnToContents(i); } - ui->keyServerListTable->blockSignals(false); + ui_->keyServerListTable->blockSignals(false); } -void KeyserverTab::slotTestListedKeyServer() { +void KeyserverTab::slot_test_listed_key_server() { auto timeout = QInputDialog::getInt(this, _("Set TCP Timeout"), tr("timeout(ms): "), QLineEdit::Normal, 500, 2000); QStringList urls; - const auto row_size = ui->keyServerListTable->rowCount(); + const auto row_size = ui_->keyServerListTable->rowCount(); for (int i = 0; i < row_size; i++) { - const auto keyserver_url = ui->keyServerListTable->item(i, 1)->text(); + const auto keyserver_url = ui_->keyServerListTable->item(i, 1)->text(); urls.push_back(keyserver_url); } - auto thread = new TestListedKeyServerThread(urls, timeout, this); + auto thread = new ListedKeyServerTestThread(urls, timeout, this); connect(thread, - &GpgFrontend::UI::TestListedKeyServerThread:: - signalKeyServerListTestResult, + &GpgFrontend::UI::ListedKeyServerTestThread:: + SignalKeyServerListTestResult, this, [=](const QStringList& result) { - const auto row_size = ui->keyServerListTable->rowCount(); + const auto row_size = ui_->keyServerListTable->rowCount(); if (result.size() != row_size) return; - ui->keyServerListTable->blockSignals(true); + ui_->keyServerListTable->blockSignals(true); for (int i = 0; i < row_size; i++) { const auto status = result[i]; - auto status_iem = ui->keyServerListTable->item(i, 3); + auto status_iem = ui_->keyServerListTable->item(i, 3); if (status == "Reachable") { status_iem->setText(_("Reachable")); status_iem->setForeground(QBrush(QColor::fromRgb(0, 255, 0))); @@ -263,7 +253,7 @@ void KeyserverTab::slotTestListedKeyServer() { status_iem->setForeground(QBrush(QColor::fromRgb(255, 0, 0))); } } - ui->keyServerListTable->blockSignals(false); + ui_->keyServerListTable->blockSignals(false); }); connect(thread, &QThread::finished, thread, &QThread::deleteLater); @@ -300,8 +290,8 @@ void KeyserverTab::slotTestListedKeyServer() { void KeyserverTab::contextMenuEvent(QContextMenuEvent* event) { QWidget::contextMenuEvent(event); - if (ui->keyServerListTable->selectedItems().length() > 0) { - popupMenu->exec(event->globalPos()); + if (ui_->keyServerListTable->selectedItems().length() > 0) { + popup_menu_->exec(event->globalPos()); } } diff --git a/src/ui/settings/SettingsKeyServer.h b/src/ui/settings/SettingsKeyServer.h index 735ace98..f983e69b 100644 --- a/src/ui/settings/SettingsKeyServer.h +++ b/src/ui/settings/SettingsKeyServer.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,38 +34,76 @@ class Ui_KeyServerSettings; namespace GpgFrontend::UI { +/** + * @brief + * + */ class KeyserverTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Keyserver Tab object + * + * @param parent + */ explicit KeyserverTab(QWidget* parent = nullptr); - void setSettings(); + /** + * @brief Set the Settings object + * + */ + void SetSettings(); - void applySettings(); + /** + * @brief + * + */ + void ApplySettings(); private: - std::shared_ptr<Ui_KeyServerSettings> ui; - QString defaultKeyServer; - QStringList keyServerStrList; - QMenu* popupMenu{}; + std::shared_ptr<Ui_KeyServerSettings> ui_; + QString default_key_server_; + QStringList key_server_str_list_; + QMenu* popup_menu_{}; - QRegularExpression url_reg{ + QRegularExpression url_reg_{ R"(^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$)"}; private slots: - void addKeyServer(); + /** + * @brief + * + */ + void slot_add_key_server(); - void refreshTable(); + /** + * @brief + * + */ + void slot_refresh_table(); - void slotTestListedKeyServer(); + /** + * @brief + * + */ + void slot_test_listed_key_server(); signals: - - void signalRestartNeeded(bool needed); + /** + * @brief + * + * @param needed + */ + void SignalRestartNeeded(bool needed); protected: + /** + * @brief + * + * @param event + */ void contextMenuEvent(QContextMenuEvent* event) override; }; } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsNetwork.cpp b/src/ui/settings/SettingsNetwork.cpp index c457c1a0..d4edae42 100644 --- a/src/ui/settings/SettingsNetwork.cpp +++ b/src/ui/settings/SettingsNetwork.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,151 +8,153 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SettingsNetwork.h" -#include "ui/function/ProxyConnectionTestThread.h" -#include "ui/settings//GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" +#include "ui/thread/ProxyConnectionTestThread.h" #include "ui_NetworkSettings.h" GpgFrontend::UI::NetworkTab::NetworkTab(QWidget *parent) - : QWidget(parent), ui(std::make_shared<Ui_NetworkSettings>()) { - ui->setupUi(this); + : QWidget(parent), ui_(std::make_shared<Ui_NetworkSettings>()) { + ui_->setupUi(this); - connect(ui->enableProxyCheckBox, &QCheckBox::stateChanged, this, + connect(ui_->enableProxyCheckBox, &QCheckBox::stateChanged, this, [=](int state) { switch_ui_enabled(state == Qt::Checked); }); connect( - ui->proxyTypeComboBox, &QComboBox::currentTextChanged, this, + ui_->proxyTypeComboBox, &QComboBox::currentTextChanged, this, [=](const QString ¤t_text) { switch_ui_proxy_type(current_text); }); - connect(ui->checkProxyConnectionButton, &QPushButton::clicked, this, - &NetworkTab::slotTestProxyConnectionResult); + connect(ui_->checkProxyConnectionButton, &QPushButton::clicked, this, + &NetworkTab::slot_test_proxy_connection_result); - ui->proxyGroupBox->setTitle(_("Proxy")); - ui->capabilityGroupBox->setTitle(_("Network Capability")); - ui->operationsGroupBox->setTitle(_("Operations")); + ui_->proxyGroupBox->setTitle(_("Proxy")); + ui_->capabilityGroupBox->setTitle(_("Network Capability")); + ui_->operationsGroupBox->setTitle(_("Operations")); - ui->enableProxyCheckBox->setText(_("Enable Proxy")); - ui->proxyServerPortLabel->setText(_("Port")); + ui_->enableProxyCheckBox->setText(_("Enable Proxy")); + ui_->proxyServerPortLabel->setText(_("Port")); - ui->proxyServerAddressLabel->setText(_("Host Address")); - ui->proxyServerPortLabel->setText(_("Port")); - ui->proxyTypeLabel->setText(_("Proxy Type")); - ui->usernameLabel->setText(_("Username")); - ui->passwordLabel->setText(_("Password")); + ui_->proxyServerAddressLabel->setText(_("Host Address")); + ui_->proxyServerPortLabel->setText(_("Port")); + ui_->proxyTypeLabel->setText(_("Proxy Type")); + ui_->usernameLabel->setText(_("Username")); + ui_->passwordLabel->setText(_("Password")); - ui->forbidALLCheckBox->setText(_("Forbid all network connection.")); - ui->forbidALLCheckBox->setDisabled(true); + ui_->forbidALLCheckBox->setText(_("Forbid all network connection.")); + ui_->forbidALLCheckBox->setDisabled(true); - ui->prohibitUpdateCheck->setText( + ui_->prohibitUpdateCheck->setText( _("Prohibit checking for version updates when the program starts.")); - ui->checkProxyConnectionButton->setText(_("Check Proxy Connection")); + ui_->checkProxyConnectionButton->setText(_("Check Proxy Connection")); - setSettings(); + SetSettings(); } -void GpgFrontend::UI::NetworkTab::setSettings() { +void GpgFrontend::UI::NetworkTab::SetSettings() { auto &settings = GlobalSettingStation::GetInstance().GetUISettings(); try { std::string proxy_host = settings.lookup("proxy.proxy_host"); - ui->proxyServerAddressEdit->setText(proxy_host.c_str()); + ui_->proxyServerAddressEdit->setText(proxy_host.c_str()); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("proxy_host"); } try { std::string std_username = settings.lookup("proxy.username"); - ui->usernameEdit->setText(std_username.c_str()); + ui_->usernameEdit->setText(std_username.c_str()); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("username"); } try { std::string std_password = settings.lookup("proxy.password"); - ui->passwordEdit->setText(std_password.c_str()); + ui_->passwordEdit->setText(std_password.c_str()); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("password"); } try { int port = settings.lookup("proxy.port"); - ui->portSpin->setValue(port); + ui_->portSpin->setValue(port); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("port"); } - ui->proxyTypeComboBox->setCurrentText("HTTP"); + ui_->proxyTypeComboBox->setCurrentText("HTTP"); try { std::string proxy_type = settings.lookup("proxy.proxy_type"); - ui->proxyTypeComboBox->setCurrentText(proxy_type.c_str()); + ui_->proxyTypeComboBox->setCurrentText(proxy_type.c_str()); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("proxy_type"); } - switch_ui_proxy_type(ui->proxyTypeComboBox->currentText()); + switch_ui_proxy_type(ui_->proxyTypeComboBox->currentText()); - ui->enableProxyCheckBox->setCheckState(Qt::Unchecked); + ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked); try { bool proxy_enable = settings.lookup("proxy.enable"); if (proxy_enable) - ui->enableProxyCheckBox->setCheckState(Qt::Checked); + ui_->enableProxyCheckBox->setCheckState(Qt::Checked); else - ui->enableProxyCheckBox->setCheckState(Qt::Unchecked); + ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("proxy_enable"); } { - auto state = ui->enableProxyCheckBox->checkState(); + auto state = ui_->enableProxyCheckBox->checkState(); switch_ui_enabled(state == Qt::Checked); } - ui->forbidALLCheckBox->setCheckState(Qt::Unchecked); + ui_->forbidALLCheckBox->setCheckState(Qt::Unchecked); try { bool forbid_all_connection = settings.lookup("network.forbid_all_connection"); if (forbid_all_connection) - ui->forbidALLCheckBox->setCheckState(Qt::Checked); + ui_->forbidALLCheckBox->setCheckState(Qt::Checked); else - ui->forbidALLCheckBox->setCheckState(Qt::Unchecked); + ui_->forbidALLCheckBox->setCheckState(Qt::Unchecked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("forbid_all_connection"); } - ui->prohibitUpdateCheck->setCheckState(Qt::Unchecked); + ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked); try { bool prohibit_update_checking = settings.lookup("network.prohibit_update_checking"); if (prohibit_update_checking) - ui->prohibitUpdateCheck->setCheckState(Qt::Checked); + ui_->prohibitUpdateCheck->setCheckState(Qt::Checked); else - ui->prohibitUpdateCheck->setCheckState(Qt::Unchecked); + ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked); } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("prohibit_update_checking"); } } -void GpgFrontend::UI::NetworkTab::applySettings() { +void GpgFrontend::UI::NetworkTab::ApplySettings() { LOG(INFO) << "called"; auto &settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); if (!settings.exists("proxy") || settings.lookup("proxy").getType() != libconfig::Setting::TypeGroup) @@ -160,43 +164,43 @@ void GpgFrontend::UI::NetworkTab::applySettings() { if (!proxy.exists("proxy_host")) proxy.add("proxy_host", libconfig::Setting::TypeString) = - ui->proxyServerAddressEdit->text().toStdString(); + ui_->proxyServerAddressEdit->text().toStdString(); else { - proxy["proxy_host"] = ui->proxyServerAddressEdit->text().toStdString(); + proxy["proxy_host"] = ui_->proxyServerAddressEdit->text().toStdString(); } if (!proxy.exists("username")) proxy.add("username", libconfig::Setting::TypeString) = - ui->usernameEdit->text().toStdString(); + ui_->usernameEdit->text().toStdString(); else { - proxy["username"] = ui->usernameEdit->text().toStdString(); + proxy["username"] = ui_->usernameEdit->text().toStdString(); } if (!proxy.exists("password")) proxy.add("password", libconfig::Setting::TypeString) = - ui->passwordEdit->text().toStdString(); + ui_->passwordEdit->text().toStdString(); else { - proxy["password"] = ui->passwordEdit->text().toStdString(); + proxy["password"] = ui_->passwordEdit->text().toStdString(); } if (!proxy.exists("port")) - proxy.add("port", libconfig::Setting::TypeInt) = ui->portSpin->value(); + proxy.add("port", libconfig::Setting::TypeInt) = ui_->portSpin->value(); else { - proxy["port"] = ui->portSpin->value(); + proxy["port"] = ui_->portSpin->value(); } if (!proxy.exists("proxy_type")) proxy.add("proxy_type", libconfig::Setting::TypeString) = - ui->proxyTypeComboBox->currentText().toStdString(); + ui_->proxyTypeComboBox->currentText().toStdString(); else { - proxy["proxy_type"] = ui->proxyTypeComboBox->currentText().toStdString(); + proxy["proxy_type"] = ui_->proxyTypeComboBox->currentText().toStdString(); } if (!proxy.exists("enable")) proxy.add("enable", libconfig::Setting::TypeBoolean) = - ui->enableProxyCheckBox->isChecked(); + ui_->enableProxyCheckBox->isChecked(); else { - proxy["enable"] = ui->enableProxyCheckBox->isChecked(); + proxy["enable"] = ui_->enableProxyCheckBox->isChecked(); } if (!settings.exists("network") || @@ -207,16 +211,16 @@ void GpgFrontend::UI::NetworkTab::applySettings() { if (!network.exists("forbid_all_connection")) network.add("forbid_all_connection", libconfig::Setting::TypeBoolean) = - ui->forbidALLCheckBox->isChecked(); + ui_->forbidALLCheckBox->isChecked(); else { - network["forbid_all_connection"] = ui->forbidALLCheckBox->isChecked(); + network["forbid_all_connection"] = ui_->forbidALLCheckBox->isChecked(); } if (!network.exists("prohibit_update_checking")) network.add("prohibit_update_checking", libconfig::Setting::TypeBoolean) = - ui->prohibitUpdateCheck->isChecked(); + ui_->prohibitUpdateCheck->isChecked(); else { - network["prohibit_update_checking"] = ui->prohibitUpdateCheck->isChecked(); + network["prohibit_update_checking"] = ui_->prohibitUpdateCheck->isChecked(); } apply_proxy_settings(); @@ -224,7 +228,7 @@ void GpgFrontend::UI::NetworkTab::applySettings() { LOG(INFO) << "done"; } -void GpgFrontend::UI::NetworkTab::slotTestProxyConnectionResult() { +void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() { apply_proxy_settings(); bool ok; @@ -235,7 +239,7 @@ void GpgFrontend::UI::NetworkTab::slotTestProxyConnectionResult() { auto thread = new ProxyConnectionTestThread(url, 800, this); connect(thread, &GpgFrontend::UI::ProxyConnectionTestThread:: - signalProxyConnectionTestResult, + SignalProxyConnectionTestResult, this, [=](const QString &result) { if (result == "Reachable") { QMessageBox::information(this, _("Success"), @@ -284,14 +288,14 @@ void GpgFrontend::UI::NetworkTab::slotTestProxyConnectionResult() { void GpgFrontend::UI::NetworkTab::apply_proxy_settings() { // apply settings QNetworkProxy _proxy; - if (ui->enableProxyCheckBox->isChecked() && + if (ui_->enableProxyCheckBox->isChecked() && proxy_type_ != QNetworkProxy::DefaultProxy) { _proxy.setType(proxy_type_); - _proxy.setHostName(ui->proxyServerAddressEdit->text()); - _proxy.setPort(ui->portSpin->value()); - if (!ui->usernameEdit->text().isEmpty()) { - _proxy.setUser(ui->usernameEdit->text()); - _proxy.setPassword(ui->passwordEdit->text()); + _proxy.setHostName(ui_->proxyServerAddressEdit->text()); + _proxy.setPort(ui_->portSpin->value()); + if (!ui_->usernameEdit->text().isEmpty()) { + _proxy.setUser(ui_->usernameEdit->text()); + _proxy.setPassword(ui_->passwordEdit->text()); } } else { _proxy.setType(proxy_type_); @@ -301,34 +305,34 @@ void GpgFrontend::UI::NetworkTab::apply_proxy_settings() { } void GpgFrontend::UI::NetworkTab::switch_ui_enabled(bool enabled) { - ui->proxyServerAddressEdit->setDisabled(!enabled); - ui->portSpin->setDisabled(!enabled); - ui->proxyTypeComboBox->setDisabled(!enabled); - ui->usernameEdit->setDisabled(!enabled); - ui->passwordEdit->setDisabled(!enabled); - ui->checkProxyConnectionButton->setDisabled(!enabled); + ui_->proxyServerAddressEdit->setDisabled(!enabled); + ui_->portSpin->setDisabled(!enabled); + ui_->proxyTypeComboBox->setDisabled(!enabled); + ui_->usernameEdit->setDisabled(!enabled); + ui_->passwordEdit->setDisabled(!enabled); + ui_->checkProxyConnectionButton->setDisabled(!enabled); if (!enabled) proxy_type_ = QNetworkProxy::NoProxy; } void GpgFrontend::UI::NetworkTab::switch_ui_proxy_type( const QString &type_text) { if (type_text == "HTTP") { - ui->proxyServerAddressEdit->setDisabled(false); - ui->portSpin->setDisabled(false); - ui->usernameEdit->setDisabled(false); - ui->passwordEdit->setDisabled(false); + ui_->proxyServerAddressEdit->setDisabled(false); + ui_->portSpin->setDisabled(false); + ui_->usernameEdit->setDisabled(false); + ui_->passwordEdit->setDisabled(false); proxy_type_ = QNetworkProxy::HttpProxy; } else if (type_text == "Socks5") { - ui->proxyServerAddressEdit->setDisabled(false); - ui->portSpin->setDisabled(false); - ui->usernameEdit->setDisabled(false); - ui->passwordEdit->setDisabled(false); + ui_->proxyServerAddressEdit->setDisabled(false); + ui_->portSpin->setDisabled(false); + ui_->usernameEdit->setDisabled(false); + ui_->passwordEdit->setDisabled(false); proxy_type_ = QNetworkProxy::Socks5Proxy; } else { - ui->proxyServerAddressEdit->setDisabled(true); - ui->portSpin->setDisabled(true); - ui->usernameEdit->setDisabled(true); - ui->passwordEdit->setDisabled(true); + ui_->proxyServerAddressEdit->setDisabled(true); + ui_->portSpin->setDisabled(true); + ui_->usernameEdit->setDisabled(true); + ui_->passwordEdit->setDisabled(true); proxy_type_ = QNetworkProxy::DefaultProxy; } } diff --git a/src/ui/settings/SettingsNetwork.h b/src/ui/settings/SettingsNetwork.h index cf136604..d4c0d00d 100644 --- a/src/ui/settings/SettingsNetwork.h +++ b/src/ui/settings/SettingsNetwork.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -34,22 +38,55 @@ class NetworkTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Network Tab object + * + * @param parent + */ explicit NetworkTab(QWidget* parent = nullptr); - void setSettings(); + /** + * @brief Set the Settings object + * + */ + void SetSettings(); - void applySettings(); + /** + * @brief + * + */ + void ApplySettings(); private slots: - void slotTestProxyConnectionResult(); + /** + * @brief + * + */ + void slot_test_proxy_connection_result(); private: - std::shared_ptr<Ui_NetworkSettings> ui; - QNetworkProxy::ProxyType proxy_type_ = QNetworkProxy::HttpProxy; + std::shared_ptr<Ui_NetworkSettings> ui_; ///< + QNetworkProxy::ProxyType proxy_type_ = QNetworkProxy::HttpProxy; ///< + /** + * @brief + * + */ void apply_proxy_settings(); + + /** + * @brief + * + * @param enabled + */ void switch_ui_enabled(bool enabled); + + /** + * @brief + * + * @param type_text + */ void switch_ui_proxy_type(const QString& type_text); }; } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsSendMail.cpp b/src/ui/settings/SettingsSendMail.cpp index f0acb10d..bb948d9a 100644 --- a/src/ui/settings/SettingsSendMail.cpp +++ b/src/ui/settings/SettingsSendMail.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,53 +8,51 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "SettingsSendMail.h" -#ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#endif - -#include "ui/function/SMTPSendMailThread.h" -#include "ui/function/SMTPTestThread.h" -#include "ui/settings/GlobalSettingStation.h" +#include "ui/struct/SettingsObject.h" +#include "ui/thread/SMTPConnectionTestThread.h" +#include "ui/thread/SMTPSendMailThread.h" #include "ui_SendMailSettings.h" namespace GpgFrontend::UI { SendMailTab::SendMailTab(QWidget* parent) - : QWidget(parent), ui(std::make_shared<Ui_SendMailSettings>()) { - ui->setupUi(this); + : QWidget(parent), ui_(std::make_shared<Ui_SendMailSettings>()) { + ui_->setupUi(this); - connect(ui->enableCheckBox, &QCheckBox::stateChanged, this, + connect(ui_->enableCheckBox, &QCheckBox::stateChanged, this, [=](int state) { switch_ui_enabled(state == Qt::Checked); }); #ifdef SMTP_SUPPORT - connect(ui->checkConnectionButton, &QPushButton::clicked, this, - &SendMailTab::slotCheckConnection); - connect(ui->senTestMailButton, &QPushButton::clicked, this, - &SendMailTab::slotSendTestMail); + connect(ui_->checkConnectionButton, &QPushButton::clicked, this, + &SendMailTab::slot_check_connection); + connect(ui_->senTestMailButton, &QPushButton::clicked, this, + &SendMailTab::slot_send_test_mail); #endif - connect(ui->identityCheckBox, &QCheckBox::stateChanged, this, + connect(ui_->identityCheckBox, &QCheckBox::stateChanged, this, [=](int state) { switch_ui_identity_enabled(state == Qt::Checked); }); - connect(ui->connextionSecurityComboBox, &QComboBox::currentTextChanged, this, + connect(ui_->connextionSecurityComboBox, &QComboBox::currentTextChanged, this, [=](const QString& current_text) { if (current_text == "SSL") { connection_type_ = SmtpClient::ConnectionType::SslConnection; @@ -63,212 +63,121 @@ SendMailTab::SendMailTab(QWidget* parent) } }); - ui->generalGroupBox->setTitle(_("General")); - ui->identityGroupBox->setTitle(_("Identity Information")); - ui->preferenceGroupBox->setTitle(_("Preference")); - ui->operationsGroupBox->setTitle(_("Operations")); + ui_->generalGroupBox->setTitle(_("General")); + ui_->identityGroupBox->setTitle(_("Identity Information")); + ui_->preferenceGroupBox->setTitle(_("Preference")); + ui_->operationsGroupBox->setTitle(_("Operations")); - ui->enableCheckBox->setText(_("Enable Send Mail Ability")); - ui->identityCheckBox->setText(_("Need Auth")); + ui_->enableCheckBox->setText(_("Enable Send Mail Ability")); + ui_->identityCheckBox->setText(_("Need Auth")); - ui->smtpServerAddressLabel->setText(_("SMTP Server Address")); - ui->smtpServerPortLabel->setText(_("SMTP Server Port")); - ui->connectionSecurityLabel->setText(_("SMTP Connection Security")); - ui->usernameLabel->setText(_("Username")); - ui->passwordLabel->setText(_("Password")); + ui_->smtpServerAddressLabel->setText(_("SMTP Server Address")); + ui_->smtpServerPortLabel->setText(_("SMTP Server Port")); + ui_->connectionSecurityLabel->setText(_("SMTP Connection Security")); + ui_->usernameLabel->setText(_("Username")); + ui_->passwordLabel->setText(_("Password")); - ui->senderLabel->setText(_("Default Sender Email")); - ui->checkConnectionButton->setText(_("Check Connection")); - ui->senTestMailButton->setText(_("Send Test Email")); - ui->gpgkeyIdLabel->setText(_("Default Sender GPG Key ID")); + ui_->senderLabel->setText(_("Default Sender Email")); + ui_->checkConnectionButton->setText(_("Check Connection")); + ui_->senTestMailButton->setText(_("Send Test Email")); + ui_->gpgkeyIdLabel->setText(_("Default Sender GPG Key ID")); - ui->tipsLabel->setText( + ui_->tipsLabel->setText( _("Tips: It is recommended that you build your own mail server or use " "a trusted mail server. If you don't know the detailed configuration " "information, you can get it from the mail service provider.")); - ui->senTestMailButton->setDisabled(true); + ui_->senTestMailButton->setDisabled(true); auto* email_validator = - new QRegularExpressionValidator(re_email, ui->defaultSenderEmailEdit); - ui->defaultSenderEmailEdit->setValidator(email_validator); + new QRegularExpressionValidator(re_email_, ui_->defaultSenderEmailEdit); + ui_->defaultSenderEmailEdit->setValidator(email_validator); - setSettings(); + SetSettings(); } -void SendMailTab::setSettings() { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); +void SendMailTab::SetSettings() { + auto smtp_passport = SettingsObject("smtp_passport"); - try { - std::string mail_address = settings.lookup("smtp.mail_address"); - ui->smtpServerAddressEdit->setText(mail_address.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("mail_address"); - } + ui_->smtpServerAddressEdit->setText( + std::string{smtp_passport.Check("smtp_address", "")}.c_str()); - try { - std::string std_username = settings.lookup("smtp.username"); - ui->usernameEdit->setText(std_username.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("username"); - } + ui_->usernameEdit->setText( + std::string{smtp_passport.Check("username", "")}.c_str()); - try { - std::string std_password = settings.lookup("smtp.password"); - ui->passwordEdit->setText(std_password.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("password"); - } + ui_->passwordEdit->setText( + std::string{smtp_passport.Check("password", "")}.c_str()); - try { - int port = settings.lookup("smtp.port"); - ui->portSpin->setValue(port); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("port"); - } + ui_->portSpin->setValue(int{smtp_passport.Check("port", 25)}); - ui->connextionSecurityComboBox->setCurrentText("None"); - try { - std::string connection_type = settings.lookup("smtp.connection_type"); - ui->connextionSecurityComboBox->setCurrentText(connection_type.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("connection_type"); - } + ui_->connextionSecurityComboBox->setCurrentText( + std::string{smtp_passport.Check("connection_type", "None")}.c_str()); - try { - std::string default_sender = settings.lookup("smtp.default_sender"); - ui->defaultSenderEmailEdit->setText(default_sender.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("default_sender"); - } + ui_->defaultSenderEmailEdit->setText( + std::string{smtp_passport.Check("default_sender", "")}.c_str()); - try { - std::string default_sender_gpg_key_id = - settings.lookup("smtp.default_sender_gpg_key_id"); - ui->gpgKeyIDEdit->setText(default_sender_gpg_key_id.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") - << _("default_sender_gpg_key_id"); - } + ui_->gpgKeyIDEdit->setText( + std::string{smtp_passport.Check("default_sender_gpg_key_id", "")} + .c_str()); + + ui_->identityCheckBox->setChecked( + bool{smtp_passport.Check("identity_enable", false)}); + + ui_->enableCheckBox->setChecked(bool{smtp_passport.Check("enable", false)}); - ui->identityCheckBox->setCheckState(Qt::Unchecked); - try { - bool identity_enable = settings.lookup("smtp.identity_enable"); - if (identity_enable) - ui->identityCheckBox->setCheckState(Qt::Checked); - else - ui->identityCheckBox->setCheckState(Qt::Unchecked); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("identity_enable"); - } - { - auto state = ui->identityCheckBox->checkState(); + auto state = ui_->identityCheckBox->checkState(); switch_ui_identity_enabled(state == Qt::Checked); } - ui->enableCheckBox->setCheckState(Qt::Unchecked); - try { - bool smtp_enable = settings.lookup("smtp.enable"); - if (smtp_enable) - ui->enableCheckBox->setCheckState(Qt::Checked); - else - ui->enableCheckBox->setCheckState(Qt::Unchecked); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked"); - } - { - auto state = ui->enableCheckBox->checkState(); + auto state = ui_->enableCheckBox->checkState(); switch_ui_enabled(state == Qt::Checked); } } -void SendMailTab::applySettings() { - auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); +void SendMailTab::ApplySettings() { + try { + auto smtp_passport = SettingsObject("smtp_passport"); - if (!settings.exists("smtp") || - settings.lookup("smtp").getType() != libconfig::Setting::TypeGroup) - settings.add("smtp", libconfig::Setting::TypeGroup); + smtp_passport["smtp_address"] = + ui_->smtpServerAddressEdit->text().toStdString(); - auto& smtp = settings["smtp"]; + smtp_passport["username"] = ui_->usernameEdit->text().toStdString(); - if (!smtp.exists("mail_address")) - smtp.add("mail_address", libconfig::Setting::TypeString) = - ui->smtpServerAddressEdit->text().toStdString(); - else { - smtp["mail_address"] = ui->smtpServerAddressEdit->text().toStdString(); - } + smtp_passport["password"] = ui_->passwordEdit->text().toStdString(); - if (!smtp.exists("username")) - smtp.add("username", libconfig::Setting::TypeString) = - ui->usernameEdit->text().toStdString(); - else { - smtp["username"] = ui->usernameEdit->text().toStdString(); - } + smtp_passport["port"] = ui_->portSpin->value(); - if (!smtp.exists("password")) - smtp.add("password", libconfig::Setting::TypeString) = - ui->passwordEdit->text().toStdString(); - else { - smtp["password"] = ui->passwordEdit->text().toStdString(); - } + smtp_passport["connection_type"] = + ui_->connextionSecurityComboBox->currentText().toStdString(); - if (!smtp.exists("port")) - smtp.add("port", libconfig::Setting::TypeInt) = ui->portSpin->value(); - else { - smtp["port"] = ui->portSpin->value(); - } + smtp_passport["default_sender"] = + ui_->defaultSenderEmailEdit->text().toStdString(); - if (!smtp.exists("connection_type")) - smtp.add("connection_type", libconfig::Setting::TypeString) = - ui->connextionSecurityComboBox->currentText().toStdString(); - else { - smtp["connection_type"] = - ui->connextionSecurityComboBox->currentText().toStdString(); - } + smtp_passport["default_sender_gpg_key_id"] = + ui_->gpgKeyIDEdit->text().toStdString(); - if (!smtp.exists("default_sender")) - smtp.add("default_sender", libconfig::Setting::TypeString) = - ui->defaultSenderEmailEdit->text().toStdString(); - else { - smtp["default_sender"] = ui->defaultSenderEmailEdit->text().toStdString(); - } + smtp_passport["identity_enable"] = ui_->identityCheckBox->isChecked(); - if (!smtp.exists("default_sender_gpg_key_id")) - smtp.add("default_sender_gpg_key_id", libconfig::Setting::TypeString) = - ui->gpgKeyIDEdit->text().toStdString(); - else { - smtp["default_sender_gpg_key_id"] = ui->gpgKeyIDEdit->text().toStdString(); - } + smtp_passport["enable"] = ui_->enableCheckBox->isChecked(); - if (!smtp.exists("identity_enable")) - smtp.add("identity_enable", libconfig::Setting::TypeBoolean) = - ui->identityCheckBox->isChecked(); - else { - smtp["identity_enable"] = ui->identityCheckBox->isChecked(); - } - - if (!smtp.exists("enable")) - smtp.add("enable", libconfig::Setting::TypeBoolean) = - ui->enableCheckBox->isChecked(); - else { - smtp["enable"] = ui->enableCheckBox->isChecked(); + } catch (...) { + LOG(ERROR) << _("apply settings failed"); } } #ifdef SMTP_SUPPORT -void SendMailTab::slotCheckConnection() { - auto host = ui->smtpServerAddressEdit->text().toStdString(); - auto port = ui->portSpin->value(); +void SendMailTab::slot_check_connection() { + auto host = ui_->smtpServerAddressEdit->text().toStdString(); + auto port = ui_->portSpin->value(); auto connection_type = connection_type_; - bool identity_needed = ui->identityCheckBox->isChecked(); - auto username = ui->usernameEdit->text().toStdString(); - auto password = ui->passwordEdit->text().toStdString(); + bool identity_needed = ui_->identityCheckBox->isChecked(); + auto username = ui_->usernameEdit->text().toStdString(); + auto password = ui_->passwordEdit->text().toStdString(); - auto thread = new SMTPTestThread(host, port, connection_type, identity_needed, - username, password); + auto thread = new SMTPConnectionTestThread( + host, port, connection_type, identity_needed, username, password); // Waiting Dialog auto* waiting_dialog = new QProgressDialog(this); @@ -281,8 +190,8 @@ void SendMailTab::slotCheckConnection() { waiting_dialog_label->setWordWrap(true); waiting_dialog->setLabel(waiting_dialog_label); waiting_dialog->resize(420, 120); - connect(thread, &SMTPTestThread::signalSMTPTestResult, this, - &SendMailTab::slotTestSMTPConnectionResult); + connect(thread, &SMTPConnectionTestThread::SignalSMTPConnectionTestResult, + this, &SendMailTab::slot_test_smtp_connection_result); connect(thread, &QThread::finished, [=]() { waiting_dialog->finished(0); waiting_dialog->deleteLater(); @@ -304,14 +213,14 @@ void SendMailTab::slotCheckConnection() { #endif #ifdef SMTP_SUPPORT -void SendMailTab::slotSendTestMail() { - auto host = ui->smtpServerAddressEdit->text().toStdString(); - auto port = ui->portSpin->value(); +void SendMailTab::slot_send_test_mail() { + auto host = ui_->smtpServerAddressEdit->text().toStdString(); + auto port = ui_->portSpin->value(); auto connection_type = connection_type_; - bool identity_needed = ui->identityCheckBox->isChecked(); - auto username = ui->usernameEdit->text().toStdString(); - auto password = ui->passwordEdit->text().toStdString(); - auto sender_address = ui->defaultSenderEmailEdit->text(); + bool identity_needed = ui_->identityCheckBox->isChecked(); + auto username = ui_->usernameEdit->text().toStdString(); + auto password = ui_->passwordEdit->text().toStdString(); + auto sender_address = ui_->defaultSenderEmailEdit->text(); auto thread = new SMTPSendMailThread(host, port, connection_type, identity_needed, username, password); @@ -327,8 +236,8 @@ void SendMailTab::slotSendTestMail() { waiting_dialog_label->setWordWrap(true); waiting_dialog->setLabel(waiting_dialog_label); waiting_dialog->resize(420, 120); - connect(thread, &SMTPSendMailThread::signalSMTPResult, this, - &SendMailTab::slotTestSMTPConnectionResult); + connect(thread, &SMTPSendMailThread::SignalSMTPResult, this, + &SendMailTab::slot_test_smtp_connection_result); connect(thread, &QThread::finished, [=]() { waiting_dialog->finished(0); waiting_dialog->deleteLater(); @@ -338,10 +247,10 @@ void SendMailTab::slotSendTestMail() { if (thread->isRunning()) thread->terminate(); }); - thread->setSender(sender_address); - thread->setRecipient(sender_address); - thread->setSubject(_("Test Email from GpgFrontend")); - thread->addTextContent( + thread->SetSender(sender_address); + thread->SetRecipient(sender_address); + thread->SetSubject(_("Test Email from GpgFrontend")); + thread->AddTextContent( _("Hello, this is a test email from GpgFrontend. If you receive this " "email, it means that you have configured the correct SMTP server " "parameters.")); @@ -356,48 +265,48 @@ void SendMailTab::slotSendTestMail() { loop.exec(); } -void SendMailTab::slotTestSMTPConnectionResult(const QString& result) { +void SendMailTab::slot_test_smtp_connection_result(const QString& result) { if (result == "Fail to connect SMTP server") { QMessageBox::critical(this, _("Fail"), _("Fail to Connect SMTP Server.")); - ui->senTestMailButton->setDisabled(true); + ui_->senTestMailButton->setDisabled(true); } else if (result == "Fail to login") { QMessageBox::critical(this, _("Fail"), _("Fail to Login.")); - ui->senTestMailButton->setDisabled(true); + ui_->senTestMailButton->setDisabled(true); } else if (result == "Fail to send mail") { QMessageBox::critical(this, _("Fail"), _("Fail to Login.")); - ui->senTestMailButton->setDisabled(true); + ui_->senTestMailButton->setDisabled(true); } else if (result == "Succeed in testing connection") { QMessageBox::information(this, _("Success"), _("Succeed in connecting and login")); - ui->senTestMailButton->setDisabled(false); + ui_->senTestMailButton->setDisabled(false); } else if (result == "Succeed in sending a test email") { QMessageBox::information( this, _("Success"), _("Succeed in sending a test email to the SMTP Server")); - ui->senTestMailButton->setDisabled(false); + ui_->senTestMailButton->setDisabled(false); } else { QMessageBox::critical(this, _("Fail"), _("Unknown error.")); - ui->senTestMailButton->setDisabled(true); + ui_->senTestMailButton->setDisabled(true); } } void SendMailTab::switch_ui_enabled(bool enabled) { - ui->smtpServerAddressEdit->setDisabled(!enabled); - ui->portSpin->setDisabled(!enabled); - ui->connextionSecurityComboBox->setDisabled(!enabled); + ui_->smtpServerAddressEdit->setDisabled(!enabled); + ui_->portSpin->setDisabled(!enabled); + ui_->connextionSecurityComboBox->setDisabled(!enabled); - ui->identityCheckBox->setDisabled(!enabled); - ui->usernameEdit->setDisabled(!enabled); - ui->passwordEdit->setDisabled(!enabled); + ui_->identityCheckBox->setDisabled(!enabled); + ui_->usernameEdit->setDisabled(!enabled); + ui_->passwordEdit->setDisabled(!enabled); - ui->defaultSenderEmailEdit->setDisabled(!enabled); - ui->gpgKeyIDEdit->setDisabled(!enabled); - ui->checkConnectionButton->setDisabled(!enabled); + ui_->defaultSenderEmailEdit->setDisabled(!enabled); + ui_->gpgKeyIDEdit->setDisabled(!enabled); + ui_->checkConnectionButton->setDisabled(!enabled); } void SendMailTab::switch_ui_identity_enabled(bool enabled) { - ui->usernameEdit->setDisabled(!enabled); - ui->passwordEdit->setDisabled(!enabled); + ui_->usernameEdit->setDisabled(!enabled); + ui_->passwordEdit->setDisabled(!enabled); } #endif diff --git a/src/ui/settings/SettingsSendMail.h b/src/ui/settings/SettingsSendMail.h index c866fa5f..84259844 100644 --- a/src/ui/settings/SettingsSendMail.h +++ b/src/ui/settings/SettingsSendMail.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,65 +8,111 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_SETTINGSSENDMAIL_H #define GPGFRONTEND_SETTINGSSENDMAIL_H -#include "smtp/SmtpMime" #include "ui/GpgFrontendUI.h" class Ui_SendMailSettings; namespace GpgFrontend::UI { +/** + * @brief + * + */ class SendMailTab : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Send Mail Tab object + * + * @param parent + */ explicit SendMailTab(QWidget* parent = nullptr); - void setSettings(); + /** + * @brief Set the Settings object + * + */ + void SetSettings(); + + /** + * @brief + * + */ + void ApplySettings(); - void applySettings(); + signals: + + /** + * @brief + * + * @param needed + */ + void SignalRestartNeeded(bool needed); private slots: - void slotTestSMTPConnectionResult(const QString& result); + /** + * @brief + * + * @param result + */ + void slot_test_smtp_connection_result(const QString& result); #ifdef SMTP_SUPPORT - void slotCheckConnection(); - - void slotSendTestMail(); + /** + * @brief + * + */ + void slot_check_connection(); + + /** + * @brief + * + */ + void slot_send_test_mail(); #endif private: - std::shared_ptr<Ui_SendMailSettings> ui; - QRegularExpression re_email{ + std::shared_ptr<Ui_SendMailSettings> ui_; ///< + QRegularExpression re_email_{ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; SmtpClient::ConnectionType connection_type_ = - SmtpClient::ConnectionType::TcpConnection; + SmtpClient::ConnectionType::TcpConnection; ///< + /** + * @brief + * + * @param enabled + */ void switch_ui_enabled(bool enabled); + /** + * @brief + * + * @param enabled + */ void switch_ui_identity_enabled(bool enabled); - - signals: - - void signalRestartNeeded(bool needed); }; } // namespace GpgFrontend::UI diff --git a/src/ui/smtp/SendMailDialog.h b/src/ui/smtp/SendMailDialog.h deleted file mode 100644 index 04224f18..00000000 --- a/src/ui/smtp/SendMailDialog.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_SENDMAILDIALOG_H -#define GPGFRONTEND_SENDMAILDIALOG_H - -#include "ui/GpgFrontendUI.h" - -class Ui_SendMailDialog; - -namespace GpgFrontend::UI { - -class SendMailDialog : public QDialog { - Q_OBJECT - public: - explicit SendMailDialog(const QString& text, QWidget* parent = nullptr); - - void setContentEncryption(bool on); - - void setAttachSignature(bool on); - - private slots: - - void slotConfirm(); - - void slotTestSMTPConnectionResult(const QString& result); - - private: - void initSettings(); - - std::shared_ptr<Ui_SendMailDialog> ui; - - bool ability_enable_ = false; - bool identity_enable_ = false; - QString smtp_address_; - QString username_; - QString password_; - QString default_sender_; - QString connection_type_settings_ = "None"; - QString default_sender_gpg_key_id = {}; - int port_ = 25; - - GpgFrontend::KeyId sender_key_id_; - GpgFrontend::KeyIdArgsListPtr recipients_key_ids_ = - std::make_unique<GpgFrontend::KeyIdArgsList>(); - - QRegularExpression re_email{ - R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; - - bool check_email_address(const QString& str); - - void set_sender_value_label(); - - void set_recipients_value_label(); -}; - -} // namespace GpgFrontend::UI - -#endif // GPGFRONTEND_SENDMAILDIALOG_H diff --git a/src/ui/struct/SettingsObject.cpp b/src/ui/struct/SettingsObject.cpp new file mode 100644 index 00000000..4a9aa7d6 --- /dev/null +++ b/src/ui/struct/SettingsObject.cpp @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "SettingsObject.h" + +nlohmann::json& GpgFrontend::UI::SettingsObject::Check( + const std::string& key, const nlohmann::json& default_value) { + // check if the self null + if (this->nlohmann::json::is_null()) { + LOG(INFO) << "SettingsObject is null, creating new one"; + this->nlohmann::json::operator=(nlohmann::json::object()); + } + + try { + if (!this->nlohmann::json::contains(key) || + this->nlohmann::json::at(key).is_null() || + this->nlohmann::json::at(key).type_name() != + default_value.type_name()) { + LOG(INFO) << "Added missing key: " << key; + if (default_value.is_null()) { + LOG(WARNING) << "Default value is null, using empty object"; + this->nlohmann::json::operator[](key) = nlohmann::json::object(); + } else { + this->nlohmann::json::operator[](key) = default_value; + } + } + return this->nlohmann::json::at(key); + } catch (nlohmann::json::exception& e) { + LOG(ERROR) << e.what(); + throw e; + } +} + +GpgFrontend::UI::SettingsObject GpgFrontend::UI::SettingsObject::Check( + const std::string& key) { + // check if the self null + if (this->nlohmann::json::is_null()) { + LOG(INFO) << "SettingsObject is null, creating new one"; + this->nlohmann::json::operator=(nlohmann::json::object()); + } + + if (!nlohmann::json::contains(key) || + this->nlohmann::json::at(key).is_null() || + this->nlohmann::json::at(key).type() != nlohmann::json::value_t::object) { + LOG(INFO) << "Added missing key: " << key; + this->nlohmann::json::operator[](key) = nlohmann::json::object(); + } + return SettingsObject{nlohmann::json::operator[](key), false}; +} + +GpgFrontend::UI::SettingsObject::SettingsObject(std::string settings_name) + : settings_name_(std::move(settings_name)) { + try { + LOG(INFO) << "Loading settings from: " << this->settings_name_; + auto _json_optional = + GpgFrontend::DataObjectOperator::GetInstance().GetDataObject( + settings_name_); + + if (_json_optional.has_value()) { + LOG(INFO) << "SettingsObject: " << settings_name_ << " loaded."; + nlohmann::json::operator=(_json_optional.value()); + } else { + LOG(INFO) << "SettingsObject: " << settings_name_ << " not found."; + nlohmann::json::operator=({}); + } + + } catch (std::exception& e) { + LOG(ERROR) << e.what(); + } +} + +GpgFrontend::UI::SettingsObject::SettingsObject(nlohmann::json _sub_json, bool) + : nlohmann::json(std::move(_sub_json)), settings_name_({}) {} + +GpgFrontend::UI::SettingsObject::~SettingsObject() { + if (!settings_name_.empty()) + GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(settings_name_, + *this); +} diff --git a/src/ui/struct/SettingsObject.h b/src/ui/struct/SettingsObject.h new file mode 100644 index 00000000..653a543f --- /dev/null +++ b/src/ui/struct/SettingsObject.h @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_SETTINGSOBJECT_H +#define GPGFRONTEND_SETTINGSOBJECT_H + +#include <utility> + +#include "core/function/DataObjectOperator.h" + +namespace GpgFrontend::UI { + +/** + * @brief The SettingsObject class + * This class is used to store settings for the application securely. + * + */ +class SettingsObject : public nlohmann::json { + public: + /** + * @brief Construct a new Settings Object object + * + * @param settings_name The name of the settings object + */ + explicit SettingsObject(std::string settings_name); + + /** + * @brief Construct a new Settings Object object + * + * @param _sub_json + */ + explicit SettingsObject(nlohmann::json _sub_json, bool); + + /** + * @brief Destroy the Settings Object object + * + */ + ~SettingsObject(); + + /** + * @brief + * + * @param key + * @param default_value + * @return nlohmann::json& + */ + nlohmann::json& Check(const std::string& key, const nlohmann::json& default_value); + + /** + * @brief + * + * @param key + * @return SettingsObject + */ + SettingsObject Check(const std::string& key); + + private: + std::string settings_name_; ///< +}; +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SETTINGSOBJECT_H diff --git a/src/ui/data_struct/SoftwareVersion.cpp b/src/ui/struct/SoftwareVersion.cpp index 2e814cb9..ecccf7c0 100644 --- a/src/ui/data_struct/SoftwareVersion.cpp +++ b/src/ui/struct/SoftwareVersion.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/src/ui/data_struct/SoftwareVersion.h b/src/ui/struct/SoftwareVersion.h index be646b71..04300053 100644 --- a/src/ui/data_struct/SoftwareVersion.h +++ b/src/ui/struct/SoftwareVersion.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -28,28 +32,50 @@ #include <boost/date_time.hpp> namespace GpgFrontend::UI { +/** + * @brief + * + */ struct SoftwareVersion { - std::string latest_version; - std::string current_version; - bool latest_prerelease = false; - bool latest_draft = false; - bool current_prerelease = false; - bool current_draft = false; - bool load_info_done = false; - bool current_version_found = false; - std::string publish_date; - std::string release_note; + std::string latest_version; ///< + std::string current_version; ///< + bool latest_prerelease = false; ///< + bool latest_draft = false; ///< + bool current_prerelease = false; ///< + bool current_draft = false; ///< + bool load_info_done = false; ///< + bool current_version_found = false; ///< + std::string publish_date; ///< + std::string release_note; ///< + /** + * @brief + * + * @return true + * @return false + */ [[nodiscard]] bool NeedUpgrade() const { return load_info_done && !latest_prerelease && !latest_draft && current_version < latest_version; } + /** + * @brief + * + * @return true + * @return false + */ [[nodiscard]] bool VersionWithDrawn() const { return load_info_done && !current_version_found && current_prerelease && !current_draft; } + /** + * @brief + * + * @return true + * @return false + */ [[nodiscard]] bool CurrentVersionReleased() const { return load_info_done && current_version_found; } diff --git a/src/ui/function/CtxCheckThread.cpp b/src/ui/thread/CtxCheckThread.cpp index b51954e1..b1e50b94 100644 --- a/src/ui/function/CtxCheckThread.cpp +++ b/src/ui/thread/CtxCheckThread.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -24,14 +26,14 @@ #include "CtxCheckThread.h" -#include "gpg/GpgContext.h" -#include "gpg/GpgCoreInit.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/GpgContext.h" +#include "core/GpgCoreInit.h" +#include "core/function/gpg/GpgKeyGetter.h" #include "ui/UserInterfaceUtils.h" GpgFrontend::UI::CtxCheckThread::CtxCheckThread() : QThread(nullptr) { - connect(this, &CtxCheckThread::signalGnupgNotInstall, - CommonUtils::GetInstance(), &CommonUtils::signalGnupgNotInstall); + connect(this, &CtxCheckThread::SignalGnupgNotInstall, + CommonUtils::GetInstance(), &CommonUtils::SignalGnupgNotInstall); } void GpgFrontend::UI::CtxCheckThread::run() { @@ -40,7 +42,7 @@ void GpgFrontend::UI::CtxCheckThread::run() { // Create & Check Gnupg Context Status if (!GpgContext::GetInstance().good()) { - emit signalGnupgNotInstall(); + emit SignalGnupgNotInstall(); } // Try fetching key else diff --git a/src/ui/function/CtxCheckThread.h b/src/ui/thread/CtxCheckThread.h index 74bdb491..36281525 100644 --- a/src/ui/function/CtxCheckThread.h +++ b/src/ui/thread/CtxCheckThread.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -26,15 +28,31 @@ #define GPGFRONTEND_CTXCHECKTRHEAD_H #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { +/** + * @brief + * + */ class CtxCheckThread : public QThread { Q_OBJECT public: + /** + * @brief Construct a new Ctx Check Thread object + * + */ CtxCheckThread(); signals: - void signalGnupgNotInstall(); + /** + * @brief + * + */ + void SignalGnupgNotInstall(); protected: + /** + * @brief + * + */ void run() override; }; } // namespace GpgFrontend::UI diff --git a/src/ui/thread/FileReadThread.cpp b/src/ui/thread/FileReadThread.cpp new file mode 100644 index 00000000..258b9405 --- /dev/null +++ b/src/ui/thread/FileReadThread.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#include "FileReadThread.h" + + +#include <utility> + +namespace GpgFrontend::UI { + +FileReadThread::FileReadThread(std::string path) : path_(std::move(path)) { + qRegisterMetaType<std::string>("std::string"); +} + +void FileReadThread::run() { + LOG(INFO) << "started reading" << path_; + +#ifdef WINDOWS + std::filesystem::path read_file_path(QString::fromStdString(path_).toStdU16String()); +#else + std::filesystem::path read_file_path(QString::fromStdString(path_).toStdString()); +#endif + + if (is_regular_file(read_file_path)) { + LOG(INFO) << "read open" << read_file_path; + + QFile file; + file.setFileName(QString::fromStdString(read_file_path.u8string())); + file.open(QIODevice::ReadOnly); + QByteArray read_buffer; + LOG(INFO) << "thread start reading"; + + const size_t buffer_size = 4096; + while ((read_buffer = file.read(buffer_size)).size() > 0) { + // Check isInterruptionRequested + if (QThread::currentThread()->isInterruptionRequested()) { + LOG(INFO) << "thread is interruption requested "; + file.close(); + return; + } + LOG(INFO) << "block size " << read_buffer.size(); + std::string buffer_str(read_buffer.toStdString()); + + emit SignalSendReadBlock(buffer_str); +#ifdef RELEASE + QThread::msleep(32); +#else + QThread::msleep(128); +#endif + } + file.close(); + emit SignalReadDone(); + LOG(INFO) << "thread end reading"; + } +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/function/FileReadThread.h b/src/ui/thread/FileReadThread.h index 46ed6cbc..e7573af8 100644 --- a/src/ui/function/FileReadThread.h +++ b/src/ui/thread/FileReadThread.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -29,23 +31,45 @@ namespace GpgFrontend::UI { +/** + * @brief + * + */ class FileReadThread : public QThread { Q_OBJECT public: + /** + * @brief Construct a new File Read Thread object + * + * @param path + */ explicit FileReadThread(std::string path); signals: - void sendReadBlock(const QString& block); + /** + * @brief + * + * @param block + */ + void SignalSendReadBlock(const std::string& block); - void readDone(); + /** + * @brief + * + */ + void SignalReadDone(); protected: + /** + * @brief + * + */ void run() override; private: - std::string path; + std::string path_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/function/TestListedKeyServerThread.cpp b/src/ui/thread/ListedKeyServerTestThread.cpp index 4f816860..8c86f0be 100644 --- a/src/ui/function/TestListedKeyServerThread.cpp +++ b/src/ui/thread/ListedKeyServerTestThread.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,25 +8,25 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. * */ -#include "TestListedKeyServerThread.h" +#include "ListedKeyServerTestThread.h" -void GpgFrontend::UI::TestListedKeyServerThread::run() { +void GpgFrontend::UI::ListedKeyServerTestThread::run() { for (const auto& url : urls_) { const auto keyserver_url = url; @@ -43,5 +45,5 @@ void GpgFrontend::UI::TestListedKeyServerThread::run() { socket.close(); } - emit signalKeyServerListTestResult(result_); + emit SignalKeyServerListTestResult(result_); } diff --git a/src/ui/function/TestListedKeyServerThread.h b/src/ui/thread/ListedKeyServerTestThread.h index 99fd6c6d..dd7c2fa8 100644 --- a/src/ui/function/TestListedKeyServerThread.h +++ b/src/ui/thread/ListedKeyServerTestThread.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,50 +8,63 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. * */ -#ifndef GPGFRONTEND_TESTLISTEDKEYSERVERTHREAD_H -#define GPGFRONTEND_TESTLISTEDKEYSERVERTHREAD_H +#ifndef GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H +#define GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H #include "GpgFrontendUI.h" namespace GpgFrontend::UI { -class TestListedKeyServerThread : public QThread { +/** + * @brief + * + */ +class ListedKeyServerTestThread : public QThread { Q_OBJECT public: - explicit TestListedKeyServerThread(const QStringList& urls, int timeout, + explicit ListedKeyServerTestThread(const QStringList& urls, int timeout, QWidget* parent = nullptr) : QThread(parent), urls_(urls), timeout_(timeout) {} signals: - void signalKeyServerListTestResult(const QStringList& result); + /** + * @brief + * + * @param result + */ + void SignalKeyServerListTestResult(const QStringList& result); protected: + /** + * @brief + * + */ void run() override; private: - QStringList urls_; - QStringList result_; - int timeout_ = 500; + QStringList urls_; ///< + QStringList result_; ///< + int timeout_ = 500; ///< }; } // namespace GpgFrontend::UI class TestListedKeyServerThread {}; -#endif // GPGFRONTEND_TESTLISTEDKEYSERVERTHREAD_H +#endif // GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H diff --git a/src/ui/function/ProxyConnectionTestThread.cpp b/src/ui/thread/ProxyConnectionTestThread.cpp index 76cf525e..062f4774 100644 --- a/src/ui/function/ProxyConnectionTestThread.cpp +++ b/src/ui/thread/ProxyConnectionTestThread.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -52,5 +54,5 @@ void GpgFrontend::UI::ProxyConnectionTestThread::run() { _reply->deleteLater(); - emit signalProxyConnectionTestResult(result_); + emit SignalProxyConnectionTestResult(result_); } diff --git a/src/ui/function/ProxyConnectionTestThread.h b/src/ui/thread/ProxyConnectionTestThread.h index 4ef75050..70757e03 100644 --- a/src/ui/function/ProxyConnectionTestThread.h +++ b/src/ui/thread/ProxyConnectionTestThread.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -33,23 +35,43 @@ class ProxyConnectionTestThread {}; namespace GpgFrontend::UI { +/** + * @brief + * + */ class ProxyConnectionTestThread : public QThread { Q_OBJECT public: + /** + * @brief Construct a new Proxy Connection Test Thread object + * + * @param url + * @param timeout + * @param parent + */ explicit ProxyConnectionTestThread(QString url, int timeout, QWidget* parent = nullptr) : QThread(parent), url_(std::move(url)), timeout_(timeout) {} signals: - void signalProxyConnectionTestResult(const QString& result); + /** + * @brief + * + * @param result + */ + void SignalProxyConnectionTestResult(const QString& result); protected: + /** + * @brief + * + */ void run() override; private: - QString url_; - QString result_; - int timeout_ = 500; + QString url_; ///< + QString result_; ///< + int timeout_ = 500; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/function/SMTPTestThread.cpp b/src/ui/thread/SMTPConnectionTestThread.cpp index 0eb267f2..95cc8f72 100644 --- a/src/ui/function/SMTPTestThread.cpp +++ b/src/ui/thread/SMTPConnectionTestThread.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,41 +8,41 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. * */ -#include "SMTPTestThread.h" +#include "SMTPConnectionTestThread.h" namespace GpgFrontend::UI { -void SMTPTestThread::run() { +void SMTPConnectionTestThread::run() { SmtpClient smtp(host_.c_str(), port_, connection_type_); if (identify_) { smtp.setUser(username_.c_str()); smtp.setPassword(password_.c_str()); } if (!smtp.connectToHost()) { - emit signalSMTPTestResult("Fail to connect SMTP server"); + emit SignalSMTPConnectionTestResult("Fail to connect SMTP server"); return; } if (!smtp.login()) { - emit signalSMTPTestResult("Fail to login"); + emit SignalSMTPConnectionTestResult("Fail to login"); return; } smtp.quit(); - emit signalSMTPTestResult("Succeed in testing connection"); + emit SignalSMTPConnectionTestResult("Succeed in testing connection"); } } // namespace GpgFrontend::UI diff --git a/src/ui/thread/SMTPConnectionTestThread.h b/src/ui/thread/SMTPConnectionTestThread.h new file mode 100644 index 00000000..b37cc09c --- /dev/null +++ b/src/ui/thread/SMTPConnectionTestThread.h @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SMTPCONNECTIONTESTTHREAD_H +#define GPGFRONTEND_SMTPCONNECTIONTESTTHREAD_H + +#include <utility> + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +class SMTPConnectionTestThread : public QThread { + Q_OBJECT + public: + /** + * @brief Construct a new SMTPConnectionTestThread object + * + * @param host + * @param port + * @param connection_type + * @param identify + * @param username + * @param password + * @param parent + */ + explicit SMTPConnectionTestThread(std::string host, int port, + SmtpClient::ConnectionType connection_type, + bool identify, std::string username, + std::string password, + QWidget* parent = nullptr) + : QThread(parent), + host_(std::move(host)), + port_(port), + connection_type_(connection_type), + identify_(identify), + username_(std::move(username)), + password_(std::move(password)) {} + + signals: + /** + * @brief + * + * @param result + */ + void SignalSMTPConnectionTestResult(const QString& result); + + protected: + /** + * @brief + * + */ + void run() override; + + private: + std::string host_; ///< + int port_; ///< + SmtpClient::ConnectionType connection_type_; ///< + bool identify_; ///< + std::string username_; ///< + std::string password_; ///< +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SMTPCONNECTIONTESTTHREAD_H diff --git a/src/ui/function/SMTPSendMailThread.cpp b/src/ui/thread/SMTPSendMailThread.cpp index edfd3156..f1cb1626 100644 --- a/src/ui/function/SMTPSendMailThread.cpp +++ b/src/ui/thread/SMTPSendMailThread.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -26,9 +28,9 @@ #include <boost/format.hpp> -#include "gpg/function/BasicOperator.h" -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExporter.h" +#include "core/function/gpg/GpgBasicOperator.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyImportExporter.h" namespace GpgFrontend::UI { @@ -64,11 +66,11 @@ void SMTPSendMailThread::run() { GpgEncrResult result; auto in_buffer = std::make_unique<ByteArray>(plain_text); auto keys = GpgKeyGetter::GetInstance().GetKeys(public_key_ids_); - auto err = BasicOperator::GetInstance().Encrypt( + auto err = GpgBasicOperator::GetInstance().Encrypt( std::move(keys), *in_buffer, out_buffer, result); if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) { - emit signalSMTPResult("Fail to encrypt with gpg keys"); + emit SignalSMTPResult("Fail to encrypt with gpg keys"); return; } text->setText(out_buffer->c_str()); @@ -126,12 +128,12 @@ void SMTPSendMailThread::run() { // The signature MUST be generated detached from the signed data // so that the process does not alter the signed data in any way. - auto err = BasicOperator::GetInstance().Sign( + auto err = GpgBasicOperator::GetInstance().Sign( std::move(keys), *in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result); if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) { - emit signalSMTPResult("Fail to sign with gpg keys"); + emit SignalSMTPResult("Fail to sign with gpg keys"); return; } @@ -174,7 +176,7 @@ void SMTPSendMailThread::run() { auto public_key_file_name = boost::format("%1%_pubkey.asc") % attached_public_key_ids_; - addFileContent(public_key_file_name.str().c_str(), out_buffer->c_str()); + AddFileContent(public_key_file_name.str().c_str(), out_buffer->c_str()); auto& key_file = files_.back(); key_file->setEncoding(MimePart::_7Bit); key_file->setContentType("application/pgp-keys"); @@ -190,70 +192,70 @@ void SMTPSendMailThread::run() { // Now we can send the mail if (!smtp.connectToHost()) { - emit signalSMTPResult("Fail to connect SMTP server"); + emit SignalSMTPResult("Fail to connect SMTP server"); return; } if (!smtp.login()) { - emit signalSMTPResult("Fail to login"); + emit SignalSMTPResult("Fail to login"); return; } if (!smtp.sendMail(message)) { - emit signalSMTPResult("Fail to send mail"); + emit SignalSMTPResult("Fail to send mail"); return; } smtp.quit(); - emit signalSMTPResult("Succeed in sending a test email"); + emit SignalSMTPResult("Succeed in sending a test email"); } -void SMTPSendMailThread::setBCC(const QString& bccs) { +void SMTPSendMailThread::SetBCC(const QString& bccs) { QStringList bcc_string_list = bccs.split(';'); for (const auto& bcc : bcc_string_list) { if (!bcc.isEmpty()) message.addBcc(new EmailAddress(bcc.trimmed())); } } -void SMTPSendMailThread::setCC(const QString& ccs) { +void SMTPSendMailThread::SetCC(const QString& ccs) { QStringList cc_string_list = ccs.split(';'); for (const auto& cc : cc_string_list) { if (!cc.isEmpty()) message.addCc(new EmailAddress(cc.trimmed())); } } -void SMTPSendMailThread::setRecipient(const QString& recipients) { +void SMTPSendMailThread::SetRecipient(const QString& recipients) { QStringList rcpt_string_list = recipients.split(';'); for (const auto& rcpt : rcpt_string_list) { if (!rcpt.isEmpty()) message.addRecipient(new EmailAddress(rcpt.trimmed())); } } -void SMTPSendMailThread::setSender(const QString& sender) { +void SMTPSendMailThread::SetSender(const QString& sender) { message.setSender(new EmailAddress(sender)); } -void SMTPSendMailThread::addTextContent(const QString& content) { +void SMTPSendMailThread::AddTextContent(const QString& content) { auto text = std::make_unique<MimeText>(content.trimmed()); texts_.push_back(std::move(text)); } -void SMTPSendMailThread::addFileContent(const QString& file_name, +void SMTPSendMailThread::AddFileContent(const QString& file_name, const QByteArray& content) { auto file = std::make_unique<MimeFile>(content, file_name); files_.push_back(std::move(file)); } -void SMTPSendMailThread::setEncryptContent( +void SMTPSendMailThread::SetEncryptContent( bool encrypt_content, GpgFrontend::KeyIdArgsListPtr public_key_ids) { this->encrypt_content_ = encrypt_content; this->public_key_ids_ = std::move(public_key_ids); } -void SMTPSendMailThread::setAttachSignatureFile( +void SMTPSendMailThread::SetAttachSignatureFile( bool attach_signature_file, GpgFrontend::KeyId private_key_id) { this->attach_signature_file_ = attach_signature_file; this->private_key_id_ = std::move(private_key_id); } -void SMTPSendMailThread::setAttachPublicKey( +void SMTPSendMailThread::SetAttachPublicKey( bool attach_public_key_file, GpgFrontend::KeyId attached_public_key_ids) { this->attach_public_key_file_ = attach_public_key_file; this->attached_public_key_ids_ = std::move(attached_public_key_ids); diff --git a/src/ui/thread/SMTPSendMailThread.h b/src/ui/thread/SMTPSendMailThread.h new file mode 100644 index 00000000..58420bf3 --- /dev/null +++ b/src/ui/thread/SMTPSendMailThread.h @@ -0,0 +1,179 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SMTPSENDMAILTHREAD_H +#define GPGFRONTEND_SMTPSENDMAILTHREAD_H + +#include <utility> + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { +/** + * @brief + * + */ +class SMTPSendMailThread : public QThread { + Q_OBJECT + public: + /** + * @brief Construct a new SMTPSendMailThread object + * + * @param host + * @param port + * @param connection_type + * @param identify + * @param username + * @param password + * @param parent + */ + explicit SMTPSendMailThread(std::string host, int port, + SmtpClient::ConnectionType connection_type, + bool identify, std::string username, + std::string password, QWidget* parent = nullptr) + : QThread(parent), + host_(std::move(host)), + port_(port), + connection_type_(connection_type), + identify_(identify), + username_(std::move(username)), + password_(std::move(password)) {} + + void SetSender(const QString& sender); + + /** + * @brief Set the Recipient object + * + * @param recipients + */ + void SetRecipient(const QString& recipients); + + /** + * @brief + * + * @param ccs + */ + void SetCC(const QString& ccs); + + /** + * @brief + * + * @param bccs + */ + void SetBCC(const QString& bccs); + + /** + * @brief Set the Subject object + * + * @param subject + */ + void SetSubject(const QString& subject) { message.setSubject(subject); } + + /** + * @brief + * + * @param content + */ + void AddTextContent(const QString& content); + + /** + * @brief + * + * @param file_name + * @param content + */ + void AddFileContent(const QString& file_name, const QByteArray& content); + + /** + * @brief Set the Encrypt Content object + * + * @param encrypt_content + * @param public_key_ids + */ + void SetEncryptContent(bool encrypt_content, + GpgFrontend::KeyIdArgsListPtr public_key_ids); + + /** + * @brief Set the Attach Signature File object + * + * @param attach_signature_file + * @param private_key_id + */ + void SetAttachSignatureFile(bool attach_signature_file, + GpgFrontend::KeyId private_key_id); + + /** + * @brief Set the Attach Public Key object + * + * @param attach_public_key_file + * @param attached_public_key_ids + */ + void SetAttachPublicKey(bool attach_public_key_file, + GpgFrontend::KeyId attached_public_key_ids); + + signals: + /** + * @brief + * + * @param result + */ + void SignalSMTPResult(const QString& result); + + protected: + /** + * @brief + * + */ + void run() override; + + private: + // SMTP Options + + std::string host_; ///< + int port_; ///< + SmtpClient::ConnectionType connection_type_; ///< + + bool identify_; ///< + std::string username_; ///< + std::string password_; ///< + + MimeMessage message; ///< + std::vector<std::unique_ptr<MimeText>> texts_; ///< + std::vector<std::unique_ptr<MimeText>> send_texts_; ///< + std::vector<std::unique_ptr<MimeFile>> files_; ///< + + // GPG Options + + bool encrypt_content_ = false; ///< + GpgFrontend::KeyIdArgsListPtr public_key_ids_; ///< + bool attach_signature_file_ = false; ///< + GpgFrontend::KeyId private_key_id_; ///< + bool attach_public_key_file_ = false; ///< + GpgFrontend::KeyId attached_public_key_ids_; ///< +}; +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SMTPSENDMAILTHREAD_H diff --git a/src/ui/function/VersionCheckThread.cpp b/src/ui/thread/VersionCheckThread.cpp index 2a1cf9af..6d73417d 100644 --- a/src/ui/function/VersionCheckThread.cpp +++ b/src/ui/thread/VersionCheckThread.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,28 +8,30 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "VersionCheckThread.h" #include <QMetaType> +#include <nlohmann/json.hpp> #include "GpgFrontendBuildInfo.h" -#include "json/json.hpp" namespace GpgFrontend::UI { @@ -115,7 +119,7 @@ void VersionCheckThread::run() { LOG(INFO) << "error occurred"; version.load_info_done = false; } - emit upgradeVersion(version); + emit SignalUpgradeVersion(version); } VersionCheckThread::VersionCheckThread() : QThread(nullptr) { diff --git a/src/ui/function/VersionCheckThread.h b/src/ui/thread/VersionCheckThread.h index 0db9770c..6ad35afe 100644 --- a/src/ui/function/VersionCheckThread.h +++ b/src/ui/thread/VersionCheckThread.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,25 +30,44 @@ #define GPGFRONTEND_VERSIONCHECKTHREAD_H #include "ui/GpgFrontendUI.h" -#include "ui/data_struct/SoftwareVersion.h" +#include "ui/struct/SoftwareVersion.h" namespace GpgFrontend::UI { +/** + * @brief + * + */ class VersionCheckThread : public QThread { Q_OBJECT public: + /** + * @brief Construct a new Version Check Thread object + * + */ explicit VersionCheckThread(); signals: - void upgradeVersion(SoftwareVersion version); + /** + * @brief + * + * @param version + */ + void SignalUpgradeVersion(SoftwareVersion version); protected: + /** + * @brief + + * + */ void run() override; private: - QByteArray latest_reply_bytes_, current_reply_bytes_; + QByteArray latest_reply_bytes_; ///< + QByteArray current_reply_bytes_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp deleted file mode 100644 index b73974a7..00000000 --- a/src/ui/widgets/EditorPage.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#include "ui/widgets/EditorPage.h" - -#include <boost/filesystem.hpp> -#include <utility> - -#include "ui/function/FileReadThread.h" - -namespace GpgFrontend::UI { - -EditorPage::EditorPage(QString filePath, QWidget* parent) - : QWidget(parent), full_file_path_(std::move(filePath)) { - // Set the Textedit properties - textPage = new QTextEdit(); - textPage->setAcceptRichText(false); - - // Set the layout style - mainLayout = new QVBoxLayout(); - mainLayout->setSpacing(0); - mainLayout->addWidget(textPage); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); - - textPage->setFocus(); - - // Front in same width - this->setFont({"Courier"}); - this->setAttribute(Qt::WA_DeleteOnClose); -} - -const QString& EditorPage::getFilePath() const { return full_file_path_; } - -QTextEdit* EditorPage::getTextPage() { return textPage; } - -void EditorPage::setFilePath(const QString& filePath) { - full_file_path_ = filePath; -} - -void EditorPage::showNotificationWidget(QWidget* widget, - const char* className) { - widget->setProperty(className, true); - mainLayout->addWidget(widget); -} - -void EditorPage::closeNoteByClass(const char* className) { - QList<QWidget*> widgets = findChildren<QWidget*>(); - for (QWidget* widget : widgets) { - if (widget->property(className) == true) { - widget->close(); - } - } -} - -void EditorPage::slotFormatGpgHeader() { - QString content = textPage->toPlainText(); - - // Get positions of the gpg-headers, if they exist - int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN); - int startSig = - content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN); - int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END); - - if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { - return; - } - - signMarked = true; - - // Set the fontstyle for the header - QTextCharFormat signFormat; - signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); - signFormat.setFontPointSize(9); - - // set font style for the signature - QTextCursor cursor(textPage->document()); - cursor.setPosition(startSig, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); - cursor.setCharFormat(signFormat); - - // set the font style for the header - int headEnd = content.indexOf("\n\n", start); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); - cursor.setCharFormat(signFormat); -} - -void EditorPage::ReadFile() { - LOG(INFO) << "Called"; - - read_done_ = false; - - auto text_page = this->getTextPage(); - text_page->setReadOnly(true); - auto thread = new FileReadThread(this->full_file_path_.toStdString()); - - connect(thread, &FileReadThread::sendReadBlock, this, - &EditorPage::slotInsertText); - - connect(thread, &FileReadThread::readDone, this, [=]() { - LOG(INFO) << "thread read done"; - text_page->document()->setModified(false); - text_page->setReadOnly(false); - }); - - connect(thread, &FileReadThread::finished, this, [=]() { - LOG(INFO) << "thread finished"; - thread->deleteLater(); - read_done_ = true; - read_hread_ = nullptr; - }); - - connect(this, &EditorPage::destroyed, [=]() { - LOG(INFO) << "request interruption for read thread"; - thread->requestInterruption(); - read_hread_ = nullptr; - }); - this->read_hread_ = thread; - thread->start(); -} - -void EditorPage::slotInsertText(const QString& text) { - this->getTextPage()->insertPlainText(text); -} -void EditorPage::PrepareToDestroy() { - if (read_hread_) { - read_hread_->requestInterruption(); - read_hread_ = nullptr; - } -} - -} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/EditorPage.h b/src/ui/widgets/EditorPage.h deleted file mode 100644 index d1bc1ac2..00000000 --- a/src/ui/widgets/EditorPage.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __EDITORPAGE_H__ -#define __EDITORPAGE_H__ - -#include "gpg/GpgConstants.h" -#include "ui/GpgFrontendUI.h" - -QT_BEGIN_NAMESPACE -class QVBoxLayout; -class QHBoxLayout; -class QString; -class QLabel; -QT_END_NAMESPACE - -namespace GpgFrontend::UI { - -/** - * @brief Class for handling a single tab of the tabwidget - * - */ -class EditorPage : public QWidget { - Q_OBJECT - public: - /** - * @details Add layout and add plaintextedit - * - * @param filePath Path of the file handled in this tab - * @param parent Pointer to the parent widget - */ - explicit EditorPage(QString filePath = "", QWidget* parent = nullptr); - - /** - * @details Get the filepath of the currently activated tab. - */ - [[nodiscard]] const QString& getFilePath() const; - - /** - * @details Set filepath of currently activated tab. - * - * @param filePath The path to be set - */ - void setFilePath(const QString& filePath); - - /** - * @details Return pointer tp the textedit of the currently activated tab. - */ - QTextEdit* getTextPage(); - - /** - * @details Show additional widget at buttom of currently active tab - * - * @param widget The widget to be added - * @param className The name to handle the added widget - */ - void showNotificationWidget(QWidget* widget, const char* className); - - /** - * @details Hide all widgets with the given className - * - * @param className The classname of the widgets to hide - */ - void closeNoteByClass(const char* className); - - void ReadFile(); - - [[nodiscard]] bool ReadDone() const { return this->read_done_; } - - void PrepareToDestroy(); - - private: - QTextEdit* textPage; /** The textedit of the tab */ - QVBoxLayout* mainLayout; /** The layout for the tab */ - QString full_file_path_; /** The path to the file handled in the tab */ - bool signMarked{}; /** true, if the signed header is marked, false if not */ - bool read_done_ = false; - QThread* read_hread_ = nullptr; - - private slots: - - /** - * @details Format the gpg header in another font-style - */ - void slotFormatGpgHeader(); - - void slotInsertText(const QString& text); -}; - -} // namespace GpgFrontend::UI - -#endif // __EDITORPAGE_H__ diff --git a/src/ui/widgets/ExportKeyPackageDialog.cpp b/src/ui/widgets/ExportKeyPackageDialog.cpp deleted file mode 100644 index d99e966a..00000000 --- a/src/ui/widgets/ExportKeyPackageDialog.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "ExportKeyPackageDialog.h" - -#include <boost/format.hpp> - -#include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExporter.h" -#include "ui/aes/qaesencryption.h" -#include "ui_ExportKeyPackageDialog.h" - -GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( - KeyIdArgsListPtr key_ids, QWidget* parent) - : QDialog(parent), - ui(std::make_shared<Ui_exportKeyPackageDialog>()), - key_ids_(std::move(key_ids)), - mt(rd()) { - ui->setupUi(this); - - generate_key_package_name(); - - connect(ui->gnerateNameButton, &QPushButton::clicked, this, - [=]() { generate_key_package_name(); }); - - connect(ui->setOutputPathButton, &QPushButton::clicked, this, [=]() { - auto file_name = QFileDialog::getSaveFileName( - this, _("Export Key Package"), ui->nameValueLabel->text() + ".gfepack", - QString(_("Key Package")) + " (*.gfepack);;All Files (*)"); - ui->outputPathLabel->setText(file_name); - }); - - connect(ui->generatePassphraseButton, &QPushButton::clicked, this, [=]() { - passphrase_ = generate_passphrase(256); - auto file_name = QFileDialog::getSaveFileName( - this, _("Export Key Package Passphrase"), - ui->nameValueLabel->text() + ".key", - QString(_("Key File")) + " (*.key);;All Files (*)"); - ui->passphraseValueLabel->setText(file_name); - write_buffer_to_file(file_name.toStdString(), passphrase_); - }); - - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, [=]() { - if (ui->outputPathLabel->text().isEmpty()) { - QMessageBox::critical( - this, _("Forbidden"), - _("Please select an output path before exporting.")); - return; - } - - if (ui->passphraseValueLabel->text().isEmpty()) { - QMessageBox::critical( - this, _("Forbidden"), - _("Please generate a password to protect your key before exporting, " - "it is very important. Don't forget to back up your password in a " - "safe place.")); - return; - } - - auto key_id_exported = std::make_unique<KeyIdArgsList>(); - auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids_); - for (const auto& key : *keys) { - if (ui->noPublicKeyCheckBox->isChecked() && !key.is_private_key()) { - continue; - } - key_id_exported->push_back(key.id()); - } - - ByteArrayPtr key_export_data = nullptr; - if (!GpgKeyImportExporter::GetInstance().ExportKeys( - key_ids_, key_export_data, - ui->includeSecretKeyCheckBox->isChecked())) { - QMessageBox::critical(this, _("Error"), _("Export Key(s) Failed.")); - this->close(); - return; - } - - auto key = QByteArray::fromStdString(passphrase_), - data = - QString::fromStdString(*key_export_data).toLocal8Bit().toBase64(); - - auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256); - QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, - QAESEncryption::Padding::ISO); - auto encoded = encryption.encode(data, hash_key); - - write_buffer_to_file(ui->outputPathLabel->text().toStdString(), - encoded.toStdString()); - - QMessageBox::information( - this, _("Success"), - QString(_( - "The Key Package has been successfully generated and has been " - "protected by encryption algorithms. You can safely transfer your " - "Key Package.")) + - "<br />" + "<b>" + - _("But the key file cannot be leaked under any " - "circumstances. Please delete the Key Package and key file as " - "soon " - "as possible after completing the transfer operation.") + - "</b>"); - }); - - connect(ui->buttonBox, &QDialogButtonBox::rejected, this, - [=]() { this->close(); }); - - ui->nameLabel->setText(_("Key Package Name")); - ui->selectOutputPathLabel->setText(_("Output Path")); - ui->passphraseLabel->setText(_("Passphrase")); - ui->tipsLabel->setText( - _("Tips: You can use Key Package to safely and conveniently transfer " - "your public and private keys between devices.")); - ui->generatePassphraseButton->setText(_("Generate and Save Passphrase")); - ui->gnerateNameButton->setText(_("Generate Key Package Name")); - ui->setOutputPathButton->setText(_("Select Output Path")); - - ui->includeSecretKeyCheckBox->setText( - _("Include secret key (Think twice before acting)")); - ui->noPublicKeyCheckBox->setText( - _("Exclude keys that do not have a private key")); - - setAttribute(Qt::WA_DeleteOnClose); - setWindowTitle(_("exportKeyPackageDialog")); -} - -std::string GpgFrontend::UI::ExportKeyPackageDialog::generate_passphrase( - const int len) { - std::uniform_int_distribution<int> dist(999, 99999); - static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - std::string tmp_str; - tmp_str.reserve(len); - - for (int i = 0; i < len; ++i) { - tmp_str += alphanum[dist(mt) % (sizeof(alphanum) - 1)]; - } - - return tmp_str; -} - -void GpgFrontend::UI::ExportKeyPackageDialog::generate_key_package_name() { - std::uniform_int_distribution<int> dist(999, 99999); - auto file_string = boost::format("KeyPackage_%1%") % dist(mt); - ui->nameValueLabel->setText(file_string.str().c_str()); - ui->outputPathLabel->clear(); - ui->passphraseValueLabel->clear(); -} diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp index 3e140bd4..1047be75 100644 --- a/src/ui/widgets/FilePage.cpp +++ b/src/ui/widgets/FilePage.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,74 +8,78 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "ui/widgets/FilePage.h" -#include <boost/filesystem.hpp> #include <string> -#include "ui/MainWindow.h" +#include "core/function/ArchiveFileOperator.h" +#include "core/function/gpg/GpgFileOpera.h" #include "ui/SignalStation.h" +#include "ui/main_window/MainWindow.h" #include "ui_FilePage.h" namespace GpgFrontend::UI { FilePage::FilePage(QWidget* parent) - : QWidget(parent), ui(std::make_shared<Ui_FilePage>()) { - ui->setupUi(this); - - firstParent = parent; - - dirModel = new QFileSystemModel(); - dirModel->setRootPath(QDir::currentPath()); - dirModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); - - ui->fileTreeView->setModel(dirModel); - ui->fileTreeView->setColumnWidth(0, 320); - ui->fileTreeView->sortByColumn(0, Qt::AscendingOrder); - mPath = boost::filesystem::path(dirModel->rootPath().toStdString()); - - createPopupMenu(); - - connect(ui->upPathButton, &QPushButton::clicked, this, - &FilePage::slotUpLevel); - connect(ui->refreshButton, &QPushButton::clicked, this, - &FilePage::slotGoPath); - ui->optionsButton->setMenu(optionPopUpMenu); - - ui->pathEdit->setText(dirModel->rootPath()); - - pathEditCompleter = new QCompleter(this); - pathCompleteModel = new QStringListModel(); - pathEditCompleter->setModel(pathCompleteModel); - pathEditCompleter->setCaseSensitivity(Qt::CaseInsensitive); - pathEditCompleter->setCompletionMode(QCompleter::UnfilteredPopupCompletion); - ui->pathEdit->setCompleter(pathEditCompleter); - - connect(ui->fileTreeView, &QTreeView::clicked, this, - &FilePage::fileTreeViewItemClicked); - connect(ui->fileTreeView, &QTreeView::doubleClicked, this, - &FilePage::fileTreeViewItemDoubleClicked); - connect(ui->fileTreeView, &QTreeView::customContextMenuRequested, this, + : QWidget(parent), ui_(std::make_shared<Ui_FilePage>()) { + ui_->setupUi(this); + + first_parent_ = parent; + + dir_model_ = new QFileSystemModel(); + dir_model_->setRootPath(QDir::currentPath()); + dir_model_->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); + + ui_->fileTreeView->setModel(dir_model_); + ui_->fileTreeView->setColumnWidth(0, 320); + ui_->fileTreeView->sortByColumn(0, Qt::AscendingOrder); + m_path_ = std::filesystem::path(dir_model_->rootPath().toStdString()); + + create_popup_menu(); + + connect(ui_->upPathButton, &QPushButton::clicked, this, + &FilePage::slot_up_level); + connect(ui_->refreshButton, &QPushButton::clicked, this, + &FilePage::SlotGoPath); + ui_->optionsButton->setMenu(option_popup_menu_); + + ui_->pathEdit->setText(dir_model_->rootPath()); + + path_edit_completer_ = new QCompleter(this); + path_complete_model_ = new QStringListModel(); + path_edit_completer_->setModel(path_complete_model_); + path_edit_completer_->setCaseSensitivity(Qt::CaseInsensitive); + path_edit_completer_->setCompletionMode( + QCompleter::UnfilteredPopupCompletion); + ui_->pathEdit->setCompleter(path_edit_completer_); + + connect(ui_->fileTreeView, &QTreeView::clicked, this, + &FilePage::slot_file_tree_view_item_clicked); + connect(ui_->fileTreeView, &QTreeView::doubleClicked, this, + &FilePage::slot_file_tree_view_item_double_clicked); + connect(ui_->fileTreeView, &QTreeView::customContextMenuRequested, this, &FilePage::onCustomContextMenu); - connect(ui->pathEdit, &QLineEdit::textChanged, [=]() { - auto path = ui->pathEdit->text(); + connect(ui_->pathEdit, &QLineEdit::textChanged, [=]() { + auto path = ui_->pathEdit->text(); auto dir = QDir(path); if (path.endsWith("/") && dir.isReadable()) { auto dir_list = dir.entryInfoList(QDir::AllEntries); @@ -84,216 +90,253 @@ FilePage::FilePage(QWidget* parent) if (file_name == "." || file_name == "..") continue; paths.append(file_path); } - pathCompleteModel->setStringList(paths); + path_complete_model_->setStringList(paths); } }); - connect(this, &FilePage::signalRefreshInfoBoard, SignalStation::GetInstance(), - &SignalStation::signalRefreshInfoBoard); + connect(this, &FilePage::SignalRefreshInfoBoard, SignalStation::GetInstance(), + &SignalStation::SignalRefreshInfoBoard); } -void FilePage::fileTreeViewItemClicked(const QModelIndex& index) { - selectedPath = boost::filesystem::path( - dirModel->fileInfo(index).absoluteFilePath().toStdString()); - mPath = selectedPath; - LOG(INFO) << "selected path" << selectedPath; -} +void FilePage::slot_file_tree_view_item_clicked(const QModelIndex& index) { +#ifdef WINDOWS + selected_path_ = std::filesystem::path( + dir_model_->fileInfo(index).absoluteFilePath().toStdU16String()); +#else + selected_path_ = std::filesystem::path( + dir_model_->fileInfo(index).absoluteFilePath().toStdString()); +#endif + + m_path_ = selected_path_; + LOG(INFO) << "selected path" << selected_path_.u8string(); + + selected_path_ = std::filesystem::path(selected_path_); + MainWindow::CryptoMenu::OperationType operation_type = + MainWindow::CryptoMenu::None; -void FilePage::slotUpLevel() { - QModelIndex currentRoot = ui->fileTreeView->rootIndex(); + if (index.isValid()) { + QFileInfo info(QString::fromStdString(selected_path_.u8string())); - auto utf8_path = - dirModel->fileInfo(currentRoot).absoluteFilePath().toStdString(); - boost::filesystem::path path_obj(utf8_path); + if ((info.isDir() || info.isFile()) && + (info.suffix() != "gpg" && info.suffix() != "sig" && + info.suffix() != "asc")) { + operation_type |= MainWindow::CryptoMenu::Encrypt; + } - mPath = path_obj; - LOG(INFO) << "get path" << mPath; - if (mPath.has_parent_path() && !mPath.parent_path().empty()) { - mPath = mPath.parent_path(); - LOG(INFO) << "parent path" << mPath; - ui->pathEdit->setText(mPath.string().c_str()); - this->slotGoPath(); + if ((info.isDir() || info.isFile()) && + (info.suffix() != "gpg" && info.suffix() != "sig" && + info.suffix() != "asc")) { + operation_type |= MainWindow::CryptoMenu::EncryptAndSign; + } + + if (info.isFile() && (info.suffix() == "gpg" || info.suffix() == "asc")) { + operation_type |= MainWindow::CryptoMenu::Decrypt; + operation_type |= MainWindow::CryptoMenu::DecryptAndVerify; + } + + if (info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig" && + info.suffix() != "asc")) { + operation_type |= MainWindow::CryptoMenu::Sign; + } + + if (info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg" || + info.suffix() == "asc")) { + operation_type |= MainWindow::CryptoMenu::Verify; + } } + + auto main_window = qobject_cast<MainWindow*>(first_parent_); + if (main_window != nullptr) main_window->SetCryptoMenuStatus(operation_type); } -void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) { - QFileInfo file_info(dirModel->fileInfo(index).absoluteFilePath()); +void FilePage::slot_up_level() { + QModelIndex currentRoot = ui_->fileTreeView->rootIndex(); +#ifdef WINDOWS + auto str_path = + dir_model_->fileInfo(currentRoot).absoluteFilePath().toStdU16String(); +#else + auto str_path = + dir_model_->fileInfo(currentRoot).absoluteFilePath().toUtf8().toStdString(); +#endif + std::filesystem::path path_obj(str_path); + + m_path_ = path_obj; + LOG(INFO) << "get path" << m_path_; + if (m_path_.has_parent_path() && !m_path_.parent_path().empty()) { + m_path_ = m_path_.parent_path(); + LOG(INFO) << "parent path" << m_path_; + ui_->pathEdit->setText(m_path_.u8string().c_str()); + this->SlotGoPath(); + } +} + +void FilePage::slot_file_tree_view_item_double_clicked( + const QModelIndex& index) { + QFileInfo file_info(dir_model_->fileInfo(index).absoluteFilePath()); if (file_info.isFile()) { - slotOpenItem(); + slot_open_item(); } else { - ui->pathEdit->setText(file_info.filePath()); - slotGoPath(); + ui_->pathEdit->setText(file_info.filePath()); + SlotGoPath(); } } -QString FilePage::getSelected() const { - return QString::fromStdString(selectedPath.string()); +QString FilePage::GetSelected() const { + return QString::fromStdString(selected_path_.u8string()); } -void FilePage::slotGoPath() { - const auto path_edit = ui->pathEdit->text().toStdString(); - boost::filesystem::path path_obj(path_edit); +void FilePage::SlotGoPath() { +#ifdef WINDOWS + std::filesystem::path path_edit_obj(ui_->pathEdit->text().toStdU16String()); +#else + std::filesystem::path path_edit_obj(ui_->pathEdit->text().toStdString()); +#endif - if (mPath.string() != path_edit) mPath = path_obj; - auto fileInfo = QFileInfo(mPath.string().c_str()); + m_path_ = m_path_ != path_edit_obj ? path_edit_obj : m_path_; + auto fileInfo = QFileInfo(m_path_.string().c_str()); if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - mPath = boost::filesystem::path(fileInfo.filePath().toStdString()); - LOG(INFO) << "set path" << mPath; - ui->fileTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); - dirModel->setRootPath(fileInfo.filePath()); - for (int i = 1; i < dirModel->columnCount(); ++i) { - ui->fileTreeView->resizeColumnToContents(i); +#ifdef WINDOWS + m_path_ = std::filesystem::path(fileInfo.filePath().toStdU16String()); +#else + m_path_ = std::filesystem::path(fileInfo.filePath().toStdString()); +#endif + + LOG(INFO) << "set path" << m_path_.u8string(); + ui_->fileTreeView->setRootIndex(dir_model_->index(fileInfo.filePath())); + dir_model_->setRootPath(fileInfo.filePath()); + for (int i = 1; i < dir_model_->columnCount(); ++i) { + ui_->fileTreeView->resizeColumnToContents(i); } - ui->pathEdit->setText(mPath.generic_path().string().c_str()); + ui_->pathEdit->setText(QString::fromStdString(m_path_.u8string())); } else { QMessageBox::critical( this, _("Error"), _("The path is not exists, unprivileged or unreachable.")); } - emit pathChanged(mPath.string().c_str()); + emit SignalPathChanged(QString::fromStdString(m_path_.u8string())); } -void FilePage::createPopupMenu() { - popUpMenu = new QMenu(); - - ui->actionOpenFile->setText(_("Open")); - connect(ui->actionOpenFile, &QAction::triggered, this, - &FilePage::slotOpenItem); - ui->actionRenameFile->setText(_("Rename")); - connect(ui->actionRenameFile, &QAction::triggered, this, - &FilePage::slotRenameItem); - ui->actionDeleteFile->setText(_("Delete")); - connect(ui->actionDeleteFile, &QAction::triggered, this, - &FilePage::slotDeleteItem); - - ui->actionEncrypt->setText(_("Encrypt")); - connect(ui->actionEncrypt, &QAction::triggered, this, - &FilePage::slotEncryptItem); - ui->actionEncryptSign->setText(_("Encrypt Sign")); - connect(ui->actionEncryptSign, &QAction::triggered, this, - &FilePage::slotEncryptSignItem); - ui->actionDecrypt->setText(QString(_("Decrypt Verify")) + " " + - _("(.gpg .asc)")); - connect(ui->actionDecrypt, &QAction::triggered, this, - &FilePage::slotDecryptItem); - ui->actionSign->setText(_("Sign")); - connect(ui->actionSign, &QAction::triggered, this, &FilePage::slotSignItem); - ui->actionVerify->setText(QString(_("Verify")) + " " + _("(.sig .gpg .asc)")); - connect(ui->actionVerify, &QAction::triggered, this, - &FilePage::slotVerifyItem); - - ui->actionCalculateHash->setText(_("Calculate Hash")); - connect(ui->actionCalculateHash, &QAction::triggered, this, - &FilePage::slotCalculateHash); - - ui->actionMakeDirectory->setText(_("Make New Directory")); - connect(ui->actionMakeDirectory, &QAction::triggered, this, - &FilePage::slotMkdir); - - ui->actionCreateEmptyFile->setText(_("Create Empty File")); - connect(ui->actionCreateEmptyFile, &QAction::triggered, this, - &FilePage::slotCreateEmptyFile); - - popUpMenu->addAction(ui->actionOpenFile); - popUpMenu->addAction(ui->actionRenameFile); - popUpMenu->addAction(ui->actionDeleteFile); - popUpMenu->addSeparator(); - popUpMenu->addAction(ui->actionEncrypt); - popUpMenu->addAction(ui->actionEncryptSign); - popUpMenu->addAction(ui->actionDecrypt); - popUpMenu->addAction(ui->actionSign); - popUpMenu->addAction(ui->actionVerify); - popUpMenu->addSeparator(); - popUpMenu->addAction(ui->actionMakeDirectory); - popUpMenu->addAction(ui->actionCreateEmptyFile); - popUpMenu->addAction(ui->actionCalculateHash); - - optionPopUpMenu = new QMenu(); +void FilePage::create_popup_menu() { + popup_menu_ = new QMenu(); + + ui_->actionOpenFile->setText(_("Open")); + connect(ui_->actionOpenFile, &QAction::triggered, this, + &FilePage::slot_open_item); + ui_->actionRenameFile->setText(_("Rename")); + connect(ui_->actionRenameFile, &QAction::triggered, this, + &FilePage::slot_rename_item); + ui_->actionDeleteFile->setText(_("Delete")); + connect(ui_->actionDeleteFile, &QAction::triggered, this, + &FilePage::slot_delete_item); + + ui_->actionCalculateHash->setText(_("Calculate Hash")); + connect(ui_->actionCalculateHash, &QAction::triggered, this, + &FilePage::slot_calculate_hash); + + ui_->actionMakeDirectory->setText(_("Directory")); + connect(ui_->actionMakeDirectory, &QAction::triggered, this, + &FilePage::slot_mkdir); + + ui_->actionCreateEmptyFile->setText(_("File")); + connect(ui_->actionCreateEmptyFile, &QAction::triggered, this, + &FilePage::slot_create_empty_file); + + ui_->actionCompressFiles->setText(_("Compress...")); + ui_->actionCompressFiles->setVisible(false); + connect(ui_->actionCompressFiles, &QAction::triggered, this, + &FilePage::slot_compress_files); + + auto new_item_action_menu = new QMenu(this); + new_item_action_menu->setTitle(_("New")); + new_item_action_menu->addAction(ui_->actionCreateEmptyFile); + new_item_action_menu->addAction(ui_->actionMakeDirectory); + + popup_menu_->addAction(ui_->actionOpenFile); + popup_menu_->addMenu(new_item_action_menu); + popup_menu_->addSeparator(); + popup_menu_->addAction(ui_->actionRenameFile); + popup_menu_->addAction(ui_->actionDeleteFile); + popup_menu_->addAction(ui_->actionCompressFiles); + popup_menu_->addAction(ui_->actionCalculateHash); + + option_popup_menu_ = new QMenu(); auto showHiddenAct = new QAction(_("Show Hidden File"), this); showHiddenAct->setCheckable(true); connect(showHiddenAct, &QAction::triggered, this, [&](bool checked) { LOG(INFO) << "Set Hidden" << checked; if (checked) - dirModel->setFilter(dirModel->filter() | QDir::Hidden); + dir_model_->setFilter(dir_model_->filter() | QDir::Hidden); else - dirModel->setFilter(dirModel->filter() & ~QDir::Hidden); - dirModel->setRootPath(mPath.string().c_str()); + dir_model_->setFilter(dir_model_->filter() & ~QDir::Hidden); + dir_model_->setRootPath(m_path_.u8string().c_str()); }); - optionPopUpMenu->addAction(showHiddenAct); + option_popup_menu_->addAction(showHiddenAct); auto showSystemAct = new QAction(_("Show System File"), this); showSystemAct->setCheckable(true); connect(showSystemAct, &QAction::triggered, this, [&](bool checked) { LOG(INFO) << "Set Hidden" << checked; if (checked) - dirModel->setFilter(dirModel->filter() | QDir::System); + dir_model_->setFilter(dir_model_->filter() | QDir::System); else - dirModel->setFilter(dirModel->filter() & ~QDir::System); - dirModel->setRootPath(mPath.string().c_str()); + dir_model_->setFilter(dir_model_->filter() & ~QDir::System); + dir_model_->setRootPath(m_path_.u8string().c_str()); }); - optionPopUpMenu->addAction(showSystemAct); + option_popup_menu_->addAction(showSystemAct); } void FilePage::onCustomContextMenu(const QPoint& point) { - QModelIndex index = ui->fileTreeView->indexAt(point); - selectedPath = boost::filesystem::path( - dirModel->fileInfo(index).absoluteFilePath().toStdString()); - LOG(INFO) << "right click" << selectedPath; + QModelIndex index = ui_->fileTreeView->indexAt(point); + LOG(INFO) << "right click" << selected_path_.u8string(); + +#ifdef WINDOWS + auto index_dir_str = dir_model_->fileInfo(index).absoluteFilePath().toStdU16String(); +#else + auto index_dir_str = dir_model_->fileInfo(index).absoluteFilePath().toStdString(); +#endif + + selected_path_ = std::filesystem::path(index_dir_str); + + // update crypt menu + slot_file_tree_view_item_clicked(index); + if (index.isValid()) { - ui->actionOpenFile->setEnabled(true); - ui->actionRenameFile->setEnabled(true); - ui->actionDeleteFile->setEnabled(true); - - QFileInfo info(QString::fromStdString(selectedPath.string())); - ui->actionEncrypt->setEnabled(info.isFile() && (info.suffix() != "gpg" && - info.suffix() != "sig" && - info.suffix() != "asc")); - ui->actionEncryptSign->setEnabled( - info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig" && - info.suffix() != "asc")); - ui->actionDecrypt->setEnabled( - info.isFile() && (info.suffix() == "gpg" || info.suffix() == "asc")); - ui->actionSign->setEnabled(info.isFile() && (info.suffix() != "gpg" && - info.suffix() != "sig" && - info.suffix() != "asc")); - ui->actionVerify->setEnabled(info.isFile() && (info.suffix() == "sig" || - info.suffix() == "gpg" || - info.suffix() == "asc")); - ui->actionCalculateHash->setEnabled(info.isFile() && info.isReadable()); + ui_->actionOpenFile->setEnabled(true); + ui_->actionRenameFile->setEnabled(true); + ui_->actionDeleteFile->setEnabled(true); + + QFileInfo info(QString::fromStdString(selected_path_.u8string())); + ui_->actionCalculateHash->setEnabled(info.isFile() && info.isReadable()); } else { - ui->actionOpenFile->setEnabled(false); - ui->actionRenameFile->setEnabled(false); - ui->actionDeleteFile->setEnabled(false); - - ui->actionEncrypt->setEnabled(false); - ui->actionEncryptSign->setEnabled(false); - ui->actionDecrypt->setEnabled(false); - ui->actionSign->setEnabled(false); - ui->actionVerify->setEnabled(false); - ui->actionCalculateHash->setEnabled(false); + ui_->actionOpenFile->setEnabled(false); + ui_->actionRenameFile->setEnabled(false); + ui_->actionDeleteFile->setEnabled(false); + + ui_->actionCalculateHash->setEnabled(false); } - popUpMenu->exec(ui->fileTreeView->viewport()->mapToGlobal(point)); + popup_menu_->exec(ui_->fileTreeView->viewport()->mapToGlobal(point)); } -void FilePage::slotOpenItem() { - QFileInfo info(QString::fromStdString(selectedPath.string())); +void FilePage::slot_open_item() { + QFileInfo info(QString::fromStdString(selected_path_.u8string())); if (info.isDir()) { if (info.isReadable() && info.isExecutable()) { - const auto file_path = info.filePath().toStdString(); + const auto file_path = info.filePath().toUtf8().toStdString(); LOG(INFO) << "set path" << file_path; - ui->pathEdit->setText(info.filePath()); - slotGoPath(); + ui_->pathEdit->setText(info.filePath().toUtf8()); + SlotGoPath(); } else { QMessageBox::critical(this, _("Error"), _("The directory is unprivileged or unreachable.")); } } else { if (info.isReadable()) { - auto mainWindow = qobject_cast<MainWindow*>(firstParent); - LOG(INFO) << "open item" << selectedPath; - auto qt_path = QString::fromStdString(selectedPath.string()); - if (mainWindow != nullptr) mainWindow->slotOpenFile(qt_path); + // handle normal text or binary file + auto main_window = qobject_cast<MainWindow*>(first_parent_); + auto qt_open_path = QString::fromStdString(selected_path_.u8string()); + LOG(INFO) << "open item" << qt_open_path.toStdString(); + if (main_window != nullptr) main_window->SlotOpenFile(qt_open_path); } else { QMessageBox::critical(this, _("Error"), _("The file is unprivileged or unreachable.")); @@ -301,22 +344,26 @@ void FilePage::slotOpenItem() { } } -void FilePage::slotRenameItem() { - auto new_name_path = selectedPath, old_name_path = selectedPath; +void FilePage::slot_rename_item() { + auto new_name_path = selected_path_, old_name_path = selected_path_; auto old_name = old_name_path.filename(); new_name_path = new_name_path.remove_filename(); bool ok; auto text = QInputDialog::getText(this, _("Rename"), _("New Filename"), - QLineEdit::Normal, old_name.string().c_str(), &ok); + QLineEdit::Normal, QString::fromStdString(old_name.u8string()), &ok); if (ok && !text.isEmpty()) { try { +#ifdef WINDOWS + new_name_path /= text.toStdU16String(); +#else new_name_path /= text.toStdString(); +#endif LOG(INFO) << "new name path" << new_name_path; - boost::filesystem::rename(old_name_path, new_name_path); + std::filesystem::rename(old_name_path, new_name_path); // refresh - this->slotGoPath(); + this->SlotGoPath(); } catch (...) { LOG(ERROR) << "rename error" << new_name_path; QMessageBox::critical(this, _("Error"), @@ -325,9 +372,9 @@ void FilePage::slotRenameItem() { } } -void FilePage::slotDeleteItem() { - QModelIndex index = ui->fileTreeView->currentIndex(); - QVariant data = ui->fileTreeView->model()->data(index); +void FilePage::slot_delete_item() { + QModelIndex index = ui_->fileTreeView->currentIndex(); + QVariant data = ui_->fileTreeView->model()->data(index); auto ret = QMessageBox::warning(this, _("Warning"), _("Are you sure you want to delete it?"), @@ -337,88 +384,19 @@ void FilePage::slotDeleteItem() { LOG(INFO) << "Delete Item" << data.toString().toStdString(); - if (!dirModel->remove(index)) { + if (!dir_model_->remove(index)) { QMessageBox::critical(this, _("Error"), _("Unable to delete the file or folder.")); } } -void FilePage::slotEncryptItem() { - auto mainWindow = qobject_cast<MainWindow*>(firstParent); - if (mainWindow != nullptr) mainWindow->slotFileEncrypt(); -} - -void FilePage::slotEncryptSignItem() { - auto mainWindow = qobject_cast<MainWindow*>(firstParent); - if (mainWindow != nullptr) mainWindow->slotFileEncryptSign(); -} - -void FilePage::slotDecryptItem() { - auto mainWindow = qobject_cast<MainWindow*>(firstParent); - if (mainWindow != nullptr) mainWindow->slotFileDecryptVerify(); +void FilePage::slot_calculate_hash() { + auto info_str = FileOperator::CalculateHash(selected_path_); + emit SignalRefreshInfoBoard(info_str.c_str(), InfoBoardStatus::INFO_ERROR_OK); } -void FilePage::slotSignItem() { - auto mainWindow = qobject_cast<MainWindow*>(firstParent); - if (mainWindow != nullptr) mainWindow->slotFileSign(); -} - -void FilePage::slotVerifyItem() { - auto mainWindow = qobject_cast<MainWindow*>(firstParent); - if (mainWindow != nullptr) mainWindow->slotFileVerify(); -} - -void FilePage::slotCalculateHash() { - // Returns empty QByteArray() on failure. - QFileInfo info(QString::fromStdString(selectedPath.string())); - - if (info.isFile() && info.isReadable()) { - std::stringstream ss; - - ss << "[#] " << _("File Hash Information") << std::endl; - ss << " " << _("filename") << _(": ") - << selectedPath.filename().string().c_str() << std::endl; - - QFile f(info.filePath()); - f.open(QFile::ReadOnly); - auto buffer = f.readAll(); - LOG(INFO) << "buffer size" << buffer.size(); - f.close(); - if (f.open(QFile::ReadOnly)) { - auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5); - // md5 - hash_md5.addData(buffer); - auto md5 = hash_md5.result().toHex().toStdString(); - LOG(INFO) << "md5" << md5; - ss << " " - << "md5" << _(": ") << md5 << std::endl; - - auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1); - // sha1 - hash_sha1.addData(buffer); - auto sha1 = hash_sha1.result().toHex().toStdString(); - LOG(INFO) << "sha1" << sha1; - ss << " " - << "sha1" << _(": ") << sha1 << std::endl; - - auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256); - // sha1 - hash_sha256.addData(buffer); - auto sha256 = hash_sha256.result().toHex().toStdString(); - LOG(INFO) << "sha256" << sha256; - ss << " " - << "sha256" << _(": ") << sha256 << std::endl; - - ss << std::endl; - - emit signalRefreshInfoBoard(ss.str().c_str(), - InfoBoardStatus::INFO_ERROR_OK); - } - } -} - -void FilePage::slotMkdir() { - auto index = ui->fileTreeView->rootIndex(); +void FilePage::slot_mkdir() { + auto index = ui_->fileTreeView->rootIndex(); QString new_dir_name; bool ok; @@ -426,13 +404,17 @@ void FilePage::slotMkdir() { QInputDialog::getText(this, _("Make New Directory"), _("Directory Name"), QLineEdit::Normal, new_dir_name, &ok); if (ok && !new_dir_name.isEmpty()) { - dirModel->mkdir(index, new_dir_name); + dir_model_->mkdir(index, new_dir_name); } } -void FilePage::slotCreateEmptyFile() { - auto root_path_str = dirModel->rootPath().toStdString(); - boost::filesystem::path root_path(root_path_str); +void FilePage::slot_create_empty_file() { +#ifdef WINDOWS + auto root_path_str = dir_model_->rootPath().toStdU16String(); +#else + auto root_path_str = dir_model_->rootPath().toStdString(); +#endif + std::filesystem::path root_path(root_path_str); QString new_file_name; bool ok; @@ -440,8 +422,12 @@ void FilePage::slotCreateEmptyFile() { _("Filename (you can given extension)"), QLineEdit::Normal, new_file_name, &ok); if (ok && !new_file_name.isEmpty()) { +#ifdef WINDOWS + auto file_path = root_path / new_file_name.toStdU16String(); +#else auto file_path = root_path / new_file_name.toStdString(); - QFile new_file(file_path.string().c_str()); +#endif + QFile new_file(file_path.u8string().c_str()); if (!new_file.open(QIODevice::WriteOnly | QIODevice::NewOnly)) { QMessageBox::critical(this, _("Error"), _("Unable to create the file.")); } @@ -451,16 +437,18 @@ void FilePage::slotCreateEmptyFile() { void FilePage::keyPressEvent(QKeyEvent* event) { LOG(INFO) << "Key Press" << event->key(); - if (ui->pathEdit->hasFocus() && + if (ui_->pathEdit->hasFocus() && (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) { - slotGoPath(); - } else if (ui->fileTreeView->currentIndex().isValid()) { + SlotGoPath(); + } else if (ui_->fileTreeView->currentIndex().isValid()) { if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) - slotOpenItem(); + slot_open_item(); else if (event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace) - slotDeleteItem(); + slot_delete_item(); } } +void FilePage::slot_compress_files() {} + } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/FilePage.h b/src/ui/widgets/FilePage.h index 1f2b51f8..cff395a8 100644 --- a/src/ui/widgets/FilePage.h +++ b/src/ui/widgets/FilePage.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,26 +8,28 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef GPGFRONTEND_FILEPAGE_H #define GPGFRONTEND_FILEPAGE_H -#include <boost/filesystem.hpp> + #include "ui/GpgFrontendUI.h" #include "ui/widgets/InfoBoardWidget.h" @@ -34,62 +38,150 @@ class Ui_FilePage; namespace GpgFrontend::UI { +/** + * @brief + * + */ class FilePage : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new File Page object + * + * @param parent + */ explicit FilePage(QWidget* parent = nullptr); - [[nodiscard]] QString getSelected() const; + /** + * @brief Get the Selected object + * + * @return QString + */ + [[nodiscard]] QString GetSelected() const; public slots: - void slotGoPath(); + /** + * @brief + * + */ + void SlotGoPath(); signals: - void pathChanged(const QString& path); - void signalRefreshInfoBoard(const QString& text, + /** + * @brief + * + * @param path + */ + void SignalPathChanged(const QString& path); + + /** + * @brief + * + * @param text + * @param verify_label_status + */ + void SignalRefreshInfoBoard(const QString& text, InfoBoardStatus verify_label_status); private slots: - void fileTreeViewItemClicked(const QModelIndex& index); - void fileTreeViewItemDoubleClicked(const QModelIndex& index); - - void slotUpLevel(); - - void slotOpenItem(); - void slotRenameItem(); - void slotDeleteItem(); - void slotEncryptItem(); - void slotEncryptSignItem(); - void slotDecryptItem(); - void slotSignItem(); - void slotVerifyItem(); - void slotCalculateHash(); - void slotMkdir(); - void slotCreateEmptyFile(); - - void onCustomContextMenu(const QPoint& point); + /** + * @brief + * + * @param index + */ + void slot_file_tree_view_item_clicked(const QModelIndex& index); + + /** + * @brief + * + * @param index + */ + void slot_file_tree_view_item_double_clicked(const QModelIndex& index); + + /** + * @brief + * + */ + void slot_up_level(); + + /** + * @brief + * + */ + void slot_open_item(); + + /** + * @brief + * + */ + void slot_rename_item(); + + /** + * @brief + * + */ + void slot_delete_item(); + + /** + * @brief + * + */ + void slot_calculate_hash(); + + /** + * @brief + * + */ + void slot_mkdir(); + + /** + * @brief + * + */ + void slot_create_empty_file(); + + /** + * @brief compress directory into gpg-zip + * + */ + void slot_compress_files(); protected: + /** + * @brief + * + * @param event + */ void keyPressEvent(QKeyEvent* event) override; + /** + * @brief + * + * @param point + */ + void onCustomContextMenu(const QPoint& point); + private: - void createPopupMenu(); + /** + * @brief Create a popup menu object + * + */ + void create_popup_menu(); - std::shared_ptr<Ui_FilePage> ui; + std::shared_ptr<Ui_FilePage> ui_; ///< - QFileSystemModel* dirModel; - QCompleter* pathEditCompleter; - QStringListModel* pathCompleteModel; + QFileSystemModel* dir_model_; ///< + QCompleter* path_edit_completer_; ///< + QStringListModel* path_complete_model_; ///< - // using boost path - boost::filesystem::path mPath; - boost::filesystem::path selectedPath; + std::filesystem::path m_path_; ///< + std::filesystem::path selected_path_; ///< - QMenu* popUpMenu{}; - QMenu* optionPopUpMenu{}; - QWidget* firstParent; + QMenu* popup_menu_{}; ///< + QMenu* option_popup_menu_{}; ///< + QWidget* first_parent_{}; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/FindWidget.cpp b/src/ui/widgets/FindWidget.cpp new file mode 100644 index 00000000..58ceda7c --- /dev/null +++ b/src/ui/widgets/FindWidget.cpp @@ -0,0 +1,171 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "FindWidget.h" + +namespace GpgFrontend::UI { + +FindWidget::FindWidget(QWidget* parent, PlainTextEditorPage* edit) + : QWidget(parent), m_text_page_(edit) { + find_edit_ = new QLineEdit(this); + auto* closeButton = new QPushButton( + this->style()->standardIcon(QStyle::SP_TitleBarCloseButton), QString(), + this); + auto* nextButton = new QPushButton(QIcon(":button_next.png"), QString()); + auto* previousButton = new QPushButton(QIcon(":button_previous.png"), ""); + + auto* notificationWidgetLayout = new QHBoxLayout(this); + notificationWidgetLayout->setContentsMargins(10, 0, 0, 0); + notificationWidgetLayout->addWidget(new QLabel(QString(_("Find")) + ": ")); + notificationWidgetLayout->addWidget(find_edit_, 2); + notificationWidgetLayout->addWidget(nextButton); + notificationWidgetLayout->addWidget(previousButton); + notificationWidgetLayout->addWidget(closeButton); + + this->setLayout(notificationWidgetLayout); + connect(find_edit_, &QLineEdit::textEdited, this, &FindWidget::slot_find); + connect(find_edit_, &QLineEdit::returnPressed, this, &FindWidget::slot_find_next); + connect(nextButton, &QPushButton::clicked, this, &FindWidget::slot_find_next); + connect(previousButton, &QPushButton::clicked, this, &FindWidget::slot_find_previous); + connect(closeButton, &QPushButton::clicked, this, &FindWidget::slot_close); + + // The timer is necessary for setting the focus + QTimer::singleShot(0, find_edit_, SLOT(setFocus())); +} + +void FindWidget::set_background() { + auto cursor = m_text_page_->GetTextPage()->textCursor(); + // if match is found set background of QLineEdit to white, otherwise to red + QPalette bgPalette(find_edit_->palette()); + + if (!find_edit_->text().isEmpty() && m_text_page_->GetTextPage() + ->document() + ->find(find_edit_->text()) + .position() < 0) { + bgPalette.setColor(QPalette::Base, "#ececba"); + } else { + bgPalette.setColor(QPalette::Base, Qt::white); + } + find_edit_->setPalette(bgPalette); +} + +void FindWidget::slot_find_next() { + QTextCursor cursor = m_text_page_->GetTextPage()->textCursor(); + cursor = m_text_page_->GetTextPage()->document()->find( + find_edit_->text(), cursor, QTextDocument::FindCaseSensitively); + + // if end of document is reached, restart search from beginning + if (cursor.position() == -1) { + cursor = m_text_page_->GetTextPage()->document()->find( + find_edit_->text(), cursor, QTextDocument::FindCaseSensitively); + } + + // cursor should not stay at -1, otherwise text is not editable + // todo: check how gedit handles this + if (cursor.position() != -1) { + m_text_page_->GetTextPage()->setTextCursor(cursor); + } + this->set_background(); +} + +void FindWidget::slot_find() { + QTextCursor cursor = m_text_page_->GetTextPage()->textCursor(); + + if (cursor.anchor() == -1) { + cursor = m_text_page_->GetTextPage()->document()->find( + find_edit_->text(), cursor, QTextDocument::FindCaseSensitively); + } else { + cursor = m_text_page_->GetTextPage()->document()->find( + find_edit_->text(), cursor.anchor(), + QTextDocument::FindCaseSensitively); + } + + // if end of document is reached, restart search from beginning + if (cursor.position() == -1) { + cursor = m_text_page_->GetTextPage()->document()->find( + find_edit_->text(), cursor, QTextDocument::FindCaseSensitively); + } + + // cursor should not stay at -1, otherwise text is not editable + // todo: check how gedit handles this + if (cursor.position() != -1) { + m_text_page_->GetTextPage()->setTextCursor(cursor); + } + this->set_background(); +} + +void FindWidget::slot_find_previous() { + QTextDocument::FindFlags flags; + flags |= QTextDocument::FindBackward; + flags |= QTextDocument::FindCaseSensitively; + + QTextCursor cursor = m_text_page_->GetTextPage()->textCursor(); + cursor = m_text_page_->GetTextPage()->document()->find(find_edit_->text(), + cursor, flags); + + // if begin of document is reached, restart search from end + if (cursor.position() == -1) { + cursor = m_text_page_->GetTextPage()->document()->find( + find_edit_->text(), QTextCursor::End, flags); + } + + // cursor should not stay at -1, otherwise text is not editable + // todo: check how gedit handles this + if (cursor.position() != -1) { + m_text_page_->GetTextPage()->setTextCursor(cursor); + } + this->set_background(); +} + +void FindWidget::keyPressEvent(QKeyEvent* e) { + switch (e->key()) { + case Qt::Key_Escape: + this->slot_close(); + break; + case Qt::Key_F3: + if (e->modifiers() & Qt::ShiftModifier) { + this->slot_find_previous(); + } else { + this->slot_find_next(); + } + break; + } +} + +void FindWidget::slot_close() { + QTextCursor cursor = m_text_page_->GetTextPage()->textCursor(); + + if (cursor.position() == -1) { + cursor.setPosition(0); + m_text_page_->GetTextPage()->setTextCursor(cursor); + } + m_text_page_->setFocus(); + close(); +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/FindWidget.h b/src/ui/widgets/FindWidget.h index e4cbdaab..dfe50f9c 100644 --- a/src/ui/FindWidget.h +++ b/src/ui/widgets/FindWidget.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -26,7 +30,7 @@ #define FINDWIDGET_H #include "ui/GpgFrontendUI.h" -#include "ui/widgets/EditorPage.h" +#include "ui/widgets/PlainTextEditorPage.h" namespace GpgFrontend::UI { @@ -42,29 +46,52 @@ class FindWidget : public QWidget { * * @param parent The parent widget */ - explicit FindWidget(QWidget* parent, QTextEdit* edit); + explicit FindWidget(QWidget* parent, PlainTextEditorPage* edit); - private: + protected: + /** + * @brief + * + * @param e + */ void keyPressEvent(QKeyEvent* e) override; + private: /** * @details Set background of findEdit to red, if no match is found (Documents * textcursor position equals -1), otherwise set it to white. */ - void setBackground(); + void set_background(); - QTextEdit* mTextpage; /** Textedit associated to the notification */ - QLineEdit* findEdit; /** Label holding the text shown in infoBoard */ + PlainTextEditorPage* + m_text_page_; ///< Textedit associated to the notification + QLineEdit* find_edit_; ///< Label holding the text shown in infoBoard private slots: - void slotFindNext(); + /** + * @brief + * + */ + void slot_find_next(); - void slotFindPrevious(); + /** + * @brief + * + */ + void slot_find_previous(); - void slotFind(); + /** + * @brief + * + */ + void slot_find(); - void slotClose(); + /** + * @brief + * + */ + void slot_close(); }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/GroupKeyList.cpp b/src/ui/widgets/GroupKeyList.cpp deleted file mode 100644 index efba4428..00000000 --- a/src/ui/widgets/GroupKeyList.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "GroupKeyList.h" diff --git a/src/ui/widgets/GroupKeyList.h b/src/ui/widgets/GroupKeyList.h deleted file mode 100644 index 163c7126..00000000 --- a/src/ui/widgets/GroupKeyList.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef GPGFRONTEND_GROUPKEYLIST_H -#define GPGFRONTEND_GROUPKEYLIST_H - -#include "ui/GpgFrontendUI.h" - -class GroupKeyList : public QWidget { - Q_OBJECT -}; - -#endif // GPGFRONTEND_GROUPKEYLIST_H diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp index 7b1e86c0..b116df30 100644 --- a/src/ui/widgets/HelpPage.cpp +++ b/src/ui/widgets/HelpPage.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,32 +33,33 @@ namespace GpgFrontend::UI { HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) { - browser = new QTextBrowser(); + browser_ = new QTextBrowser(); auto* mainLayout = new QVBoxLayout(); mainLayout->setSpacing(0); - mainLayout->addWidget(browser); + mainLayout->addWidget(browser_); mainLayout->setContentsMargins(0, 0, 0, 0); setLayout(mainLayout); - connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl))); - browser->setOpenLinks(false); - browser->setSource(localizedHelp(QUrl(path))); - browser->setFocus(); + connect(browser_, &QTextBrowser::anchorClicked, this, + &HelpPage::slot_open_url); + browser_->setOpenLinks(false); + browser_->setSource(localized_help(QUrl(path))); + browser_->setFocus(); } -void HelpPage::slotOpenUrl(const QUrl& url) { - browser->setSource(localizedHelp(url)); +void HelpPage::slot_open_url(const QUrl& url) { + browser_->setSource(localized_help(url)); }; /** - * @brief HelpPage::localizedHelp + * @brief HelpPage::localized_help * check if the requested file is also available with the locale, * e.g. return index.de.html if index.html was requested but the * locale is de and index.de.html is available * @param url * @return */ -QUrl HelpPage::localizedHelp(const QUrl& url) { +QUrl HelpPage::localized_help(const QUrl& url) { QString path = url.toLocalFile(); QString filename = path.mid(path.lastIndexOf("/") + 1); QString filepath = path.left(path.lastIndexOf("/") + 1); @@ -77,6 +82,6 @@ QUrl HelpPage::localizedHelp(const QUrl& url) { } } -QTextBrowser* HelpPage::getBrowser() { return browser; } +QTextBrowser* HelpPage::GetBrowser() { return browser_; } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/HelpPage.h b/src/ui/widgets/HelpPage.h index 25490557..0b0db5ea 100644 --- a/src/ui/widgets/HelpPage.h +++ b/src/ui/widgets/HelpPage.h @@ -1,22 +1,29 @@ -/* - * helppage.h +/** + * Copyright (C) 2021 Saturneric * - * Copyright 2008 gpg4usb-team <[email protected]> + * This file is part of GpgFrontend. * - * This file is part of gpg4usb. + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * Gpg4usb is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Gpg4usb is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later * - * You should have received a copy of the GNU General Public License - * along with gpg4usb. If not, see <http://www.gnu.org/licenses/> */ #ifndef HELPPAGE_H @@ -26,22 +33,40 @@ namespace GpgFrontend::UI { +/** + * @brief + * + */ class HelpPage : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Help Page object + * + * @param path + * @param parent + */ explicit HelpPage(const QString& path, QWidget* parent = nullptr); - QTextBrowser* getBrowser(); - - signals: + /** + * @brief Get the Browser object + * + * @return QTextBrowser* + */ + QTextBrowser* GetBrowser(); public slots: - void slotOpenUrl(const QUrl& url); + /** + * @brief + * + * @param url + */ + void slot_open_url(const QUrl& url); private: - QTextBrowser* browser; /** The textbrowser of the tab */ - QUrl localizedHelp(const QUrl& path); + QTextBrowser* browser_; ///< The textbrowser of the tab + QUrl localized_help(const QUrl& path); }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 7718cba3..ec2971cc 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,55 +8,58 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "ui/widgets/InfoBoardWidget.h" #include "ui/SignalStation.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" #include "ui_InfoBoard.h" +#include "ui/struct/SettingsObject.h" namespace GpgFrontend::UI { InfoBoardWidget::InfoBoardWidget(QWidget* parent) - : QWidget(parent), ui(std::make_shared<Ui_InfoBoard>()) { - ui->setupUi(this); - - ui->actionButtonLayout->addStretch(); - ui->copyButton->setText(_("Copy")); - ui->saveButton->setText(_("Save File")); - ui->clearButton->setText(_("Clear")); - - connect(ui->copyButton, &QPushButton::clicked, this, - &InfoBoardWidget::slotCopy); - connect(ui->saveButton, &QPushButton::clicked, this, - &InfoBoardWidget::slotSave); - connect(ui->clearButton, &QPushButton::clicked, this, - &InfoBoardWidget::slotReset); - - connect(SignalStation::GetInstance(), &SignalStation::signalRefreshInfoBoard, - this, &InfoBoardWidget::slotRefresh); + : QWidget(parent), ui_(std::make_shared<Ui_InfoBoard>()) { + ui_->setupUi(this); + + ui_->actionButtonLayout->addStretch(); + ui_->copyButton->setText(_("Copy")); + ui_->saveButton->setText(_("Save File")); + ui_->clearButton->setText(_("Clear")); + + connect(ui_->copyButton, &QPushButton::clicked, this, + &InfoBoardWidget::slot_copy); + connect(ui_->saveButton, &QPushButton::clicked, this, + &InfoBoardWidget::slot_save); + connect(ui_->clearButton, &QPushButton::clicked, this, + &InfoBoardWidget::SlotReset); + + connect(SignalStation::GetInstance(), &SignalStation::SignalRefreshInfoBoard, + this, &InfoBoardWidget::SlotRefresh); } -void InfoBoardWidget::setInfoBoard(const QString& text, - InfoBoardStatus verifyLabelStatus) { +void InfoBoardWidget::SetInfoBoard(const QString& text, + InfoBoardStatus verify_label_status) { QString color; - ui->infoBoard->clear(); - switch (verifyLabelStatus) { + ui_->infoBoard->clear(); + switch (verify_label_status) { case INFO_ERROR_OK: color = "#008000"; break; @@ -67,98 +72,95 @@ void InfoBoardWidget::setInfoBoard(const QString& text, default: break; } - ui->infoBoard->append(text); + ui_->infoBoard->append(text); - ui->infoBoard->setAutoFillBackground(true); - QPalette status = ui->infoBoard->palette(); + ui_->infoBoard->setAutoFillBackground(true); + QPalette status = ui_->infoBoard->palette(); status.setColor(QPalette::Text, color); - ui->infoBoard->setPalette(status); + ui_->infoBoard->setPalette(status); - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + SettingsObject main_windows_state("main_windows_state"); // info board font size - auto info_font_size = 10; - try { - info_font_size = settings.lookup("window.info_font_size"); - if (info_font_size < 9 || info_font_size > 18) info_font_size = 10; - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("info_font_size"); - } - ui->infoBoard->setFont(QFont("Times", info_font_size)); + auto info_font_size = main_windows_state.Check("info_font_size", 10); + ui_->infoBoard->setFont(QFont("Times", info_font_size)); } -void InfoBoardWidget::slotRefresh(const QString& text, InfoBoardStatus status) { - ui->infoBoard->clear(); - setInfoBoard(text, status); - ui->infoBoard->verticalScrollBar()->setValue(0); +void InfoBoardWidget::SlotRefresh(const QString& text, InfoBoardStatus status) { + ui_->infoBoard->clear(); + SetInfoBoard(text, status); + ui_->infoBoard->verticalScrollBar()->setValue(0); } -void InfoBoardWidget::associateTextEdit(QTextEdit* edit) { - if (mTextPage != nullptr) - disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); - this->mTextPage = edit; - connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); +void InfoBoardWidget::AssociateTextEdit(QTextEdit* edit) { + if (m_text_page_ != nullptr) + disconnect(m_text_page_, &QTextEdit::textChanged, this, + &InfoBoardWidget::SlotReset); + this->m_text_page_ = edit; + connect(edit, &QTextEdit::textChanged, this, &InfoBoardWidget::SlotReset); } -void InfoBoardWidget::associateTabWidget(QTabWidget* tab) { - mTextPage = nullptr; - mTabWidget = tab; - connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); - connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); +void InfoBoardWidget::AssociateTabWidget(QTabWidget* tab) { + m_text_page_ = nullptr; + m_tab_widget_ = tab; + connect(tab, &QTabWidget::tabBarClicked, this, &InfoBoardWidget::SlotReset); + connect(tab, &QTabWidget::tabCloseRequested, this, + &InfoBoardWidget::SlotReset); // reset - this->slotReset(); + this->SlotReset(); } -void InfoBoardWidget::addOptionalAction(const QString& name, +void InfoBoardWidget::AddOptionalAction(const QString& name, const std::function<void()>& action) { LOG(INFO) << "add option" << name.toStdString(); auto actionButton = new QPushButton(name); auto layout = new QHBoxLayout(); layout->setContentsMargins(5, 0, 5, 0); - ui->infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + ui_->infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); // set margin from surroundings layout->addWidget(actionButton); - ui->actionButtonLayout->addLayout(layout); + ui_->actionButtonLayout->addLayout(layout); connect(actionButton, &QPushButton::clicked, this, [=]() { action(); }); } /** * Delete All item in actionButtonLayout */ -void InfoBoardWidget::resetOptionActionsMenu() { +void InfoBoardWidget::ResetOptionActionsMenu() { // skip stretch - deleteWidgetsInLayout(ui->actionButtonLayout, 1); + delete_widgets_in_layout(ui_->actionButtonLayout, 1); } -void InfoBoardWidget::slotReset() { - ui->infoBoard->clear(); - resetOptionActionsMenu(); +void InfoBoardWidget::SlotReset() { + ui_->infoBoard->clear(); + ResetOptionActionsMenu(); } /** * Try Delete all widget from target layout * @param layout target layout */ -void InfoBoardWidget::deleteWidgetsInLayout(QLayout* layout, int start_index) { +void InfoBoardWidget::delete_widgets_in_layout(QLayout* layout, + int start_index) { LOG(INFO) << "Called"; QLayoutItem* item; while ((item = layout->layout()->takeAt(start_index)) != nullptr) { layout->removeItem(item); if (item->layout() != nullptr) - deleteWidgetsInLayout(item->layout()); + delete_widgets_in_layout(item->layout()); else if (item->widget() != nullptr) delete item->widget(); delete item; } } -void InfoBoardWidget::slotCopy() { +void InfoBoardWidget::slot_copy() { auto* clipboard = QGuiApplication::clipboard(); - clipboard->setText(ui->infoBoard->toPlainText()); + clipboard->setText(ui_->infoBoard->toPlainText()); } -void InfoBoardWidget::slotSave() { +void InfoBoardWidget::slot_save() { auto file_path = QFileDialog::getSaveFileName( this, _("Save Information Board's Content"), {}, tr("Text (*.txt)")); LOG(INFO) << "file path" << file_path.toStdString(); @@ -166,7 +168,7 @@ void InfoBoardWidget::slotSave() { QFile file(file_path); if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - file.write(ui->infoBoard->toPlainText().toUtf8()); + file.write(ui_->infoBoard->toPlainText().toUtf8()); } else { QMessageBox::critical( this, _("Error"), diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h index 8d37be6c..7f456777 100644 --- a/src/ui/widgets/InfoBoardWidget.h +++ b/src/ui/widgets/InfoBoardWidget.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,27 +8,29 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef __VERIFYNOTIFICATION_H__ #define __VERIFYNOTIFICATION_H__ -#include "EditorPage.h" -#include "gpg/result_analyse/VerifyResultAnalyse.h" +#include "PlainTextEditorPage.h" +#include "core/function/result_analyse/GpgVerifyResultAnalyse.h" #include "ui/details/VerifyDetailsDialog.h" class Ui_InfoBoard; @@ -34,7 +38,7 @@ class Ui_InfoBoard; namespace GpgFrontend::UI { /** - * @details Enumeration for the status of Verifylabel + * @details Enumeration for the status of Verify label */ typedef enum { INFO_ERROR_OK = 0, @@ -44,7 +48,7 @@ typedef enum { } InfoBoardStatus; /** - * @brief Class for handling the verifylabel shown at buttom of a textedit-page + * @brief Class for handling the verify label shown at bottom of a textedit-page */ class InfoBoardWidget : public QWidget { Q_OBJECT @@ -57,45 +61,86 @@ class InfoBoardWidget : public QWidget { */ explicit InfoBoardWidget(QWidget* parent); - void associateTextEdit(QTextEdit* edit); + /** + * @brief + * + * @param edit + */ + void AssociateTextEdit(QTextEdit* edit); - void associateTabWidget(QTabWidget* tab); + /** + * @brief + * + * @param tab + */ + void AssociateTabWidget(QTabWidget* tab); - void addOptionalAction(const QString& name, + /** + * @brief + * + * @param name + * @param action + */ + void AddOptionalAction(const QString& name, const std::function<void()>& action); - void resetOptionActionsMenu(); + /** + * @brief + * + */ + void ResetOptionActionsMenu(); /** * @details Set the text and background-color of verify notification. * * @param text The text to be set. - * @param verifyLabelStatus The status of label to set the specified color. + * @param verify_label_status The status of label to set the specified color. */ - void setInfoBoard(const QString& text, InfoBoardStatus verifyLabelStatus); + void SetInfoBoard(const QString& text, + GpgFrontend::UI::InfoBoardStatus verify_label_status); public slots: - void slotReset(); + /** + * @brief + * + */ + void SlotReset(); /** * @details Refresh the contents of dialog. */ - void slotRefresh(const QString& text, InfoBoardStatus status); + void SlotRefresh(const QString& text, + GpgFrontend::UI::InfoBoardStatus status); private slots: - void slotCopy(); + /** + * @brief + * + */ + void slot_copy(); - void slotSave(); + /** + * @brief + * + */ + void slot_save(); private: - std::shared_ptr<Ui_InfoBoard> ui; + std::shared_ptr<Ui_InfoBoard> ui_; ///< - QTextEdit* mTextPage{nullptr}; /** TextEdit associated to the notification */ - QTabWidget* mTabWidget{nullptr}; + QTextEdit* m_text_page_{ + nullptr}; ///< TextEdit associated to the notification + QTabWidget* m_tab_widget_{nullptr}; ///< - void deleteWidgetsInLayout(QLayout* layout, int start_index = 0); + /** + * @brief + * + * @param layout + * @param start_index + */ + void delete_widgets_in_layout(QLayout* layout, int start_index = 0); }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 89634f95..60cfbc84 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -27,21 +31,21 @@ #include <boost/format.hpp> #include <utility> -#include "gpg/GpgCoreInit.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/GpgCoreInit.h" +#include "core/function/gpg/GpgKeyGetter.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" -#include "ui/settings/GlobalSettingStation.h" +#include "core/function/GlobalSettingStation.h" #include "ui_KeyList.h" namespace GpgFrontend::UI { -int KeyList::key_list_id = 2048; +int KeyList::key_list_id_ = 2048; KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent) : QWidget(parent), - _m_key_list_id(key_list_id++), - ui(std::make_shared<Ui_KeyList>()), + m_key_list_id_(key_list_id_++), + ui_(std::make_shared<Ui_KeyList>()), menu_ability_(menu_ability) { init(); } @@ -49,70 +53,73 @@ KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent) void KeyList::init() { #ifdef GPG_STANDALONE_MODE LOG(INFO) << "GPG_STANDALONE_MODE Enabled"; - auto gpg_path = GpgFrontend::UI::GlobalSettingStation::GetInstance() + auto gpg_path = GpgFrontend::GlobalSettingStation::GetInstance() .GetStandaloneGpgBinDir(); - auto db_path = GpgFrontend::UI::GlobalSettingStation::GetInstance() + auto db_path = GpgFrontend::GlobalSettingStation::GetInstance() .GetStandaloneDatabaseDir(); GpgContext::CreateInstance( - _m_key_list_id, std::make_unique<GpgContext>(true, db_path.string(), true, + _m_key_list_id, std::make_unique<GpgContext>(true, db_path.u8string(), true, gpg_path.string())); #else - new_default_settings_channel(_m_key_list_id); + new_default_settings_channel(m_key_list_id_); #endif - ui->setupUi(this); + ui_->setupUi(this); - ui->menuWidget->setHidden(!menu_ability_); - ui->refreshKeyListButton->setHidden(~menu_ability_ & KeyMenuAbility::REFRESH); - ui->syncButton->setHidden(~menu_ability_ & KeyMenuAbility::SYNC_PUBLIC_KEY); - ui->uncheckButton->setHidden(~menu_ability_ & KeyMenuAbility::UNCHECK_ALL); + ui_->menuWidget->setHidden(!menu_ability_); + ui_->refreshKeyListButton->setHidden(~menu_ability_ & + KeyMenuAbility::REFRESH); + ui_->syncButton->setHidden(~menu_ability_ & KeyMenuAbility::SYNC_PUBLIC_KEY); + ui_->uncheckButton->setHidden(~menu_ability_ & KeyMenuAbility::UNCHECK_ALL); - ui->keyGroupTab->clear(); - popupMenu = new QMenu(this); + ui_->keyGroupTab->clear(); + popup_menu_ = new QMenu(this); // register key database refresh signal - connect(this, &KeyList::signalRefreshDatabase, SignalStation::GetInstance(), - &SignalStation::KeyDatabaseRefresh); - connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, - SLOT(slotRefresh())); - connect(ui->refreshKeyListButton, &QPushButton::clicked, this, - &KeyList::slotRefresh); - connect(ui->uncheckButton, &QPushButton::clicked, this, - &KeyList::slotUncheckALL); - connect(ui->checkALLButton, &QPushButton::clicked, this, - &KeyList::slotCheckALL); - connect(ui->syncButton, &QPushButton::clicked, this, - &KeyList::slotSyncWithKeyServer); - connect(this, &KeyList::signalRefreshStatusBar, SignalStation::GetInstance(), - &SignalStation::signalRefreshStatusBar); + connect(this, &KeyList::SignalRefreshDatabase, SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh); + connect(SignalStation::GetInstance(), + &SignalStation::SignalKeyDatabaseRefresh, this, + &KeyList::SlotRefresh); + connect(ui_->refreshKeyListButton, &QPushButton::clicked, this, + &KeyList::SlotRefresh); + connect(ui_->uncheckButton, &QPushButton::clicked, this, + &KeyList::uncheck_all); + connect(ui_->checkALLButton, &QPushButton::clicked, this, + &KeyList::check_all); + connect(ui_->syncButton, &QPushButton::clicked, this, + &KeyList::slot_sync_with_key_server); + connect(this, &KeyList::SignalRefreshStatusBar, SignalStation::GetInstance(), + &SignalStation::SignalRefreshStatusBar); setAcceptDrops(true); - ui->refreshKeyListButton->setText(_("Refresh")); - ui->refreshKeyListButton->setToolTip( + ui_->refreshKeyListButton->setText(_("Refresh")); + ui_->refreshKeyListButton->setToolTip( _("Refresh the key list to synchronize changes.")); - ui->syncButton->setText(_("Sync Public Key")); - ui->syncButton->setToolTip(_("Sync public key with your default keyserver.")); - ui->uncheckButton->setText(_("Uncheck ALL")); - ui->uncheckButton->setToolTip( + ui_->syncButton->setText(_("Sync Public Key")); + ui_->syncButton->setToolTip( + _("Sync public key with your default keyserver.")); + ui_->uncheckButton->setText(_("Uncheck ALL")); + ui_->uncheckButton->setToolTip( _("Cancel all checked items in the current tab at once.")); - ui->checkALLButton->setText(_("Check ALL")); - ui->checkALLButton->setToolTip( + ui_->checkALLButton->setText(_("Check ALL")); + ui_->checkALLButton->setToolTip( _("Check all items in the current tab at once")); } -void KeyList::addListGroupTab( +void KeyList::AddListGroupTab( const QString& name, KeyListRow::KeyType selectType, KeyListColumn::InfoType infoType, const std::function<bool(const GpgKey&)>& filter) { LOG(INFO) << _("Called") << name.toStdString(); auto key_list = new QTableWidget(this); - if (mKeyList == nullptr) { - mKeyList = key_list; + if (m_key_list_ == nullptr) { + m_key_list_ = key_list; } - ui->keyGroupTab->addTab(key_list, name); - mKeyTables.emplace_back(key_list, selectType, infoType, filter); + ui_->keyGroupTab->addTab(key_list, name); + m_key_tables_.emplace_back(key_list, selectType, infoType, filter); key_list->setColumnCount(7); key_list->horizontalHeader()->setSectionResizeMode( @@ -159,96 +166,100 @@ void KeyList::addListGroupTab( key_list->horizontalHeader()->setStretchLastSection(false); connect(key_list, &QTableWidget::doubleClicked, this, - &KeyList::slotDoubleClicked); + &KeyList::slot_double_clicked); } -void KeyList::slotRefresh() { - LOG(INFO) << _("Called") << "_m_key_list_id" << _m_key_list_id; - emit signalRefreshStatusBar(_("Refreshing Key List..."), 3000); - auto thread = QThread::create([this, _id = _m_key_list_id]() { - std::lock_guard<std::mutex> guard(buffered_key_list_mutex); - _buffered_keys_list = nullptr; +void KeyList::SlotRefresh() { + LOG(INFO) << _("Called") << "_m_key_list_id" << m_key_list_id_; + emit SignalRefreshStatusBar(_("Refreshing Key List..."), 3000); + auto thread = QThread::create([this, _id = m_key_list_id_]() { + std::lock_guard<std::mutex> guard(buffered_key_list_mutex_); + buffered_keys_list_ = nullptr; // buffered keys list - _buffered_keys_list = GpgKeyGetter::GetInstance(_id).FetchKey(); + buffered_keys_list_ = GpgKeyGetter::GetInstance(_id).FetchKey(); }); - connect(thread, &QThread::finished, this, &KeyList::slotRefreshUI); + connect(thread, &QThread::finished, this, &KeyList::slot_refresh_ui); connect(thread, &QThread::finished, thread, &QThread::deleteLater); - ui->refreshKeyListButton->setDisabled(true); - ui->syncButton->setDisabled(true); + ui_->refreshKeyListButton->setDisabled(true); + ui_->syncButton->setDisabled(true); thread->start(); } -KeyIdArgsListPtr KeyList::getChecked(const KeyTable& key_table) { +KeyIdArgsListPtr KeyList::GetChecked(const KeyTable& key_table) { auto ret = std::make_unique<KeyIdArgsList>(); - for (int i = 0; i < key_table.key_list->rowCount(); i++) { - if (key_table.key_list->item(i, 0)->checkState() == Qt::Checked) { - ret->push_back(key_table.buffered_keys[i].id()); + for (int i = 0; i < key_table.key_list_->rowCount(); i++) { + if (key_table.key_list_->item(i, 0)->checkState() == Qt::Checked) { + ret->push_back(key_table.buffered_keys_[i].GetId()); } } return ret; } -KeyIdArgsListPtr KeyList::getChecked() { - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +KeyIdArgsListPtr KeyList::GetChecked() { + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; + m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_; auto ret = std::make_unique<KeyIdArgsList>(); for (int i = 0; i < key_list->rowCount(); i++) { if (key_list->item(i, 0)->checkState() == Qt::Checked) { - ret->push_back(buffered_keys[i].id()); + ret->push_back(buffered_keys[i].GetId()); } } return ret; } -KeyIdArgsListPtr KeyList::getAllPrivateKeys() { - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +KeyIdArgsListPtr KeyList::GetAllPrivateKeys() { + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; + m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_; auto ret = std::make_unique<KeyIdArgsList>(); for (int i = 0; i < key_list->rowCount(); i++) { - if (key_list->item(i, 1) && buffered_keys[i].is_private_key()) { - ret->push_back(buffered_keys[i].id()); + if (key_list->item(i, 1) && buffered_keys[i].IsPrivateKey()) { + ret->push_back(buffered_keys[i].GetId()); } } return ret; } -KeyIdArgsListPtr KeyList::getPrivateChecked() { +KeyIdArgsListPtr KeyList::GetPrivateChecked() { auto ret = std::make_unique<KeyIdArgsList>(); - if (ui->keyGroupTab->size().isEmpty()) return ret; + if (ui_->keyGroupTab->size().isEmpty()) return ret; - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; + m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_; for (int i = 0; i < key_list->rowCount(); i++) { if ((key_list->item(i, 0)->checkState() == Qt::Checked) && (key_list->item(i, 1))) { - ret->push_back(buffered_keys[i].id()); + ret->push_back(buffered_keys[i].GetId()); } } return ret; } -void KeyList::setChecked(const KeyIdArgsListPtr& keyIds, +void KeyList::SetChecked(const KeyIdArgsListPtr& keyIds, const KeyTable& key_table) { if (!keyIds->empty()) { - for (int i = 0; i < key_table.key_list->rowCount(); i++) { + for (int i = 0; i < key_table.key_list_->rowCount(); i++) { if (std::find(keyIds->begin(), keyIds->end(), - key_table.buffered_keys[i].id()) != keyIds->end()) { - key_table.key_list->item(i, 0)->setCheckState(Qt::Checked); + key_table.buffered_keys_[i].GetId()) != keyIds->end()) { + key_table.key_list_->item(i, 0)->setCheckState(Qt::Checked); } } } } -void KeyList::setChecked(KeyIdArgsListPtr key_ids) { - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +void KeyList::SetChecked(KeyIdArgsListPtr key_ids) { + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); if (key_list == nullptr) return; - if (!mKeyTables.empty()) { - for (auto& key_table : mKeyTables) { - if (key_table.key_list == key_list) { + if (!m_key_tables_.empty()) { + for (auto& key_table : m_key_tables_) { + if (key_table.key_list_ == key_list) { key_table.SetChecked(std::move(key_ids)); break; } @@ -256,53 +267,54 @@ void KeyList::setChecked(KeyIdArgsListPtr key_ids) { } } -KeyIdArgsListPtr KeyList::getSelected() { +KeyIdArgsListPtr KeyList::GetSelected() { auto ret = std::make_unique<KeyIdArgsList>(); - if (ui->keyGroupTab->size().isEmpty()) return ret; + if (ui_->keyGroupTab->size().isEmpty()) return ret; - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; + m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_; for (int i = 0; i < key_list->rowCount(); i++) { if (key_list->item(i, 0)->isSelected() == 1) { - ret->push_back(buffered_keys[i].id()); + ret->push_back(buffered_keys[i].GetId()); } } return ret; } -[[maybe_unused]] bool KeyList::containsPrivateKeys() { - if (ui->keyGroupTab->size().isEmpty()) return false; - mKeyList = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +[[maybe_unused]] bool KeyList::ContainsPrivateKeys() { + if (ui_->keyGroupTab->size().isEmpty()) return false; + m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 1)) { + for (int i = 0; i < m_key_list_->rowCount(); i++) { + if (m_key_list_->item(i, 1)) { return true; } } return false; } -void KeyList::setColumnWidth(int row, int size) { - if (ui->keyGroupTab->size().isEmpty()) return; - mKeyList = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +void KeyList::SetColumnWidth(int row, int size) { + if (ui_->keyGroupTab->size().isEmpty()) return; + m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); - mKeyList->setColumnWidth(row, size); + m_key_list_->setColumnWidth(row, size); } void KeyList::contextMenuEvent(QContextMenuEvent* event) { - if (ui->keyGroupTab->size().isEmpty()) return; - mKeyList = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); + if (ui_->keyGroupTab->size().isEmpty()) return; + m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); - if (mKeyList->selectedItems().length() > 0) { - popupMenu->exec(event->globalPos()); + if (m_key_list_->selectedItems().length() > 0) { + popup_menu_->exec(event->globalPos()); } } -void KeyList::addSeparator() { popupMenu->addSeparator(); } +void KeyList::AddSeparator() { popup_menu_->addSeparator(); } -void KeyList::addMenuAction(QAction* act) { popupMenu->addAction(act); } +void KeyList::AddMenuAction(QAction* act) { popup_menu_->addAction(act); } void KeyList::dropEvent(QDropEvent* event) { auto* dialog = new QDialog(); @@ -331,8 +343,8 @@ void KeyList::dropEvent(QDropEvent* event) { // Buttons for ok and cancel auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + connect(buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject); auto* vbox = new QVBoxLayout(); vbox->addWidget(label); @@ -355,7 +367,7 @@ void KeyList::dropEvent(QDropEvent* event) { else { general["confirm_import_keys"] = checkBox->isChecked(); } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } if (event->mimeData()->hasUrls()) { @@ -367,12 +379,12 @@ void KeyList::dropEvent(QDropEvent* event) { << tmp.toString().toStdString(); } QByteArray inBuffer = file.readAll(); - this->importKeys(inBuffer); + this->import_keys(inBuffer); file.close(); } } else { QByteArray inBuffer(event->mimeData()->text().toUtf8()); - this->importKeys(inBuffer); + this->import_keys(inBuffer); } } @@ -383,102 +395,103 @@ void KeyList::dragEnterEvent(QDragEnterEvent* event) { /** set background color for Keys and put them to top * */ -[[maybe_unused]] void KeyList::markKeys(QStringList* keyIds) { +[[maybe_unused]] void KeyList::MarkKeys(QStringList* keyIds) { foreach (QString id, *keyIds) { qDebug() << "marked: " << id; } } -void KeyList::importKeys(const QByteArray& inBuffer) { +void KeyList::import_keys(const QByteArray& inBuffer) { auto std_buffer = std::make_unique<ByteArray>(inBuffer.toStdString()); GpgImportInformation result = - GpgKeyImportExporter::GetInstance(_m_key_list_id) + GpgKeyImportExporter::GetInstance(m_key_list_id_) .ImportKey(std::move(std_buffer)); new KeyImportDetailDialog(result, false, this); } -void KeyList::slotDoubleClicked(const QModelIndex& index) { - if (ui->keyGroupTab->size().isEmpty()) return; +void KeyList::slot_double_clicked(const QModelIndex& index) { + if (ui_->keyGroupTab->size().isEmpty()) return; const auto& buffered_keys = - mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; - if (mAction != nullptr) { - const auto key = GpgKeyGetter::GetInstance(_m_key_list_id) - .GetKey(buffered_keys[index.row()].id()); - mAction(key, this); + m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_; + if (m_action_ != nullptr) { + const auto key = GpgKeyGetter::GetInstance(m_key_list_id_) + .GetKey(buffered_keys[index.row()].GetId()); + m_action_(key, this); } } -void KeyList::setDoubleClickedAction( +void KeyList::SetDoubleClickedAction( std::function<void(const GpgKey&, QWidget*)> action) { - this->mAction = std::move(action); + this->m_action_ = std::move(action); } -std::string KeyList::getSelectedKey() { - if (ui->keyGroupTab->size().isEmpty()) return {}; +std::string KeyList::GetSelectedKey() { + if (ui_->keyGroupTab->size().isEmpty()) return {}; const auto& buffered_keys = - mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; + m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_; - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->isSelected() == 1) { - return buffered_keys[i].id(); + for (int i = 0; i < m_key_list_->rowCount(); i++) { + if (m_key_list_->item(i, 0)->isSelected() == 1) { + return buffered_keys[i].GetId(); } } return {}; } -void KeyList::slotRefreshUI() { - LOG(INFO) << _("Called") << _buffered_keys_list.get(); - if (_buffered_keys_list != nullptr) { - std::lock_guard<std::mutex> guard(buffered_key_list_mutex); - for (auto& key_table : mKeyTables) { - key_table.Refresh(GpgKeyGetter::GetKeysCopy(_buffered_keys_list)); +void KeyList::slot_refresh_ui() { + LOG(INFO) << _("Called") << buffered_keys_list_.get(); + if (buffered_keys_list_ != nullptr) { + std::lock_guard<std::mutex> guard(buffered_key_list_mutex_); + for (auto& key_table : m_key_tables_) { + key_table.Refresh(GpgKeyGetter::GetKeysCopy(buffered_keys_list_)); } } - emit signalRefreshStatusBar(_("Key List Refreshed."), 1000); - ui->refreshKeyListButton->setDisabled(false); - ui->syncButton->setDisabled(false); + emit SignalRefreshStatusBar(_("Key List Refreshed."), 1000); + ui_->refreshKeyListButton->setDisabled(false); + ui_->syncButton->setDisabled(false); } -void KeyList::slotSyncWithKeyServer() { +void KeyList::slot_sync_with_key_server() { KeyIdArgsList key_ids; { - std::lock_guard<std::mutex> guard(buffered_key_list_mutex); - for (const auto& key : *_buffered_keys_list) { - if (!(key.is_private_key() && key.has_master_key())) - key_ids.push_back(key.id()); + std::lock_guard<std::mutex> guard(buffered_key_list_mutex_); + for (const auto& key : *buffered_keys_list_) { + if (!(key.IsPrivateKey() && key.IsHasMasterKey())) + key_ids.push_back(key.GetId()); } } - ui->refreshKeyListButton->setDisabled(true); - ui->syncButton->setDisabled(true); + ui_->refreshKeyListButton->setDisabled(true); + ui_->syncButton->setDisabled(true); - emit signalRefreshStatusBar(_("Syncing Key List..."), 3000); - CommonUtils::slotImportKeyFromKeyServer( - _m_key_list_id, key_ids, + emit SignalRefreshStatusBar(_("Syncing Key List..."), 3000); + CommonUtils::SlotImportKeyFromKeyServer( + m_key_list_id_, key_ids, [=](const std::string& key_id, const std::string& status, size_t current_index, size_t all_index) { LOG(INFO) << _("Called") << key_id << status << current_index << all_index; - auto key = GpgKeyGetter::GetInstance(_m_key_list_id).GetKey(key_id); + auto key = GpgKeyGetter::GetInstance(m_key_list_id_).GetKey(key_id); boost::format status_str = boost::format(_("Sync [%1%/%2%] %3% %4%")) % current_index % all_index % - key.uids()->front().uid() % status; - emit signalRefreshStatusBar(status_str.str().c_str(), 1500); + key.GetUIDs()->front().GetUID() % status; + emit SignalRefreshStatusBar(status_str.str().c_str(), 1500); if (current_index == all_index) { - ui->syncButton->setDisabled(false); - ui->refreshKeyListButton->setDisabled(false); - emit signalRefreshStatusBar(_("Key List Sync Done."), 3000); - emit signalRefreshDatabase(); + ui_->syncButton->setDisabled(false); + ui_->refreshKeyListButton->setDisabled(false); + emit SignalRefreshStatusBar(_("Key List Sync Done."), 3000); + emit SignalRefreshDatabase(); } }); } -void KeyList::slotUncheckALL() { - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +void KeyList::uncheck_all() { + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); if (key_list == nullptr) return; - if (!mKeyTables.empty()) { - for (auto& key_table : mKeyTables) { - if (key_table.key_list == key_list) { + if (!m_key_tables_.empty()) { + for (auto& key_table : m_key_tables_) { + if (key_table.key_list_ == key_list) { key_table.UncheckALL(); break; } @@ -486,12 +499,13 @@ void KeyList::slotUncheckALL() { } } -void KeyList::slotCheckALL() { - auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); +void KeyList::check_all() { + auto key_list = + qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget()); if (key_list == nullptr) return; - if (!mKeyTables.empty()) { - for (auto& key_table : mKeyTables) { - if (key_table.key_list == key_list) { + if (!m_key_tables_.empty()) { + for (auto& key_table : m_key_tables_) { + if (key_table.key_list_ == key_list) { key_table.CheckALL(); break; } @@ -504,9 +518,9 @@ KeyIdArgsListPtr& KeyTable::GetChecked() { if (checked_key_ids_ == nullptr) checked_key_ids_ = std::make_unique<KeyIdArgsList>(); auto& ret = checked_key_ids_; - for (int i = 0; i < key_list->rowCount(); i++) { - auto key_id = buffered_keys[i].id(); - if (key_list->item(i, 0)->checkState() == Qt::Checked && + for (int i = 0; i < key_list_->rowCount(); i++) { + auto key_id = buffered_keys_[i].GetId(); + if (key_list_->item(i, 0)->checkState() == Qt::Checked && std::find(ret->begin(), ret->end(), key_id) == ret->end()) { ret->push_back(key_id); } @@ -525,8 +539,8 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { auto& checked_key_list = GetChecked(); // while filling the table, sort enabled causes errors - key_list->setSortingEnabled(false); - key_list->clearContents(); + key_list_->setSortingEnabled(false); + key_list_->clearContents(); // Optimization for copy KeyLinkListPtr keys = nullptr; @@ -539,13 +553,13 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { int row_count = 0; while (it != keys->end()) { - if (filter != nullptr) { - if (!filter(*it)) { + if (filter_ != nullptr) { + if (!filter_(*it)) { it = keys->erase(it); continue; } } - if (select_type == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) { + if (select_type_ == KeyListRow::ONLY_SECRET_KEY && !it->IsPrivateKey()) { it = keys->erase(it); continue; } @@ -553,72 +567,73 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { it++; } - key_list->setRowCount(row_count); + key_list_->setRowCount(row_count); int row_index = 0; it = keys->begin(); - auto& table_buffered_keys = buffered_keys; + auto& table_buffered_keys = buffered_keys_; table_buffered_keys.clear(); while (it != keys->end()) { - table_buffered_keys.push_back(it->copy()); + table_buffered_keys.push_back(it->Copy()); auto* tmp0 = new QTableWidgetItem(QString::number(row_index)); tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); tmp0->setTextAlignment(Qt::AlignCenter); tmp0->setCheckState(Qt::Unchecked); - key_list->setItem(row_index, 0, tmp0); + key_list_->setItem(row_index, 0, tmp0); QString type_str; QTextStream type_steam(&type_str); - if (it->is_private_key()) { + if (it->IsPrivateKey()) { type_steam << "pub/sec"; } else { type_steam << "pub"; } - if (it->is_private_key() && !it->has_master_key()) { + if (it->IsPrivateKey() && !it->IsHasMasterKey()) { type_steam << "#"; } - if(it->HasCardKey()) { + if (it->IsHasCardKey()) { type_steam << "^"; } auto* tmp1 = new QTableWidgetItem(type_str); - key_list->setItem(row_index, 1, tmp1); + key_list_->setItem(row_index, 1, tmp1); - auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name())); - key_list->setItem(row_index, 2, tmp2); - auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email())); - key_list->setItem(row_index, 3, tmp3); + auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->GetName())); + key_list_->setItem(row_index, 2, tmp2); + auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->GetEmail())); + key_list_->setItem(row_index, 3, tmp3); QString usage; QTextStream usage_steam(&usage); - if (it->CanCertActual()) usage_steam << "C"; - if (it->CanEncrActual()) usage_steam << "E"; - if (it->CanSignActual()) usage_steam << "S"; - if (it->CanAuthActual()) usage_steam << "A"; + if (it->IsHasActualCertificationCapability()) usage_steam << "C"; + if (it->IsHasActualEncryptionCapability()) usage_steam << "E"; + if (it->IsHasActualSigningCapability()) usage_steam << "S"; + if (it->IsHasActualAuthenticationCapability()) usage_steam << "A"; auto* temp_usage = new QTableWidgetItem(usage); temp_usage->setTextAlignment(Qt::AlignCenter); - key_list->setItem(row_index, 4, temp_usage); + key_list_->setItem(row_index, 4, temp_usage); auto* temp_validity = - new QTableWidgetItem(QString::fromStdString(it->owner_trust())); + new QTableWidgetItem(QString::fromStdString(it->GetOwnerTrust())); temp_validity->setTextAlignment(Qt::AlignCenter); - key_list->setItem(row_index, 5, temp_validity); + key_list_->setItem(row_index, 5, temp_validity); - auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr())); + auto* temp_fpr = + new QTableWidgetItem(QString::fromStdString(it->GetFingerprint())); temp_fpr->setTextAlignment(Qt::AlignCenter); - key_list->setItem(row_index, 6, temp_fpr); + key_list_->setItem(row_index, 6, temp_fpr); // strike out expired keys - if (it->expired() || it->revoked()) { + if (it->IsExpired() || it->IsRevoked()) { QFont strike = tmp2->font(); strike.setStrikeOut(true); tmp0->setFont(strike); @@ -634,10 +649,10 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { } if (!checked_key_list->empty()) { - for (int i = 0; i < key_list->rowCount(); i++) { + for (int i = 0; i < key_list_->rowCount(); i++) { if (std::find(checked_key_list->begin(), checked_key_list->end(), - buffered_keys[i].id()) != checked_key_list->end()) { - key_list->item(i, 0)->setCheckState(Qt::Checked); + buffered_keys_[i].GetId()) != checked_key_list->end()) { + key_list_->item(i, 0)->setCheckState(Qt::Checked); } } } @@ -646,14 +661,14 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { } void KeyTable::UncheckALL() const { - for (int i = 0; i < key_list->rowCount(); i++) { - key_list->item(i, 0)->setCheckState(Qt::Unchecked); + for (int i = 0; i < key_list_->rowCount(); i++) { + key_list_->item(i, 0)->setCheckState(Qt::Unchecked); } } void KeyTable::CheckALL() const { - for (int i = 0; i < key_list->rowCount(); i++) { - key_list->item(i, 0)->setCheckState(Qt::Checked); + for (int i = 0; i < key_list_->rowCount(); i++) { + key_list_->item(i, 0)->setCheckState(Qt::Checked); } } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h index 4b41decd..d79f9331 100644 --- a/src/ui/widgets/KeyList.h +++ b/src/ui/widgets/KeyList.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -27,147 +31,357 @@ #include <utility> -#include "gpg/GpgContext.h" -#include "ui/KeyImportDetailDialog.h" +#include "core/GpgContext.h" +#include "ui/import_export/KeyImportDetailDialog.h" class Ui_KeyList; namespace GpgFrontend::UI { +/** + * @brief + * + */ struct KeyListRow { using KeyType = unsigned int; - static const KeyType SECRET_OR_PUBLIC_KEY = 0; - static const KeyType ONLY_SECRET_KEY = 1; + static const KeyType SECRET_OR_PUBLIC_KEY = 0; ///< + static const KeyType ONLY_SECRET_KEY = 1; ///< }; +/** + * @brief + * + */ struct KeyListColumn { using InfoType = unsigned int; - static constexpr InfoType ALL = ~0; - static constexpr InfoType TYPE = 1 << 0; - static constexpr InfoType NAME = 1 << 1; - static constexpr InfoType EmailAddress = 1 << 2; - static constexpr InfoType Usage = 1 << 3; - static constexpr InfoType Validity = 1 << 4; - static constexpr InfoType FingerPrint = 1 << 5; + static constexpr InfoType ALL = ~0; ///< + static constexpr InfoType TYPE = 1 << 0; ///< + static constexpr InfoType NAME = 1 << 1; ///< + static constexpr InfoType EmailAddress = 1 << 2; ///< + static constexpr InfoType Usage = 1 << 3; ///< + static constexpr InfoType Validity = 1 << 4; ///< + static constexpr InfoType FingerPrint = 1 << 5; ///< }; +/** + * @brief + * + */ struct KeyMenuAbility { using AbilityType = unsigned int; - static constexpr AbilityType ALL = ~0; - static constexpr AbilityType NONE = 0; - static constexpr AbilityType REFRESH = 1 << 0; - static constexpr AbilityType SYNC_PUBLIC_KEY = 1 << 1; - static constexpr AbilityType UNCHECK_ALL = 1 << 3; - static constexpr AbilityType CHECK_ALL = 1 << 5; + static constexpr AbilityType ALL = ~0; ///< + static constexpr AbilityType NONE = 0; ///< + static constexpr AbilityType REFRESH = 1 << 0; ///< + static constexpr AbilityType SYNC_PUBLIC_KEY = 1 << 1; ///< + static constexpr AbilityType UNCHECK_ALL = 1 << 3; ///< + static constexpr AbilityType CHECK_ALL = 1 << 5; ///< }; +/** + * @brief + * + */ struct KeyTable { - QTableWidget* key_list; - KeyListRow::KeyType select_type; - KeyListColumn::InfoType info_type; - std::vector<GpgKey> buffered_keys; - std::function<bool(const GpgKey&)> filter; - KeyIdArgsListPtr checked_key_ids_; - + QTableWidget* key_list_; ///< + KeyListRow::KeyType select_type_; ///< + KeyListColumn::InfoType info_type_; ///< + std::vector<GpgKey> buffered_keys_; ///< + std::function<bool(const GpgKey&)> filter_; ///< + KeyIdArgsListPtr checked_key_ids_; ///< + + /** + * @brief Construct a new Key Table object + * + * @param _key_list + * @param _select_type + * @param _info_type + * @param _filter + */ KeyTable( QTableWidget* _key_list, KeyListRow::KeyType _select_type, KeyListColumn::InfoType _info_type, std::function<bool(const GpgKey&)> _filter = [](const GpgKey&) -> bool { return true; }) - : key_list(_key_list), - select_type(_select_type), - info_type(_info_type), - filter(std::move(_filter)) {} - + : key_list_(_key_list), + select_type_(_select_type), + info_type_(_info_type), + filter_(std::move(_filter)) {} + + /** + * @brief + * + * @param m_keys + */ void Refresh(KeyLinkListPtr m_keys = nullptr); + /** + * @brief Get the Checked object + * + * @return KeyIdArgsListPtr& + */ KeyIdArgsListPtr& GetChecked(); + /** + * @brief + * + */ void UncheckALL() const; + /** + * @brief + * + */ void CheckALL() const; + /** + * @brief Set the Checked object + * + * @param key_ids + */ void SetChecked(KeyIdArgsListPtr key_ids); }; +/** + * @brief + * + */ class KeyList : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Key List object + * + * @param menu_ability + * @param parent + */ explicit KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent = nullptr); - void addListGroupTab( + /** + * @brief + * + * @param name + * @param selectType + * @param infoType + * @param filter + */ + void AddListGroupTab( const QString& name, KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListColumn::InfoType infoType = KeyListColumn::ALL, const std::function<bool(const GpgKey&)>& filter = [](const GpgKey&) -> bool { return true; }); - void setDoubleClickedAction( + /** + * @brief Set the Double Clicked Action object + * + * @param action + */ + void SetDoubleClickedAction( std::function<void(const GpgKey&, QWidget*)> action); - void setColumnWidth(int row, int size); - void addMenuAction(QAction* act); - void addSeparator(); + /** + * @brief Set the Column Width object + * + * @param row + * @param size + */ + void SetColumnWidth(int row, int size); + + /** + * @brief + * + * @param act + */ + void AddMenuAction(QAction* act); + + /** + * @brief + * + */ + void AddSeparator(); + + /** + * @brief Get the Checked object + * + * @return KeyIdArgsListPtr + */ + KeyIdArgsListPtr GetChecked(); + + /** + * @brief Get the Checked object + * + * @param key_table + * @return KeyIdArgsListPtr + */ + static KeyIdArgsListPtr GetChecked(const KeyTable& key_table); + + /** + * @brief Get the Private Checked object + * + * @return KeyIdArgsListPtr + */ + KeyIdArgsListPtr GetPrivateChecked(); + + /** + * @brief Get the All Private Keys object + * + * @return KeyIdArgsListPtr + */ + KeyIdArgsListPtr GetAllPrivateKeys(); + + /** + * @brief Set the Checked object + * + * @param key_ids + */ + void SetChecked(KeyIdArgsListPtr key_ids); - KeyIdArgsListPtr getChecked(); - static KeyIdArgsListPtr getChecked(const KeyTable& key_table); - KeyIdArgsListPtr getPrivateChecked(); - KeyIdArgsListPtr getAllPrivateKeys(); - void setChecked(KeyIdArgsListPtr key_ids); - static void setChecked(const KeyIdArgsListPtr& keyIds, + /** + * @brief Set the Checked object + * + * @param keyIds + * @param key_table + */ + static void SetChecked(const KeyIdArgsListPtr& keyIds, const KeyTable& key_table); - KeyIdArgsListPtr getSelected(); - std::string getSelectedKey(); - - [[maybe_unused]] static void markKeys(QStringList* keyIds); - [[maybe_unused]] bool containsPrivateKeys(); + /** + * @brief Get the Selected object + * + * @return KeyIdArgsListPtr + */ + KeyIdArgsListPtr GetSelected(); + + /** + * @brief Get the Selected Key object + * + * @return std::string + */ + std::string GetSelectedKey(); + + /** + * @brief + * + * @param keyIds + */ + [[maybe_unused]] static void MarkKeys(QStringList* keyIds); + + /** + * @brief + * + * @return true + * @return false + */ + [[maybe_unused]] bool ContainsPrivateKeys(); signals: - void signalRefreshStatusBar(const QString& message, int timeout); - void signalRefreshDatabase(); + /** + * @brief + * + * @param message + * @param timeout + */ + void SignalRefreshStatusBar(const QString& message, int timeout); + + /** + * @brief + * + */ + void SignalRefreshDatabase(); public slots: - void slotRefresh(); + /** + * @brief + * + */ + void SlotRefresh(); private: + /** + * @brief + * + */ void init(); - void importKeys(const QByteArray& inBuffer); - void slotUncheckALL(); - void slotCheckALL(); - - static int key_list_id; - int _m_key_list_id; - std::mutex buffered_key_list_mutex; - - std::shared_ptr<Ui_KeyList> ui; - QTableWidget* mKeyList{}; - std::vector<KeyTable> mKeyTables; - QMenu* popupMenu{}; - GpgFrontend::KeyLinkListPtr _buffered_keys_list; - std::function<void(const GpgKey&, QWidget*)> mAction = nullptr; - KeyMenuAbility::AbilityType menu_ability_ = KeyMenuAbility::ALL; - private slots: - - void slotDoubleClicked(const QModelIndex& index); + /** + * @brief + * + * @param inBuffer + */ + void import_keys(const QByteArray& inBuffer); + + /** + * @brief + * + */ + void uncheck_all(); + + /** + * @brief + * + */ + void check_all(); + + static int key_list_id_; ///< + int m_key_list_id_; ///< + std::mutex buffered_key_list_mutex_; ///< + + std::shared_ptr<Ui_KeyList> ui_; ///< + QTableWidget* m_key_list_{}; ///< + std::vector<KeyTable> m_key_tables_; ///< + QMenu* popup_menu_{}; ///< + GpgFrontend::KeyLinkListPtr buffered_keys_list_; ///< + std::function<void(const GpgKey&, QWidget*)> m_action_ = nullptr; ///< + KeyMenuAbility::AbilityType menu_ability_ = KeyMenuAbility::ALL; ///< - void slotRefreshUI(); + private slots: - void slotSyncWithKeyServer(); + /** + * @brief + * + * @param index + */ + void slot_double_clicked(const QModelIndex& index); + + /** + * @brief + * + */ + void slot_refresh_ui(); + + /** + * @brief + * + */ + void slot_sync_with_key_server(); protected: + /** + * @brief + * + * @param event + */ void contextMenuEvent(QContextMenuEvent* event) override; + /** + * @brief + * + * @param event + */ void dragEnterEvent(QDragEnterEvent* event) override; + /** + * @brief + * + * @param event + */ void dropEvent(QDropEvent* event) override; }; diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp new file mode 100644 index 00000000..c70991b9 --- /dev/null +++ b/src/ui/widgets/PlainTextEditorPage.cpp @@ -0,0 +1,260 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#include "ui/widgets/PlainTextEditorPage.h" + +#include <encoding-detect/TextEncodingDetect.h> + +#include <boost/format.hpp> +#include <utility> + +#include "ui/thread/FileReadThread.h" +#include "ui_PlainTextEditor.h" + +namespace GpgFrontend::UI { + +PlainTextEditorPage::PlainTextEditorPage(QString file_path, QWidget *parent) + : QWidget(parent), + ui_(std::make_shared<Ui_PlainTextEditor>()), + full_file_path_(std::move(file_path)) { + ui_->setupUi(this); + + if (full_file_path_.isEmpty()) read_done_ = true; + + ui_->textPage->setFocus(); + ui_->loadingLabel->setHidden(true); + + // Front in same width + this->setFont({"Courier"}); + this->setAttribute(Qt::WA_DeleteOnClose); + + this->ui_->characterLabel->setText(_("0 character")); + this->ui_->lfLabel->setText(_("None")); + this->ui_->encodingLabel->setText(_("Binary")); + + connect(ui_->textPage, &QPlainTextEdit::textChanged, this, [=]() { + if (!read_done_) return; + + auto text = ui_->textPage->document()->toPlainText(); + auto str = boost::format(_("%1% character(s)")) % text.size(); + this->ui_->characterLabel->setText(str.str().c_str()); + + detect_cr_lf(text); + detect_encoding(text.toStdString()); + }); + + ui_->loadingLabel->setText(_("Loading...")); +} + +const QString &PlainTextEditorPage::GetFilePath() const { + return full_file_path_; +} + +QPlainTextEdit *PlainTextEditorPage::GetTextPage() { return ui_->textPage; } + +void PlainTextEditorPage::SetFilePath(const QString &filePath) { + full_file_path_ = filePath; +} + +void PlainTextEditorPage::ShowNotificationWidget(QWidget *widget, + const char *className) { + widget->setProperty(className, true); + ui_->verticalLayout->addWidget(widget); +} + +void PlainTextEditorPage::CloseNoteByClass(const char *className) { + QList<QWidget *> widgets = findChildren<QWidget *>(); + for (QWidget *widget : widgets) { + if (widget->property(className) == true) { + widget->close(); + } + } +} + +void PlainTextEditorPage::slot_format_gpg_header() { + QString content = ui_->textPage->toPlainText(); + + // Get positions of the gpg-headers, if they exist + int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN); + int startSig = + content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN); + int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END); + + if (start < 0 || startSig < 0 || endSig < 0 || sign_marked_) { + return; + } + + sign_marked_ = true; + + // Set the fontstyle for the header + QTextCharFormat signFormat; + signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); + signFormat.setFontPointSize(9); + + // set font style for the signature + QTextCursor cursor(ui_->textPage->document()); + cursor.setPosition(startSig, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); + cursor.setCharFormat(signFormat); + + // set the font style for the header + int headEnd = content.indexOf("\n\n", start); + cursor.setPosition(start, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); + cursor.setCharFormat(signFormat); +} + +void PlainTextEditorPage::ReadFile() { + LOG(INFO) << "called"; + + read_done_ = false; + read_bytes_ = 0; + ui_->textPage->setEnabled(false); + ui_->textPage->setReadOnly(true); + ui_->textPage->blockSignals(true); + ui_->loadingLabel->setHidden(false); + ui_->textPage->document()->blockSignals(true); + + auto text_page = this->GetTextPage(); + text_page->setReadOnly(true); + auto thread = new FileReadThread(this->full_file_path_.toStdString()); + + connect(thread, &FileReadThread::SignalSendReadBlock, this, + &PlainTextEditorPage::slot_insert_text); + + connect(thread, &FileReadThread::SignalReadDone, this, [=]() { + LOG(INFO) << "thread read done"; + if (!binary_mode_) { + text_page->setReadOnly(false); + } + }); + + connect(thread, &FileReadThread::finished, this, [=]() { + LOG(INFO) << "thread finished"; + thread->deleteLater(); + read_done_ = true; + read_thread_ = nullptr; + ui_->textPage->setEnabled(true); + text_page->document()->setModified(false); + ui_->textPage->blockSignals(false); + ui_->textPage->document()->blockSignals(false); + ui_->loadingLabel->setHidden(true); + }); + + connect(this, &PlainTextEditorPage::destroyed, [=]() { + LOG(INFO) << "request interruption for read thread"; + if (read_thread_ && thread->isRunning()) thread->requestInterruption(); + read_thread_ = nullptr; + }); + this->read_thread_ = thread; + thread->start(); +} + +std::string binary_to_string(const std::string &source) { + static char syms[] = "0123456789ABCDEF"; + std::stringstream ss; + for (unsigned char c : source) + ss << syms[((c >> 4) & 0xf)] << syms[c & 0xf] << " "; + return ss.str(); +} + +void PlainTextEditorPage::slot_insert_text(const std::string &data) { + LOG(INFO) << "data size" << data.size(); + read_bytes_ += data.size(); + // If binary format is detected, the entire file is converted to binary format + // for display + bool if_last_binary_mode = binary_mode_; + if (!binary_mode_) { + detect_encoding(data); + } + + if (binary_mode_) { + if (if_last_binary_mode != binary_mode_) { + auto text_buffer = + ui_->textPage->document()->toRawText().toLocal8Bit().toStdString(); + ui_->textPage->clear(); + this->GetTextPage()->insertPlainText( + binary_to_string(text_buffer).c_str()); + this->ui_->lfLabel->setText("None"); + } + this->GetTextPage()->insertPlainText(binary_to_string(data).c_str()); + + auto str = boost::format(_("%1% byte(s)")) % read_bytes_; + this->ui_->characterLabel->setText(str.str().c_str()); + } else { + this->GetTextPage()->insertPlainText(data.c_str()); + + auto text = this->GetTextPage()->toPlainText(); + auto str = boost::format(_("%1% character(s)")) % text.size(); + this->ui_->characterLabel->setText(str.str().c_str()); + detect_cr_lf(text); + } +} + +void PlainTextEditorPage::PrepareToDestroy() { + if (read_thread_) { + read_thread_->requestInterruption(); + read_thread_ = nullptr; + } +} + +void PlainTextEditorPage::detect_encoding(const std::string &data) { + AutoIt::Common::TextEncodingDetect text_detect; + AutoIt::Common::TextEncodingDetect::Encoding encoding = + text_detect.DetectEncoding((unsigned char *)(data.data()), data.size()); + + if (encoding == AutoIt::Common::TextEncodingDetect::None) { + binary_mode_ = true; + ui_->encodingLabel->setText(_("Binary")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::ASCII) { + ui_->encodingLabel->setText(_("ASCII(7 bits)")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::ANSI) { + ui_->encodingLabel->setText(_("ASCII(8 bits)")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::UTF8_BOM || + encoding == AutoIt::Common::TextEncodingDetect::UTF8_NOBOM) { + ui_->encodingLabel->setText(_("UTF-8")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::UTF16_LE_BOM || + encoding == AutoIt::Common::TextEncodingDetect::UTF16_LE_NOBOM) { + ui_->encodingLabel->setText(_("UTF-16")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::UTF16_BE_BOM || + encoding == AutoIt::Common::TextEncodingDetect::UTF16_BE_NOBOM) { + ui_->encodingLabel->setText(_("UTF-16(BE)")); + } +} + +void PlainTextEditorPage::detect_cr_lf(const QString &data) { + if (binary_mode_) { + this->ui_->lfLabel->setText("None"); + return; + } + if (data.contains("\r\n")) { + this->ui_->lfLabel->setText("CRLF"); + } else { + this->ui_->lfLabel->setText("LF"); + } +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/PlainTextEditorPage.h b/src/ui/widgets/PlainTextEditorPage.h new file mode 100644 index 00000000..e76c11e3 --- /dev/null +++ b/src/ui/widgets/PlainTextEditorPage.h @@ -0,0 +1,147 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef __EDITORPAGE_H__ +#define __EDITORPAGE_H__ + +#include "core/GpgConstants.h" +#include "ui/GpgFrontendUI.h" + +class Ui_PlainTextEditor; + +namespace GpgFrontend::UI { + +/** + * @brief Class for handling a single tab of the tabwidget + * + */ +class PlainTextEditorPage : public QWidget { + Q_OBJECT + public: + /** + * @details Add layout and add plaintextedit + * + * @param file_path Path of the file handled in this tab + * @param parent Pointer to the parent widget + */ + explicit PlainTextEditorPage(QString file_path = "", + QWidget* parent = nullptr); + + /** + * @details Get the filepath of the currently activated tab. + */ + [[nodiscard]] const QString& GetFilePath() const; + + /** + * @details Set filepath of currently activated tab. + * + * @param filePath The path to be set + */ + void SetFilePath(const QString& filePath); + + /** + * @details Return pointer tp the textedit of the currently activated tab. + */ + QPlainTextEdit* GetTextPage(); + + /** + * @details Show additional widget at buttom of currently active tab + * + * @param widget The widget to be added + * @param className The name to handle the added widget + */ + void ShowNotificationWidget(QWidget* widget, const char* className); + + /** + * @details Hide all widgets with the given className + * + * @param className The classname of the widgets to hide + */ + void CloseNoteByClass(const char* className); + + /** + * @brief + * + */ + void ReadFile(); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] bool ReadDone() const { return this->read_done_; } + + /** + * @brief + * + */ + void PrepareToDestroy(); + + private: + std::shared_ptr<Ui_PlainTextEditor> ui_; ///< + QString full_file_path_; ///< The path to the file handled in the tab + bool sign_marked_{}; ///< true, if the signed header is marked, false if not + bool read_done_ = false; ///< + QThread* read_thread_ = nullptr; ///< + bool binary_mode_ = false; ///< + size_t read_bytes_ = 0; ///< + + /** + * @brief + * + * @param data + */ + void detect_encoding(const std::string& data); + + /** + * @brief + * + * @param data + */ + void detect_cr_lf(const QString& data); + + private slots: + + /** + * @details Format the gpg header in another font-style + */ + void slot_format_gpg_header(); + + /** + * @brief + * + * @param data + */ + void slot_insert_text(const std::string& data); +}; + +} // namespace GpgFrontend::UI + +#endif // __EDITORPAGE_H__ diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp index b035bf19..75f6b2ba 100644 --- a/src/ui/widgets/SignersPicker.cpp +++ b/src/ui/widgets/SignersPicker.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -30,15 +34,17 @@ namespace GpgFrontend::UI { SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) { auto confirm_button = new QPushButton(_("Confirm")); - connect(confirm_button, SIGNAL(clicked(bool)), this, SLOT(accept())); + connect(confirm_button, &QPushButton::clicked, this, &SignersPicker::accept); /*Setup KeyList*/ key_list_ = new KeyList(false, this); - key_list_->addListGroupTab( + key_list_->AddListGroupTab( _("Signers"), KeyListRow::ONLY_SECRET_KEY, KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage, - [](const GpgKey& key) -> bool { return key.CanSignActual(); }); - key_list_->slotRefresh(); + [](const GpgKey& key) -> bool { + return key.IsHasActualSigningCapability(); + }); + key_list_->SlotRefresh(); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(new QLabel(QString(_("Select Signer(s)")) + ": ")); @@ -61,8 +67,8 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) { this->show(); } -GpgFrontend::KeyIdArgsListPtr SignersPicker::getCheckedSigners() { - return key_list_->getPrivateChecked(); +GpgFrontend::KeyIdArgsListPtr SignersPicker::GetCheckedSigners() { + return key_list_->GetPrivateChecked(); } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/SignersPicker.h b/src/ui/widgets/SignersPicker.h index 08972a76..30f872f8 100644 --- a/src/ui/widgets/SignersPicker.h +++ b/src/ui/widgets/SignersPicker.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -31,16 +35,30 @@ namespace GpgFrontend::UI { class KeyList; +/** + * @brief + * + */ class SignersPicker : public QDialog { Q_OBJECT public: + /** + * @brief Construct a new Signers Picker object + * + * @param parent + */ explicit SignersPicker(QWidget* parent = nullptr); - GpgFrontend::KeyIdArgsListPtr getCheckedSigners(); + /** + * @brief Get the Checked Signers object + * + * @return GpgFrontend::KeyIdArgsListPtr + */ + GpgFrontend::KeyIdArgsListPtr GetCheckedSigners(); private: - KeyList* key_list_; + KeyList* key_list_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/TOFUInfoPage.cpp b/src/ui/widgets/TOFUInfoPage.cpp index a1f76d7a..709a66e1 100644 --- a/src/ui/widgets/TOFUInfoPage.cpp +++ b/src/ui/widgets/TOFUInfoPage.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. diff --git a/src/ui/widgets/TOFUInfoPage.h b/src/ui/widgets/TOFUInfoPage.h index 29f004d1..445b1567 100644 --- a/src/ui/widgets/TOFUInfoPage.h +++ b/src/ui/widgets/TOFUInfoPage.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,16 +8,16 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * * The source code version of this software was modified and released * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. @@ -25,17 +27,26 @@ #ifndef GPGFRONTEND_TOFUINFOPAGE_H #define GPGFRONTEND_TOFUINFOPAGE_H -#include "gpg/GpgModel.h" +#include "core/GpgModel.h" #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { + +/** + * @brief + * + */ class TOFUInfoPage : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new TOFUInfoPage object + * + * @param tofu_info + * @param parent + */ explicit TOFUInfoPage(const GpgTOFUInfo &tofu_info, QWidget *parent = nullptr); - - private: }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp index be6ec181..ecf1a4bd 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,68 +33,68 @@ namespace GpgFrontend::UI { TextEdit::TextEdit(QWidget* parent) : QWidget(parent) { - countPage = 0; - tabWidget = new QTabWidget(this); - tabWidget->setMovable(true); - tabWidget->setTabsClosable(true); - tabWidget->setDocumentMode(true); + count_page_ = 0; + tab_widget_ = new QTabWidget(this); + tab_widget_->setMovable(true); + tab_widget_->setTabsClosable(true); + tab_widget_->setDocumentMode(true); auto* layout = new QVBoxLayout; - layout->addWidget(tabWidget); + layout->addWidget(tab_widget_); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); setLayout(layout); - connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, - SLOT(removeTab(int))); - slotNewTab(); + connect(tab_widget_, &QTabWidget::tabCloseRequested, this, + &TextEdit::slot_remove_tab); + SlotNewTab(); setAcceptDrops(false); } -void TextEdit::slotNewTab() { - QString header = _("untitled") + QString::number(++countPage) + ".txt"; +void TextEdit::SlotNewTab() { + QString header = _("untitled") + QString::number(++count_page_) + ".txt"; - auto* page = new EditorPage(); - auto index = tabWidget->addTab(page, header); - tabWidget->setTabIcon(index, QIcon(":file.png")); - tabWidget->setCurrentIndex(tabWidget->count() - 1); - page->getTextPage()->setFocus(); - connect(page->getTextPage()->document(), &QTextDocument::modificationChanged, - this, &TextEdit::slotShowModified); + auto* page = new PlainTextEditorPage(); + auto index = tab_widget_->addTab(page, header); + tab_widget_->setTabIcon(index, QIcon(":file.png")); + tab_widget_->setCurrentIndex(tab_widget_->count() - 1); + page->GetTextPage()->setFocus(); + connect(page->GetTextPage()->document(), &QTextDocument::modificationChanged, + this, &TextEdit::SlotShowModified); } void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const { auto* page = new HelpPage(path); - tabWidget->addTab(page, title); - tabWidget->setCurrentIndex(tabWidget->count() - 1); + tab_widget_->addTab(page, title); + tab_widget_->setCurrentIndex(tab_widget_->count() - 1); } -void TextEdit::slotNewFileTab() const { +void TextEdit::SlotNewFileTab() const { auto* page = new FilePage(qobject_cast<QWidget*>(parent())); - auto index = tabWidget->addTab(page, QString()); - tabWidget->setTabIcon(index, QIcon(":file-browser.png")); - tabWidget->setCurrentIndex(tabWidget->count() - 1); - connect(page, &FilePage::pathChanged, this, - &TextEdit::slotFilePagePathChanged); - page->slotGoPath(); + auto index = tab_widget_->addTab(page, QString()); + tab_widget_->setTabIcon(index, QIcon(":file-browser.png")); + tab_widget_->setCurrentIndex(tab_widget_->count() - 1); + connect(page, &FilePage::SignalPathChanged, this, + &TextEdit::slot_file_page_path_changed); + page->SlotGoPath(); } -void TextEdit::slotOpenFile(QString& path) { +void TextEdit::SlotOpenFile(QString& path) { QFile file(path); LOG(INFO) << "path" << path.toStdString(); auto result = file.open(QIODevice::ReadOnly | QIODevice::Text); if (result) { - auto* page = new EditorPage(path); - connect(page->getTextPage()->document(), + auto* page = new PlainTextEditorPage(path); + connect(page->GetTextPage()->document(), &QTextDocument::modificationChanged, this, - &TextEdit::slotShowModified); - + &TextEdit::SlotShowModified); + QApplication::setOverrideCursor(Qt::WaitCursor); - auto index = tabWidget->addTab(page, strippedName(path)); - tabWidget->setTabIcon(index, QIcon(":file.png")); - tabWidget->setCurrentIndex(tabWidget->count() - 1); + auto index = tab_widget_->addTab(page, stripped_name(path)); + tab_widget_->setTabIcon(index, QIcon(":file.png")); + tab_widget_->setCurrentIndex(tab_widget_->count() - 1); QApplication::restoreOverrideCursor(); - page->getTextPage()->setFocus(); + page->GetTextPage()->setFocus(); page->ReadFile(); } else { QMessageBox::warning(this, _("Warning"), @@ -103,37 +107,37 @@ void TextEdit::slotOpenFile(QString& path) { file.close(); } -void TextEdit::slotOpen() { - QStringList fileNames = +void TextEdit::SlotOpen() { + QStringList file_names = QFileDialog::getOpenFileNames(this, _("Open file"), QDir::currentPath()); - for (const auto& fileName : fileNames) { - if (!fileName.isEmpty()) { - QFile file(fileName); + for (const auto& file_name : file_names) { + if (!file_name.isEmpty()) { + QFile file(file_name); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto* page = new EditorPage(fileName); + auto* page = new PlainTextEditorPage(file_name); QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); - page->getTextPage()->setPlainText(in.readAll()); - page->setFilePath(fileName); - QTextDocument* document = page->getTextPage()->document(); + page->GetTextPage()->setPlainText(in.readAll()); + page->SetFilePath(file_name); + QTextDocument* document = page->GetTextPage()->document(); document->setModified(false); - tabWidget->addTab(page, strippedName(fileName)); - tabWidget->setCurrentIndex(tabWidget->count() - 1); + tab_widget_->addTab(page, stripped_name(file_name)); + tab_widget_->setCurrentIndex(tab_widget_->count() - 1); QApplication::restoreOverrideCursor(); - page->getTextPage()->setFocus(); - connect(page->getTextPage()->document(), - SIGNAL(modificationChanged(bool)), this, - SLOT(slotShowModified())); + page->GetTextPage()->setFocus(); + connect(page->GetTextPage()->document(), + &QTextDocument::modificationChanged, this, + &TextEdit::SlotShowModified); // enableAction(true) file.close(); } else { QMessageBox::warning( this, _("Warning"), (boost::format(_("Cannot read file %1%:\n%2%.")) % - fileName.toStdString() % file.errorString().toStdString()) + file_name.toStdString() % file.errorString().toStdString()) .str() .c_str()); } @@ -141,23 +145,23 @@ void TextEdit::slotOpen() { } } -void TextEdit::slotSave() { - if (tabWidget->count() == 0 || slotCurPageTextEdit() == 0) { +void TextEdit::SlotSave() { + if (tab_widget_->count() == 0 || SlotCurPageTextEdit() == 0) { return; } - QString fileName = slotCurPageTextEdit()->getFilePath(); + QString fileName = SlotCurPageTextEdit()->GetFilePath(); if (fileName.isEmpty()) { // QString docname = tabWidget->tabText(tabWidget->currentIndex()); // docname.remove(0,2); - slotSaveAs(); + SlotSaveAs(); } else { - saveFile(fileName); + save_file(fileName); } } -bool TextEdit::saveFile(const QString& fileName) { +bool TextEdit::save_file(const QString& fileName) { if (fileName.isEmpty()) { return false; } @@ -165,19 +169,19 @@ bool TextEdit::saveFile(const QString& fileName) { QFile file(fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - EditorPage* page = slotCurPageTextEdit(); + PlainTextEditorPage* page = SlotCurPageTextEdit(); QTextStream outputStream(&file); QApplication::setOverrideCursor(Qt::WaitCursor); - outputStream << page->getTextPage()->toPlainText(); + outputStream << page->GetTextPage()->toPlainText(); QApplication::restoreOverrideCursor(); - QTextDocument* document = page->getTextPage()->document(); + QTextDocument* document = page->GetTextPage()->document(); document->setModified(false); - int curIndex = tabWidget->currentIndex(); - tabWidget->setTabText(curIndex, strippedName(fileName)); - page->setFilePath(fileName); + int curIndex = tab_widget_->currentIndex(); + tab_widget_->setTabText(curIndex, stripped_name(fileName)); + page->SetFilePath(fileName); // statusBar()->showMessage(_("File saved"), 2000); file.close(); return true; @@ -192,53 +196,53 @@ bool TextEdit::saveFile(const QString& fileName) { } } -bool TextEdit::slotSaveAs() { - if (tabWidget->count() == 0 || slotCurPageTextEdit() == nullptr) { +bool TextEdit::SlotSaveAs() { + if (tab_widget_->count() == 0 || SlotCurPageTextEdit() == nullptr) { return true; } - EditorPage* page = slotCurPageTextEdit(); + PlainTextEditorPage* page = SlotCurPageTextEdit(); QString path; - if (!page->getFilePath().isEmpty()) { - path = page->getFilePath(); + if (!page->GetFilePath().isEmpty()) { + path = page->GetFilePath(); } else { - path = tabWidget->tabText(tabWidget->currentIndex()).remove(0, 2); + path = tab_widget_->tabText(tab_widget_->currentIndex()).remove(0, 2); } QString fileName = QFileDialog::getSaveFileName(this, _("Save file"), path); - return saveFile(fileName); + return save_file(fileName); } -void TextEdit::slotCloseTab() { - removeTab(tabWidget->currentIndex()); - if (tabWidget->count() != 0) { - slotCurPageTextEdit()->getTextPage()->setFocus(); +void TextEdit::SlotCloseTab() { + slot_remove_tab(tab_widget_->currentIndex()); + if (tab_widget_->count() != 0) { + SlotCurPageTextEdit()->GetTextPage()->setFocus(); } } -void TextEdit::removeTab(int index) { +void TextEdit::slot_remove_tab(int index) { // Do nothing, if no tab is opened - if (tabWidget->count() == 0) { + if (tab_widget_->count() == 0) { return; } // get the index of the actual current tab - int lastIndex = tabWidget->currentIndex(); + int last_index = tab_widget_->currentIndex(); // set the focus to argument index - tabWidget->setCurrentIndex(index); + tab_widget_->setCurrentIndex(index); - if (maybeSaveCurrentTab(true)) { - tabWidget->removeTab(index); + if (maybe_save_current_tab(true)) { + tab_widget_->removeTab(index); - if (index >= lastIndex) { - tabWidget->setCurrentIndex(lastIndex); + if (index >= last_index) { + tab_widget_->setCurrentIndex(last_index); } else { - tabWidget->setCurrentIndex(lastIndex - 1); + tab_widget_->setCurrentIndex(last_index - 1); } } - if (tabWidget->count() == 0) { + if (tab_widget_->count() == 0) { // enableAction(false); } } @@ -249,28 +253,28 @@ void TextEdit::removeTab(int index) { * * If it returns false, the close event should be aborted. */ -bool TextEdit::maybeSaveCurrentTab(bool askToSave) { - EditorPage* page = slotCurPageTextEdit(); +bool TextEdit::maybe_save_current_tab(bool askToSave) { + PlainTextEditorPage* page = SlotCurPageTextEdit(); // if this page is no textedit, there should be nothing to save if (page == nullptr) { return true; } - QTextDocument* document = page->getTextPage()->document(); + QTextDocument* document = page->GetTextPage()->document(); if (page->ReadDone() && document->isModified()) { QMessageBox::StandardButton result = QMessageBox::Cancel; // write title of tab to docname and remove the leading * - QString docname = tabWidget->tabText(tabWidget->currentIndex()); - docname.remove(0, 2); + QString doc_name = tab_widget_->tabText(tab_widget_->currentIndex()); + doc_name.remove(0, 2); - const QString& filePath = page->getFilePath(); + const QString& file_path = page->GetFilePath(); if (askToSave) { result = QMessageBox::warning( this, _("Unsaved document"), QString(_("The document \"%1\" has been modified. Do you want to " "save your changes?")) - .arg(docname) + + .arg(doc_name) + "<br/><b>" + _("Note:") + "</b>" + _("If you don't save these files, all changes are " "lost.") + @@ -278,12 +282,12 @@ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); } if ((result == QMessageBox::Save) || (!askToSave)) { - if (filePath.isEmpty()) { + if (file_path.isEmpty()) { // QString docname = tabWidget->tabText(tabWidget->currentIndex()); // docname.remove(0,2); - return slotSaveAs(); + return SlotSaveAs(); } else { - return saveFile(filePath); + return save_file(file_path); } } else if (result == QMessageBox::Discard) { return true; @@ -297,9 +301,9 @@ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { return true; } -bool TextEdit::maybeSaveAnyTab() { +bool TextEdit::MaybeSaveAnyTab() { // get a list of all unsaved documents and their tabids - QHash<int, QString> unsaved_docs = this->unsavedDocuments(); + QHash<int, QString> unsaved_docs = this->UnsavedDocuments(); /* * no unsaved documents, so app can be closed @@ -313,8 +317,8 @@ bool TextEdit::maybeSaveAnyTab() { */ if (unsaved_docs.size() == 1) { int modifiedTab = unsaved_docs.keys().at(0); - tabWidget->setCurrentIndex(modifiedTab); - return maybeSaveCurrentTab(true); + tab_widget_->setCurrentIndex(modifiedTab); + return maybe_save_current_tab(true); } /* @@ -330,18 +334,18 @@ bool TextEdit::maybeSaveAnyTab() { // if result is QDialog::Rejected, discard or cancel was clicked if (result == QDialog::Rejected) { // return true, if discard is clicked, so app can be closed - if (dialog->isDiscarded()) { + if (dialog->IsDiscarded()) { return true; } else { return false; } } else { bool all_saved = true; - QList<int> tabIdsToSave = dialog->getTabIdsToSave(); + QList<int> tabIdsToSave = dialog->GetTabIdsToSave(); for (const auto& tabId : tabIdsToSave) { - tabWidget->setCurrentIndex(tabId); - if (!maybeSaveCurrentTab(false)) { + tab_widget_->setCurrentIndex(tabId); + if (!maybe_save_current_tab(false)) { all_saved = false; } } @@ -352,17 +356,12 @@ bool TextEdit::maybeSaveAnyTab() { return false; } -QTextEdit* TextEdit::curTextPage() const { - auto* curTextPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); - if (curTextPage != nullptr) { - return curTextPage->getTextPage(); - } else { - return nullptr; - } +PlainTextEditorPage* TextEdit::CurTextPage() const { + return qobject_cast<PlainTextEditorPage*>(tab_widget_->currentWidget()); } -FilePage* TextEdit::curFilePage() const { - auto* curFilePage = qobject_cast<FilePage*>(tabWidget->currentWidget()); +FilePage* TextEdit::CurFilePage() const { + auto* curFilePage = qobject_cast<FilePage*>(tab_widget_->currentWidget()); if (curFilePage != nullptr) { return curFilePage; } else { @@ -370,24 +369,25 @@ FilePage* TextEdit::curFilePage() const { } } -int TextEdit::tabCount() const { return tabWidget->count(); } +int TextEdit::TabCount() const { return tab_widget_->count(); } -EditorPage* TextEdit::slotCurPageTextEdit() const { - auto* curPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); +PlainTextEditorPage* TextEdit::SlotCurPageTextEdit() const { + auto* curPage = + qobject_cast<PlainTextEditorPage*>(tab_widget_->currentWidget()); return curPage; } -FilePage* TextEdit::slotCurPageFileTreeView() const { - auto* curPage = qobject_cast<FilePage*>(tabWidget->currentWidget()); +FilePage* TextEdit::SlotCurPageFileTreeView() const { + auto* curPage = qobject_cast<FilePage*>(tab_widget_->currentWidget()); return curPage; } -void TextEdit::slotQuote() const { - if (tabWidget->count() == 0 || curTextPage() == nullptr) { +void TextEdit::SlotQuote() const { + if (tab_widget_->count() == 0 || CurTextPage() == nullptr) { return; } - QTextCursor cursor(curTextPage()->document()); + QTextCursor cursor(CurTextPage()->GetTextPage()->document()); // beginEditBlock and endEditBlock() let operation look like single undo/redo // operation @@ -404,15 +404,15 @@ void TextEdit::slotQuote() const { cursor.endEditBlock(); } -void TextEdit::slotFillTextEditWithText(const QString& text) const { - QTextCursor cursor(curTextPage()->document()); +void TextEdit::SlotFillTextEditWithText(const QString& text) const { + QTextCursor cursor(CurTextPage()->GetTextPage()->document()); cursor.beginEditBlock(); - this->curTextPage()->selectAll(); - this->curTextPage()->insertPlainText(text); + this->CurTextPage()->GetTextPage()->selectAll(); + this->CurTextPage()->GetTextPage()->insertPlainText(text); cursor.endEditBlock(); } -void TextEdit::loadFile(const QString& fileName) { +void TextEdit::LoadFile(const QString& fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning( @@ -425,27 +425,27 @@ void TextEdit::loadFile(const QString& fileName) { } QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); - curTextPage()->setPlainText(in.readAll()); + CurTextPage()->GetTextPage()->setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); - slotCurPageTextEdit()->setFilePath(fileName); - tabWidget->setTabText(tabWidget->currentIndex(), strippedName(fileName)); + SlotCurPageTextEdit()->SetFilePath(fileName); + tab_widget_->setTabText(tab_widget_->currentIndex(), stripped_name(fileName)); file.close(); // statusBar()->showMessage(_("File loaded"), 2000); } -QString TextEdit::strippedName(const QString& full_file_name) { +QString TextEdit::stripped_name(const QString& full_file_name) { return QFileInfo(full_file_name).fileName(); } -void TextEdit::slotPrint() { - if (tabWidget->count() == 0) { +void TextEdit::SlotPrint() { + if (tab_widget_->count() == 0) { return; } #ifndef QT_NO_PRINTER QTextDocument* document; - if (curTextPage() != nullptr) { - document = curTextPage()->document(); + if (CurTextPage() != nullptr) { + document = CurTextPage()->GetTextPage()->document(); } QPrinter printer; @@ -459,45 +459,45 @@ void TextEdit::slotPrint() { #endif } -void TextEdit::slotShowModified() const { - int index = tabWidget->currentIndex(); - QString title = tabWidget->tabText(index); +void TextEdit::SlotShowModified() const { + int index = tab_widget_->currentIndex(); + QString title = tab_widget_->tabText(index); // if doc is modified now, add leading * to title, // otherwise remove the leading * from the title - if (curTextPage()->document()->isModified()) { - tabWidget->setTabText(index, title.prepend("* ")); + if (CurTextPage()->GetTextPage()->document()->isModified()) { + tab_widget_->setTabText(index, title.prepend("* ")); } else { - tabWidget->setTabText(index, title.remove(0, 2)); + tab_widget_->setTabText(index, title.remove(0, 2)); } } -void TextEdit::slotSwitchTabUp() const { - if (tabWidget->count() > 1) { - int new_index = (tabWidget->currentIndex() + 1) % (tabWidget->count()); - tabWidget->setCurrentIndex(new_index); +void TextEdit::SlotSwitchTabUp() const { + if (tab_widget_->count() > 1) { + int new_index = (tab_widget_->currentIndex() + 1) % (tab_widget_->count()); + tab_widget_->setCurrentIndex(new_index); } } -void TextEdit::slotSwitchTabDown() const { - if (tabWidget->count() > 1) { - int newindex = (tabWidget->currentIndex() - 1 + tabWidget->count()) % - tabWidget->count(); - tabWidget->setCurrentIndex(newindex); +void TextEdit::SlotSwitchTabDown() const { + if (tab_widget_->count() > 1) { + int newindex = (tab_widget_->currentIndex() - 1 + tab_widget_->count()) % + tab_widget_->count(); + tab_widget_->setCurrentIndex(newindex); } } /* * return a hash of tabindexes and title of unsaved tabs */ -QHash<int, QString> TextEdit::unsavedDocuments() const { +QHash<int, QString> TextEdit::UnsavedDocuments() const { QHash<int, QString> unsavedDocs; // this list could be used to implement // gedit like "unsaved changed"-dialog - for (int i = 0; i < tabWidget->count(); i++) { - auto* ep = qobject_cast<EditorPage*>(tabWidget->widget(i)); + for (int i = 0; i < tab_widget_->count(); i++) { + auto* ep = qobject_cast<PlainTextEditorPage*>(tab_widget_->widget(i)); if (ep != nullptr && ep->ReadDone() && - ep->getTextPage()->document()->isModified()) { - QString doc_name = tabWidget->tabText(i); + ep->GetTextPage()->document()->isModified()) { + QString doc_name = tab_widget_->tabText(i); LOG(INFO) << "unsaved" << doc_name.toStdString(); // remove * before name of modified doc @@ -508,77 +508,77 @@ QHash<int, QString> TextEdit::unsavedDocuments() const { return unsavedDocs; } -void TextEdit::slotCut() const { - if (tabWidget->count() == 0 || curTextPage() == nullptr) { +void TextEdit::SlotCut() const { + if (tab_widget_->count() == 0 || CurTextPage() == nullptr) { return; } - curTextPage()->cut(); + CurTextPage()->GetTextPage()->cut(); } -void TextEdit::slotCopy() const { - if (tabWidget->count() == 0) { +void TextEdit::SlotCopy() const { + if (tab_widget_->count() == 0) { return; } - if (curTextPage() != nullptr) { - curTextPage()->copy(); + if (CurTextPage() != nullptr) { + CurTextPage()->GetTextPage()->copy(); } } -void TextEdit::slotPaste() const { - if (tabWidget->count() == 0 || curTextPage() == nullptr) { +void TextEdit::SlotPaste() const { + if (tab_widget_->count() == 0 || CurTextPage() == nullptr) { return; } - curTextPage()->paste(); + CurTextPage()->GetTextPage()->paste(); } -void TextEdit::slotUndo() const { - if (tabWidget->count() == 0 || curTextPage() == nullptr) { +void TextEdit::SlotUndo() const { + if (tab_widget_->count() == 0 || CurTextPage() == nullptr) { return; } - curTextPage()->undo(); + CurTextPage()->GetTextPage()->undo(); } -void TextEdit::slotRedo() const { - if (tabWidget->count() == 0 || curTextPage() == nullptr) { +void TextEdit::SlotRedo() const { + if (tab_widget_->count() == 0 || CurTextPage() == nullptr) { return; } - curTextPage()->redo(); + CurTextPage()->GetTextPage()->redo(); } -void TextEdit::slotZoomIn() const { - if (tabWidget->count() == 0) { +void TextEdit::SlotZoomIn() const { + if (tab_widget_->count() == 0) { return; } - if (curTextPage() != nullptr) { - curTextPage()->zoomIn(); + if (CurTextPage() != nullptr) { + CurTextPage()->GetTextPage()->zoomIn(); } } -void TextEdit::slotZoomOut() const { - if (tabWidget->count() == 0) { +void TextEdit::SlotZoomOut() const { + if (tab_widget_->count() == 0) { return; } - if (curTextPage() != nullptr) { - curTextPage()->zoomOut(); + if (CurTextPage() != nullptr) { + CurTextPage()->GetTextPage()->zoomOut(); } } -void TextEdit::slotSelectAll() const { - if (tabWidget->count() == 0 || curTextPage() == nullptr) { +void TextEdit::SlotSelectAll() const { + if (tab_widget_->count() == 0 || CurTextPage() == nullptr) { return; } - curTextPage()->selectAll(); + CurTextPage()->GetTextPage()->selectAll(); } -void TextEdit::slotFilePagePathChanged(const QString& path) const { - int index = tabWidget->currentIndex(); +void TextEdit::slot_file_page_path_changed(const QString& path) const { + int index = tab_widget_->currentIndex(); QString mPath; QFileInfo fileInfo(path); QString tPath = fileInfo.absoluteFilePath(); @@ -587,7 +587,7 @@ void TextEdit::slotFilePagePathChanged(const QString& path) const { } else { mPath = tPath; } - tabWidget->setTabText(index, mPath); + tab_widget_->setTabText(index, mPath); } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h index e877ccc1..cb32bfb2 100644 --- a/src/ui/widgets/TextEdit.h +++ b/src/ui/widgets/TextEdit.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,29 +8,31 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef __TEXTEDIT_H__ #define __TEXTEDIT_H__ -#include "ui/QuitDialog.h" -#include "ui/widgets/EditorPage.h" +#include "ui/dialog/QuitDialog.h" #include "ui/widgets/FilePage.h" #include "ui/widgets/HelpPage.h" +#include "ui/widgets/PlainTextEditorPage.h" namespace GpgFrontend::UI { /** @@ -48,7 +52,7 @@ class TextEdit : public QWidget { * @param fileName QString containing the filename to load * @return nothing */ - void loadFile(const QString& fileName); + void LoadFile(const QString& fileName); /** * @details Checks if there are unsaved documents in any tab, @@ -57,26 +61,36 @@ class TextEdit : public QWidget { * @return \li false, if the close event should be aborted. * \li true, otherwise */ - bool maybeSaveAnyTab(); + bool MaybeSaveAnyTab(); - [[nodiscard]] int tabCount() const; + /** + * @brief + * + * @return int + */ + [[nodiscard]] int TabCount() const; /** * @details textpage of the currently activated tab * @return \li reference to QTextEdit if tab has one * \li 0 otherwise (e.g. if helppage) */ - [[nodiscard]] QTextEdit* curTextPage() const; + [[nodiscard]] PlainTextEditorPage* CurTextPage() const; - [[nodiscard]] FilePage* curFilePage() const; + /** + * @brief + * + * @return FilePage* + */ + [[nodiscard]] FilePage* CurFilePage() const; /** * @details List of currently unsaved tabs. - * @returns QHash<int, QString> Hash of tabindexes and title of unsaved tabs. + * @returns QHash<int, QString> Hash of tab indexes and title of unsaved tabs. */ - [[nodiscard]] QHash<int, QString> unsavedDocuments() const; + [[nodiscard]] QHash<int, QString> UnsavedDocuments() const; - QTabWidget* tabWidget; /** Widget containing the tabs of the editor */ + QTabWidget* tab_widget_; /** Widget containing the tabs of the editor */ public slots: @@ -84,62 +98,62 @@ class TextEdit : public QWidget { * @details Return pointer to the currently activated text edit tab page. * */ - EditorPage* slotCurPageTextEdit() const; + PlainTextEditorPage* SlotCurPageTextEdit() const; /** - * @details Return pointer to the currently activated file treeview tab page. + * @details Return pointer to the currently activated file tree view tab page. * */ - FilePage* slotCurPageFileTreeView() const; + FilePage* SlotCurPageFileTreeView() const; /** - * @details Insert a ">" at the begining of every line of current textedit. + * @details Insert a ">" at the beginning of every line of current textedit. */ - void slotQuote() const; + void SlotQuote() const; /** * @details replace the text of currently active textedit with given text. * @param text to fill on. */ - void slotFillTextEditWithText(const QString& text) const; + void SlotFillTextEditWithText(const QString& text) const; /** * @details Saves the content of the current tab, if it has a filepath * otherwise it calls saveAs for the current tab */ - void slotSave(); + void SlotSave(); /** - * @details Opens a savefiledialog and calls saveFile with the choosen + * @details Opens a savefiledialog and calls save_file with the choosen * filename. * * @return Return the return value of the savefile method */ - bool slotSaveAs(); + bool SlotSaveAs(); /** * @details Show an OpenFileDoalog and open the file in a new tab. * Shows an error dialog, if the open fails. * Set the focus to the tab of the opened file. */ - void slotOpen(); + void SlotOpen(); /** * @details Open a print-dialog for the current tab */ - void slotPrint(); + void SlotPrint(); /** * @details Adds a new tab with the title "untitled"+countpage+".txt" * Sets the focus to the new tab. Increase Tab-Count by * one */ - void slotNewTab(); + void SlotNewTab(); /** * @details Adds a new tab with opening file by path */ - void slotOpenFile(QString& path); + void SlotOpenFile(QString& path); /** * @details Adds a new tab with the given title and opens given html file. @@ -152,31 +166,31 @@ class TextEdit : public QWidget { /** * New File Tab to do file operation */ - void slotNewFileTab() const; + void SlotNewFileTab() const; /** * @details put a * in front of current tabs title, if current textedit is * modified */ - void slotShowModified() const; + void SlotShowModified() const; /** * @details close the current tab and decrease TabWidget->count by \a 1 * */ - void slotCloseTab(); + void SlotCloseTab(); /** * @details Switch to the next tab. * */ - void slotSwitchTabUp() const; + void SlotSwitchTabUp() const; /** * @details Switch to the previous tab. * */ - void slotSwitchTabDown() const; + void SlotSwitchTabDown() const; private: /** @@ -185,96 +199,82 @@ class TextEdit : public QWidget { * @param a filename path * @return QString containing the filename */ - static QString strippedName(const QString& full_file_name); + static QString stripped_name(const QString& full_file_name); /** * @brief * * @param askToSave */ - bool maybeSaveCurrentTab(bool askToSave); + bool maybe_save_current_tab(bool askToSave); - /**************************************************************************************** - * Name: countPage - * Description: int cotaining the number of added tabs - */ - int countPage; /* TODO */ + int count_page_; ///< int containing the number of added tabs private slots: - void slotFilePagePathChanged(const QString& path) const; + void slot_file_page_path_changed(const QString& path) const; /** * @details Remove the tab with given index * * @param index Tab-number to remove */ - void removeTab(int index); + void slot_remove_tab(int index); + + public slots: /** - * @details Cut selected text in current textpage. + * @details Cut selected text in current text page. */ - void slotCut() const; + void SlotCut() const; /** - * @details Copy selected text of current textpage to clipboard. + * @details Copy selected text of current text page to clipboard. */ - void slotCopy() const; + void SlotCopy() const; /** - * @details Paste text from clipboard to current textpage. + * @details Paste text from clipboard to current text page. */ - void slotPaste() const; + void SlotPaste() const; /** * @details Undo last change in current textpage. * */ - void slotUndo() const; - /**************************************************************************************** - * Name: redo - * Description: redo last change in current textpage - * Parameters: none - * Return Values: none - * Change on members: none + void SlotUndo() const; + + /** + * @brief redo last change in current text page + * */ + void SlotRedo() const; + /** * @brief * */ - void slotRedo() const; - - void slotZoomIn() const; + void SlotZoomIn() const; - void slotZoomOut() const; - /**************************************************************************************** - * Name: selectAll - * Description: select all in current textpage - * Parameters: none - * Return Values: none - * Change on members: none - */ /** * @brief * */ - void slotSelectAll() const; + void SlotZoomOut() const; - protected: - /**************************************************************************************** - * Name: saveFile - * Description: Saves the content of currentTab to the file filename - * Parameters: QString filename contains the full path of the file to - * save Return Values: true, if the file was saved succesfully false, if - * parameter filename is empty or the saving failed Change on members: sets - * isModified of the current tab to false + /** + * @brief select all in current text page + * */ + void SlotSelectAll() const; + + protected: /** - * @brief + * @brief Saves the content of currentTab to the file filename * * @param fileName */ - bool saveFile(const QString& fileName); + bool save_file(const QString& fileName); }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp index 3187e156..4c936f4f 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.cpp +++ b/src/ui/widgets/VerifyKeyDetailBox.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,41 +8,43 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #include "ui/widgets/VerifyKeyDetailBox.h" -#include "gpg/function/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyGetter.h" namespace GpgFrontend::UI { VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, QWidget* parent) - : QGroupBox(parent), fpr(signature.fpr()) { + : QGroupBox(parent), fpr_(signature.GetFingerprint()) { auto* vbox = new QVBoxLayout(); - switch (gpg_err_code(signature.status())) { + switch (gpg_err_code(signature.GetStatus())) { case GPG_ERR_NO_PUBKEY: { this->setTitle("A Error Signature"); auto* importButton = new QPushButton(_("Import from keyserver")); - connect(importButton, SIGNAL(clicked()), this, - SLOT(slotImportFormKeyserver())); + connect(importButton,&QPushButton::clicked, this, + &VerifyKeyDetailBox::slot_import_form_key_server); - this->setTitle(QString(_("Key not present with id 0x")) + fpr.c_str()); + this->setTitle(QString(_("Key not present with id 0x")) + fpr_.c_str()); auto grid = new QGridLayout(); @@ -55,14 +59,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, } case GPG_ERR_NO_ERROR: { this->setTitle(QString(_("A Signature")) + ":"); - auto gird = createKeyInfoGrid(signature); + auto gird = create_key_info_grid(signature); if (gird != nullptr) { vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (!signature.fpr().empty()) { + if (!signature.GetFingerprint().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - signature.fpr().c_str())); + signature.GetFingerprint().c_str())); } } break; @@ -71,14 +75,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, this->setTitle("An Error Signature"); vbox->addWidget( new QLabel(QString(_("Status")) + ":" + _("Cert Revoked"))); - auto gird = createKeyInfoGrid(signature); + auto gird = create_key_info_grid(signature); if (gird != nullptr) { vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (!signature.fpr().empty()) { + if (!signature.GetFingerprint().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - signature.fpr().c_str())); + signature.GetFingerprint().c_str())); } } break; @@ -87,14 +91,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, this->setTitle("An Error Signature"); vbox->addWidget( new QLabel(QString(_("Status")) + ":" + _("Signature Expired"))); - auto gird = createKeyInfoGrid(signature); + auto gird = create_key_info_grid(signature); if (gird != nullptr) { vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (!signature.fpr().empty()) { + if (!signature.GetFingerprint().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - signature.fpr().c_str())); + signature.GetFingerprint().c_str())); } } break; @@ -105,14 +109,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, new QLabel(QString(_("Status")) + ":" + _("Key Expired"))); vbox->addWidget( new QLabel(QString(_("Status")) + ":" + _("Key Expired"))); - auto gird = createKeyInfoGrid(signature); + auto gird = create_key_info_grid(signature); if (gird != nullptr) { vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (!signature.fpr().empty()) { + if (!signature.GetFingerprint().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - signature.fpr().c_str())); + signature.GetFingerprint().c_str())); } } break; @@ -121,14 +125,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, this->setTitle("An Error Signature"); vbox->addWidget( new QLabel(QString(_("Status")) + ":" + _("General Error"))); - auto gird = createKeyInfoGrid(signature); + auto gird = create_key_info_grid(signature); if (gird != nullptr) { vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (!signature.fpr().empty()) { + if (!signature.GetFingerprint().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - signature.fpr().c_str())); + signature.GetFingerprint().c_str())); } } break; @@ -136,14 +140,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, default: { this->setTitle("An Error Signature"); this->setTitle(QString(_("Status")) + ":" + _("Unknown Error ")); - auto gird = createKeyInfoGrid(signature); + auto gird = create_key_info_grid(signature); if (gird != nullptr) { vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (!signature.fpr().empty()) { + if (!signature.GetFingerprint().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - signature.fpr().c_str())); + signature.GetFingerprint().c_str())); } } break; @@ -152,30 +156,30 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, this->setLayout(vbox); } -void VerifyKeyDetailBox::slotImportFormKeyserver() { +void VerifyKeyDetailBox::slot_import_form_key_server() { auto* importDialog = new KeyServerImportDialog(false, this); auto key_ids = std::make_unique<KeyIdArgsList>(); - key_ids->push_back(fpr); - importDialog->slotImport(key_ids); + key_ids->push_back(fpr_); + importDialog->SlotImport(key_ids); } -QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( +QGridLayout* VerifyKeyDetailBox::create_key_info_grid( const GpgSignature& signature) { auto grid = new QGridLayout(); - GpgKey key = GpgKeyGetter::GetInstance().GetKey(fpr); + GpgKey key = GpgKeyGetter::GetInstance().GetKey(fpr_); - if (!key.good()) return nullptr; + if (!key.IsGood()) return nullptr; grid->addWidget(new QLabel(QString(_("Signer Name")) + ":"), 0, 0); grid->addWidget(new QLabel(QString(_("Signer Email")) + ":"), 1, 0); grid->addWidget(new QLabel(QString(_("Key's Fingerprint")) + ":"), 2, 0); grid->addWidget(new QLabel(QString(_("Valid")) + ":"), 3, 0); grid->addWidget(new QLabel(QString(_("Flags")) + ":"), 4, 0); - grid->addWidget(new QLabel(QString::fromStdString(key.name())), 0, 1); - grid->addWidget(new QLabel(QString::fromStdString(key.email())), 1, 1); - grid->addWidget(new QLabel(beautify_fingerprint(fpr).c_str()), 2, 1); + grid->addWidget(new QLabel(QString::fromStdString(key.GetName())), 0, 1); + grid->addWidget(new QLabel(QString::fromStdString(key.GetEmail())), 1, 1); + grid->addWidget(new QLabel(beautify_fingerprint(fpr_).c_str()), 2, 1); - if (signature.summary() & GPGME_SIGSUM_VALID) { + if (signature.GetSummary() & GPGME_SIGSUM_VALID) { grid->addWidget(new QLabel(_("Fully Valid")), 3, 1); } else { grid->addWidget(new QLabel(_("NOT Fully Valid")), 3, 1); @@ -183,25 +187,25 @@ QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( std::stringstream text_stream; - if (signature.summary() & GPGME_SIGSUM_GREEN) { + if (signature.GetSummary() & GPGME_SIGSUM_GREEN) { text_stream << _("Good") << " "; } - if (signature.summary() & GPGME_SIGSUM_RED) { + if (signature.GetSummary() & GPGME_SIGSUM_RED) { text_stream << _("Bad") << " "; } - if (signature.summary() & GPGME_SIGSUM_SIG_EXPIRED) { + if (signature.GetSummary() & GPGME_SIGSUM_SIG_EXPIRED) { text_stream << _("Expired") << " "; } - if (signature.summary() & GPGME_SIGSUM_KEY_MISSING) { + if (signature.GetSummary() & GPGME_SIGSUM_KEY_MISSING) { text_stream << _("Missing Key") << " "; } - if (signature.summary() & GPGME_SIGSUM_KEY_REVOKED) { + if (signature.GetSummary() & GPGME_SIGSUM_KEY_REVOKED) { text_stream << _("Revoked Key") << " "; } - if (signature.summary() & GPGME_SIGSUM_KEY_EXPIRED) { + if (signature.GetSummary() & GPGME_SIGSUM_KEY_EXPIRED) { text_stream << _("Expired Key") << " "; } - if (signature.summary() & GPGME_SIGSUM_CRL_MISSING) { + if (signature.GetSummary() & GPGME_SIGSUM_CRL_MISSING) { text_stream << _("Missing CRL") << " "; } diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h index b01d628d..18fa7963 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.h +++ b/src/ui/widgets/VerifyKeyDetailBox.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,43 +8,64 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifndef __VERIFYKEYDETAILBOX_H__ #define __VERIFYKEYDETAILBOX_H__ -#include "ui/KeyServerImportDialog.h" +#include "ui/import_export/KeyServerImportDialog.h" #include "ui/widgets/KeyList.h" namespace GpgFrontend::UI { - +/** + * @brief + * + */ class VerifyKeyDetailBox : public QGroupBox { Q_OBJECT public: + /** + * @brief Construct a new Verify Key Detail Box object + * + * @param signature + * @param parent + */ explicit VerifyKeyDetailBox(const GpgSignature& signature, QWidget* parent); private slots: - void slotImportFormKeyserver(); + /** + * @brief + * + */ + void slot_import_form_key_server(); private: - QGridLayout* createKeyInfoGrid(const GpgSignature& signature); + /** + * @brief Create a key info grid object + * + * @param signature + * @return QGridLayout* + */ + QGridLayout* create_key_info_grid(const GpgSignature& signature); - std::string fpr; + std::string fpr_; ///< }; } // namespace GpgFrontend::UI diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cee1720b..84fc9f9a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,29 @@ +# +# Copyright (C) 2021 Saturneric +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric<[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + find_package(GTest REQUIRED) # Set configure for test diff --git a/test/GpgCoreTest.cpp b/test/GpgCoreTest.cpp index ab9dbf28..224fad18 100644 --- a/test/GpgCoreTest.cpp +++ b/test/GpgCoreTest.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/test/GpgCoreTestBasicOpera.cpp b/test/GpgCoreTestBasicOpera.cpp index 283ceb82..57339453 100644 --- a/test/GpgCoreTestBasicOpera.cpp +++ b/test/GpgCoreTestBasicOpera.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -29,9 +33,9 @@ #include "GpgFrontendTest.h" #include "gpg/GpgConstants.h" -#include "gpg/function/BasicOperator.h" +#include "gpg/function/GpgBasicOperator.h" #include "gpg/function/GpgKeyGetter.h" -#include "gpg/result_analyse/DecryptResultAnalyse.h" +#include "gpg/result_analyse/GpgDecryptResultAnalyse.h" using namespace GpgFrontend; diff --git a/test/GpgCoreTestImportExport.cpp b/test/GpgCoreTestImportExport.cpp index 1e226247..bef5660a 100644 --- a/test/GpgCoreTestImportExport.cpp +++ b/test/GpgCoreTestImportExport.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/test/GpgCoreTestKeyModel.cpp b/test/GpgCoreTestKeyModel.cpp index 79cd7dcd..41498e95 100644 --- a/test/GpgCoreTestKeyModel.cpp +++ b/test/GpgCoreTestKeyModel.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/test/GpgCoreTestKeyModelAlone.cpp b/test/GpgCoreTestKeyModelAlone.cpp index 3d5bd175..31d33bf9 100644 --- a/test/GpgCoreTestKeyModelAlone.cpp +++ b/test/GpgCoreTestKeyModelAlone.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/test/GpgCoreTestKeygen.cpp b/test/GpgCoreTestKeygen.cpp index b703ee40..ebfe398b 100644 --- a/test/GpgCoreTestKeygen.cpp +++ b/test/GpgCoreTestKeygen.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/test/GpgCoreTestKeygenAlone.cpp b/test/GpgCoreTestKeygenAlone.cpp index 4a725ba7..71deb626 100644 --- a/test/GpgCoreTestKeygenAlone.cpp +++ b/test/GpgCoreTestKeygenAlone.cpp @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ diff --git a/test/GpgFrontendTest.h b/test/GpgFrontendTest.h index 84476106..ebd5e33a 100644 --- a/test/GpgFrontendTest.h +++ b/test/GpgFrontendTest.h @@ -1,4 +1,6 @@ /** + * Copyright (C) 2021 Saturneric + * * This file is part of GpgFrontend. * * GpgFrontend is free software: you can redistribute it and/or modify @@ -6,19 +8,21 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Foobar is distributed in the hope that it will be useful, + * GpgFrontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. + * SPDX-License-Identifier: GPL-3.0-or-later * */ @@ -164,8 +168,8 @@ class GpgCoreTest : public ::testing::Test { GpgFrontend::GpgContextInitArgs args; args.gpg_alone = true; args.independent_database = true; - args.db_path = db_path.string(); - args.gpg_path = gpg_path.string(); + args.db_path = db_path.u8string(); + args.gpg_path = gpg_path.u8string(); args.test_mode = true; return std::make_unique<GpgFrontend::GpgContext>(args); }); diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 874fe37f..0df99211 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -1,13 +1,217 @@ -if (EASY_LOGGING_PP) - message(STATUS "Build dependency easyloggingpp") - add_subdirectory(easyloggingpp) -endif () - -if (APP_IMAGE_UPDATE) - message(STATUS "Build dependency AppImageUpdate") - set(USE_SYSTEM_BOOST 1) - set(USE_SYSTEM_XZ 1) - set(USE_SYSTEM_SQUASHFUSE 1) - set(USE_SYSTEM_LIBARCHIVE 1) - add_subdirectory(AppImageUpdate) +# +# Copyright (C) 2021 Saturneric +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric<[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# easyloggingpp +set(build_static_lib 1 CACHE BOOL "" FORCE) +add_subdirectory(easyloggingpp) +target_include_directories(easyloggingpp PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/easyloggingpp/src) + +# json +set(JSON_BuildTests OFF CACHE INTERNAL "") +add_subdirectory(json) + +# qt-aes +include(GenerateExportHeader) +add_subdirectory(qt-aes) + +# vmime +set(VMIME_HAVE_MESSAGING_PROTO_SENDMAIL OFF CACHE BOOL "" FORCE) +set(VMIME_HAVE_SASL_SUPPORT OFF CACHE BOOL "" FORCE) +set(VMIME_BUILD_STATIC_LIBRARY ON CACHE BOOL "" FORCE) +set(VMIME_BUILD_SHARED_LIBRARY OFF CACHE BOOL "" FORCE) +set(VMIME_CHARSETCONV_LIB "iconv" CACHE STRING "" FORCE) +set(VMIME_TLS_SUPPORT_LIB "openssl" CACHE STRING "" FORCE) + +set(VMIME_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vmime) +set(VMIME_BIN ${CMAKE_CURRENT_BINARY_DIR}/vmime) + +set(VMIME_INCLUDES ${VMIME_DIR}/src ${CMAKE_BINARY_DIR}/src/vmime/ ${CMAKE_BINARY_DIR}/src/) + +set(VMIME_BIN_STATIC_LIB ${VMIME_BIN}/build/lib/libvmime.a) + +add_subdirectory(vmime) + +add_library(gpgfrontend_vmime STATIC IMPORTED GLOBAL) +add_dependencies(gpgfrontend_vmime vmime-static vmime-static-config) +set_target_properties(gpgfrontend_vmime PROPERTIES IMPORTED_LOCATION ${VMIME_BIN_STATIC_LIB}) +set_target_properties(gpgfrontend_vmime PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${VMIME_INCLUDES}") + +# gnupg + +include(ExternalProject) + +# libgpg-error + + +if (NOT MINGW) + set(GPG_ERROR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libgpg-error) + set(GPG_ERROR_BIN ${CMAKE_CURRENT_BINARY_DIR}/libgpg-error) + set(GPG_ERROR_STATIC_LIB ${GPG_ERROR_BIN}/lib/libgpg-error.a) + set(GPG_ERROR_INCLUDES ${GPG_ERROR_BIN}/include) + set(GPG_ERROR_LIBS ${GPG_ERROR_BIN}/lib) + file(MAKE_DIRECTORY ${GPG_ERROR_INCLUDES}) +else () + find_library(GPG_ERROR_STATIC_LIB libgpg-error.a) +endif () + +if (NOT MINGW) + + ExternalProject_Add(libgpg-error + PREFIX ${GPG_ERROR_BIN} + SOURCE_DIR ${GPG_ERROR_DIR} + CONFIGURE_COMMAND ${GPG_ERROR_DIR}/configure --enable-maintainer-mode --prefix=${GPG_ERROR_BIN} --enable-static=yes + BUILD_COMMAND make + INSTALL_COMMAND make install + BUILD_BYPRODUCTS ${GPG_ERROR_STATIC_LIB}) + + ExternalProject_Add_Step(libgpg-error autogen + WORKING_DIRECTORY ${GPG_ERROR_DIR} + COMMAND ${GPG_ERROR_DIR}/autogen.sh + DEPENDERS configure) + +endif () + +add_library(gpg-error STATIC IMPORTED GLOBAL) +if (NOT MINGW) + add_dependencies(gpg-error libgpg-error) + set_target_properties(gpg-error PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${GPG_ERROR_INCLUDES}) +endif () +set_target_properties(gpg-error PROPERTIES IMPORTED_LOCATION ${GPG_ERROR_STATIC_LIB}) + +# libassuan + +if (NOT MINGW) + set(ASSUAN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libassuan) + set(ASSUAN_BIN ${CMAKE_CURRENT_BINARY_DIR}/libassuan) + set(ASSUAN_STATIC_LIB ${ASSUAN_BIN}/lib/libassuan.a) + set(ASSUAN_INCLUDES ${ASSUAN_BIN}/include) + set(ASSUAN_LIBS ${ASSUAN_BIN}/lib) + file(MAKE_DIRECTORY ${ASSUAN_INCLUDES}) +else () + find_library(ASSUAN_STATIC_LIB libassuan.a) +endif () + +if (NOT MINGW) + + ExternalProject_Add(libassuan + PREFIX ${ASSUAN_BIN} + SOURCE_DIR ${ASSUAN_DIR} + CONFIGURE_COMMAND ${ASSUAN_DIR}/configure --enable-maintainer-mode --prefix=${ASSUAN_BIN} --enable-static=yes + --with-libgpg-error-prefix=${GPG_ERROR_BIN} + BUILD_COMMAND make + INSTALL_COMMAND make install + BUILD_BYPRODUCTS ${ASSUAN_STATIC_LIB}) + + ExternalProject_Add_Step(libassuan autogen + WORKING_DIRECTORY ${ASSUAN_DIR} + COMMAND ${ASSUAN_DIR}/autogen.sh + DEPENDERS configure) + + ExternalProject_Add_StepDependencies(libassuan autogen libgpg-error) + +endif () + +add_library(assuan STATIC IMPORTED GLOBAL) +if (NOT MINGW) + add_dependencies(assuan libassuan gpg-error) + set_target_properties(assuan PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${ASSUAN_INCLUDES}) +endif () +set_target_properties(assuan PROPERTIES IMPORTED_LOCATION ${ASSUAN_STATIC_LIB}) + +# gpgme + +if (NOT MINGW) + set(GPGME_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gpgme) + set(GPGME_BIN ${CMAKE_CURRENT_BINARY_DIR}/gpgme) + set(GPGME_STATIC_LIB ${GPGME_BIN}/lib/libgpgme.a) + set(GPGME_INCLUDES ${GPGME_BIN}/include) + file(MAKE_DIRECTORY ${GPGME_INCLUDES}) +else () + find_library(GPGME_STATIC_LIB libgpgme.a) +endif () + +if (NOT MINGW) + + ExternalProject_Add(libgpgme + PREFIX ${GPGME_BIN} + SOURCE_DIR ${GPGME_DIR} + CONFIGURE_COMMAND ${GPGME_DIR}/configure --enable-maintainer-mode --prefix=${GPGME_BIN} --enable-shared=no --enable-static=yes --disable-gpg-test --enable-languages=cpp + --with-libgpg-error-prefix=${GPG_ERROR_BIN} + --with-libassuan-prefix=${ASSUAN_BIN} + "LIB=-lassuan -lgpg-error" + "LDFLAGS=-L${ASSUAN_LIBS} -L${GPG_ERROR_LIBS} " + BUILD_COMMAND make + INSTALL_COMMAND make install + BUILD_BYPRODUCTS ${GPGME_STATIC_LIB}) + + ExternalProject_Add_Step(libgpgme autogen + WORKING_DIRECTORY ${GPGME_DIR} + COMMAND ${GPGME_DIR}/autogen.sh + DEPENDERS configure) + + ExternalProject_Add_StepDependencies(libgpgme autogen libassuan libgpg-error) + +endif () + +add_library(gpgme STATIC IMPORTED GLOBAL) +if (NOT MINGW) + add_dependencies(gpgme libgpgme assuan gpg-error) + set_target_properties(gpgme PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${GPGME_INCLUDES}) +endif () +set_target_properties(gpgme PROPERTIES IMPORTED_LOCATION ${GPGME_STATIC_LIB}) + +if (SMTP_SUPPORT) + message(STATUS "Build SMTP Support") + aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/smtp-mime/src SMTP_MIME_SOURCE) + add_library(smtp-mime STATIC ${SMTP_MIME_SOURCE}) + target_link_libraries(smtp-mime + Qt5::Network Qt5::Core) + target_include_directories(smtp-mime PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/smtp-mime/src) + if (XCODE_BUILD) + set_target_properties(smtp-mime + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) + endif () +endif () + +# encoding detect library +aux_source_directory(./encoding-detect ENCODING_DETECT_SOURCE_CODE) +add_library(encoding_detect STATIC ${ENCODING_DETECT_SOURCE_CODE}) + +# libarchive +if (NOT MINGW) + remove_definitions(-DDEBUG) + add_subdirectory(libarchive) +endif () + +if (NOT MINGW) +# libconfig +add_subdirectory(libconfig) endif ()
\ No newline at end of file diff --git a/third_party/easyloggingpp b/third_party/easyloggingpp new file mode 160000 +Subproject 8489989bb26c6371df103f6cbced3fbee1bc3c2 diff --git a/third_party/easyloggingpp/CMakeLists.txt b/third_party/easyloggingpp/CMakeLists.txt deleted file mode 100644 index 40b4bd14..00000000 --- a/third_party/easyloggingpp/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -aux_source_directory(. EASY_LOGGING_CPP_SOURCE) - -add_library(easy_logging_pp STATIC ${EASY_LOGGING_CPP_SOURCE}) -target_link_libraries(easy_logging_pp stdc++) -if(XCODE_BUILD) -set_target_properties(easy_logging_pp - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) -endif()
\ No newline at end of file diff --git a/third_party/easyloggingpp/easylogging++.cc b/third_party/easyloggingpp/easylogging++.cc deleted file mode 100644 index 7451a3c1..00000000 --- a/third_party/easyloggingpp/easylogging++.cc +++ /dev/null @@ -1,3526 +0,0 @@ -// -// Bismillah ar-Rahmaan ar-Raheem -// -// Easylogging++ v9.96.7 -// Cross-platform logging library for C++ applications -// -// Copyright (c) 2012-2018 Amrayn Web Services -// Copyright (c) 2012-2018 @abumusamq -// -// This library is released under the MIT Licence. -// https://github.com/amrayn/easyloggingpp/blob/master/LICENSE -// -// https://amrayn.com -// http://muflihun.com -// - -#include "easylogging++.h" - -#if defined(AUTO_INITIALIZE_EASYLOGGINGPP) -INITIALIZE_EASYLOGGINGPP -#endif - -namespace el { - -// el::base -namespace base { -// el::base::consts -namespace consts { - -// Level log values - These are values that are replaced in place of %level -// format specifier Extra spaces after format specifiers are only for -// readability purposes in log files -static const base::type::char_t *kInfoLevelLogValue = ELPP_LITERAL("INFO"); -static const base::type::char_t *kDebugLevelLogValue = ELPP_LITERAL("DEBUG"); -static const base::type::char_t *kWarningLevelLogValue = - ELPP_LITERAL("WARNING"); -static const base::type::char_t *kErrorLevelLogValue = ELPP_LITERAL("ERROR"); -static const base::type::char_t *kFatalLevelLogValue = ELPP_LITERAL("FATAL"); -static const base::type::char_t *kVerboseLevelLogValue = - ELPP_LITERAL("VERBOSE"); // will become VERBOSE-x where x = verbose level -static const base::type::char_t *kTraceLevelLogValue = ELPP_LITERAL("TRACE"); -static const base::type::char_t *kInfoLevelShortLogValue = ELPP_LITERAL("I"); -static const base::type::char_t *kDebugLevelShortLogValue = ELPP_LITERAL("D"); -static const base::type::char_t *kWarningLevelShortLogValue = ELPP_LITERAL("W"); -static const base::type::char_t *kErrorLevelShortLogValue = ELPP_LITERAL("E"); -static const base::type::char_t *kFatalLevelShortLogValue = ELPP_LITERAL("F"); -static const base::type::char_t *kVerboseLevelShortLogValue = ELPP_LITERAL("V"); -static const base::type::char_t *kTraceLevelShortLogValue = ELPP_LITERAL("T"); -// Format specifiers - These are used to define log format -static const base::type::char_t *kAppNameFormatSpecifier = ELPP_LITERAL("%app"); -static const base::type::char_t *kLoggerIdFormatSpecifier = - ELPP_LITERAL("%logger"); -static const base::type::char_t *kThreadIdFormatSpecifier = - ELPP_LITERAL("%thread"); -static const base::type::char_t *kSeverityLevelFormatSpecifier = - ELPP_LITERAL("%level"); -static const base::type::char_t *kSeverityLevelShortFormatSpecifier = - ELPP_LITERAL("%levshort"); -static const base::type::char_t *kDateTimeFormatSpecifier = - ELPP_LITERAL("%datetime"); -static const base::type::char_t *kLogFileFormatSpecifier = - ELPP_LITERAL("%file"); -static const base::type::char_t *kLogFileBaseFormatSpecifier = - ELPP_LITERAL("%fbase"); -static const base::type::char_t *kLogLineFormatSpecifier = - ELPP_LITERAL("%line"); -static const base::type::char_t *kLogLocationFormatSpecifier = - ELPP_LITERAL("%loc"); -static const base::type::char_t *kLogFunctionFormatSpecifier = - ELPP_LITERAL("%func"); -static const base::type::char_t *kCurrentUserFormatSpecifier = - ELPP_LITERAL("%user"); -static const base::type::char_t *kCurrentHostFormatSpecifier = - ELPP_LITERAL("%host"); -static const base::type::char_t *kMessageFormatSpecifier = ELPP_LITERAL("%msg"); -static const base::type::char_t *kVerboseLevelFormatSpecifier = - ELPP_LITERAL("%vlevel"); -static const char *kDateTimeFormatSpecifierForFilename = "%datetime"; -// Date/time -static const char *kDays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday"}; -static const char *kDaysAbbrev[7] = {"Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat"}; -static const char *kMonths[12] = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"}; -static const char *kMonthsAbbrev[12] = {"Jan", "Feb", "Mar", "Apr", - "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec"}; -static const char *kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g"; -static const char *kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m"; -static const int kYearBase = 1900; -static const char *kAm = "AM"; -static const char *kPm = "PM"; -// Miscellaneous constants - -static const char *kNullPointer = "nullptr"; -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED -static const base::type::VerboseLevel kMaxVerboseLevel = 9; -static const char *kUnknownUser = "unknown-user"; -static const char *kUnknownHost = "unknown-host"; - -//---------------- DEFAULT LOG FILE ----------------------- - -#if defined(ELPP_NO_DEFAULT_LOG_FILE) -#if ELPP_OS_UNIX -static const char *kDefaultLogFile = "/dev/null"; -#elif ELPP_OS_WINDOWS -static const char *kDefaultLogFile = "nul"; -#endif // ELPP_OS_UNIX -#elif defined(ELPP_DEFAULT_LOG_FILE) -static const char *kDefaultLogFile = ELPP_DEFAULT_LOG_FILE; -#else -static const char *kDefaultLogFile = "myeasylog.log"; -#endif // defined(ELPP_NO_DEFAULT_LOG_FILE) - -#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) -static const char *kDefaultLogFileParam = "--default-log-file"; -#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) -#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) -static const char *kLoggingFlagsParam = "--logging-flags"; -#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) -static const char *kValidLoggerIdSymbols = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._"; -static const char *kConfigurationComment = "##"; -static const char *kConfigurationLevel = "*"; -static const char *kConfigurationLoggerId = "--"; -} // namespace consts -// el::base::utils -namespace utils { - -/// @brief Aborts application due with user-defined status -static void abort(int status, const std::string &reason) { - // Both status and reason params are there for debugging with tools like gdb - // etc - ELPP_UNUSED(status); - ELPP_UNUSED(reason); -#if defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) - // Ignore msvc critical error dialog - break instead (on debug mode) - _asm int 3 -#else - ::abort(); -#endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) -} - -} // namespace utils -} // namespace base - -// el - -// LevelHelper - -const char *LevelHelper::convertToString(Level level) { - // Do not use switch over strongly typed enums because Intel C++ compilers - // dont support them yet. - if (level == Level::Global) - return "GLOBAL"; - if (level == Level::Debug) - return "DEBUG"; - if (level == Level::Info) - return "INFO"; - if (level == Level::Warning) - return "WARNING"; - if (level == Level::Error) - return "ERROR"; - if (level == Level::Fatal) - return "FATAL"; - if (level == Level::Verbose) - return "VERBOSE"; - if (level == Level::Trace) - return "TRACE"; - return "UNKNOWN"; -} - -struct StringToLevelItem { - const char *levelString; - Level level; -}; - -static struct StringToLevelItem stringToLevelMap[] = { - {"global", Level::Global}, {"debug", Level::Debug}, - {"info", Level::Info}, {"warning", Level::Warning}, - {"error", Level::Error}, {"fatal", Level::Fatal}, - {"verbose", Level::Verbose}, {"trace", Level::Trace}}; - -Level LevelHelper::convertFromString(const char *levelStr) { - for (auto &item : stringToLevelMap) { - if (base::utils::Str::cStringCaseEq(levelStr, item.levelString)) { - return item.level; - } - } - return Level::Unknown; -} - -void LevelHelper::forEachLevel(base::type::EnumType *startIndex, - const std::function<bool(void)> &fn) { - base::type::EnumType lIndexMax = LevelHelper::kMaxValid; - do { - if (fn()) { - break; - } - *startIndex = static_cast<base::type::EnumType>(*startIndex << 1); - } while (*startIndex <= lIndexMax); -} - -// ConfigurationTypeHelper - -const char * -ConfigurationTypeHelper::convertToString(ConfigurationType configurationType) { - // Do not use switch over strongly typed enums because Intel C++ compilers - // dont support them yet. - if (configurationType == ConfigurationType::Enabled) - return "ENABLED"; - if (configurationType == ConfigurationType::Filename) - return "FILENAME"; - if (configurationType == ConfigurationType::Format) - return "FORMAT"; - if (configurationType == ConfigurationType::ToFile) - return "TO_FILE"; - if (configurationType == ConfigurationType::ToStandardOutput) - return "TO_STANDARD_OUTPUT"; - if (configurationType == ConfigurationType::SubsecondPrecision) - return "SUBSECOND_PRECISION"; - if (configurationType == ConfigurationType::PerformanceTracking) - return "PERFORMANCE_TRACKING"; - if (configurationType == ConfigurationType::MaxLogFileSize) - return "MAX_LOG_FILE_SIZE"; - if (configurationType == ConfigurationType::LogFlushThreshold) - return "LOG_FLUSH_THRESHOLD"; - return "UNKNOWN"; -} - -struct ConfigurationStringToTypeItem { - const char *configString; - ConfigurationType configType; -}; - -static struct ConfigurationStringToTypeItem configStringToTypeMap[] = { - {"enabled", ConfigurationType::Enabled}, - {"to_file", ConfigurationType::ToFile}, - {"to_standard_output", ConfigurationType::ToStandardOutput}, - {"format", ConfigurationType::Format}, - {"filename", ConfigurationType::Filename}, - {"subsecond_precision", ConfigurationType::SubsecondPrecision}, - {"milliseconds_width", ConfigurationType::MillisecondsWidth}, - {"performance_tracking", ConfigurationType::PerformanceTracking}, - {"max_log_file_size", ConfigurationType::MaxLogFileSize}, - {"log_flush_threshold", ConfigurationType::LogFlushThreshold}, -}; - -ConfigurationType -ConfigurationTypeHelper::convertFromString(const char *configStr) { - for (auto &item : configStringToTypeMap) { - if (base::utils::Str::cStringCaseEq(configStr, item.configString)) { - return item.configType; - } - } - return ConfigurationType::Unknown; -} - -void ConfigurationTypeHelper::forEachConfigType( - base::type::EnumType *startIndex, const std::function<bool(void)> &fn) { - base::type::EnumType cIndexMax = ConfigurationTypeHelper::kMaxValid; - do { - if (fn()) { - break; - } - *startIndex = static_cast<base::type::EnumType>(*startIndex << 1); - } while (*startIndex <= cIndexMax); -} - -// Configuration - -Configuration::Configuration(const Configuration &c) - : m_level(c.m_level), m_configurationType(c.m_configurationType), - m_value(c.m_value) {} - -Configuration &Configuration::operator=(const Configuration &c) { - if (&c != this) { - m_level = c.m_level; - m_configurationType = c.m_configurationType; - m_value = c.m_value; - } - return *this; -} - -/// @brief Full constructor used to sets value of configuration -Configuration::Configuration(Level level, ConfigurationType configurationType, - const std::string &value) - : m_level(level), m_configurationType(configurationType), m_value(value) {} - -void Configuration::log(el::base::type::ostream_t &os) const { - os << LevelHelper::convertToString(m_level) << ELPP_LITERAL(" ") - << ConfigurationTypeHelper::convertToString(m_configurationType) - << ELPP_LITERAL(" = ") << m_value.c_str(); -} - -/// @brief Used to find configuration from configuration (pointers) repository. -/// Avoid using it. -Configuration::Predicate::Predicate(Level level, - ConfigurationType configurationType) - : m_level(level), m_configurationType(configurationType) {} - -bool Configuration::Predicate::operator()(const Configuration *conf) const { - return ((conf != nullptr) && (conf->level() == m_level) && - (conf->configurationType() == m_configurationType)); -} - -// Configurations - -Configurations::Configurations(void) - : m_configurationFile(std::string()), m_isFromFile(false) {} - -Configurations::Configurations(const std::string &configurationFile, - bool useDefaultsForRemaining, - Configurations *base) - : m_configurationFile(configurationFile), m_isFromFile(false) { - parseFromFile(configurationFile, base); - if (useDefaultsForRemaining) { - setRemainingToDefault(); - } -} - -bool Configurations::parseFromFile(const std::string &configurationFile, - Configurations *base) { - // We initial assertion with true because if we have assertion disabled, we - // want to pass this check and if assertion is enabled we will have values - // re-assigned any way. - bool assertionPassed = true; - ELPP_ASSERT((assertionPassed = base::utils::File::pathExists( - configurationFile.c_str(), true)) == true, - "Configuration file [" << configurationFile - << "] does not exist!"); - if (!assertionPassed) { - return false; - } - bool success = Parser::parseFromFile(configurationFile, this, base); - m_isFromFile = success; - return success; -} - -bool Configurations::parseFromText(const std::string &configurationsString, - Configurations *base) { - bool success = Parser::parseFromText(configurationsString, this, base); - if (success) { - m_isFromFile = false; - } - return success; -} - -void Configurations::setFromBase(Configurations *base) { - if (base == nullptr || base == this) { - return; - } - base::threading::ScopedLock scopedLock(base->lock()); - for (Configuration *&conf : base->list()) { - set(conf); - } -} - -bool Configurations::hasConfiguration(ConfigurationType configurationType) { - base::type::EnumType lIndex = LevelHelper::kMinValid; - bool result = false; - LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { - if (hasConfiguration(LevelHelper::castFromInt(lIndex), configurationType)) { - result = true; - } - return result; - }); - return result; -} - -bool Configurations::hasConfiguration(Level level, - ConfigurationType configurationType) { - base::threading::ScopedLock scopedLock(lock()); -#if ELPP_COMPILER_INTEL - // We cant specify template types here, Intel C++ throws compilation error - // "error: type name is not allowed" - return RegistryWithPred::get(level, configurationType) != nullptr; -#else - return RegistryWithPred<Configuration, Configuration::Predicate>::get( - level, configurationType) != nullptr; -#endif // ELPP_COMPILER_INTEL -} - -void Configurations::set(Level level, ConfigurationType configurationType, - const std::string &value) { - base::threading::ScopedLock scopedLock(lock()); - unsafeSet(level, configurationType, - value); // This is not unsafe anymore as we have locked mutex - if (level == Level::Global) { - unsafeSetGlobally(configurationType, value, - false); // Again this is not unsafe either - } -} - -void Configurations::set(Configuration *conf) { - if (conf == nullptr) { - return; - } - set(conf->level(), conf->configurationType(), conf->value()); -} - -void Configurations::setToDefault(void) { - setGlobally(ConfigurationType::Enabled, std::string("true"), true); - setGlobally(ConfigurationType::Filename, - std::string(base::consts::kDefaultLogFile), true); -#if defined(ELPP_NO_LOG_TO_FILE) - setGlobally(ConfigurationType::ToFile, std::string("false"), true); -#else - setGlobally(ConfigurationType::ToFile, std::string("true"), true); -#endif // defined(ELPP_NO_LOG_TO_FILE) - setGlobally(ConfigurationType::ToStandardOutput, std::string("true"), true); - setGlobally(ConfigurationType::SubsecondPrecision, std::string("3"), true); - setGlobally(ConfigurationType::PerformanceTracking, std::string("true"), - true); - setGlobally(ConfigurationType::MaxLogFileSize, std::string("0"), true); - setGlobally(ConfigurationType::LogFlushThreshold, std::string("0"), true); - - setGlobally(ConfigurationType::Format, - std::string("%datetime %level [%logger] %msg"), true); - set(Level::Debug, ConfigurationType::Format, - std::string( - "%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg")); - // INFO and WARNING are set to default by Level::Global - set(Level::Error, ConfigurationType::Format, - std::string("%datetime %level [%logger] %msg")); - set(Level::Fatal, ConfigurationType::Format, - std::string("%datetime %level [%logger] %msg")); - set(Level::Verbose, ConfigurationType::Format, - std::string("%datetime %level-%vlevel [%logger] %msg")); - set(Level::Trace, ConfigurationType::Format, - std::string("%datetime %level [%logger] [%func] [%loc] %msg")); -} - -void Configurations::setRemainingToDefault(void) { - base::threading::ScopedLock scopedLock(lock()); -#if defined(ELPP_NO_LOG_TO_FILE) - unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, - std::string("false")); -#else - unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, - std::string("true")); -#endif // defined(ELPP_NO_LOG_TO_FILE) - unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, - std::string(base::consts::kDefaultLogFile)); - unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, - std::string("true")); - unsafeSetIfNotExist(Level::Global, ConfigurationType::SubsecondPrecision, - std::string("3")); - unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, - std::string("true")); - unsafeSetIfNotExist(Level::Global, ConfigurationType::MaxLogFileSize, - std::string("0")); - unsafeSetIfNotExist(Level::Global, ConfigurationType::Format, - std::string("%datetime %level [%logger] %msg")); - unsafeSetIfNotExist( - Level::Debug, ConfigurationType::Format, - std::string( - "%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg")); - // INFO and WARNING are set to default by Level::Global - unsafeSetIfNotExist(Level::Error, ConfigurationType::Format, - std::string("%datetime %level [%logger] %msg")); - unsafeSetIfNotExist(Level::Fatal, ConfigurationType::Format, - std::string("%datetime %level [%logger] %msg")); - unsafeSetIfNotExist(Level::Verbose, ConfigurationType::Format, - std::string("%datetime %level-%vlevel [%logger] %msg")); - unsafeSetIfNotExist( - Level::Trace, ConfigurationType::Format, - std::string("%datetime %level [%logger] [%func] [%loc] %msg")); -} - -bool Configurations::Parser::parseFromFile(const std::string &configurationFile, - Configurations *sender, - Configurations *base) { - sender->setFromBase(base); - std::ifstream fileStream_(configurationFile.c_str(), std::ifstream::in); - ELPP_ASSERT(fileStream_.is_open(), "Unable to open configuration file [" - << configurationFile - << "] for parsing."); - bool parsedSuccessfully = false; - std::string line = std::string(); - Level currLevel = Level::Unknown; - std::string currConfigStr = std::string(); - std::string currLevelStr = std::string(); - while (fileStream_.good()) { - std::getline(fileStream_, line); - parsedSuccessfully = - parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender); - ELPP_ASSERT(parsedSuccessfully, - "Unable to parse configuration line: " << line); - } - return parsedSuccessfully; -} - -bool Configurations::Parser::parseFromText( - const std::string &configurationsString, Configurations *sender, - Configurations *base) { - sender->setFromBase(base); - bool parsedSuccessfully = false; - std::stringstream ss(configurationsString); - std::string line = std::string(); - Level currLevel = Level::Unknown; - std::string currConfigStr = std::string(); - std::string currLevelStr = std::string(); - while (std::getline(ss, line)) { - parsedSuccessfully = - parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender); - ELPP_ASSERT(parsedSuccessfully, - "Unable to parse configuration line: " << line); - } - return parsedSuccessfully; -} - -void Configurations::Parser::ignoreComments(std::string *line) { - std::size_t foundAt = 0; - std::size_t quotesStart = line->find("\""); - std::size_t quotesEnd = std::string::npos; - if (quotesStart != std::string::npos) { - quotesEnd = line->find("\"", quotesStart + 1); - while (quotesEnd != std::string::npos && line->at(quotesEnd - 1) == '\\') { - // Do not erase slash yet - we will erase it in parseLine(..) while loop - quotesEnd = line->find("\"", quotesEnd + 2); - } - } - if ((foundAt = line->find(base::consts::kConfigurationComment)) != - std::string::npos) { - if (foundAt < quotesEnd) { - foundAt = line->find(base::consts::kConfigurationComment, quotesEnd + 1); - } - *line = line->substr(0, foundAt); - } -} - -bool Configurations::Parser::isLevel(const std::string &line) { - return base::utils::Str::startsWith( - line, std::string(base::consts::kConfigurationLevel)); -} - -bool Configurations::Parser::isComment(const std::string &line) { - return base::utils::Str::startsWith( - line, std::string(base::consts::kConfigurationComment)); -} - -bool Configurations::Parser::isConfig(const std::string &line) { - std::size_t assignment = line.find('='); - return line != "" && - ((line[0] >= 'A' && line[0] <= 'Z') || - (line[0] >= 'a' && line[0] <= 'z')) && - (assignment != std::string::npos) && (line.size() > assignment); -} - -bool Configurations::Parser::parseLine(std::string *line, - std::string *currConfigStr, - std::string *currLevelStr, - Level *currLevel, Configurations *conf) { - ConfigurationType currConfig = ConfigurationType::Unknown; - std::string currValue = std::string(); - *line = base::utils::Str::trim(*line); - if (isComment(*line)) - return true; - ignoreComments(line); - *line = base::utils::Str::trim(*line); - if (line->empty()) { - // Comment ignored - return true; - } - if (isLevel(*line)) { - if (line->size() <= 2) { - return true; - } - *currLevelStr = line->substr(1, line->size() - 2); - *currLevelStr = base::utils::Str::toUpper(*currLevelStr); - *currLevelStr = base::utils::Str::trim(*currLevelStr); - *currLevel = LevelHelper::convertFromString(currLevelStr->c_str()); - return true; - } - if (isConfig(*line)) { - std::size_t assignment = line->find('='); - *currConfigStr = line->substr(0, assignment); - *currConfigStr = base::utils::Str::toUpper(*currConfigStr); - *currConfigStr = base::utils::Str::trim(*currConfigStr); - currConfig = - ConfigurationTypeHelper::convertFromString(currConfigStr->c_str()); - currValue = line->substr(assignment + 1); - currValue = base::utils::Str::trim(currValue); - std::size_t quotesStart = currValue.find("\"", 0); - std::size_t quotesEnd = std::string::npos; - if (quotesStart != std::string::npos) { - quotesEnd = currValue.find("\"", quotesStart + 1); - while (quotesEnd != std::string::npos && - currValue.at(quotesEnd - 1) == '\\') { - currValue = currValue.erase(quotesEnd - 1, 1); - quotesEnd = currValue.find("\"", quotesEnd + 2); - } - } - if (quotesStart != std::string::npos && quotesEnd != std::string::npos) { - // Quote provided - check and strip if valid - ELPP_ASSERT((quotesStart < quotesEnd), - "Configuration error - No ending quote found in [" - << currConfigStr << "]"); - ELPP_ASSERT((quotesStart + 1 != quotesEnd), - "Empty configuration value for [" << currConfigStr << "]"); - if ((quotesStart != quotesEnd) && (quotesStart + 1 != quotesEnd)) { - // Explicit check in case if assertion is disabled - currValue = currValue.substr(quotesStart + 1, quotesEnd - 1); - } - } - } - ELPP_ASSERT(*currLevel != Level::Unknown, - "Unrecognized severity level [" << *currLevelStr << "]"); - ELPP_ASSERT(currConfig != ConfigurationType::Unknown, - "Unrecognized configuration [" << *currConfigStr << "]"); - if (*currLevel == Level::Unknown || - currConfig == ConfigurationType::Unknown) { - return false; // unrecognizable level or config - } - conf->set(*currLevel, currConfig, currValue); - return true; -} - -void Configurations::unsafeSetIfNotExist(Level level, - ConfigurationType configurationType, - const std::string &value) { - Configuration *conf = - RegistryWithPred<Configuration, Configuration::Predicate>::get( - level, configurationType); - if (conf == nullptr) { - unsafeSet(level, configurationType, value); - } -} - -void Configurations::unsafeSet(Level level, ConfigurationType configurationType, - const std::string &value) { - Configuration *conf = - RegistryWithPred<Configuration, Configuration::Predicate>::get( - level, configurationType); - if (conf == nullptr) { - registerNew(new Configuration(level, configurationType, value)); - } else { - conf->setValue(value); - } - if (level == Level::Global) { - unsafeSetGlobally(configurationType, value, false); - } -} - -void Configurations::setGlobally(ConfigurationType configurationType, - const std::string &value, - bool includeGlobalLevel) { - if (includeGlobalLevel) { - set(Level::Global, configurationType, value); - } - base::type::EnumType lIndex = LevelHelper::kMinValid; - LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { - set(LevelHelper::castFromInt(lIndex), configurationType, value); - return false; // Do not break lambda function yet as we need to set all - // levels regardless - }); -} - -void Configurations::unsafeSetGlobally(ConfigurationType configurationType, - const std::string &value, - bool includeGlobalLevel) { - if (includeGlobalLevel) { - unsafeSet(Level::Global, configurationType, value); - } - base::type::EnumType lIndex = LevelHelper::kMinValid; - LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { - unsafeSet(LevelHelper::castFromInt(lIndex), configurationType, value); - return false; // Do not break lambda function yet as we need to set all - // levels regardless - }); -} - -// LogBuilder - -void LogBuilder::convertToColoredOutput(base::type::string_t *logLine, - Level level) { - if (!m_termSupportsColor) - return; - const base::type::char_t *resetColor = ELPP_LITERAL("\x1b[0m"); - if (level == Level::Error || level == Level::Fatal) - *logLine = ELPP_LITERAL("\x1b[31m") + *logLine + resetColor; - else if (level == Level::Warning) - *logLine = ELPP_LITERAL("\x1b[33m") + *logLine + resetColor; - else if (level == Level::Debug) - *logLine = ELPP_LITERAL("\x1b[32m") + *logLine + resetColor; - else if (level == Level::Info) - *logLine = ELPP_LITERAL("\x1b[36m") + *logLine + resetColor; - else if (level == Level::Trace) - *logLine = ELPP_LITERAL("\x1b[35m") + *logLine + resetColor; -} - -// Logger - -Logger::Logger(const std::string &id, - base::LogStreamsReferenceMapPtr logStreamsReference) - : m_id(id), m_typedConfigurations(nullptr), - m_parentApplicationName(std::string()), m_isConfigured(false), - m_logStreamsReference(logStreamsReference) { - initUnflushedCount(); -} - -Logger::Logger(const std::string &id, const Configurations &configurations, - base::LogStreamsReferenceMapPtr logStreamsReference) - : m_id(id), m_typedConfigurations(nullptr), - m_parentApplicationName(std::string()), m_isConfigured(false), - m_logStreamsReference(logStreamsReference) { - initUnflushedCount(); - configure(configurations); -} - -Logger::Logger(const Logger &logger) { - base::utils::safeDelete(m_typedConfigurations); - m_id = logger.m_id; - m_typedConfigurations = logger.m_typedConfigurations; - m_parentApplicationName = logger.m_parentApplicationName; - m_isConfigured = logger.m_isConfigured; - m_configurations = logger.m_configurations; - m_unflushedCount = logger.m_unflushedCount; - m_logStreamsReference = logger.m_logStreamsReference; -} - -Logger &Logger::operator=(const Logger &logger) { - if (&logger != this) { - base::utils::safeDelete(m_typedConfigurations); - m_id = logger.m_id; - m_typedConfigurations = logger.m_typedConfigurations; - m_parentApplicationName = logger.m_parentApplicationName; - m_isConfigured = logger.m_isConfigured; - m_configurations = logger.m_configurations; - m_unflushedCount = logger.m_unflushedCount; - m_logStreamsReference = logger.m_logStreamsReference; - } - return *this; -} - -void Logger::configure(const Configurations &configurations) { - m_isConfigured = false; // we set it to false in case if we fail - initUnflushedCount(); - if (m_typedConfigurations != nullptr) { - Configurations *c = - const_cast<Configurations *>(m_typedConfigurations->configurations()); - if (c->hasConfiguration(Level::Global, ConfigurationType::Filename)) { - flush(); - } - } - base::threading::ScopedLock scopedLock(lock()); - if (m_configurations != configurations) { - m_configurations.setFromBase(const_cast<Configurations *>(&configurations)); - } - base::utils::safeDelete(m_typedConfigurations); - m_typedConfigurations = - new base::TypedConfigurations(&m_configurations, m_logStreamsReference); - resolveLoggerFormatSpec(); - m_isConfigured = true; -} - -void Logger::reconfigure(void) { - ELPP_INTERNAL_INFO(1, "Reconfiguring logger [" << m_id << "]"); - configure(m_configurations); -} - -bool Logger::isValidId(const std::string &id) { - for (std::string::const_iterator it = id.begin(); it != id.end(); ++it) { - if (!base::utils::Str::contains(base::consts::kValidLoggerIdSymbols, *it)) { - return false; - } - } - return true; -} - -void Logger::flush(void) { - ELPP_INTERNAL_INFO(3, "Flushing logger [" << m_id << "] all levels"); - base::threading::ScopedLock scopedLock(lock()); - base::type::EnumType lIndex = LevelHelper::kMinValid; - LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { - flush(LevelHelper::castFromInt(lIndex), nullptr); - return false; - }); -} - -void Logger::flush(Level level, base::type::fstream_t *fs) { - if (fs == nullptr && m_typedConfigurations->toFile(level)) { - fs = m_typedConfigurations->fileStream(level); - } - if (fs != nullptr) { - fs->flush(); - std::unordered_map<Level, unsigned int>::iterator iter = - m_unflushedCount.find(level); - if (iter != m_unflushedCount.end()) { - iter->second = 0; - } - Helpers::validateFileRolling(this, level); - } -} - -void Logger::initUnflushedCount(void) { - m_unflushedCount.clear(); - base::type::EnumType lIndex = LevelHelper::kMinValid; - LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { - m_unflushedCount.insert( - std::make_pair(LevelHelper::castFromInt(lIndex), 0)); - return false; - }); -} - -void Logger::resolveLoggerFormatSpec(void) const { - base::type::EnumType lIndex = LevelHelper::kMinValid; - LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { - base::LogFormat *logFormat = const_cast<base::LogFormat *>( - &m_typedConfigurations->logFormat(LevelHelper::castFromInt(lIndex))); - base::utils::Str::replaceFirstWithEscape( - logFormat->m_format, base::consts::kLoggerIdFormatSpecifier, m_id); - return false; - }); -} - -// el::base -namespace base { - -// el::base::utils -namespace utils { - -// File - -base::type::fstream_t *File::newFileStream(const std::string &filename) { - base::type::fstream_t *fs = new base::type::fstream_t( - filename.c_str(), base::type::fstream_t::out -#if !defined(ELPP_FRESH_LOG_FILE) - | base::type::fstream_t::app -#endif - ); -#if defined(ELPP_UNICODE) - std::locale elppUnicodeLocale(""); -#if ELPP_OS_WINDOWS - std::locale elppUnicodeLocaleWindows(elppUnicodeLocale, - new std::codecvt_utf8_utf16<wchar_t>); - elppUnicodeLocale = elppUnicodeLocaleWindows; -#endif // ELPP_OS_WINDOWS - fs->imbue(elppUnicodeLocale); -#endif // defined(ELPP_UNICODE) - if (fs->is_open()) { - fs->flush(); - } else { - base::utils::safeDelete(fs); - ELPP_INTERNAL_ERROR("Bad file [" << filename << "]", true); - } - return fs; -} - -std::size_t File::getSizeOfFile(base::type::fstream_t *fs) { - if (fs == nullptr) { - return 0; - } - // Since the file stream is appended to or truncated, the current - // offset is the file size. - std::size_t size = static_cast<std::size_t>(fs->tellg()); - return size; -} - -bool File::pathExists(const char *path, bool considerFile) { - if (path == nullptr) { - return false; - } -#if ELPP_OS_UNIX - ELPP_UNUSED(considerFile); - struct stat st; - return (stat(path, &st) == 0); -#elif ELPP_OS_WINDOWS - DWORD fileType = GetFileAttributesA(path); - if (fileType == INVALID_FILE_ATTRIBUTES) { - return false; - } - return considerFile - ? true - : ((fileType & FILE_ATTRIBUTE_DIRECTORY) == 0 ? false : true); -#endif // ELPP_OS_UNIX -} - -bool File::createPath(const std::string &path) { - if (path.empty()) { - return false; - } - if (base::utils::File::pathExists(path.c_str())) { - return true; - } - int status = -1; - - char *currPath = const_cast<char *>(path.c_str()); - std::string builtPath = std::string(); -#if ELPP_OS_UNIX - if (path[0] == '/') { - builtPath = "/"; - } - currPath = STRTOK(currPath, base::consts::kFilePathSeparator, 0); -#elif ELPP_OS_WINDOWS - // Use secure functions API - char *nextTok_ = nullptr; - currPath = STRTOK(currPath, base::consts::kFilePathSeparator, &nextTok_); - ELPP_UNUSED(nextTok_); -#endif // ELPP_OS_UNIX - while (currPath != nullptr) { - builtPath.append(currPath); - builtPath.append(base::consts::kFilePathSeparator); -#if ELPP_OS_UNIX - status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS); - currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, 0); -#elif ELPP_OS_WINDOWS - status = _mkdir(builtPath.c_str()); - currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, &nextTok_); -#endif // ELPP_OS_UNIX - } - if (status == -1) { - ELPP_INTERNAL_ERROR("Error while creating path [" << path << "]", true); - return false; - } - return true; -} - -std::string File::extractPathFromFilename(const std::string &fullPath, - const char *separator) { - if ((fullPath == "") || (fullPath.find(separator) == std::string::npos)) { - return fullPath; - } - std::size_t lastSlashAt = fullPath.find_last_of(separator); - if (lastSlashAt == 0) { - return std::string(separator); - } - return fullPath.substr(0, lastSlashAt + 1); -} - -void File::buildStrippedFilename(const char *filename, char buff[], - std::size_t limit) { - std::size_t sizeOfFilename = strlen(filename); - if (sizeOfFilename >= limit) { - filename += (sizeOfFilename - limit); - if (filename[0] != '.' && filename[1] != '.') { // prepend if not already - filename += 3; // 3 = '..' - STRCAT(buff, "..", limit); - } - } - STRCAT(buff, filename, limit); -} - -void File::buildBaseFilename(const std::string &fullPath, char buff[], - std::size_t limit, const char *separator) { - const char *filename = fullPath.c_str(); - std::size_t lastSlashAt = fullPath.find_last_of(separator); - filename += lastSlashAt ? lastSlashAt + 1 : 0; - std::size_t sizeOfFilename = strlen(filename); - if (sizeOfFilename >= limit) { - filename += (sizeOfFilename - limit); - if (filename[0] != '.' && filename[1] != '.') { // prepend if not already - filename += 3; // 3 = '..' - STRCAT(buff, "..", limit); - } - } - STRCAT(buff, filename, limit); -} - -// Str - -bool Str::wildCardMatch(const char *str, const char *pattern) { - while (*pattern) { - switch (*pattern) { - case '?': - if (!*str) - return false; - ++str; - ++pattern; - break; - case '*': - if (wildCardMatch(str, pattern + 1)) - return true; - if (*str && wildCardMatch(str + 1, pattern)) - return true; - return false; - default: - if (*str++ != *pattern++) - return false; - break; - } - } - return !*str && !*pattern; -} - -std::string &Str::ltrim(std::string &str) { - str.erase(str.begin(), std::find_if(str.begin(), str.end(), - [](char c) { return !std::isspace(c); })); - return str; -} - -std::string &Str::rtrim(std::string &str) { - str.erase(std::find_if(str.rbegin(), str.rend(), - [](char c) { return !std::isspace(c); }) - .base(), - str.end()); - return str; -} - -std::string &Str::trim(std::string &str) { return ltrim(rtrim(str)); } - -bool Str::startsWith(const std::string &str, const std::string &start) { - return (str.length() >= start.length()) && - (str.compare(0, start.length(), start) == 0); -} - -bool Str::endsWith(const std::string &str, const std::string &end) { - return (str.length() >= end.length()) && - (str.compare(str.length() - end.length(), end.length(), end) == 0); -} - -std::string &Str::replaceAll(std::string &str, char replaceWhat, - char replaceWith) { - std::replace(str.begin(), str.end(), replaceWhat, replaceWith); - return str; -} - -std::string &Str::replaceAll(std::string &str, const std::string &replaceWhat, - const std::string &replaceWith) { - if (replaceWhat == replaceWith) - return str; - std::size_t foundAt = std::string::npos; - while ((foundAt = str.find(replaceWhat, foundAt + 1)) != std::string::npos) { - str.replace(foundAt, replaceWhat.length(), replaceWith); - } - return str; -} - -void Str::replaceFirstWithEscape(base::type::string_t &str, - const base::type::string_t &replaceWhat, - const base::type::string_t &replaceWith) { - std::size_t foundAt = base::type::string_t::npos; - while ((foundAt = str.find(replaceWhat, foundAt + 1)) != - base::type::string_t::npos) { - if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) { - str.erase(foundAt - 1, 1); - ++foundAt; - } else { - str.replace(foundAt, replaceWhat.length(), replaceWith); - return; - } - } -} -#if defined(ELPP_UNICODE) -void Str::replaceFirstWithEscape(base::type::string_t &str, - const base::type::string_t &replaceWhat, - const std::string &replaceWith) { - replaceFirstWithEscape( - str, replaceWhat, - base::type::string_t(replaceWith.begin(), replaceWith.end())); -} -#endif // defined(ELPP_UNICODE) - -std::string &Str::toUpper(std::string &str) { - std::transform(str.begin(), str.end(), str.begin(), - [](char c) { return static_cast<char>(::toupper(c)); }); - return str; -} - -bool Str::cStringEq(const char *s1, const char *s2) { - if (s1 == nullptr && s2 == nullptr) - return true; - if (s1 == nullptr || s2 == nullptr) - return false; - return strcmp(s1, s2) == 0; -} - -bool Str::cStringCaseEq(const char *s1, const char *s2) { - if (s1 == nullptr && s2 == nullptr) - return true; - if (s1 == nullptr || s2 == nullptr) - return false; - - // With thanks to cygwin for this code - int d = 0; - - while (true) { - const int c1 = toupper(*s1++); - const int c2 = toupper(*s2++); - - if (((d = c1 - c2) != 0) || (c2 == '\0')) { - break; - } - } - - return d == 0; -} - -bool Str::contains(const char *str, char c) { - for (; *str; ++str) { - if (*str == c) - return true; - } - return false; -} - -char *Str::convertAndAddToBuff(std::size_t n, int len, char *buf, - const char *bufLim, bool zeroPadded) { - char localBuff[10] = ""; - char *p = localBuff + sizeof(localBuff) - 2; - if (n > 0) { - for (; n > 0 && p > localBuff && len > 0; n /= 10, --len) - *--p = static_cast<char>(n % 10 + '0'); - } else { - *--p = '0'; - --len; - } - if (zeroPadded) - while (p > localBuff && len-- > 0) - *--p = static_cast<char>('0'); - return addToBuff(p, buf, bufLim); -} - -char *Str::addToBuff(const char *str, char *buf, const char *bufLim) { - while ((buf < bufLim) && ((*buf = *str++) != '\0')) - ++buf; - return buf; -} - -char *Str::clearBuff(char buff[], std::size_t lim) { - STRCPY(buff, "", lim); - ELPP_UNUSED( - lim); // For *nix we dont have anything using lim in above STRCPY macro - return buff; -} - -/// @brief Converts wchar* to char* -/// NOTE: Need to free return value after use! -char *Str::wcharPtrToCharPtr(const wchar_t *line) { - std::size_t len_ = wcslen(line) + 1; - char *buff_ = static_cast<char *>(malloc(len_ + 1)); -#if ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) - std::wcstombs(buff_, line, len_); -#elif ELPP_OS_WINDOWS - std::size_t convCount_ = 0; - mbstate_t mbState_; - ::memset(static_cast<void *>(&mbState_), 0, sizeof(mbState_)); - wcsrtombs_s(&convCount_, buff_, len_, &line, len_, &mbState_); -#endif // ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) - return buff_; -} - -// OS - -#if ELPP_OS_WINDOWS -/// @brief Gets environment variables for Windows based OS. -/// We are not using <code>getenv(const char*)</code> because of CRT -/// deprecation -/// @param varname Variable name to get environment variable value for -/// @return If variable exist the value of it otherwise nullptr -const char *OS::getWindowsEnvironmentVariable(const char *varname) { - const DWORD bufferLen = 50; - static char buffer[bufferLen]; - if (GetEnvironmentVariableA(varname, buffer, bufferLen)) { - return buffer; - } - return nullptr; -} -#endif // ELPP_OS_WINDOWS -#if ELPP_OS_ANDROID -std::string OS::getProperty(const char *prop) { - char propVal[PROP_VALUE_MAX + 1]; - int ret = __system_property_get(prop, propVal); - return ret == 0 ? std::string() : std::string(propVal); -} - -std::string OS::getDeviceName(void) { - std::stringstream ss; - std::string manufacturer = getProperty("ro.product.manufacturer"); - std::string model = getProperty("ro.product.model"); - if (manufacturer.empty() || model.empty()) { - return std::string(); - } - ss << manufacturer << "-" << model; - return ss.str(); -} -#endif // ELPP_OS_ANDROID - -const std::string OS::getBashOutput(const char *command) { -#if (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) - if (command == nullptr) { - return std::string(); - } - FILE *proc = nullptr; - if ((proc = popen(command, "r")) == nullptr) { - ELPP_INTERNAL_ERROR("\nUnable to run command [" << command << "]", true); - return std::string(); - } - char hBuff[4096]; - if (fgets(hBuff, sizeof(hBuff), proc) != nullptr) { - pclose(proc); - const std::size_t buffLen = strlen(hBuff); - if (buffLen > 0 && hBuff[buffLen - 1] == '\n') { - hBuff[buffLen - 1] = '\0'; - } - return std::string(hBuff); - } else { - pclose(proc); - } - return std::string(); -#else - ELPP_UNUSED(command); - return std::string(); -#endif // (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) -} - -std::string OS::getEnvironmentVariable(const char *variableName, - const char *defaultVal, - const char *alternativeBashCommand) { -#if ELPP_OS_UNIX - const char *val = getenv(variableName); -#elif ELPP_OS_WINDOWS - const char *val = getWindowsEnvironmentVariable(variableName); -#endif // ELPP_OS_UNIX - if ((val == nullptr) || ((strcmp(val, "") == 0))) { -#if ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) - // Try harder on unix-based systems - std::string valBash = - base::utils::OS::getBashOutput(alternativeBashCommand); - if (valBash.empty()) { - return std::string(defaultVal); - } else { - return valBash; - } -#elif ELPP_OS_WINDOWS || ELPP_OS_UNIX - ELPP_UNUSED(alternativeBashCommand); - return std::string(defaultVal); -#endif // ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) - } - return std::string(val); -} - -std::string OS::currentUser(void) { -#if ELPP_OS_UNIX && !ELPP_OS_ANDROID - return getEnvironmentVariable("USER", base::consts::kUnknownUser, "whoami"); -#elif ELPP_OS_WINDOWS - return getEnvironmentVariable("USERNAME", base::consts::kUnknownUser); -#elif ELPP_OS_ANDROID - ELPP_UNUSED(base::consts::kUnknownUser); - return std::string("android"); -#else - return std::string(); -#endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID -} - -std::string OS::currentHost(void) { -#if ELPP_OS_UNIX && !ELPP_OS_ANDROID - return getEnvironmentVariable("HOSTNAME", base::consts::kUnknownHost, - "hostname"); -#elif ELPP_OS_WINDOWS - return getEnvironmentVariable("COMPUTERNAME", base::consts::kUnknownHost); -#elif ELPP_OS_ANDROID - ELPP_UNUSED(base::consts::kUnknownHost); - return getDeviceName(); -#else - return std::string(); -#endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID -} - -bool OS::termSupportsColor(void) { - std::string term = getEnvironmentVariable("TERM", ""); - return term == "xterm" || term == "xterm-color" || term == "xterm-256color" || - term == "screen" || term == "linux" || term == "cygwin" || - term == "screen-256color"; -} - -// DateTime - -void DateTime::gettimeofday(struct timeval *tv) { -#if ELPP_OS_WINDOWS - if (tv != nullptr) { -#if ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) - const unsigned __int64 delta_ = 11644473600000000Ui64; -#else - const unsigned __int64 delta_ = 11644473600000000ULL; -#endif // ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) - const double secOffSet = 0.000001; - const unsigned long usecOffSet = 1000000; - FILETIME fileTime; - GetSystemTimeAsFileTime(&fileTime); - unsigned __int64 present = 0; - present |= fileTime.dwHighDateTime; - present = present << 32; - present |= fileTime.dwLowDateTime; - present /= 10; // mic-sec - // Subtract the difference - present -= delta_; - tv->tv_sec = static_cast<long>(present * secOffSet); - tv->tv_usec = static_cast<long>(present % usecOffSet); - } -#else - ::gettimeofday(tv, nullptr); -#endif // ELPP_OS_WINDOWS -} - -std::string DateTime::getDateTime(const char *format, - const base::SubsecondPrecision *ssPrec) { - struct timeval currTime; - gettimeofday(&currTime); - return timevalToString(currTime, format, ssPrec); -} - -std::string -DateTime::timevalToString(struct timeval tval, const char *format, - const el::base::SubsecondPrecision *ssPrec) { - struct ::tm timeInfo; - buildTimeInfo(&tval, &timeInfo); - const int kBuffSize = 30; - char buff_[kBuffSize] = ""; - parseFormat(buff_, kBuffSize, format, &timeInfo, - static_cast<std::size_t>(tval.tv_usec / ssPrec->m_offset), - ssPrec); - return std::string(buff_); -} - -base::type::string_t DateTime::formatTime(unsigned long long time, - base::TimestampUnit timestampUnit) { - base::type::EnumType start = static_cast<base::type::EnumType>(timestampUnit); - const base::type::char_t *unit = base::consts::kTimeFormats[start].unit; - for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; - ++i) { - if (time <= base::consts::kTimeFormats[i].value) { - break; - } - if (base::consts::kTimeFormats[i].value == 1000.0f && - time / 1000.0f < 1.9f) { - break; - } - time /= static_cast<decltype(time)>(base::consts::kTimeFormats[i].value); - unit = base::consts::kTimeFormats[i + 1].unit; - } - base::type::stringstream_t ss; - ss << time << " " << unit; - return ss.str(); -} - -unsigned long long -DateTime::getTimeDifference(const struct timeval &endTime, - const struct timeval &startTime, - base::TimestampUnit timestampUnit) { - if (timestampUnit == base::TimestampUnit::Microsecond) { - return static_cast<unsigned long long>( - static_cast<unsigned long long>(1000000 * endTime.tv_sec + - endTime.tv_usec) - - static_cast<unsigned long long>(1000000 * startTime.tv_sec + - startTime.tv_usec)); - } - // milliseconds - auto conv = [](const struct timeval &tim) { - return static_cast<unsigned long long>((tim.tv_sec * 1000) + - (tim.tv_usec / 1000)); - }; - return static_cast<unsigned long long>(conv(endTime) - conv(startTime)); -} - -struct ::tm *DateTime::buildTimeInfo(struct timeval *currTime, - struct ::tm *timeInfo) { -#if ELPP_OS_UNIX - time_t rawTime = currTime->tv_sec; - ::elpptime_r(&rawTime, timeInfo); - return timeInfo; -#else -#if ELPP_COMPILER_MSVC - ELPP_UNUSED(currTime); - time_t t; -#if defined(_USE_32BIT_TIME_T) - _time32(&t); -#else - _time64(&t); -#endif - elpptime_s(timeInfo, &t); - return timeInfo; -#else - // For any other compilers that don't have CRT warnings issue e.g, MinGW or - // TDM GCC- we use different method - time_t rawTime = currTime->tv_sec; - struct tm *tmInf = elpptime(&rawTime); - *timeInfo = *tmInf; - return timeInfo; -#endif // ELPP_COMPILER_MSVC -#endif // ELPP_OS_UNIX -} - -char *DateTime::parseFormat(char *buf, std::size_t bufSz, const char *format, - const struct tm *tInfo, std::size_t msec, - const base::SubsecondPrecision *ssPrec) { - const char *bufLim = buf + bufSz; - for (; *format; ++format) { - if (*format == base::consts::kFormatSpecifierChar) { - switch (*++format) { - case base::consts::kFormatSpecifierChar: // Escape - break; - case '\0': // End - --format; - break; - case 'd': // Day - buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, - bufLim); - continue; - case 'a': // Day of week (short) - buf = base::utils::Str::addToBuff( - base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim); - continue; - case 'A': // Day of week (long) - buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], - buf, bufLim); - continue; - case 'M': // month - buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, - bufLim); - continue; - case 'b': // month (short) - buf = base::utils::Str::addToBuff( - base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim); - continue; - case 'B': // month (long) - buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], - buf, bufLim); - continue; - case 'y': // year (two digits) - buf = base::utils::Str::convertAndAddToBuff( - tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim); - continue; - case 'Y': // year (four digits) - buf = base::utils::Str::convertAndAddToBuff( - tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim); - continue; - case 'h': // hour (12-hour) - buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, - bufLim); - continue; - case 'H': // hour (24-hour) - buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, - bufLim); - continue; - case 'm': // minute - buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, - bufLim); - continue; - case 's': // second - buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, - bufLim); - continue; - case 'z': // subsecond part - case 'g': - buf = base::utils::Str::convertAndAddToBuff(msec, ssPrec->m_width, buf, - bufLim); - continue; - case 'F': // AM/PM - buf = base::utils::Str::addToBuff( - (tInfo->tm_hour >= 12) ? base::consts::kPm : base::consts::kAm, buf, - bufLim); - continue; - default: - continue; - } - } - if (buf == bufLim) - break; - *buf++ = *format; - } - return buf; -} - -// CommandLineArgs - -void CommandLineArgs::setArgs(int argc, char **argv) { - m_params.clear(); - m_paramsWithValue.clear(); - if (argc == 0 || argv == nullptr) { - return; - } - m_argc = argc; - m_argv = argv; - for (int i = 1; i < m_argc; ++i) { - const char *v = (strstr(m_argv[i], "=")); - if (v != nullptr && strlen(v) > 0) { - std::string key = std::string(m_argv[i]); - key = key.substr(0, key.find_first_of('=')); - if (hasParamWithValue(key.c_str())) { - ELPP_INTERNAL_INFO(1, "Skipping [" - << key << "] arg since it already has value [" - << getParamValue(key.c_str()) << "]"); - } else { - m_paramsWithValue.insert(std::make_pair(key, std::string(v + 1))); - } - } - if (v == nullptr) { - if (hasParam(m_argv[i])) { - ELPP_INTERNAL_INFO(1, "Skipping [" << m_argv[i] - << "] arg since it already exists"); - } else { - m_params.push_back(std::string(m_argv[i])); - } - } - } -} - -bool CommandLineArgs::hasParamWithValue(const char *paramKey) const { - return m_paramsWithValue.find(std::string(paramKey)) != - m_paramsWithValue.end(); -} - -const char *CommandLineArgs::getParamValue(const char *paramKey) const { - std::unordered_map<std::string, std::string>::const_iterator iter = - m_paramsWithValue.find(std::string(paramKey)); - return iter != m_paramsWithValue.end() ? iter->second.c_str() : ""; -} - -bool CommandLineArgs::hasParam(const char *paramKey) const { - return std::find(m_params.begin(), m_params.end(), std::string(paramKey)) != - m_params.end(); -} - -bool CommandLineArgs::empty(void) const { - return m_params.empty() && m_paramsWithValue.empty(); -} - -std::size_t CommandLineArgs::size(void) const { - return m_params.size() + m_paramsWithValue.size(); -} - -base::type::ostream_t &operator<<(base::type::ostream_t &os, - const CommandLineArgs &c) { - for (int i = 1; i < c.m_argc; ++i) { - os << ELPP_LITERAL("[") << c.m_argv[i] << ELPP_LITERAL("]"); - if (i < c.m_argc - 1) { - os << ELPP_LITERAL(" "); - } - } - return os; -} - -} // namespace utils - -// el::base::threading -namespace threading { - -#if ELPP_THREADING_ENABLED -#if ELPP_USE_STD_THREADING -#if ELPP_ASYNC_LOGGING -static void msleep(int ms) { - // Only when async logging enabled - this is because async is strict on - // compiler -#if defined(ELPP_NO_SLEEP_FOR) - usleep(ms * 1000); -#else - std::this_thread::sleep_for(std::chrono::milliseconds(ms)); -#endif // defined(ELPP_NO_SLEEP_FOR) -} -#endif // ELPP_ASYNC_LOGGING -#endif // !ELPP_USE_STD_THREADING -#endif // ELPP_THREADING_ENABLED - -} // namespace threading - -// el::base - -// SubsecondPrecision - -void SubsecondPrecision::init(int width) { - if (width < 1 || width > 6) { - width = base::consts::kDefaultSubsecondPrecision; - } - m_width = width; - switch (m_width) { - case 3: - m_offset = 1000; - break; - case 4: - m_offset = 100; - break; - case 5: - m_offset = 10; - break; - case 6: - m_offset = 1; - break; - default: - m_offset = 1000; - break; - } -} - -// LogFormat - -LogFormat::LogFormat(void) - : m_level(Level::Unknown), m_userFormat(base::type::string_t()), - m_format(base::type::string_t()), m_dateTimeFormat(std::string()), - m_flags(0x0), m_currentUser(base::utils::OS::currentUser()), - m_currentHost(base::utils::OS::currentHost()) {} - -LogFormat::LogFormat(Level level, const base::type::string_t &format) - : m_level(level), m_userFormat(format), - m_currentUser(base::utils::OS::currentUser()), - m_currentHost(base::utils::OS::currentHost()) { - parseFromFormat(m_userFormat); -} - -LogFormat::LogFormat(const LogFormat &logFormat) - : m_level(logFormat.m_level), m_userFormat(logFormat.m_userFormat), - m_format(logFormat.m_format), - m_dateTimeFormat(logFormat.m_dateTimeFormat), m_flags(logFormat.m_flags), - m_currentUser(logFormat.m_currentUser), - m_currentHost(logFormat.m_currentHost) {} - -LogFormat::LogFormat(LogFormat &&logFormat) { - m_level = std::move(logFormat.m_level); - m_userFormat = std::move(logFormat.m_userFormat); - m_format = std::move(logFormat.m_format); - m_dateTimeFormat = std::move(logFormat.m_dateTimeFormat); - m_flags = std::move(logFormat.m_flags); - m_currentUser = std::move(logFormat.m_currentUser); - m_currentHost = std::move(logFormat.m_currentHost); -} - -LogFormat &LogFormat::operator=(const LogFormat &logFormat) { - if (&logFormat != this) { - m_level = logFormat.m_level; - m_userFormat = logFormat.m_userFormat; - m_dateTimeFormat = logFormat.m_dateTimeFormat; - m_flags = logFormat.m_flags; - m_currentUser = logFormat.m_currentUser; - m_currentHost = logFormat.m_currentHost; - } - return *this; -} - -bool LogFormat::operator==(const LogFormat &other) { - return m_level == other.m_level && m_userFormat == other.m_userFormat && - m_format == other.m_format && - m_dateTimeFormat == other.m_dateTimeFormat && m_flags == other.m_flags; -} - -/// @brief Updates format to be used while logging. -/// @param userFormat User provided format -void LogFormat::parseFromFormat(const base::type::string_t &userFormat) { - // We make copy because we will be changing the format - // i.e, removing user provided date format from original format - // and then storing it. - base::type::string_t formatCopy = userFormat; - m_flags = 0x0; - auto conditionalAddFlag = [&](const base::type::char_t *specifier, - base::FormatFlags flag) { - std::size_t foundAt = base::type::string_t::npos; - while ((foundAt = formatCopy.find(specifier, foundAt + 1)) != - base::type::string_t::npos) { - if (foundAt > 0 && - formatCopy[foundAt - 1] == base::consts::kFormatSpecifierChar) { - if (hasFlag(flag)) { - // If we already have flag we remove the escape chars so that '%%' is - // turned to '%' even after specifier resolution - this is because we - // only replaceFirst specifier - formatCopy.erase(foundAt - 1, 1); - ++foundAt; - } - } else { - if (!hasFlag(flag)) - addFlag(flag); - } - } - }; - conditionalAddFlag(base::consts::kAppNameFormatSpecifier, - base::FormatFlags::AppName); - conditionalAddFlag(base::consts::kSeverityLevelFormatSpecifier, - base::FormatFlags::Level); - conditionalAddFlag(base::consts::kSeverityLevelShortFormatSpecifier, - base::FormatFlags::LevelShort); - conditionalAddFlag(base::consts::kLoggerIdFormatSpecifier, - base::FormatFlags::LoggerId); - conditionalAddFlag(base::consts::kThreadIdFormatSpecifier, - base::FormatFlags::ThreadId); - conditionalAddFlag(base::consts::kLogFileFormatSpecifier, - base::FormatFlags::File); - conditionalAddFlag(base::consts::kLogFileBaseFormatSpecifier, - base::FormatFlags::FileBase); - conditionalAddFlag(base::consts::kLogLineFormatSpecifier, - base::FormatFlags::Line); - conditionalAddFlag(base::consts::kLogLocationFormatSpecifier, - base::FormatFlags::Location); - conditionalAddFlag(base::consts::kLogFunctionFormatSpecifier, - base::FormatFlags::Function); - conditionalAddFlag(base::consts::kCurrentUserFormatSpecifier, - base::FormatFlags::User); - conditionalAddFlag(base::consts::kCurrentHostFormatSpecifier, - base::FormatFlags::Host); - conditionalAddFlag(base::consts::kMessageFormatSpecifier, - base::FormatFlags::LogMessage); - conditionalAddFlag(base::consts::kVerboseLevelFormatSpecifier, - base::FormatFlags::VerboseLevel); - // For date/time we need to extract user's date format first - std::size_t dateIndex = std::string::npos; - if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != - std::string::npos) { - while (dateIndex != std::string::npos && dateIndex > 0 && - formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) { - dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, - dateIndex + 1); - } - if (dateIndex != std::string::npos) { - addFlag(base::FormatFlags::DateTime); - updateDateFormat(dateIndex, formatCopy); - } - } - m_format = formatCopy; - updateFormatSpec(); -} - -void LogFormat::updateDateFormat(std::size_t index, - base::type::string_t &currFormat) { - if (hasFlag(base::FormatFlags::DateTime)) { - index += ELPP_STRLEN(base::consts::kDateTimeFormatSpecifier); - } - const base::type::char_t *ptr = currFormat.c_str() + index; - if ((currFormat.size() > index) && (ptr[0] == '{')) { - // User has provided format for date/time - ++ptr; - int count = 1; // Start by 1 in order to remove starting brace - std::stringstream ss; - for (; *ptr; ++ptr, ++count) { - if (*ptr == '}') { - ++count; // In order to remove ending brace - break; - } - ss << static_cast<char>(*ptr); - } - currFormat.erase(index, count); - m_dateTimeFormat = ss.str(); - } else { - // No format provided, use default - if (hasFlag(base::FormatFlags::DateTime)) { - m_dateTimeFormat = std::string(base::consts::kDefaultDateTimeFormat); - } - } -} - -void LogFormat::updateFormatSpec(void) { - // Do not use switch over strongly typed enums because Intel C++ compilers - // dont support them yet. - if (m_level == Level::Debug) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kDebugLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kDebugLevelShortLogValue); - } else if (m_level == Level::Info) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kInfoLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kInfoLevelShortLogValue); - } else if (m_level == Level::Warning) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kWarningLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kWarningLevelShortLogValue); - } else if (m_level == Level::Error) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kErrorLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kErrorLevelShortLogValue); - } else if (m_level == Level::Fatal) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kFatalLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kFatalLevelShortLogValue); - } else if (m_level == Level::Verbose) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kVerboseLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kVerboseLevelShortLogValue); - } else if (m_level == Level::Trace) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelFormatSpecifier, - base::consts::kTraceLevelLogValue); - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kSeverityLevelShortFormatSpecifier, - base::consts::kTraceLevelShortLogValue); - } - if (hasFlag(base::FormatFlags::User)) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kCurrentUserFormatSpecifier, m_currentUser); - } - if (hasFlag(base::FormatFlags::Host)) { - base::utils::Str::replaceFirstWithEscape( - m_format, base::consts::kCurrentHostFormatSpecifier, m_currentHost); - } - // Ignore Level::Global and Level::Unknown -} - -// TypedConfigurations - -TypedConfigurations::TypedConfigurations( - Configurations *configurations, - LogStreamsReferenceMapPtr logStreamsReference) { - m_configurations = configurations; - m_logStreamsReference = logStreamsReference; - build(m_configurations); -} - -TypedConfigurations::TypedConfigurations(const TypedConfigurations &other) { - this->m_configurations = other.m_configurations; - this->m_logStreamsReference = other.m_logStreamsReference; - build(m_configurations); -} - -bool TypedConfigurations::enabled(Level level) { - return getConfigByVal<bool>(level, &m_enabledMap, "enabled"); -} - -bool TypedConfigurations::toFile(Level level) { - return getConfigByVal<bool>(level, &m_toFileMap, "toFile"); -} - -const std::string &TypedConfigurations::filename(Level level) { - return getConfigByRef<std::string>(level, &m_filenameMap, "filename"); -} - -bool TypedConfigurations::toStandardOutput(Level level) { - return getConfigByVal<bool>(level, &m_toStandardOutputMap, - "toStandardOutput"); -} - -const base::LogFormat &TypedConfigurations::logFormat(Level level) { - return getConfigByRef<base::LogFormat>(level, &m_logFormatMap, "logFormat"); -} - -const base::SubsecondPrecision & -TypedConfigurations::subsecondPrecision(Level level) { - return getConfigByRef<base::SubsecondPrecision>( - level, &m_subsecondPrecisionMap, "subsecondPrecision"); -} - -const base::MillisecondsWidth & -TypedConfigurations::millisecondsWidth(Level level) { - return getConfigByRef<base::MillisecondsWidth>( - level, &m_subsecondPrecisionMap, "millisecondsWidth"); -} - -bool TypedConfigurations::performanceTracking(Level level) { - return getConfigByVal<bool>(level, &m_performanceTrackingMap, - "performanceTracking"); -} - -base::type::fstream_t *TypedConfigurations::fileStream(Level level) { - return getConfigByRef<base::FileStreamPtr>(level, &m_fileStreamMap, - "fileStream") - .get(); -} - -std::size_t TypedConfigurations::maxLogFileSize(Level level) { - return getConfigByVal<std::size_t>(level, &m_maxLogFileSizeMap, - "maxLogFileSize"); -} - -std::size_t TypedConfigurations::logFlushThreshold(Level level) { - return getConfigByVal<std::size_t>(level, &m_logFlushThresholdMap, - "logFlushThreshold"); -} - -void TypedConfigurations::build(Configurations *configurations) { - base::threading::ScopedLock scopedLock(lock()); - auto getBool = [](std::string boolStr) -> bool { // Pass by value for trimming - base::utils::Str::trim(boolStr); - return (boolStr == "TRUE" || boolStr == "true" || boolStr == "1"); - }; - std::vector<Configuration *> withFileSizeLimit; - for (Configurations::const_iterator it = configurations->begin(); - it != configurations->end(); ++it) { - Configuration *conf = *it; - // We cannot use switch on strong enums because Intel C++ dont support them - // yet - if (conf->configurationType() == ConfigurationType::Enabled) { - setValue(conf->level(), getBool(conf->value()), &m_enabledMap); - } else if (conf->configurationType() == ConfigurationType::ToFile) { - setValue(conf->level(), getBool(conf->value()), &m_toFileMap); - } else if (conf->configurationType() == - ConfigurationType::ToStandardOutput) { - setValue(conf->level(), getBool(conf->value()), &m_toStandardOutputMap); - } else if (conf->configurationType() == ConfigurationType::Filename) { - // We do not yet configure filename but we will configure in another - // loop. This is because if file cannot be created, we will force ToFile - // to be false. Because configuring logger is not necessarily performance - // sensitive operation, we can live with another loop; (by the way this - // loop is not very heavy either) - } else if (conf->configurationType() == ConfigurationType::Format) { - setValue(conf->level(), - base::LogFormat(conf->level(), - base::type::string_t(conf->value().begin(), - conf->value().end())), - &m_logFormatMap); - } else if (conf->configurationType() == - ConfigurationType::SubsecondPrecision) { - setValue( - Level::Global, - base::SubsecondPrecision(static_cast<int>(getULong(conf->value()))), - &m_subsecondPrecisionMap); - } else if (conf->configurationType() == - ConfigurationType::PerformanceTracking) { - setValue(Level::Global, getBool(conf->value()), - &m_performanceTrackingMap); - } else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) { - auto v = getULong(conf->value()); - setValue(conf->level(), static_cast<std::size_t>(v), - &m_maxLogFileSizeMap); - if (v != 0) { - withFileSizeLimit.push_back(conf); - } - } else if (conf->configurationType() == - ConfigurationType::LogFlushThreshold) { - setValue(conf->level(), static_cast<std::size_t>(getULong(conf->value())), - &m_logFlushThresholdMap); - } - } - // As mentioned earlier, we will now set filename configuration in separate - // loop to deal with non-existent files - for (Configurations::const_iterator it = configurations->begin(); - it != configurations->end(); ++it) { - Configuration *conf = *it; - if (conf->configurationType() == ConfigurationType::Filename) { - insertFile(conf->level(), conf->value()); - } - } - for (std::vector<Configuration *>::iterator conf = withFileSizeLimit.begin(); - conf != withFileSizeLimit.end(); ++conf) { - // This is not unsafe as mutex is locked in currect scope - unsafeValidateFileRolling((*conf)->level(), - base::defaultPreRollOutCallback); - } -} - -unsigned long TypedConfigurations::getULong(std::string confVal) { - bool valid = true; - base::utils::Str::trim(confVal); - valid = !confVal.empty() && - std::find_if(confVal.begin(), confVal.end(), [](char c) { - return !base::utils::Str::isDigit(c); - }) == confVal.end(); - if (!valid) { - valid = false; - ELPP_ASSERT(valid, - "Configuration value not a valid integer [" << confVal << "]"); - return 0; - } - return atol(confVal.c_str()); -} - -std::string TypedConfigurations::resolveFilename(const std::string &filename) { - std::string resultingFilename = filename; - std::size_t dateIndex = std::string::npos; - std::string dateTimeFormatSpecifierStr = - std::string(base::consts::kDateTimeFormatSpecifierForFilename); - if ((dateIndex = resultingFilename.find( - dateTimeFormatSpecifierStr.c_str())) != std::string::npos) { - while (dateIndex > 0 && resultingFilename[dateIndex - 1] == - base::consts::kFormatSpecifierChar) { - dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), - dateIndex + 1); - } - if (dateIndex != std::string::npos) { - const char *ptr = resultingFilename.c_str() + dateIndex; - // Goto end of specifier - ptr += dateTimeFormatSpecifierStr.size(); - std::string fmt; - if ((resultingFilename.size() > dateIndex) && (ptr[0] == '{')) { - // User has provided format for date/time - ++ptr; - int count = 1; // Start by 1 in order to remove starting brace - std::stringstream ss; - for (; *ptr; ++ptr, ++count) { - if (*ptr == '}') { - ++count; // In order to remove ending brace - break; - } - ss << *ptr; - } - resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), - count); - fmt = ss.str(); - } else { - fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename); - } - base::SubsecondPrecision ssPrec(3); - std::string now = - base::utils::DateTime::getDateTime(fmt.c_str(), &ssPrec); - base::utils::Str::replaceAll( - now, '/', - '-'); // Replace path element since we are dealing with filename - base::utils::Str::replaceAll(resultingFilename, - dateTimeFormatSpecifierStr, now); - } - } - return resultingFilename; -} - -void TypedConfigurations::insertFile(Level level, - const std::string &fullFilename) { - std::string resolvedFilename = resolveFilename(fullFilename); - if (resolvedFilename.empty()) { - std::cerr << "Could not load empty file for logging, please re-check your " - "configurations for level [" - << LevelHelper::convertToString(level) << "]"; - } - std::string filePath = base::utils::File::extractPathFromFilename( - resolvedFilename, base::consts::kFilePathSeparator); - if (filePath.size() < resolvedFilename.size()) { - base::utils::File::createPath(filePath); - } - auto create = [&](Level level) { - base::LogStreamsReferenceMap::iterator filestreamIter = - m_logStreamsReference->find(resolvedFilename); - base::type::fstream_t *fs = nullptr; - if (filestreamIter == m_logStreamsReference->end()) { - // We need a completely new stream, nothing to share with - fs = base::utils::File::newFileStream(resolvedFilename); - m_filenameMap.insert(std::make_pair(level, resolvedFilename)); - m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(fs))); - m_logStreamsReference->insert(std::make_pair( - resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level)))); - } else { - // Woops! we have an existing one, share it! - m_filenameMap.insert(std::make_pair(level, filestreamIter->first)); - m_fileStreamMap.insert( - std::make_pair(level, base::FileStreamPtr(filestreamIter->second))); - fs = filestreamIter->second.get(); - } - if (fs == nullptr) { - // We display bad file error from newFileStream() - ELPP_INTERNAL_ERROR("Setting [TO_FILE] of [" - << LevelHelper::convertToString(level) - << "] to FALSE", - false); - setValue(level, false, &m_toFileMap); - } - }; - // If we dont have file conf for any level, create it for Level::Global first - // otherwise create for specified level - create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global - : level); -} - -bool TypedConfigurations::unsafeValidateFileRolling( - Level level, const PreRollOutCallback &preRollOutCallback) { - base::type::fstream_t *fs = - unsafeGetConfigByRef(level, &m_fileStreamMap, "fileStream").get(); - if (fs == nullptr) { - return true; - } - std::size_t maxLogFileSize = - unsafeGetConfigByVal(level, &m_maxLogFileSizeMap, "maxLogFileSize"); - std::size_t currFileSize = base::utils::File::getSizeOfFile(fs); - if (maxLogFileSize != 0 && currFileSize >= maxLogFileSize) { - std::string fname = unsafeGetConfigByRef(level, &m_filenameMap, "filename"); - ELPP_INTERNAL_INFO(1, "Truncating log file [" - << fname - << "] as a result of configurations for level [" - << LevelHelper::convertToString(level) << "]"); - fs->close(); - preRollOutCallback(fname.c_str(), currFileSize); - fs->open(fname, std::fstream::out | std::fstream::trunc); - return true; - } - return false; -} - -// RegisteredHitCounters - -bool RegisteredHitCounters::validateEveryN(const char *filename, - base::type::LineNumber lineNumber, - std::size_t n) { - base::threading::ScopedLock scopedLock(lock()); - base::HitCounter *counter = get(filename, lineNumber); - if (counter == nullptr) { - registerNew(counter = new base::HitCounter(filename, lineNumber)); - } - counter->validateHitCounts(n); - bool result = - (n >= 1 && counter->hitCounts() != 0 && counter->hitCounts() % n == 0); - return result; -} - -/// @brief Validates counter for hits >= N, i.e, registers new if does not exist -/// otherwise updates original one -/// @return True if validation resulted in triggering hit. Meaning logs should -/// be written everytime true is returned -bool RegisteredHitCounters::validateAfterN(const char *filename, - base::type::LineNumber lineNumber, - std::size_t n) { - base::threading::ScopedLock scopedLock(lock()); - base::HitCounter *counter = get(filename, lineNumber); - if (counter == nullptr) { - registerNew(counter = new base::HitCounter(filename, lineNumber)); - } - // Do not use validateHitCounts here since we do not want to reset counter - // here Note the >= instead of > because we are incrementing after this check - if (counter->hitCounts() >= n) - return true; - counter->increment(); - return false; -} - -/// @brief Validates counter for hits are <= n, i.e, registers new if does not -/// exist otherwise updates original one -/// @return True if validation resulted in triggering hit. Meaning logs should -/// be written everytime true is returned -bool RegisteredHitCounters::validateNTimes(const char *filename, - base::type::LineNumber lineNumber, - std::size_t n) { - base::threading::ScopedLock scopedLock(lock()); - base::HitCounter *counter = get(filename, lineNumber); - if (counter == nullptr) { - registerNew(counter = new base::HitCounter(filename, lineNumber)); - } - counter->increment(); - // Do not use validateHitCounts here since we do not want to reset counter - // here - if (counter->hitCounts() <= n) - return true; - return false; -} - -// RegisteredLoggers - -RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr &defaultLogBuilder) - : m_defaultLogBuilder(defaultLogBuilder) { - m_defaultConfigurations.setToDefault(); - m_logStreamsReference = std::make_shared<base::LogStreamsReferenceMap>(); -} - -Logger *RegisteredLoggers::get(const std::string &id, bool forceCreation) { - base::threading::ScopedLock scopedLock(lock()); - Logger *logger_ = base::utils::Registry<Logger, std::string>::get(id); - if (logger_ == nullptr && forceCreation) { - bool validId = Logger::isValidId(id); - if (!validId) { - ELPP_ASSERT(validId, "Invalid logger ID [" - << id << "]. Not registering this logger."); - return nullptr; - } - logger_ = new Logger(id, m_defaultConfigurations, m_logStreamsReference); - logger_->m_logBuilder = m_defaultLogBuilder; - registerNew(id, logger_); - LoggerRegistrationCallback *callback = nullptr; - for (const std::pair<std::string, base::type::LoggerRegistrationCallbackPtr> - h : m_loggerRegistrationCallbacks) { - callback = h.second.get(); - if (callback != nullptr && callback->enabled()) { - callback->handle(logger_); - } - } - } - return logger_; -} - -bool RegisteredLoggers::remove(const std::string &id) { - if (id == base::consts::kDefaultLoggerId) { - return false; - } - // get has internal lock - Logger *logger = base::utils::Registry<Logger, std::string>::get(id); - if (logger != nullptr) { - // unregister has internal lock - unregister(logger); - } - return true; -} - -void RegisteredLoggers::unsafeFlushAll(void) { - ELPP_INTERNAL_INFO(1, "Flushing all log files"); - for (base::LogStreamsReferenceMap::iterator it = - m_logStreamsReference->begin(); - it != m_logStreamsReference->end(); ++it) { - if (it->second.get() == nullptr) - continue; - it->second->flush(); - } -} - -// VRegistry - -VRegistry::VRegistry(base::type::VerboseLevel level, - base::type::EnumType *pFlags) - : m_level(level), m_pFlags(pFlags) {} - -/// @brief Sets verbose level. Accepted range is 0-9 -void VRegistry::setLevel(base::type::VerboseLevel level) { - base::threading::ScopedLock scopedLock(lock()); - if (level > 9) - m_level = base::consts::kMaxVerboseLevel; - else - m_level = level; -} - -void VRegistry::setModules(const char *modules) { - base::threading::ScopedLock scopedLock(lock()); - auto addSuffix = [](std::stringstream &ss, const char *sfx, - const char *prev) { - if (prev != nullptr && - base::utils::Str::endsWith(ss.str(), std::string(prev))) { - std::string chr(ss.str().substr(0, ss.str().size() - strlen(prev))); - ss.str(std::string("")); - ss << chr; - } - if (base::utils::Str::endsWith(ss.str(), std::string(sfx))) { - std::string chr(ss.str().substr(0, ss.str().size() - strlen(sfx))); - ss.str(std::string("")); - ss << chr; - } - ss << sfx; - }; - auto insert = [&](std::stringstream &ss, base::type::VerboseLevel level) { - if (!base::utils::hasFlag(LoggingFlag::DisableVModulesExtensions, - *m_pFlags)) { - addSuffix(ss, ".h", nullptr); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".c", ".h"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".cpp", ".c"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".cc", ".cpp"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".cxx", ".cc"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".-inl.h", ".cxx"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".hxx", ".-inl.h"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".hpp", ".hxx"); - m_modules.insert(std::make_pair(ss.str(), level)); - addSuffix(ss, ".hh", ".hpp"); - } - m_modules.insert(std::make_pair(ss.str(), level)); - }; - bool isMod = true; - bool isLevel = false; - std::stringstream ss; - int level = -1; - for (; *modules; ++modules) { - switch (*modules) { - case '=': - isLevel = true; - isMod = false; - break; - case ',': - isLevel = false; - isMod = true; - if (!ss.str().empty() && level != -1) { - insert(ss, static_cast<base::type::VerboseLevel>(level)); - ss.str(std::string("")); - level = -1; - } - break; - default: - if (isMod) { - ss << *modules; - } else if (isLevel) { - if (isdigit(*modules)) { - level = static_cast<base::type::VerboseLevel>(*modules) - 48; - } - } - break; - } - } - if (!ss.str().empty() && level != -1) { - insert(ss, static_cast<base::type::VerboseLevel>(level)); - } -} - -bool VRegistry::allowed(base::type::VerboseLevel vlevel, const char *file) { - base::threading::ScopedLock scopedLock(lock()); - if (m_modules.empty() || file == nullptr) { - return vlevel <= m_level; - } else { - char baseFilename[base::consts::kSourceFilenameMaxLength] = ""; - base::utils::File::buildBaseFilename(file, baseFilename); - std::unordered_map<std::string, base::type::VerboseLevel>::iterator it = - m_modules.begin(); - for (; it != m_modules.end(); ++it) { - if (base::utils::Str::wildCardMatch(baseFilename, it->first.c_str())) { - return vlevel <= it->second; - } - } - if (base::utils::hasFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified, - *m_pFlags)) { - return true; - } - return false; - } -} - -void VRegistry::setFromArgs( - const base::utils::CommandLineArgs *commandLineArgs) { - if (commandLineArgs->hasParam("-v") || - commandLineArgs->hasParam("--verbose") || - commandLineArgs->hasParam("-V") || - commandLineArgs->hasParam("--VERBOSE")) { - setLevel(base::consts::kMaxVerboseLevel); - } else if (commandLineArgs->hasParamWithValue("--v")) { - setLevel(static_cast<base::type::VerboseLevel>( - atoi(commandLineArgs->getParamValue("--v")))); - } else if (commandLineArgs->hasParamWithValue("--V")) { - setLevel(static_cast<base::type::VerboseLevel>( - atoi(commandLineArgs->getParamValue("--V")))); - } else if ((commandLineArgs->hasParamWithValue("-vmodule")) && - vModulesEnabled()) { - setModules(commandLineArgs->getParamValue("-vmodule")); - } else if (commandLineArgs->hasParamWithValue("-VMODULE") && - vModulesEnabled()) { - setModules(commandLineArgs->getParamValue("-VMODULE")); - } -} - -#if !defined(ELPP_DEFAULT_LOGGING_FLAGS) -#define ELPP_DEFAULT_LOGGING_FLAGS 0x0 -#endif // !defined(ELPP_DEFAULT_LOGGING_FLAGS) -// Storage -#if ELPP_ASYNC_LOGGING -Storage::Storage(const LogBuilderPtr &defaultLogBuilder, - base::IWorker *asyncDispatchWorker) - : -#else -Storage::Storage(const LogBuilderPtr &defaultLogBuilder) - : -#endif // ELPP_ASYNC_LOGGING - m_registeredHitCounters(new base::RegisteredHitCounters()), - m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)), - m_flags(ELPP_DEFAULT_LOGGING_FLAGS), - m_vRegistry(new base::VRegistry(0, &m_flags)), - -#if ELPP_ASYNC_LOGGING - m_asyncLogQueue(new base::AsyncLogQueue()), - m_asyncDispatchWorker(asyncDispatchWorker), -#endif // ELPP_ASYNC_LOGGING - - m_preRollOutCallback(base::defaultPreRollOutCallback) { - // Register default logger - m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId)); - // We register default logger anyway (worse case it's not going to register) - // just in case - m_registeredLoggers->get("default"); - -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - // Register performance logger and reconfigure format - Logger *performanceLogger = - m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId)); - m_registeredLoggers->get("performance"); - performanceLogger->configurations()->setGlobally( - ConfigurationType::Format, std::string("%datetime %level %msg")); - performanceLogger->reconfigure(); -#endif // defined(ELPP_FEATURE_ALL) || - // defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - -#if defined(ELPP_SYSLOG) - // Register syslog logger and reconfigure format - Logger *sysLogLogger = - m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId)); - sysLogLogger->configurations()->setGlobally(ConfigurationType::Format, - std::string("%level: %msg")); - sysLogLogger->reconfigure(); -#endif // defined(ELPP_SYSLOG) - addFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified); -#if ELPP_ASYNC_LOGGING - installLogDispatchCallback<base::AsyncLogDispatchCallback>( - std::string("AsyncLogDispatchCallback")); -#else - installLogDispatchCallback<base::DefaultLogDispatchCallback>( - std::string("DefaultLogDispatchCallback")); -#endif // ELPP_ASYNC_LOGGING -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - installPerformanceTrackingCallback<base::DefaultPerformanceTrackingCallback>( - std::string("DefaultPerformanceTrackingCallback")); -#endif // defined(ELPP_FEATURE_ALL) || - // defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - ELPP_INTERNAL_INFO(1, "Easylogging++ has been initialized"); -#if ELPP_ASYNC_LOGGING - m_asyncDispatchWorker->start(); -#endif // ELPP_ASYNC_LOGGING -} - -Storage::~Storage(void) { - ELPP_INTERNAL_INFO(4, "Destroying storage"); -#if ELPP_ASYNC_LOGGING - ELPP_INTERNAL_INFO(5, "Replacing log dispatch callback to synchronous"); - uninstallLogDispatchCallback<base::AsyncLogDispatchCallback>( - std::string("AsyncLogDispatchCallback")); - installLogDispatchCallback<base::DefaultLogDispatchCallback>( - std::string("DefaultLogDispatchCallback")); - ELPP_INTERNAL_INFO(5, "Destroying asyncDispatchWorker"); - base::utils::safeDelete(m_asyncDispatchWorker); - ELPP_INTERNAL_INFO(5, "Destroying asyncLogQueue"); - base::utils::safeDelete(m_asyncLogQueue); -#endif // ELPP_ASYNC_LOGGING - ELPP_INTERNAL_INFO(5, "Destroying registeredHitCounters"); - base::utils::safeDelete(m_registeredHitCounters); - ELPP_INTERNAL_INFO(5, "Destroying registeredLoggers"); - base::utils::safeDelete(m_registeredLoggers); - ELPP_INTERNAL_INFO(5, "Destroying vRegistry"); - base::utils::safeDelete(m_vRegistry); -} - -bool Storage::hasCustomFormatSpecifier(const char *formatSpecifier) { - base::threading::ScopedLock scopedLock(customFormatSpecifiersLock()); - return std::find(m_customFormatSpecifiers.begin(), - m_customFormatSpecifiers.end(), - formatSpecifier) != m_customFormatSpecifiers.end(); -} - -void Storage::installCustomFormatSpecifier( - const CustomFormatSpecifier &customFormatSpecifier) { - if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) { - return; - } - base::threading::ScopedLock scopedLock(customFormatSpecifiersLock()); - m_customFormatSpecifiers.push_back(customFormatSpecifier); -} - -bool Storage::uninstallCustomFormatSpecifier(const char *formatSpecifier) { - base::threading::ScopedLock scopedLock(customFormatSpecifiersLock()); - std::vector<CustomFormatSpecifier>::iterator it = - std::find(m_customFormatSpecifiers.begin(), - m_customFormatSpecifiers.end(), formatSpecifier); - if (it != m_customFormatSpecifiers.end() && - strcmp(formatSpecifier, it->formatSpecifier()) == 0) { - m_customFormatSpecifiers.erase(it); - return true; - } - return false; -} - -void Storage::setApplicationArguments(int argc, char **argv) { - m_commandLineArgs.setArgs(argc, argv); - m_vRegistry->setFromArgs(commandLineArgs()); - // default log file -#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) - if (m_commandLineArgs.hasParamWithValue(base::consts::kDefaultLogFileParam)) { - Configurations c; - c.setGlobally(ConfigurationType::Filename, - std::string(m_commandLineArgs.getParamValue( - base::consts::kDefaultLogFileParam))); - registeredLoggers()->setDefaultConfigurations(c); - for (base::RegisteredLoggers::iterator it = registeredLoggers()->begin(); - it != registeredLoggers()->end(); ++it) { - it->second->configure(c); - } - } -#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) -#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) - if (m_commandLineArgs.hasParamWithValue(base::consts::kLoggingFlagsParam)) { - int userInput = - atoi(m_commandLineArgs.getParamValue(base::consts::kLoggingFlagsParam)); - if (ELPP_DEFAULT_LOGGING_FLAGS == 0x0) { - m_flags = userInput; - } else { - base::utils::addFlag<base::type::EnumType>(userInput, &m_flags); - } - } -#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) -} - -} // namespace base - -// LogDispatchCallback -#if defined(ELPP_THREAD_SAFE) -void LogDispatchCallback::handle(const LogDispatchData *data) { - base::threading::ScopedLock scopedLock(m_fileLocksMapLock); - std::string filename = - data->logMessage()->logger()->typedConfigurations()->filename( - data->logMessage()->level()); - auto lock = m_fileLocks.find(filename); - if (lock == m_fileLocks.end()) { - m_fileLocks.emplace(std::make_pair( - filename, - std::unique_ptr<base::threading::Mutex>(new base::threading::Mutex))); - } -} -#else -void LogDispatchCallback::handle(const LogDispatchData * /*data*/) {} -#endif - -base::threading::Mutex & -LogDispatchCallback::fileHandle(const LogDispatchData *data) { - auto it = m_fileLocks.find( - data->logMessage()->logger()->typedConfigurations()->filename( - data->logMessage()->level())); - return *(it->second.get()); -} - -namespace base { -// DefaultLogDispatchCallback - -void DefaultLogDispatchCallback::handle(const LogDispatchData *data) { -#if defined(ELPP_THREAD_SAFE) - LogDispatchCallback::handle(data); - base::threading::ScopedLock scopedLock(fileHandle(data)); -#endif - m_data = data; - dispatch(m_data->logMessage()->logger()->logBuilder()->build( - m_data->logMessage(), - m_data->dispatchAction() == base::DispatchAction::NormalLog)); -} - -void DefaultLogDispatchCallback::dispatch(base::type::string_t &&logLine) { - if (m_data->dispatchAction() == base::DispatchAction::NormalLog) { - if (m_data->logMessage()->logger()->m_typedConfigurations->toFile( - m_data->logMessage()->level())) { - base::type::fstream_t *fs = - m_data->logMessage()->logger()->m_typedConfigurations->fileStream( - m_data->logMessage()->level()); - if (fs != nullptr) { - fs->write(logLine.c_str(), logLine.size()); - if (fs->fail()) { - ELPP_INTERNAL_ERROR( - "Unable to write log to file [" - << m_data->logMessage() - ->logger() - ->m_typedConfigurations->filename( - m_data->logMessage()->level()) - << "].\n" - << "Few possible reasons (could be something else):\n" - << " * Permission denied\n" - << " * Disk full\n" - << " * Disk is not writable", - true); - } else { - if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || - (m_data->logMessage()->logger()->isFlushNeeded( - m_data->logMessage()->level()))) { - m_data->logMessage()->logger()->flush(m_data->logMessage()->level(), - fs); - } - } - } else { - ELPP_INTERNAL_ERROR( - "Log file for [" - << LevelHelper::convertToString(m_data->logMessage()->level()) - << "] " - << "has not been configured but [TO_FILE] is configured to " - "TRUE. [Logger ID: " - << m_data->logMessage()->logger()->id() << "]", - false); - } - } - if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput( - m_data->logMessage()->level())) { - if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput)) - m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput( - &logLine, m_data->logMessage()->level()); - ELPP_COUT << ELPP_COUT_LINE(logLine); - } - } -#if defined(ELPP_SYSLOG) - else if (m_data->dispatchAction() == base::DispatchAction::SysLog) { - // Determine syslog priority - int sysLogPriority = 0; - if (m_data->logMessage()->level() == Level::Fatal) - sysLogPriority = LOG_EMERG; - else if (m_data->logMessage()->level() == Level::Error) - sysLogPriority = LOG_ERR; - else if (m_data->logMessage()->level() == Level::Warning) - sysLogPriority = LOG_WARNING; - else if (m_data->logMessage()->level() == Level::Info) - sysLogPriority = LOG_INFO; - else if (m_data->logMessage()->level() == Level::Debug) - sysLogPriority = LOG_DEBUG; - else - sysLogPriority = LOG_NOTICE; -#if defined(ELPP_UNICODE) - char *line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str()); - syslog(sysLogPriority, "%s", line); - free(line); -#else - syslog(sysLogPriority, "%s", logLine.c_str()); -#endif - } -#endif // defined(ELPP_SYSLOG) -} - -#if ELPP_ASYNC_LOGGING - -// AsyncLogDispatchCallback - -void AsyncLogDispatchCallback::handle(const LogDispatchData *data) { - base::type::string_t logLine = - data->logMessage()->logger()->logBuilder()->build( - data->logMessage(), - data->dispatchAction() == base::DispatchAction::NormalLog); - if (data->dispatchAction() == base::DispatchAction::NormalLog && - data->logMessage()->logger()->typedConfigurations()->toStandardOutput( - data->logMessage()->level())) { - if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput)) - data->logMessage()->logger()->logBuilder()->convertToColoredOutput( - &logLine, data->logMessage()->level()); - ELPP_COUT << ELPP_COUT_LINE(logLine); - } - // Save resources and only queue if we want to write to file otherwise just - // ignore handler - if (data->logMessage()->logger()->typedConfigurations()->toFile( - data->logMessage()->level())) { - ELPP->asyncLogQueue()->push( - AsyncLogItem(*(data->logMessage()), *data, logLine)); - } -} - -// AsyncDispatchWorker -AsyncDispatchWorker::AsyncDispatchWorker() { setContinueRunning(false); } - -AsyncDispatchWorker::~AsyncDispatchWorker() { - setContinueRunning(false); - ELPP_INTERNAL_INFO(6, "Stopping dispatch worker - Cleaning log queue"); - clean(); - ELPP_INTERNAL_INFO(6, "Log queue cleaned"); -} - -bool AsyncDispatchWorker::clean(void) { - std::mutex m; - std::unique_lock<std::mutex> lk(m); - cv.wait(lk, [] { return !ELPP->asyncLogQueue()->empty(); }); - emptyQueue(); - lk.unlock(); - cv.notify_one(); - return ELPP->asyncLogQueue()->empty(); -} - -void AsyncDispatchWorker::emptyQueue(void) { - while (!ELPP->asyncLogQueue()->empty()) { - AsyncLogItem data = ELPP->asyncLogQueue()->next(); - handle(&data); - base::threading::msleep(100); - } -} - -void AsyncDispatchWorker::start(void) { - base::threading::msleep(5000); // 5s (why?) - setContinueRunning(true); - std::thread t1(&AsyncDispatchWorker::run, this); - t1.join(); -} - -void AsyncDispatchWorker::handle(AsyncLogItem *logItem) { - LogDispatchData *data = logItem->data(); - LogMessage *logMessage = logItem->logMessage(); - Logger *logger = logMessage->logger(); - base::TypedConfigurations *conf = logger->typedConfigurations(); - base::type::string_t logLine = logItem->logLine(); - if (data->dispatchAction() == base::DispatchAction::NormalLog) { - if (conf->toFile(logMessage->level())) { - base::type::fstream_t *fs = conf->fileStream(logMessage->level()); - if (fs != nullptr) { - fs->write(logLine.c_str(), logLine.size()); - if (fs->fail()) { - ELPP_INTERNAL_ERROR( - "Unable to write log to file [" - << conf->filename(logMessage->level()) << "].\n" - << "Few possible reasons (could be something else):\n" - << " * Permission denied\n" - << " * Disk full\n" - << " * Disk is not writable", - true); - } else { - if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || - (logger->isFlushNeeded(logMessage->level()))) { - logger->flush(logMessage->level(), fs); - } - } - } else { - ELPP_INTERNAL_ERROR( - "Log file for [" - << LevelHelper::convertToString(logMessage->level()) << "] " - << "has not been configured but [TO_FILE] is configured to " - "TRUE. [Logger ID: " - << logger->id() << "]", - false); - } - } - } -#if defined(ELPP_SYSLOG) - else if (data->dispatchAction() == base::DispatchAction::SysLog) { - // Determine syslog priority - int sysLogPriority = 0; - if (logMessage->level() == Level::Fatal) - sysLogPriority = LOG_EMERG; - else if (logMessage->level() == Level::Error) - sysLogPriority = LOG_ERR; - else if (logMessage->level() == Level::Warning) - sysLogPriority = LOG_WARNING; - else if (logMessage->level() == Level::Info) - sysLogPriority = LOG_INFO; - else if (logMessage->level() == Level::Debug) - sysLogPriority = LOG_DEBUG; - else - sysLogPriority = LOG_NOTICE; -#if defined(ELPP_UNICODE) - char *line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str()); - syslog(sysLogPriority, "%s", line); - free(line); -#else - syslog(sysLogPriority, "%s", logLine.c_str()); -#endif - } -#endif // defined(ELPP_SYSLOG) -} - -void AsyncDispatchWorker::run(void) { - while (continueRunning()) { - emptyQueue(); - base::threading::msleep(10); // 10ms - } -} -#endif // ELPP_ASYNC_LOGGING - -// DefaultLogBuilder - -base::type::string_t DefaultLogBuilder::build(const LogMessage *logMessage, - bool appendNewLine) const { - base::TypedConfigurations *tc = logMessage->logger()->typedConfigurations(); - const base::LogFormat *logFormat = &tc->logFormat(logMessage->level()); - base::type::string_t logLine = logFormat->format(); - char buff[base::consts::kSourceFilenameMaxLength + - base::consts::kSourceLineMaxLength] = ""; - const char *bufLim = buff + sizeof(buff); - if (logFormat->hasFlag(base::FormatFlags::AppName)) { - // App name - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kAppNameFormatSpecifier, - logMessage->logger()->parentApplicationName()); - } - if (logFormat->hasFlag(base::FormatFlags::ThreadId)) { - // Thread ID - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kThreadIdFormatSpecifier, - ELPP->getThreadName(base::threading::getCurrentThreadId())); - } - if (logFormat->hasFlag(base::FormatFlags::DateTime)) { - // DateTime - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kDateTimeFormatSpecifier, - base::utils::DateTime::getDateTime( - logFormat->dateTimeFormat().c_str(), - &tc->subsecondPrecision(logMessage->level()))); - } - if (logFormat->hasFlag(base::FormatFlags::Function)) { - // Function - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kLogFunctionFormatSpecifier, logMessage->func()); - } - if (logFormat->hasFlag(base::FormatFlags::File)) { - // File - base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength); - base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff); - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kLogFileFormatSpecifier, std::string(buff)); - } - if (logFormat->hasFlag(base::FormatFlags::FileBase)) { - // FileBase - base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength); - base::utils::File::buildBaseFilename(logMessage->file(), buff); - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kLogFileBaseFormatSpecifier, std::string(buff)); - } - if (logFormat->hasFlag(base::FormatFlags::Line)) { - // Line - char *buf = - base::utils::Str::clearBuff(buff, base::consts::kSourceLineMaxLength); - buf = base::utils::Str::convertAndAddToBuff( - logMessage->line(), base::consts::kSourceLineMaxLength, buf, bufLim, - false); - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kLogLineFormatSpecifier, std::string(buff)); - } - if (logFormat->hasFlag(base::FormatFlags::Location)) { - // Location - char *buf = base::utils::Str::clearBuff( - buff, base::consts::kSourceFilenameMaxLength + - base::consts::kSourceLineMaxLength); - base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff); - buf = base::utils::Str::addToBuff(buff, buf, bufLim); - buf = base::utils::Str::addToBuff(":", buf, bufLim); - buf = base::utils::Str::convertAndAddToBuff( - logMessage->line(), base::consts::kSourceLineMaxLength, buf, bufLim, - false); - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kLogLocationFormatSpecifier, std::string(buff)); - } - if (logMessage->level() == Level::Verbose && - logFormat->hasFlag(base::FormatFlags::VerboseLevel)) { - // Verbose level - char *buf = base::utils::Str::clearBuff(buff, 1); - buf = base::utils::Str::convertAndAddToBuff(logMessage->verboseLevel(), 1, - buf, bufLim, false); - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kVerboseLevelFormatSpecifier, std::string(buff)); - } - if (logFormat->hasFlag(base::FormatFlags::LogMessage)) { - // Log message - base::utils::Str::replaceFirstWithEscape( - logLine, base::consts::kMessageFormatSpecifier, logMessage->message()); - } -#if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) - el::base::threading::ScopedLock lock_(ELPP->customFormatSpecifiersLock()); - ELPP_UNUSED(lock_); - for (std::vector<CustomFormatSpecifier>::const_iterator it = - ELPP->customFormatSpecifiers()->begin(); - it != ELPP->customFormatSpecifiers()->end(); ++it) { - std::string fs(it->formatSpecifier()); - base::type::string_t wcsFormatSpecifier(fs.begin(), fs.end()); - base::utils::Str::replaceFirstWithEscape(logLine, wcsFormatSpecifier, - it->resolver()(logMessage)); - } -#endif // !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) - if (appendNewLine) - logLine += ELPP_LITERAL("\n"); - return logLine; -} - -// LogDispatcher - -void LogDispatcher::dispatch(void) { - if (m_proceed && m_dispatchAction == base::DispatchAction::None) { - m_proceed = false; - } - if (!m_proceed) { - return; - } -#ifndef ELPP_NO_GLOBAL_LOCK - // see https://github.com/muflihun/easyloggingpp/issues/580 - // global lock is turned on by default unless - // ELPP_NO_GLOBAL_LOCK is defined - base::threading::ScopedLock scopedLock(ELPP->lock()); -#endif - base::TypedConfigurations *tc = m_logMessage->logger()->m_typedConfigurations; - if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) { - tc->validateFileRolling(m_logMessage->level(), ELPP->preRollOutCallback()); - } - LogDispatchCallback *callback = nullptr; - LogDispatchData data; - for (const std::pair<std::string, base::type::LogDispatchCallbackPtr> h : - ELPP->m_logDispatchCallbacks) { - callback = h.second.get(); - if (callback != nullptr && callback->enabled()) { - data.setLogMessage(m_logMessage); - data.setDispatchAction(m_dispatchAction); - callback->handle(&data); - } - } -} - -// MessageBuilder - -void MessageBuilder::initialize(Logger *logger) { - m_logger = logger; - m_containerLogSeparator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) - ? ELPP_LITERAL("\n ") - : ELPP_LITERAL(", "); -} - -MessageBuilder &MessageBuilder::operator<<(const wchar_t *msg) { - if (msg == nullptr) { - m_logger->stream() << base::consts::kNullPointer; - return *this; - } -#if defined(ELPP_UNICODE) - m_logger->stream() << msg; -#else - char *buff_ = base::utils::Str::wcharPtrToCharPtr(msg); - m_logger->stream() << buff_; - free(buff_); -#endif - if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { - m_logger->stream() << " "; - } - return *this; -} - -// Writer - -Writer &Writer::construct(Logger *logger, bool needLock) { - m_logger = logger; - initializeLogger(logger->id(), false, needLock); - m_messageBuilder.initialize(m_logger); - return *this; -} - -Writer &Writer::construct(int count, const char *loggerIds, ...) { - if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { - va_list loggersList; - va_start(loggersList, loggerIds); - const char *id = loggerIds; - m_loggerIds.reserve(count); - for (int i = 0; i < count; ++i) { - m_loggerIds.push_back(std::string(id)); - id = va_arg(loggersList, const char *); - } - va_end(loggersList); - initializeLogger(m_loggerIds.at(0)); - } else { - initializeLogger(std::string(loggerIds)); - } - m_messageBuilder.initialize(m_logger); - return *this; -} - -void Writer::initializeLogger(const std::string &loggerId, bool lookup, - bool needLock) { - if (lookup) { - m_logger = ELPP->registeredLoggers()->get( - loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically)); - } - if (m_logger == nullptr) { - { - if (!ELPP->registeredLoggers()->has( - std::string(base::consts::kDefaultLoggerId))) { - // Somehow default logger has been unregistered. Not good! Register - // again - ELPP->registeredLoggers()->get( - std::string(base::consts::kDefaultLoggerId)); - } - } - Writer(Level::Debug, m_file, m_line, m_func) - .construct(1, base::consts::kDefaultLoggerId) - << "Logger [" << loggerId << "] is not registered yet!"; - m_proceed = false; - } else { - if (needLock) { - m_logger->acquireLock(); // This should not be unlocked by checking - // m_proceed because - // m_proceed can be changed by lines below - } - if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) { - m_proceed = m_level == Level::Verbose - ? m_logger->enabled(m_level) - : LevelHelper::castToInt(m_level) >= - LevelHelper::castToInt(ELPP->m_loggingLevel); - } else { - m_proceed = m_logger->enabled(m_level); - } - } -} - -void Writer::processDispatch() { -#if ELPP_LOGGING_ENABLED - if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { - bool firstDispatched = false; - base::type::string_t logMessage; - std::size_t i = 0; - do { - if (m_proceed) { - if (firstDispatched) { - m_logger->stream() << logMessage; - } else { - firstDispatched = true; - if (m_loggerIds.size() > 1) { - logMessage = m_logger->stream().str(); - } - } - triggerDispatch(); - } else if (m_logger != nullptr) { - m_logger->stream().str(ELPP_LITERAL("")); - m_logger->releaseLock(); - } - if (i + 1 < m_loggerIds.size()) { - initializeLogger(m_loggerIds.at(i + 1)); - } - } while (++i < m_loggerIds.size()); - } else { - if (m_proceed) { - triggerDispatch(); - } else if (m_logger != nullptr) { - m_logger->stream().str(ELPP_LITERAL("")); - m_logger->releaseLock(); - } - } -#else - if (m_logger != nullptr) { - m_logger->stream().str(ELPP_LITERAL("")); - m_logger->releaseLock(); - } -#endif // ELPP_LOGGING_ENABLED -} - -void Writer::triggerDispatch(void) { - try { - if (m_proceed) { - if (m_msg == nullptr) { - LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel, - m_logger); - base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch(); - } else { - base::LogDispatcher(m_proceed, m_msg, m_dispatchAction).dispatch(); - } - } - if (m_logger != nullptr) { - m_logger->stream().str(ELPP_LITERAL("")); - m_logger->releaseLock(); - } - if (m_proceed && m_level == Level::Fatal && - !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) { - base::Writer(Level::Warning, m_file, m_line, m_func) - .construct(1, base::consts::kDefaultLoggerId) - << "Aborting application. Reason: Fatal log at [" << m_file << ":" - << m_line << "]"; - std::stringstream reasonStream; - reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]" - << " If you wish to disable 'abort on fatal log' please use " - << "el::Loggers::addFlag(el::LoggingFlag::" - "DisableApplicationAbortOnFatalLog)"; - base::utils::abort(1, reasonStream.str()); - } - m_proceed = false; - } catch (std::exception &ex) { - // Extremely low memory situation; don't let exception be unhandled. - } -} - -// PErrorWriter - -PErrorWriter::~PErrorWriter(void) { - if (m_proceed) { -#if ELPP_COMPILER_MSVC - char buff[256]; - strerror_s(buff, 256, errno); - m_logger->stream() << ": " << buff << " [" << errno << "]"; -#else - m_logger->stream() << ": " << strerror(errno) << " [" << errno << "]"; -#endif - } -} - -// PerformanceTracker - -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - -PerformanceTracker::PerformanceTracker(const std::string &blockName, - base::TimestampUnit timestampUnit, - const std::string &loggerId, - bool scopedLog, Level level) - : m_blockName(blockName), m_timestampUnit(timestampUnit), - m_loggerId(loggerId), m_scopedLog(scopedLog), m_level(level), - m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) { -#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED - // We store it locally so that if user happen to change configuration by the - // end of scope or before calling checkpoint, we still depend on state of - // configuration at time of construction - el::Logger *loggerPtr = ELPP->registeredLoggers()->get(loggerId, false); - m_enabled = loggerPtr != nullptr && - loggerPtr->m_typedConfigurations->performanceTracking(m_level); - if (m_enabled) { - base::utils::DateTime::gettimeofday(&m_startTime); - } -#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED -} - -PerformanceTracker::~PerformanceTracker(void) { -#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED - if (m_enabled) { - base::threading::ScopedLock scopedLock(lock()); - if (m_scopedLog) { - base::utils::DateTime::gettimeofday(&m_endTime); - base::type::string_t formattedTime = getFormattedTimeTaken(); - PerformanceTrackingData data(PerformanceTrackingData::DataType::Complete); - data.init(this); - data.m_formattedTimeTaken = formattedTime; - PerformanceTrackingCallback *callback = nullptr; - for (const std::pair<std::string, - base::type::PerformanceTrackingCallbackPtr> &h : - ELPP->m_performanceTrackingCallbacks) { - callback = h.second.get(); - if (callback != nullptr && callback->enabled()) { - callback->handle(&data); - } - } - } - } -#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) -} - -void PerformanceTracker::checkpoint(const std::string &id, const char *file, - base::type::LineNumber line, - const char *func) { -#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED - if (m_enabled) { - base::threading::ScopedLock scopedLock(lock()); - base::utils::DateTime::gettimeofday(&m_endTime); - base::type::string_t formattedTime = - m_hasChecked ? getFormattedTimeTaken(m_lastCheckpointTime) - : ELPP_LITERAL(""); - PerformanceTrackingData data(PerformanceTrackingData::DataType::Checkpoint); - data.init(this); - data.m_checkpointId = id; - data.m_file = file; - data.m_line = line; - data.m_func = func; - data.m_formattedTimeTaken = formattedTime; - PerformanceTrackingCallback *callback = nullptr; - for (const std::pair<std::string, - base::type::PerformanceTrackingCallbackPtr> &h : - ELPP->m_performanceTrackingCallbacks) { - callback = h.second.get(); - if (callback != nullptr && callback->enabled()) { - callback->handle(&data); - } - } - base::utils::DateTime::gettimeofday(&m_lastCheckpointTime); - m_hasChecked = true; - m_lastCheckpointId = id; - } -#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED - ELPP_UNUSED(id); - ELPP_UNUSED(file); - ELPP_UNUSED(line); - ELPP_UNUSED(func); -} - -const base::type::string_t -PerformanceTracker::getFormattedTimeTaken(struct timeval startTime) const { - if (ELPP->hasFlag(LoggingFlag::FixedTimeFormat)) { - base::type::stringstream_t ss; - ss << base::utils::DateTime::getTimeDifference(m_endTime, startTime, - m_timestampUnit) - << " " - << base::consts::kTimeFormats[static_cast<base::type::EnumType>( - m_timestampUnit)] - .unit; - return ss.str(); - } - return base::utils::DateTime::formatTime( - base::utils::DateTime::getTimeDifference(m_endTime, startTime, - m_timestampUnit), - m_timestampUnit); -} - -#endif // defined(ELPP_FEATURE_ALL) || - // defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - -namespace debug { -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - -// StackTrace - -StackTrace::StackTraceEntry::StackTraceEntry(std::size_t index, - const std::string &loc, - const std::string &demang, - const std::string &hex, - const std::string &addr) - : m_index(index), m_location(loc), m_demangled(demang), m_hex(hex), - m_addr(addr) {} - -std::ostream &operator<<(std::ostream &ss, - const StackTrace::StackTraceEntry &si) { - ss << "[" << si.m_index << "] " << si.m_location - << (si.m_hex.empty() ? "" : "+") << si.m_hex << " " << si.m_addr - << (si.m_demangled.empty() ? "" : ":") << si.m_demangled; - return ss; -} - -std::ostream &operator<<(std::ostream &os, const StackTrace &st) { - std::vector<StackTrace::StackTraceEntry>::const_iterator it = - st.m_stack.begin(); - while (it != st.m_stack.end()) { - os << " " << *it++ << "\n"; - } - return os; -} - -void StackTrace::generateNew(void) { -#ifdef HAVE_EXECINFO - m_stack.clear(); - void *stack[kMaxStack]; - unsigned int size = backtrace(stack, kMaxStack); - char **strings = backtrace_symbols(stack, size); - if (size > kStackStart) { // Skip StackTrace c'tor and generateNew - for (std::size_t i = kStackStart; i < size; ++i) { - std::string mangName; - std::string location; - std::string hex; - std::string addr; - - // entry: 2 crash.cpp.bin 0x0000000101552be5 - // _ZN2el4base5debug10StackTraceC1Ev + 21 - const std::string line(strings[i]); - auto p = line.find("_"); - if (p != std::string::npos) { - mangName = line.substr(p); - mangName = mangName.substr(0, mangName.find(" +")); - } - p = line.find("0x"); - if (p != std::string::npos) { - addr = line.substr(p); - addr = addr.substr(0, addr.find("_")); - } - // Perform demangling if parsed properly - if (!mangName.empty()) { - int status = 0; - char *demangName = abi::__cxa_demangle(mangName.data(), 0, 0, &status); - // if demangling is successful, output the demangled function name - if (status == 0) { - // Success (see - // http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html) - StackTraceEntry entry(i - 1, location, demangName, hex, addr); - m_stack.push_back(entry); - } else { - // Not successful - we will use mangled name - StackTraceEntry entry(i - 1, location, mangName, hex, addr); - m_stack.push_back(entry); - } - free(demangName); - } else { - StackTraceEntry entry(i - 1, line); - m_stack.push_back(entry); - } - } - } - free(strings); -#else - ELPP_INTERNAL_INFO( - 1, "Stacktrace generation not supported for selected compiler"); -#endif // ELPP_STACKTRACE -} - -// Static helper functions - -static std::string crashReason(int sig) { - std::stringstream ss; - bool foundReason = false; - for (int i = 0; i < base::consts::kCrashSignalsCount; ++i) { - if (base::consts::kCrashSignals[i].numb == sig) { - ss << "Application has crashed due to [" - << base::consts::kCrashSignals[i].name << "] signal"; - if (ELPP->hasFlag(el::LoggingFlag::LogDetailedCrashReason)) { - ss << std::endl - << " " << base::consts::kCrashSignals[i].brief << std::endl - << " " << base::consts::kCrashSignals[i].detail; - } - foundReason = true; - } - } - if (!foundReason) { - ss << "Application has crashed due to unknown signal [" << sig << "]"; - } - return ss.str(); -} -/// @brief Logs reason of crash from sig -static void logCrashReason(int sig, bool stackTraceIfAvailable, Level level, - const char *logger) { - if (sig == SIGINT && ELPP->hasFlag(el::LoggingFlag::IgnoreSigInt)) { - return; - } - std::stringstream ss; - ss << "CRASH HANDLED; "; - ss << crashReason(sig); -#if ELPP_STACKTRACE - if (stackTraceIfAvailable) { - ss << std::endl - << " ======= Backtrace: =========" << std::endl - << base::debug::StackTrace(); - } -#else - ELPP_UNUSED(stackTraceIfAvailable); -#endif // ELPP_STACKTRACE - ELPP_WRITE_LOG(el::base::Writer, level, base::DispatchAction::NormalLog, - logger) - << ss.str(); -} - -static inline void crashAbort(int sig) { - base::utils::abort(sig, std::string()); -} - -/// @brief Default application crash handler -/// -/// @detail This function writes log using 'default' logger, prints stack trace -/// for GCC based compilers and aborts program. -static inline void defaultCrashHandler(int sig) { - base::debug::logCrashReason(sig, true, Level::Fatal, - base::consts::kDefaultLoggerId); - base::debug::crashAbort(sig); -} - -// CrashHandler - -CrashHandler::CrashHandler(bool useDefault) { - if (useDefault) { - setHandler(defaultCrashHandler); - } -} - -void CrashHandler::setHandler(const Handler &cHandler) { - m_handler = cHandler; -#if defined(ELPP_HANDLE_SIGABRT) - int i = 0; // SIGABRT is at base::consts::kCrashSignals[0] -#else - int i = 1; -#endif // defined(ELPP_HANDLE_SIGABRT) - for (; i < base::consts::kCrashSignalsCount; ++i) { - m_handler = signal(base::consts::kCrashSignals[i].numb, cHandler); - } -} - -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) -} // namespace debug -} // namespace base - -// el - -// Helpers - -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - -void Helpers::crashAbort(int sig, const char *sourceFile, - unsigned int long line) { - std::stringstream ss; - ss << base::debug::crashReason(sig).c_str(); - ss << " - [Called el::Helpers::crashAbort(" << sig << ")]"; - if (sourceFile != nullptr && strlen(sourceFile) > 0) { - ss << " - Source: " << sourceFile; - if (line > 0) - ss << ":" << line; - else - ss << " (line number not specified)"; - } - base::utils::abort(sig, ss.str()); -} - -void Helpers::logCrashReason(int sig, bool stackTraceIfAvailable, Level level, - const char *logger) { - el::base::debug::logCrashReason(sig, stackTraceIfAvailable, level, logger); -} - -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - -// Loggers - -Logger *Loggers::getLogger(const std::string &identity, - bool registerIfNotAvailable) { - return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable); -} - -void Loggers::setDefaultLogBuilder(el::LogBuilderPtr &logBuilderPtr) { - ELPP->registeredLoggers()->setDefaultLogBuilder(logBuilderPtr); -} - -bool Loggers::unregisterLogger(const std::string &identity) { - return ELPP->registeredLoggers()->remove(identity); -} - -bool Loggers::hasLogger(const std::string &identity) { - return ELPP->registeredLoggers()->has(identity); -} - -Logger *Loggers::reconfigureLogger(Logger *logger, - const Configurations &configurations) { - if (!logger) - return nullptr; - logger->configure(configurations); - return logger; -} - -Logger *Loggers::reconfigureLogger(const std::string &identity, - const Configurations &configurations) { - return Loggers::reconfigureLogger(Loggers::getLogger(identity), - configurations); -} - -Logger *Loggers::reconfigureLogger(const std::string &identity, - ConfigurationType configurationType, - const std::string &value) { - Logger *logger = Loggers::getLogger(identity); - if (logger == nullptr) { - return nullptr; - } - logger->configurations()->set(Level::Global, configurationType, value); - logger->reconfigure(); - return logger; -} - -void Loggers::reconfigureAllLoggers(const Configurations &configurations) { - for (base::RegisteredLoggers::iterator it = - ELPP->registeredLoggers()->begin(); - it != ELPP->registeredLoggers()->end(); ++it) { - Loggers::reconfigureLogger(it->second, configurations); - } -} - -void Loggers::reconfigureAllLoggers(Level level, - ConfigurationType configurationType, - const std::string &value) { - for (base::RegisteredLoggers::iterator it = - ELPP->registeredLoggers()->begin(); - it != ELPP->registeredLoggers()->end(); ++it) { - Logger *logger = it->second; - logger->configurations()->set(level, configurationType, value); - logger->reconfigure(); - } -} - -void Loggers::setDefaultConfigurations(const Configurations &configurations, - bool reconfigureExistingLoggers) { - ELPP->registeredLoggers()->setDefaultConfigurations(configurations); - if (reconfigureExistingLoggers) { - Loggers::reconfigureAllLoggers(configurations); - } -} - -const Configurations *Loggers::defaultConfigurations(void) { - return ELPP->registeredLoggers()->defaultConfigurations(); -} - -const base::LogStreamsReferenceMapPtr Loggers::logStreamsReference(void) { - return ELPP->registeredLoggers()->logStreamsReference(); -} - -base::TypedConfigurations Loggers::defaultTypedConfigurations(void) { - return base::TypedConfigurations( - ELPP->registeredLoggers()->defaultConfigurations(), - ELPP->registeredLoggers()->logStreamsReference()); -} - -std::vector<std::string> * -Loggers::populateAllLoggerIds(std::vector<std::string> *targetList) { - targetList->clear(); - for (base::RegisteredLoggers::iterator it = - ELPP->registeredLoggers()->list().begin(); - it != ELPP->registeredLoggers()->list().end(); ++it) { - targetList->push_back(it->first); - } - return targetList; -} - -void Loggers::configureFromGlobal(const char *globalConfigurationFilePath) { - std::ifstream gcfStream(globalConfigurationFilePath, std::ifstream::in); - ELPP_ASSERT(gcfStream.is_open(), "Unable to open global configuration file [" - << globalConfigurationFilePath - << "] for parsing."); - std::string line = std::string(); - std::stringstream ss; - Logger *logger = nullptr; - auto configure = [&](void) { - ELPP_INTERNAL_INFO(8, "Configuring logger: '" - << logger->id() << "' with configurations \n" - << ss.str() << "\n--------------"); - Configurations c; - c.parseFromText(ss.str()); - logger->configure(c); - }; - while (gcfStream.good()) { - std::getline(gcfStream, line); - ELPP_INTERNAL_INFO(1, "Parsing line: " << line); - base::utils::Str::trim(line); - if (Configurations::Parser::isComment(line)) - continue; - Configurations::Parser::ignoreComments(&line); - base::utils::Str::trim(line); - if (line.size() > 2 && - base::utils::Str::startsWith( - line, std::string(base::consts::kConfigurationLoggerId))) { - if (!ss.str().empty() && logger != nullptr) { - configure(); - } - ss.str(std::string("")); - line = line.substr(2); - base::utils::Str::trim(line); - if (line.size() > 1) { - ELPP_INTERNAL_INFO(1, "Getting logger: '" << line << "'"); - logger = getLogger(line); - } - } else { - ss << line << "\n"; - } - } - if (!ss.str().empty() && logger != nullptr) { - configure(); - } -} - -bool Loggers::configureFromArg(const char *argKey) { -#if defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) - ELPP_UNUSED(argKey); -#else - if (!Helpers::commandLineArgs()->hasParamWithValue(argKey)) { - return false; - } - configureFromGlobal(Helpers::commandLineArgs()->getParamValue(argKey)); -#endif // defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) - return true; -} - -void Loggers::flushAll(void) { ELPP->registeredLoggers()->flushAll(); } - -void Loggers::setVerboseLevel(base::type::VerboseLevel level) { - ELPP->vRegistry()->setLevel(level); -} - -base::type::VerboseLevel Loggers::verboseLevel(void) { - return ELPP->vRegistry()->level(); -} - -void Loggers::setVModules(const char *modules) { - if (ELPP->vRegistry()->vModulesEnabled()) { - ELPP->vRegistry()->setModules(modules); - } -} - -void Loggers::clearVModules(void) { ELPP->vRegistry()->clearModules(); } - -// VersionInfo - -const std::string VersionInfo::version(void) { return std::string("9.96.7"); } -/// @brief Release date of current version -const std::string VersionInfo::releaseDate(void) { - return std::string("24-11-2018 0728hrs"); -} - -} // namespace el diff --git a/third_party/easyloggingpp/easylogging++.h b/third_party/easyloggingpp/easylogging++.h deleted file mode 100644 index 6e81edfb..00000000 --- a/third_party/easyloggingpp/easylogging++.h +++ /dev/null @@ -1,4576 +0,0 @@ -// -// Bismillah ar-Rahmaan ar-Raheem -// -// Easylogging++ v9.96.7 -// Single-header only, cross-platform logging library for C++ applications -// -// Copyright (c) 2012-2018 Amrayn Web Services -// Copyright (c) 2012-2018 @abumusamq -// -// This library is released under the MIT Licence. -// https://github.com/amrayn/easyloggingpp/blob/master/LICENSE -// -// https://amrayn.com -// http://muflihun.com -// - -#ifndef EASYLOGGINGPP_H -#define EASYLOGGINGPP_H -// Compilers and C++0x/C++11 Evaluation -#if __cplusplus >= 201103L -# define ELPP_CXX11 1 -#endif // __cplusplus >= 201103L -#if (defined(__GNUC__)) -# define ELPP_COMPILER_GCC 1 -#else -# define ELPP_COMPILER_GCC 0 -#endif -#if ELPP_COMPILER_GCC -# define ELPP_GCC_VERSION (__GNUC__ * 10000 \ -+ __GNUC_MINOR__ * 100 \ -+ __GNUC_PATCHLEVEL__) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define ELPP_CXX0X 1 -# endif -#endif -// Visual C++ -#if defined(_MSC_VER) -# define ELPP_COMPILER_MSVC 1 -#else -# define ELPP_COMPILER_MSVC 0 -#endif -#define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC -#if ELPP_COMPILER_MSVC -# if (_MSC_VER == 1600) -# define ELPP_CXX0X 1 -# elif(_MSC_VER >= 1700) -# define ELPP_CXX11 1 -# endif -#endif -// Clang++ -#if (defined(__clang__) && (__clang__ == 1)) -# define ELPP_COMPILER_CLANG 1 -#else -# define ELPP_COMPILER_CLANG 0 -#endif -#if ELPP_COMPILER_CLANG -# if __has_include(<thread>) -# include <cstddef> // Make __GLIBCXX__ defined when using libstdc++ -# if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426 -# define ELPP_CLANG_SUPPORTS_THREAD -# endif // !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426 -# endif // __has_include(<thread>) -#endif -#if (defined(__MINGW32__) || defined(__MINGW64__)) -# define ELPP_MINGW 1 -#else -# define ELPP_MINGW 0 -#endif -#if (defined(__CYGWIN__) && (__CYGWIN__ == 1)) -# define ELPP_CYGWIN 1 -#else -# define ELPP_CYGWIN 0 -#endif -#if (defined(__INTEL_COMPILER)) -# define ELPP_COMPILER_INTEL 1 -#else -# define ELPP_COMPILER_INTEL 0 -#endif -// Operating System Evaluation -// Windows -#if (defined(_WIN32) || defined(_WIN64)) -# define ELPP_OS_WINDOWS 1 -#else -# define ELPP_OS_WINDOWS 0 -#endif -// Linux -#if (defined(__linux) || defined(__linux__)) -# define ELPP_OS_LINUX 1 -#else -# define ELPP_OS_LINUX 0 -#endif -#if (defined(__APPLE__)) -# define ELPP_OS_MAC 1 -#else -# define ELPP_OS_MAC 0 -#endif -#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) -# define ELPP_OS_FREEBSD 1 -#else -# define ELPP_OS_FREEBSD 0 -#endif -#if (defined(__sun)) -# define ELPP_OS_SOLARIS 1 -#else -# define ELPP_OS_SOLARIS 0 -#endif -#if (defined(_AIX)) -# define ELPP_OS_AIX 1 -#else -# define ELPP_OS_AIX 0 -#endif -#if (defined(__NetBSD__)) -# define ELPP_OS_NETBSD 1 -#else -# define ELPP_OS_NETBSD 0 -#endif -#if defined(__EMSCRIPTEN__) -# define ELPP_OS_EMSCRIPTEN 1 -#else -# define ELPP_OS_EMSCRIPTEN 0 -#endif -#if (defined(__QNX__) || defined(__QNXNTO__)) -# define ELPP_OS_QNX 1 -#else -# define ELPP_OS_QNX 0 -#endif -// Unix -#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN || ELPP_OS_QNX) && (!ELPP_OS_WINDOWS)) -# define ELPP_OS_UNIX 1 -#else -# define ELPP_OS_UNIX 0 -#endif -#if (defined(__ANDROID__)) -# define ELPP_OS_ANDROID 1 -#else -# define ELPP_OS_ANDROID 0 -#endif -// Evaluating Cygwin as *nix OS -#if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN -# undef ELPP_OS_UNIX -# undef ELPP_OS_LINUX -# define ELPP_OS_UNIX 1 -# define ELPP_OS_LINUX 1 -#endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN -#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO) -# define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR) -# define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -#if !defined(ELPP_INTERNAL_DEBUGGING_ENDL) -# define ELPP_INTERNAL_DEBUGGING_ENDL std::endl -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -#if !defined(ELPP_INTERNAL_DEBUGGING_MSG) -# define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg -#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) -// Internal Assertions and errors -#if !defined(ELPP_DISABLE_ASSERT) -# if (defined(ELPP_DEBUG_ASSERT_FAILURE)) -# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ -std::stringstream internalInfoStream; internalInfoStream << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ -<< "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \ -<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \ -"ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); } -# else -# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ -std::stringstream internalInfoStream; internalInfoStream << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR\ -<< "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \ -<< __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \ -<< ELPP_INTERNAL_DEBUGGING_ENDL; } -# endif // (defined(ELPP_DEBUG_ASSERT_FAILURE)) -#else -# define ELPP_ASSERT(x, y) -#endif //(!defined(ELPP_DISABLE_ASSERT) -#if ELPP_COMPILER_MSVC -# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ -{ char buff[256]; strerror_s(buff, 256, errno); \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0 -#else -# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0 -#endif // ELPP_COMPILER_MSVC -#if defined(ELPP_DEBUG_ERRORS) -# if !defined(ELPP_INTERNAL_ERROR) -# define ELPP_INTERNAL_ERROR(msg, pe) { \ -std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ -<< "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \ -<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \ -if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0 -# endif -#else -# undef ELPP_INTERNAL_INFO -# define ELPP_INTERNAL_ERROR(msg, pe) -#endif // defined(ELPP_DEBUG_ERRORS) -#if (defined(ELPP_DEBUG_INFO)) -# if !(defined(ELPP_INTERNAL_INFO_LEVEL)) -# define ELPP_INTERNAL_INFO_LEVEL 9 -# endif // !(defined(ELPP_INTERNAL_INFO_LEVEL)) -# if !defined(ELPP_INTERNAL_INFO) -# define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \ -std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \ -ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \ -<< ELPP_INTERNAL_DEBUGGING_ENDL; }} -# endif -#else -# undef ELPP_INTERNAL_INFO -# define ELPP_INTERNAL_INFO(lvl, msg) -#endif // (defined(ELPP_DEBUG_INFO)) -#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) -# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_CYGWIN && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN && !ELPP_OS_QNX) -# define ELPP_STACKTRACE 1 -# else -# if ELPP_COMPILER_MSVC -# pragma message("Stack trace not available for this compiler") -# else -# warning "Stack trace not available for this compiler"; -# endif // ELPP_COMPILER_MSVC -# define ELPP_STACKTRACE 0 -# endif // ELPP_COMPILER_GCC -#else -# define ELPP_STACKTRACE 0 -#endif // (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) -// Miscellaneous macros -#define ELPP_UNUSED(x) (void)x -#if ELPP_OS_UNIX -// Log file permissions for unix-based systems -# define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH -#endif // ELPP_OS_UNIX -#if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC -# if defined(ELPP_EXPORT_SYMBOLS) -# define ELPP_EXPORT __declspec(dllexport) -# else -# define ELPP_EXPORT __declspec(dllimport) -# endif // defined(ELPP_EXPORT_SYMBOLS) -#else -# define ELPP_EXPORT -#endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC -// Some special functions that are VC++ specific -#undef STRTOK -#undef STRERROR -#undef STRCAT -#undef STRCPY -#if ELPP_CRT_DBG_WARNINGS -# define STRTOK(a, b, c) strtok_s(a, b, c) -# define STRERROR(a, b, c) strerror_s(a, b, c) -# define STRCAT(a, b, len) strcat_s(a, len, b) -# define STRCPY(a, b, len) strcpy_s(a, len, b) -#else -# define STRTOK(a, b, c) strtok(a, b) -# define STRERROR(a, b, c) strerror(c) -# define STRCAT(a, b, len) strcat(a, b) -# define STRCPY(a, b, len) strcpy(a, b) -#endif -// Compiler specific support evaluations -#if (ELPP_MINGW && !defined(ELPP_FORCE_USE_STD_THREAD)) -# define ELPP_USE_STD_THREADING 0 -#else -# if ((ELPP_COMPILER_CLANG && defined(ELPP_CLANG_SUPPORTS_THREAD)) || \ - (!ELPP_COMPILER_CLANG && defined(ELPP_CXX11)) || \ - defined(ELPP_FORCE_USE_STD_THREAD)) -# define ELPP_USE_STD_THREADING 1 -# else -# define ELPP_USE_STD_THREADING 0 -# endif -#endif -#undef ELPP_FINAL -#if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) -# define ELPP_FINAL -#else -# define ELPP_FINAL final -#endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) -#if defined(ELPP_EXPERIMENTAL_ASYNC) -# define ELPP_ASYNC_LOGGING 1 -#else -# define ELPP_ASYNC_LOGGING 0 -#endif // defined(ELPP_EXPERIMENTAL_ASYNC) -#if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING -# define ELPP_THREADING_ENABLED 1 -#else -# define ELPP_THREADING_ENABLED 0 -#endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING -// Function macro ELPP_FUNC -#undef ELPP_FUNC -#if ELPP_COMPILER_MSVC // Visual C++ -# define ELPP_FUNC __FUNCSIG__ -#elif ELPP_COMPILER_GCC // GCC -# define ELPP_FUNC __PRETTY_FUNCTION__ -#elif ELPP_COMPILER_INTEL // Intel C++ -# define ELPP_FUNC __PRETTY_FUNCTION__ -#elif ELPP_COMPILER_CLANG // Clang++ -# define ELPP_FUNC __PRETTY_FUNCTION__ -#else -# if defined(__func__) -# define ELPP_FUNC __func__ -# else -# define ELPP_FUNC "" -# endif // defined(__func__) -#endif // defined(_MSC_VER) -#undef ELPP_VARIADIC_TEMPLATES_SUPPORTED -// Keep following line commented until features are fixed -#define ELPP_VARIADIC_TEMPLATES_SUPPORTED \ -(ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)) -// Logging Enable/Disable macros -#if defined(ELPP_DISABLE_LOGS) -#define ELPP_LOGGING_ENABLED 0 -#else -#define ELPP_LOGGING_ENABLED 1 -#endif -#if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_DEBUG_LOG 1 -#else -# define ELPP_DEBUG_LOG 0 -#endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_INFO_LOG 1 -#else -# define ELPP_INFO_LOG 0 -#endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_WARNING_LOG 1 -#else -# define ELPP_WARNING_LOG 0 -#endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_ERROR_LOG 1 -#else -# define ELPP_ERROR_LOG 0 -#endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_FATAL_LOG 1 -#else -# define ELPP_FATAL_LOG 0 -#endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_TRACE_LOG 1 -#else -# define ELPP_TRACE_LOG 0 -#endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) -# define ELPP_VERBOSE_LOG 1 -#else -# define ELPP_VERBOSE_LOG 0 -#endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) -#if (!(ELPP_CXX0X || ELPP_CXX11)) -# error "C++0x (or higher) support not detected! (Is `-std=c++11' missing?)" -#endif // (!(ELPP_CXX0X || ELPP_CXX11)) -// Headers -#if defined(ELPP_SYSLOG) -# include <syslog.h> -#endif // defined(ELPP_SYSLOG) -#include <ctime> -#include <cstring> -#include <cstdlib> -#include <cctype> -#include <cwchar> -#include <csignal> -#include <cerrno> -#include <cstdarg> -#if defined(ELPP_UNICODE) -# include <locale> -# if ELPP_OS_WINDOWS -# include <codecvt> -# endif // ELPP_OS_WINDOWS -#endif // defined(ELPP_UNICODE) -#ifdef HAVE_EXECINFO -# include <cxxabi.h> -# include <execinfo.h> -#endif // ENABLE_EXECINFO -#if ELPP_OS_ANDROID -# include <sys/system_properties.h> -#endif // ELPP_OS_ANDROID -#if ELPP_OS_UNIX -# include <sys/stat.h> -# include <sys/time.h> -#elif ELPP_OS_WINDOWS -# include <direct.h> -# include <windows.h> -# if defined(WIN32_LEAN_AND_MEAN) -# if defined(ELPP_WINSOCK2) -# include <winsock2.h> -# else -# include <winsock.h> -# endif // defined(ELPP_WINSOCK2) -# endif // defined(WIN32_LEAN_AND_MEAN) -#endif // ELPP_OS_UNIX -#include <string> -#include <vector> -#include <map> -#include <unordered_map> -#include <utility> -#include <functional> -#include <algorithm> -#include <fstream> -#include <iostream> -#include <sstream> -#include <memory> -#include <type_traits> -#if ELPP_THREADING_ENABLED -# if ELPP_USE_STD_THREADING -# include <mutex> -# include <thread> -# else -# if ELPP_OS_UNIX -# include <pthread.h> -# endif // ELPP_OS_UNIX -# endif // ELPP_USE_STD_THREADING -#endif // ELPP_THREADING_ENABLED -#if ELPP_ASYNC_LOGGING -# if defined(ELPP_NO_SLEEP_FOR) -# include <unistd.h> -# endif // defined(ELPP_NO_SLEEP_FOR) -# include <thread> -# include <queue> -# include <condition_variable> -#endif // ELPP_ASYNC_LOGGING -#if defined(ELPP_STL_LOGGING) -// For logging STL based templates -# include <list> -# include <queue> -# include <deque> -# include <set> -# include <bitset> -# include <stack> -# if defined(ELPP_LOG_STD_ARRAY) -# include <array> -# endif // defined(ELPP_LOG_STD_ARRAY) -# if defined(ELPP_LOG_UNORDERED_SET) -# include <unordered_set> -# endif // defined(ELPP_UNORDERED_SET) -#endif // defined(ELPP_STL_LOGGING) -#if defined(ELPP_QT_LOGGING) -// For logging Qt based classes & templates -# include <QString> -# include <QByteArray> -# include <QVector> -# include <QList> -# include <QPair> -# include <QMap> -# include <QQueue> -# include <QSet> -# include <QLinkedList> -# include <QHash> -# include <QMultiHash> -# include <QStack> -#endif // defined(ELPP_QT_LOGGING) -#if defined(ELPP_BOOST_LOGGING) -// For logging boost based classes & templates -# include <boost/container/vector.hpp> -# include <boost/container/stable_vector.hpp> -# include <boost/container/list.hpp> -# include <boost/container/deque.hpp> -# include <boost/container/map.hpp> -# include <boost/container/flat_map.hpp> -# include <boost/container/set.hpp> -# include <boost/container/flat_set.hpp> -#endif // defined(ELPP_BOOST_LOGGING) -#if defined(ELPP_WXWIDGETS_LOGGING) -// For logging wxWidgets based classes & templates -# include <wx/vector.h> -#endif // defined(ELPP_WXWIDGETS_LOGGING) -#if defined(ELPP_UTC_DATETIME) -# define elpptime_r gmtime_r -# define elpptime_s gmtime_s -# define elpptime gmtime -#else -# define elpptime_r localtime_r -# define elpptime_s localtime_s -# define elpptime localtime -#endif // defined(ELPP_UTC_DATETIME) -// Forward declarations -namespace el { -class Logger; -class LogMessage; -class PerformanceTrackingData; -class Loggers; -class Helpers; -template <typename T> class Callback; -class LogDispatchCallback; -class PerformanceTrackingCallback; -class LoggerRegistrationCallback; -class LogDispatchData; -namespace base { -class Storage; -class RegisteredLoggers; -class PerformanceTracker; -class MessageBuilder; -class Writer; -class PErrorWriter; -class LogDispatcher; -class DefaultLogBuilder; -class DefaultLogDispatchCallback; -#if ELPP_ASYNC_LOGGING -class AsyncLogDispatchCallback; -class AsyncDispatchWorker; -#endif // ELPP_ASYNC_LOGGING -class DefaultPerformanceTrackingCallback; -} // namespace base -} // namespace el -/// @brief Easylogging++ entry namespace -namespace el { -/// @brief Namespace containing base/internal functionality used by Easylogging++ -namespace base { -/// @brief Data types used by Easylogging++ -namespace type { -#undef ELPP_LITERAL -#undef ELPP_STRLEN -#undef ELPP_COUT -#if defined(ELPP_UNICODE) -# define ELPP_LITERAL(txt) L##txt -# define ELPP_STRLEN wcslen -# if defined ELPP_CUSTOM_COUT -# define ELPP_COUT ELPP_CUSTOM_COUT -# else -# define ELPP_COUT std::wcout -# endif // defined ELPP_CUSTOM_COUT -typedef wchar_t char_t; -typedef std::wstring string_t; -typedef std::wstringstream stringstream_t; -typedef std::wfstream fstream_t; -typedef std::wostream ostream_t; -#else -# define ELPP_LITERAL(txt) txt -# define ELPP_STRLEN strlen -# if defined ELPP_CUSTOM_COUT -# define ELPP_COUT ELPP_CUSTOM_COUT -# else -# define ELPP_COUT std::cout -# endif // defined ELPP_CUSTOM_COUT -typedef char char_t; -typedef std::string string_t; -typedef std::stringstream stringstream_t; -typedef std::fstream fstream_t; -typedef std::ostream ostream_t; -#endif // defined(ELPP_UNICODE) -#if defined(ELPP_CUSTOM_COUT_LINE) -# define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine) -#else -# define ELPP_COUT_LINE(logLine) logLine << std::flush -#endif // defined(ELPP_CUSTOM_COUT_LINE) -typedef unsigned int EnumType; -typedef unsigned short VerboseLevel; -typedef unsigned long int LineNumber; -typedef std::shared_ptr<base::Storage> StoragePointer; -typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr; -typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr; -typedef std::shared_ptr<LoggerRegistrationCallback> LoggerRegistrationCallbackPtr; -typedef std::unique_ptr<el::base::PerformanceTracker> PerformanceTrackerPtr; -} // namespace type -/// @brief Internal helper class that prevent copy constructor for class -/// -/// @detail When using this class simply inherit it privately -class NoCopy { - protected: - NoCopy(void) {} - private: - NoCopy(const NoCopy&); - NoCopy& operator=(const NoCopy&); -}; -/// @brief Internal helper class that makes all default constructors private. -/// -/// @detail This prevents initializing class making it static unless an explicit constructor is declared. -/// When using this class simply inherit it privately -class StaticClass { - private: - StaticClass(void); - StaticClass(const StaticClass&); - StaticClass& operator=(const StaticClass&); -}; -} // namespace base -/// @brief Represents enumeration for severity level used to determine level of logging -/// -/// @detail With Easylogging++, developers may disable or enable any level regardless of -/// what the severity is. Or they can choose to log using hierarchical logging flag -enum class Level : base::type::EnumType { - /// @brief Generic level that represents all the levels. Useful when setting global configuration for all levels - Global = 1, - /// @brief Information that can be useful to back-trace certain events - mostly useful than debug logs. - Trace = 2, - /// @brief Informational events most useful for developers to debug application - Debug = 4, - /// @brief Severe error information that will presumably abort application - Fatal = 8, - /// @brief Information representing errors in application but application will keep running - Error = 16, - /// @brief Useful when application has potentially harmful situations - Warning = 32, - /// @brief Information that can be highly useful and vary with verbose logging level. - Verbose = 64, - /// @brief Mainly useful to represent current progress of application - Info = 128, - /// @brief Represents unknown level - Unknown = 1010 -}; -} // namespace el -namespace std { -template<> struct hash<el::Level> { - public: - std::size_t operator()(const el::Level& l) const { - return hash<el::base::type::EnumType> {}(static_cast<el::base::type::EnumType>(l)); - } -}; -} -namespace el { -/// @brief Static class that contains helper functions for el::Level -class LevelHelper : base::StaticClass { - public: - /// @brief Represents minimum valid level. Useful when iterating through enum. - static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(Level::Trace); - /// @brief Represents maximum valid level. This is used internally and you should not need it. - static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(Level::Info); - /// @brief Casts level to int, useful for iterating through enum. - static base::type::EnumType castToInt(Level level) { - return static_cast<base::type::EnumType>(level); - } - /// @brief Casts int(ushort) to level, useful for iterating through enum. - static Level castFromInt(base::type::EnumType l) { - return static_cast<Level>(l); - } - /// @brief Converts level to associated const char* - /// @return Upper case string based level. - static const char* convertToString(Level level); - /// @brief Converts from levelStr to Level - /// @param levelStr Upper case string based level. - /// Lower case is also valid but providing upper case is recommended. - static Level convertFromString(const char* levelStr); - /// @brief Applies specified function to each level starting from startIndex - /// @param startIndex initial value to start the iteration from. This is passed as pointer and - /// is left-shifted so this can be used inside function (fn) to represent current level. - /// @param fn function to apply with each level. This bool represent whether or not to stop iterating through levels. - static void forEachLevel(base::type::EnumType* startIndex, const std::function<bool(void)>& fn); -}; -/// @brief Represents enumeration of ConfigurationType used to configure or access certain aspect -/// of logging -enum class ConfigurationType : base::type::EnumType { - /// @brief Determines whether or not corresponding level and logger of logging is enabled - /// You may disable all logs by using el::Level::Global - Enabled = 1, - /// @brief Whether or not to write corresponding log to log file - ToFile = 2, - /// @brief Whether or not to write corresponding level and logger log to standard output. - /// By standard output meaning termnal, command prompt etc - ToStandardOutput = 4, - /// @brief Determines format of logging corresponding level and logger. - Format = 8, - /// @brief Determines log file (full path) to write logs to for corresponding level and logger - Filename = 16, - /// @brief Specifies precision of the subsecond part. It should be within range (1-6). - SubsecondPrecision = 32, - /// @brief Alias of SubsecondPrecision (for backward compatibility) - MillisecondsWidth = SubsecondPrecision, - /// @brief Determines whether or not performance tracking is enabled. - /// - /// @detail This does not depend on logger or level. Performance tracking always uses 'performance' logger - PerformanceTracking = 64, - /// @brief Specifies log file max size. - /// - /// @detail If file size of corresponding log file (for corresponding level) is >= specified size, log file will - /// be truncated and re-initiated. - MaxLogFileSize = 128, - /// @brief Specifies number of log entries to hold until we flush pending log data - LogFlushThreshold = 256, - /// @brief Represents unknown configuration - Unknown = 1010 -}; -/// @brief Static class that contains helper functions for el::ConfigurationType -class ConfigurationTypeHelper : base::StaticClass { - public: - /// @brief Represents minimum valid configuration type. Useful when iterating through enum. - static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(ConfigurationType::Enabled); - /// @brief Represents maximum valid configuration type. This is used internally and you should not need it. - static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(ConfigurationType::MaxLogFileSize); - /// @brief Casts configuration type to int, useful for iterating through enum. - static base::type::EnumType castToInt(ConfigurationType configurationType) { - return static_cast<base::type::EnumType>(configurationType); - } - /// @brief Casts int(ushort) to configuration type, useful for iterating through enum. - static ConfigurationType castFromInt(base::type::EnumType c) { - return static_cast<ConfigurationType>(c); - } - /// @brief Converts configuration type to associated const char* - /// @returns Upper case string based configuration type. - static const char* convertToString(ConfigurationType configurationType); - /// @brief Converts from configStr to ConfigurationType - /// @param configStr Upper case string based configuration type. - /// Lower case is also valid but providing upper case is recommended. - static ConfigurationType convertFromString(const char* configStr); - /// @brief Applies specified function to each configuration type starting from startIndex - /// @param startIndex initial value to start the iteration from. This is passed by pointer and is left-shifted - /// so this can be used inside function (fn) to represent current configuration type. - /// @param fn function to apply with each configuration type. - /// This bool represent whether or not to stop iterating through configurations. - static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn); -}; -/// @brief Flags used while writing logs. This flags are set by user -enum class LoggingFlag : base::type::EnumType { - /// @brief Makes sure we have new line for each container log entry - NewLineForContainer = 1, - /// @brief Makes sure if -vmodule is used and does not specifies a module, then verbose - /// logging is allowed via that module. - AllowVerboseIfModuleNotSpecified = 2, - /// @brief When handling crashes by default, detailed crash reason will be logged as well - LogDetailedCrashReason = 4, - /// @brief Allows to disable application abortion when logged using FATAL level - DisableApplicationAbortOnFatalLog = 8, - /// @brief Flushes log with every log-entry (performance sensitive) - Disabled by default - ImmediateFlush = 16, - /// @brief Enables strict file rolling - StrictLogFileSizeCheck = 32, - /// @brief Make terminal output colorful for supported terminals - ColoredTerminalOutput = 64, - /// @brief Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network") - MultiLoggerSupport = 128, - /// @brief Disables comparing performance tracker's checkpoints - DisablePerformanceTrackingCheckpointComparison = 256, - /// @brief Disable VModules - DisableVModules = 512, - /// @brief Disable VModules extensions - DisableVModulesExtensions = 1024, - /// @brief Enables hierarchical logging - HierarchicalLogging = 2048, - /// @brief Creates logger automatically when not available - CreateLoggerAutomatically = 4096, - /// @brief Adds spaces b/w logs that separated by left-shift operator - AutoSpacing = 8192, - /// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only) - FixedTimeFormat = 16384, - // @brief Ignore SIGINT or crash - IgnoreSigInt = 32768, -}; -namespace base { -/// @brief Namespace containing constants used internally. -namespace consts { -static const char kFormatSpecifierCharValue = 'v'; -static const char kFormatSpecifierChar = '%'; -static const unsigned int kMaxLogPerCounter = 100000; -static const unsigned int kMaxLogPerContainer = 100; -static const unsigned int kDefaultSubsecondPrecision = 3; - -#ifdef ELPP_DEFAULT_LOGGER -static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER; -#else -static const char* kDefaultLoggerId = "default"; -#endif - -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) -#ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER -static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER; -#else -static const char* kPerformanceLoggerId = "performance"; -#endif // ELPP_DEFAULT_PERFORMANCE_LOGGER -#endif - -#if defined(ELPP_SYSLOG) -static const char* kSysLogLoggerId = "syslog"; -#endif // defined(ELPP_SYSLOG) - -#if ELPP_OS_WINDOWS -static const char* kFilePathSeparator = "\\"; -#else -static const char* kFilePathSeparator = "/"; -#endif // ELPP_OS_WINDOWS - -static const std::size_t kSourceFilenameMaxLength = 100; -static const std::size_t kSourceLineMaxLength = 10; -static const Level kPerformanceTrackerDefaultLevel = Level::Info; -const struct { - double value; - const base::type::char_t* unit; -} kTimeFormats[] = { - { 1000.0f, ELPP_LITERAL("us") }, - { 1000.0f, ELPP_LITERAL("ms") }, - { 60.0f, ELPP_LITERAL("seconds") }, - { 60.0f, ELPP_LITERAL("minutes") }, - { 24.0f, ELPP_LITERAL("hours") }, - { 7.0f, ELPP_LITERAL("days") } -}; -static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]); -const struct { - int numb; - const char* name; - const char* brief; - const char* detail; -} kCrashSignals[] = { - // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..) - { - SIGABRT, "SIGABRT", "Abnormal termination", - "Program was abnormally terminated." - }, - { - SIGFPE, "SIGFPE", "Erroneous arithmetic operation", - "Arithmetic operation issue such as division by zero or operation resulting in overflow." - }, - { - SIGILL, "SIGILL", "Illegal instruction", - "Generally due to a corruption in the code or to an attempt to execute data." - }, - { - SIGSEGV, "SIGSEGV", "Invalid access to memory", - "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory." - }, - { - SIGINT, "SIGINT", "Interactive attention signal", - "Interruption generated (generally) by user or operating system." - }, -}; -static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]); -} // namespace consts -} // namespace base -typedef std::function<void(const char*, std::size_t)> PreRollOutCallback; -namespace base { -static inline void defaultPreRollOutCallback(const char*, std::size_t) {} -/// @brief Enum to represent timestamp unit -enum class TimestampUnit : base::type::EnumType { - Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5 -}; -/// @brief Format flags used to determine specifiers that are active for performance improvements. -enum class FormatFlags : base::type::EnumType { - DateTime = 1 << 1, - LoggerId = 1 << 2, - File = 1 << 3, - Line = 1 << 4, - Location = 1 << 5, - Function = 1 << 6, - User = 1 << 7, - Host = 1 << 8, - LogMessage = 1 << 9, - VerboseLevel = 1 << 10, - AppName = 1 << 11, - ThreadId = 1 << 12, - Level = 1 << 13, - FileBase = 1 << 14, - LevelShort = 1 << 15 -}; -/// @brief A subsecond precision class containing actual width and offset of the subsecond part -class SubsecondPrecision { - public: - SubsecondPrecision(void) { - init(base::consts::kDefaultSubsecondPrecision); - } - explicit SubsecondPrecision(int width) { - init(width); - } - bool operator==(const SubsecondPrecision& ssPrec) { - return m_width == ssPrec.m_width && m_offset == ssPrec.m_offset; - } - int m_width; - unsigned int m_offset; - private: - void init(int width); -}; -/// @brief Type alias of SubsecondPrecision -typedef SubsecondPrecision MillisecondsWidth; -/// @brief Namespace containing utility functions/static classes used internally -namespace utils { -/// @brief Deletes memory safely and points to null -template <typename T> -static -typename std::enable_if<std::is_pointer<T*>::value, void>::type -safeDelete(T*& pointer) { - if (pointer == nullptr) - return; - delete pointer; - pointer = nullptr; -} -/// @brief Bitwise operations for C++11 strong enum class. This casts e into Flag_T and returns value after bitwise operation -/// Use these function as <pre>flag = bitwise::Or<MyEnum>(MyEnum::val1, flag);</pre> -namespace bitwise { -template <typename Enum> -static inline base::type::EnumType And(Enum e, base::type::EnumType flag) { - return static_cast<base::type::EnumType>(flag) & static_cast<base::type::EnumType>(e); -} -template <typename Enum> -static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) { - return static_cast<base::type::EnumType>(flag) & ~(static_cast<base::type::EnumType>(e)); -} -template <typename Enum> -static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) { - return static_cast<base::type::EnumType>(flag) | static_cast<base::type::EnumType>(e); -} -} // namespace bitwise -template <typename Enum> -static inline void addFlag(Enum e, base::type::EnumType* flag) { - *flag = base::utils::bitwise::Or<Enum>(e, *flag); -} -template <typename Enum> -static inline void removeFlag(Enum e, base::type::EnumType* flag) { - *flag = base::utils::bitwise::Not<Enum>(e, *flag); -} -template <typename Enum> -static inline bool hasFlag(Enum e, base::type::EnumType flag) { - return base::utils::bitwise::And<Enum>(e, flag) > 0x0; -} -} // namespace utils -namespace threading { -#if ELPP_THREADING_ENABLED -# if !ELPP_USE_STD_THREADING -namespace internal { -/// @brief A mutex wrapper for compiler that dont yet support std::recursive_mutex -class Mutex : base::NoCopy { - public: - Mutex(void) { -# if ELPP_OS_UNIX - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&m_underlyingMutex, &attr); - pthread_mutexattr_destroy(&attr); -# elif ELPP_OS_WINDOWS - InitializeCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - virtual ~Mutex(void) { -# if ELPP_OS_UNIX - pthread_mutex_destroy(&m_underlyingMutex); -# elif ELPP_OS_WINDOWS - DeleteCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - inline void lock(void) { -# if ELPP_OS_UNIX - pthread_mutex_lock(&m_underlyingMutex); -# elif ELPP_OS_WINDOWS - EnterCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - inline bool try_lock(void) { -# if ELPP_OS_UNIX - return (pthread_mutex_trylock(&m_underlyingMutex) == 0); -# elif ELPP_OS_WINDOWS - return TryEnterCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - inline void unlock(void) { -# if ELPP_OS_UNIX - pthread_mutex_unlock(&m_underlyingMutex); -# elif ELPP_OS_WINDOWS - LeaveCriticalSection(&m_underlyingMutex); -# endif // ELPP_OS_UNIX - } - - private: -# if ELPP_OS_UNIX - pthread_mutex_t m_underlyingMutex; -# elif ELPP_OS_WINDOWS - CRITICAL_SECTION m_underlyingMutex; -# endif // ELPP_OS_UNIX -}; -/// @brief Scoped lock for compiler that dont yet support std::lock_guard -template <typename M> -class ScopedLock : base::NoCopy { - public: - explicit ScopedLock(M& mutex) { - m_mutex = &mutex; - m_mutex->lock(); - } - - virtual ~ScopedLock(void) { - m_mutex->unlock(); - } - private: - M* m_mutex; - ScopedLock(void); -}; -} // namespace internal -typedef base::threading::internal::Mutex Mutex; -typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock; -# else -typedef std::recursive_mutex Mutex; -typedef std::lock_guard<base::threading::Mutex> ScopedLock; -# endif // !ELPP_USE_STD_THREADING -#else -namespace internal { -/// @brief Mutex wrapper used when multi-threading is disabled. -class NoMutex : base::NoCopy { - public: - NoMutex(void) {} - inline void lock(void) {} - inline bool try_lock(void) { - return true; - } - inline void unlock(void) {} -}; -/// @brief Lock guard wrapper used when multi-threading is disabled. -template <typename Mutex> -class NoScopedLock : base::NoCopy { - public: - explicit NoScopedLock(Mutex&) { - } - virtual ~NoScopedLock(void) { - } - private: - NoScopedLock(void); -}; -} // namespace internal -typedef base::threading::internal::NoMutex Mutex; -typedef base::threading::internal::NoScopedLock<base::threading::Mutex> ScopedLock; -#endif // ELPP_THREADING_ENABLED -/// @brief Base of thread safe class, this class is inheritable-only -class ThreadSafe { - public: - virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); } - virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); } - virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; } - protected: - ThreadSafe(void) {} - virtual ~ThreadSafe(void) {} - private: - base::threading::Mutex m_mutex; -}; - -#if ELPP_THREADING_ENABLED -# if !ELPP_USE_STD_THREADING -/// @brief Gets ID of currently running threading in windows systems. On unix, nothing is returned. -static std::string getCurrentThreadId(void) { - std::stringstream ss; -# if (ELPP_OS_WINDOWS) - ss << GetCurrentThreadId(); -# endif // (ELPP_OS_WINDOWS) - return ss.str(); -} -# else -/// @brief Gets ID of currently running threading using std::this_thread::get_id() -static std::string getCurrentThreadId(void) { - std::stringstream ss; - ss << std::this_thread::get_id(); - return ss.str(); -} -# endif // !ELPP_USE_STD_THREADING -#else -static inline std::string getCurrentThreadId(void) { - return std::string(); -} -#endif // ELPP_THREADING_ENABLED -} // namespace threading -namespace utils { -class File : base::StaticClass { - public: - /// @brief Creates new out file stream for specified filename. - /// @return Pointer to newly created fstream or nullptr - static base::type::fstream_t* newFileStream(const std::string& filename); - - /// @brief Gets size of file provided in stream - static std::size_t getSizeOfFile(base::type::fstream_t* fs); - - /// @brief Determines whether or not provided path exist in current file system - static bool pathExists(const char* path, bool considerFile = false); - - /// @brief Creates specified path on file system - /// @param path Path to create. - static bool createPath(const std::string& path); - /// @brief Extracts path of filename with leading slash - static std::string extractPathFromFilename(const std::string& fullPath, - const char* separator = base::consts::kFilePathSeparator); - /// @brief builds stripped filename and puts it in buff - static void buildStrippedFilename(const char* filename, char buff[], - std::size_t limit = base::consts::kSourceFilenameMaxLength); - /// @brief builds base filename and puts it in buff - static void buildBaseFilename(const std::string& fullPath, char buff[], - std::size_t limit = base::consts::kSourceFilenameMaxLength, - const char* separator = base::consts::kFilePathSeparator); -}; -/// @brief String utilities helper class used internally. You should not use it. -class Str : base::StaticClass { - public: - /// @brief Checks if character is digit. Dont use libc implementation of it to prevent locale issues. - static inline bool isDigit(char c) { - return c >= '0' && c <= '9'; - } - - /// @brief Matches wildcards, '*' and '?' only supported. - static bool wildCardMatch(const char* str, const char* pattern); - - static std::string& ltrim(std::string& str); - static std::string& rtrim(std::string& str); - static std::string& trim(std::string& str); - - /// @brief Determines whether or not str starts with specified string - /// @param str String to check - /// @param start String to check against - /// @return Returns true if starts with specified string, false otherwise - static bool startsWith(const std::string& str, const std::string& start); - - /// @brief Determines whether or not str ends with specified string - /// @param str String to check - /// @param end String to check against - /// @return Returns true if ends with specified string, false otherwise - static bool endsWith(const std::string& str, const std::string& end); - - /// @brief Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performance. - /// @param [in,out] str String to replace from - /// @param replaceWhat Character to replace - /// @param replaceWith Character to replace with - /// @return Modified version of str - static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith); - - /// @brief Replaces all instances of 'replaceWhat' with 'replaceWith'. (String version) Replaces in place - /// @param str String to replace from - /// @param replaceWhat Character to replace - /// @param replaceWith Character to replace with - /// @return Modified (original) str - static std::string& replaceAll(std::string& str, const std::string& replaceWhat, - const std::string& replaceWith); - - static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, - const base::type::string_t& replaceWith); -#if defined(ELPP_UNICODE) - static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, - const std::string& replaceWith); -#endif // defined(ELPP_UNICODE) - /// @brief Converts string to uppercase - /// @param str String to convert - /// @return Uppercase string - static std::string& toUpper(std::string& str); - - /// @brief Compares cstring equality - uses strcmp - static bool cStringEq(const char* s1, const char* s2); - - /// @brief Compares cstring equality (case-insensitive) - uses toupper(char) - /// Dont use strcasecmp because of CRT (VC++) - static bool cStringCaseEq(const char* s1, const char* s2); - - /// @brief Returns true if c exist in str - static bool contains(const char* str, char c); - - static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true); - static char* addToBuff(const char* str, char* buf, const char* bufLim); - static char* clearBuff(char buff[], std::size_t lim); - - /// @brief Converts wchar* to char* - /// NOTE: Need to free return value after use! - static char* wcharPtrToCharPtr(const wchar_t* line); -}; -/// @brief Operating System helper static class used internally. You should not use it. -class OS : base::StaticClass { - public: -#if ELPP_OS_WINDOWS - /// @brief Gets environment variables for Windows based OS. - /// We are not using <code>getenv(const char*)</code> because of CRT deprecation - /// @param varname Variable name to get environment variable value for - /// @return If variable exist the value of it otherwise nullptr - static const char* getWindowsEnvironmentVariable(const char* varname); -#endif // ELPP_OS_WINDOWS -#if ELPP_OS_ANDROID - /// @brief Reads android property value - static std::string getProperty(const char* prop); - - /// @brief Reads android device name - static std::string getDeviceName(void); -#endif // ELPP_OS_ANDROID - - /// @brief Runs command on terminal and returns the output. - /// - /// @detail This is applicable only on unix based systems, for all other OS, an empty string is returned. - /// @param command Bash command - /// @return Result of bash output or empty string if no result found. - static const std::string getBashOutput(const char* command); - - /// @brief Gets environment variable. This is cross-platform and CRT safe (for VC++) - /// @param variableName Environment variable name - /// @param defaultVal If no environment variable or value found the value to return by default - /// @param alternativeBashCommand If environment variable not found what would be alternative bash command - /// in order to look for value user is looking for. E.g, for 'user' alternative command will 'whoami' - static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal, - const char* alternativeBashCommand = nullptr); - /// @brief Gets current username. - static std::string currentUser(void); - - /// @brief Gets current host name or computer name. - /// - /// @detail For android systems this is device name with its manufacturer and model separated by hyphen - static std::string currentHost(void); - /// @brief Whether or not terminal supports colors - static bool termSupportsColor(void); -}; -/// @brief Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str -class DateTime : base::StaticClass { - public: - /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond. - /// - /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a separate implementation is provided - /// @param [in,out] tv Pointer that gets updated - static void gettimeofday(struct timeval* tv); - - /// @brief Gets current date and time with a subsecond part. - /// @param format User provided date/time format - /// @param ssPrec A pointer to base::SubsecondPrecision from configuration (non-null) - /// @returns string based date time in specified format. - static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec); - - /// @brief Converts timeval (struct from ctime) to string using specified format and subsecond precision - static std::string timevalToString(struct timeval tval, const char* format, - const el::base::SubsecondPrecision* ssPrec); - - /// @brief Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc - static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit); - - /// @brief Gets time difference in milli/micro second depending on timestampUnit - static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime, - base::TimestampUnit timestampUnit); - - - static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo); - private: - static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo, - std::size_t msec, const base::SubsecondPrecision* ssPrec); -}; -/// @brief Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGINGPP(..) -class CommandLineArgs { - public: - CommandLineArgs(void) { - setArgs(0, static_cast<char**>(nullptr)); - } - CommandLineArgs(int argc, const char** argv) { - setArgs(argc, argv); - } - CommandLineArgs(int argc, char** argv) { - setArgs(argc, argv); - } - virtual ~CommandLineArgs(void) {} - /// @brief Sets arguments and parses them - inline void setArgs(int argc, const char** argv) { - setArgs(argc, const_cast<char**>(argv)); - } - /// @brief Sets arguments and parses them - void setArgs(int argc, char** argv); - /// @brief Returns true if arguments contain paramKey with a value (separated by '=') - bool hasParamWithValue(const char* paramKey) const; - /// @brief Returns value of arguments - /// @see hasParamWithValue(const char*) - const char* getParamValue(const char* paramKey) const; - /// @brief Return true if arguments has a param (not having a value) i,e without '=' - bool hasParam(const char* paramKey) const; - /// @brief Returns true if no params available. This exclude argv[0] - bool empty(void) const; - /// @brief Returns total number of arguments. This exclude argv[0] - std::size_t size(void) const; - friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c); - - private: - int m_argc; - char** m_argv; - std::unordered_map<std::string, std::string> m_paramsWithValue; - std::vector<std::string> m_params; -}; -/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type. -/// -/// @detail Most of the functions are virtual final methods but anything implementing this abstract class should implement -/// unregisterAll() and deepCopy(const AbstractRegistry<T_Ptr, Container>&) and write registerNew() method according to container -/// and few more methods; get() to find element, unregister() to unregister single entry. -/// Please note that this is thread-unsafe and should also implement thread-safety mechanisms in implementation. -template <typename T_Ptr, typename Container> -class AbstractRegistry : public base::threading::ThreadSafe { - public: - typedef typename Container::iterator iterator; - typedef typename Container::const_iterator const_iterator; - - /// @brief Default constructor - AbstractRegistry(void) {} - - /// @brief Move constructor that is useful for base classes - AbstractRegistry(AbstractRegistry&& sr) { - if (this == &sr) { - return; - } - unregisterAll(); - m_list = std::move(sr.m_list); - } - - bool operator==(const AbstractRegistry<T_Ptr, Container>& other) { - if (size() != other.size()) { - return false; - } - for (std::size_t i = 0; i < m_list.size(); ++i) { - if (m_list.at(i) != other.m_list.at(i)) { - return false; - } - } - return true; - } - - bool operator!=(const AbstractRegistry<T_Ptr, Container>& other) { - if (size() != other.size()) { - return true; - } - for (std::size_t i = 0; i < m_list.size(); ++i) { - if (m_list.at(i) != other.m_list.at(i)) { - return true; - } - } - return false; - } - - /// @brief Assignment move operator - AbstractRegistry& operator=(AbstractRegistry&& sr) { - if (this == &sr) { - return *this; - } - unregisterAll(); - m_list = std::move(sr.m_list); - return *this; - } - - virtual ~AbstractRegistry(void) { - } - - /// @return Iterator pointer from start of repository - virtual inline iterator begin(void) ELPP_FINAL { - return m_list.begin(); - } - - /// @return Iterator pointer from end of repository - virtual inline iterator end(void) ELPP_FINAL { - return m_list.end(); - } - - - /// @return Constant iterator pointer from start of repository - virtual inline const_iterator cbegin(void) const ELPP_FINAL { - return m_list.cbegin(); - } - - /// @return End of repository - virtual inline const_iterator cend(void) const ELPP_FINAL { - return m_list.cend(); - } - - /// @return Whether or not repository is empty - virtual inline bool empty(void) const ELPP_FINAL { - return m_list.empty(); - } - - /// @return Size of repository - virtual inline std::size_t size(void) const ELPP_FINAL { - return m_list.size(); - } - - /// @brief Returns underlying container by reference - virtual inline Container& list(void) ELPP_FINAL { - return m_list; - } - - /// @brief Returns underlying container by constant reference. - virtual inline const Container& list(void) const ELPP_FINAL { - return m_list; - } - - /// @brief Unregisters all the pointers from current repository. - virtual void unregisterAll(void) = 0; - - protected: - virtual void deepCopy(const AbstractRegistry<T_Ptr, Container>&) = 0; - void reinitDeepCopy(const AbstractRegistry<T_Ptr, Container>& sr) { - unregisterAll(); - deepCopy(sr); - } - - private: - Container m_list; -}; - -/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate version) -/// -/// @detail NOTE: This is thread-unsafe implementation (although it contains lock function, it does not use these functions) -/// of AbstractRegistry<T_Ptr, Container>. Any implementation of this class should be -/// explicitly (by using lock functions) -template <typename T_Ptr, typename T_Key = const char*> -class Registry : public AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>> { - public: - typedef typename Registry<T_Ptr, T_Key>::iterator iterator; - typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator; - - Registry(void) {} - - /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. - Registry(const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() { - if (this == &sr) { - return; - } - this->reinitDeepCopy(sr); - } - - /// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element - /// @see unregisterAll() - /// @see deepCopy(const AbstractRegistry&) - Registry& operator=(const Registry& sr) { - if (this == &sr) { - return *this; - } - this->reinitDeepCopy(sr); - return *this; - } - - virtual ~Registry(void) { - unregisterAll(); - } - - protected: - virtual void unregisterAll(void) ELPP_FINAL { - if (!this->empty()) { - for (auto&& curr : this->list()) { - base::utils::safeDelete(curr.second); - } - this->list().clear(); - } - } - -/// @brief Registers new registry to repository. - virtual void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL { - unregister(uniqKey); - this->list().insert(std::make_pair(uniqKey, ptr)); - } - -/// @brief Unregisters single entry mapped to specified unique key - void unregister(const T_Key& uniqKey) { - T_Ptr* existing = get(uniqKey); - if (existing != nullptr) { - this->list().erase(uniqKey); - base::utils::safeDelete(existing); - } - } - -/// @brief Gets pointer from repository. If none found, nullptr is returned. - T_Ptr* get(const T_Key& uniqKey) { - iterator it = this->list().find(uniqKey); - return it == this->list().end() - ? nullptr - : it->second; - } - - private: - virtual void deepCopy(const AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>>& sr) ELPP_FINAL { - for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) { - registerNew(it->first, new T_Ptr(*it->second)); - } - } -}; - -/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (predicate version) -/// -/// @detail NOTE: This is thread-unsafe implementation of AbstractRegistry<T_Ptr, Container>. Any implementation of this class -/// should be made thread-safe explicitly -template <typename T_Ptr, typename Pred> -class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> { - public: - typedef typename RegistryWithPred<T_Ptr, Pred>::iterator iterator; - typedef typename RegistryWithPred<T_Ptr, Pred>::const_iterator const_iterator; - - RegistryWithPred(void) { - } - - virtual ~RegistryWithPred(void) { - unregisterAll(); - } - - /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. - RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() { - if (this == &sr) { - return; - } - this->reinitDeepCopy(sr); - } - - /// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element - /// @see unregisterAll() - /// @see deepCopy(const AbstractRegistry&) - RegistryWithPred& operator=(const RegistryWithPred& sr) { - if (this == &sr) { - return *this; - } - this->reinitDeepCopy(sr); - return *this; - } - - friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const RegistryWithPred& sr) { - for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { - os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n"); - } - return os; - } - - protected: - virtual void unregisterAll(void) ELPP_FINAL { - if (!this->empty()) { - for (auto&& curr : this->list()) { - base::utils::safeDelete(curr); - } - this->list().clear(); - } - } - - virtual void unregister(T_Ptr*& ptr) ELPP_FINAL { - if (ptr) { - iterator iter = this->begin(); - for (; iter != this->end(); ++iter) { - if (ptr == *iter) { - break; - } - } - if (iter != this->end() && *iter != nullptr) { - this->list().erase(iter); - base::utils::safeDelete(*iter); - } - } - } - - virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL { - this->list().push_back(ptr); - } - -/// @brief Gets pointer from repository with specified arguments. Arguments are passed to predicate -/// in order to validate pointer. - template <typename T, typename T2> - T_Ptr* get(const T& arg1, const T2 arg2) { - iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2)); - if (iter != this->list().end() && *iter != nullptr) { - return *iter; - } - return nullptr; - } - - private: - virtual void deepCopy(const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr) { - for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { - registerNew(new T_Ptr(**it)); - } - } -}; -class Utils { - public: - template <typename T, typename TPtr> - static bool installCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) { - if (mapT->find(id) == mapT->end()) { - mapT->insert(std::make_pair(id, TPtr(new T()))); - return true; - } - return false; - } - - template <typename T, typename TPtr> - static void uninstallCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) { - if (mapT->find(id) != mapT->end()) { - mapT->erase(id); - } - } - - template <typename T, typename TPtr> - static T* callback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) { - typename std::unordered_map<std::string, TPtr>::iterator iter = mapT->find(id); - if (iter != mapT->end()) { - return static_cast<T*>(iter->second.get()); - } - return nullptr; - } -}; -} // namespace utils -} // namespace base -/// @brief Base of Easylogging++ friendly class -/// -/// @detail After inheriting this class publicly, implement pure-virtual function `void log(std::ostream&) const` -class Loggable { - public: - virtual ~Loggable(void) {} - virtual void log(el::base::type::ostream_t&) const = 0; - private: - friend inline el::base::type::ostream_t& operator<<(el::base::type::ostream_t& os, const Loggable& loggable) { - loggable.log(os); - return os; - } -}; -namespace base { -/// @brief Represents log format containing flags and date format. This is used internally to start initial log -class LogFormat : public Loggable { - public: - LogFormat(void); - LogFormat(Level level, const base::type::string_t& format); - LogFormat(const LogFormat& logFormat); - LogFormat(LogFormat&& logFormat); - LogFormat& operator=(const LogFormat& logFormat); - virtual ~LogFormat(void) {} - bool operator==(const LogFormat& other); - - /// @brief Updates format to be used while logging. - /// @param userFormat User provided format - void parseFromFormat(const base::type::string_t& userFormat); - - inline Level level(void) const { - return m_level; - } - - inline const base::type::string_t& userFormat(void) const { - return m_userFormat; - } - - inline const base::type::string_t& format(void) const { - return m_format; - } - - inline const std::string& dateTimeFormat(void) const { - return m_dateTimeFormat; - } - - inline base::type::EnumType flags(void) const { - return m_flags; - } - - inline bool hasFlag(base::FormatFlags flag) const { - return base::utils::hasFlag(flag, m_flags); - } - - virtual void log(el::base::type::ostream_t& os) const { - os << m_format; - } - - protected: - /// @brief Updates date time format if available in currFormat. - /// @param index Index where %datetime, %date or %time was found - /// @param [in,out] currFormat current format that is being used to format - virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL; - - /// @brief Updates %level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level - virtual void updateFormatSpec(void) ELPP_FINAL; - - inline void addFlag(base::FormatFlags flag) { - base::utils::addFlag(flag, &m_flags); - } - - private: - Level m_level; - base::type::string_t m_userFormat; - base::type::string_t m_format; - std::string m_dateTimeFormat; - base::type::EnumType m_flags; - std::string m_currentUser; - std::string m_currentHost; - friend class el::Logger; // To resolve loggerId format specifier easily -}; -} // namespace base -/// @brief Resolving function for format specifier -typedef std::function<std::string(const LogMessage*)> FormatSpecifierValueResolver; -/// @brief User-provided custom format specifier -/// @see el::Helpers::installCustomFormatSpecifier -/// @see FormatSpecifierValueResolver -class CustomFormatSpecifier { - public: - CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) : - m_formatSpecifier(formatSpecifier), m_resolver(resolver) {} - inline const char* formatSpecifier(void) const { - return m_formatSpecifier; - } - inline const FormatSpecifierValueResolver& resolver(void) const { - return m_resolver; - } - inline bool operator==(const char* formatSpecifier) { - return strcmp(m_formatSpecifier, formatSpecifier) == 0; - } - - private: - const char* m_formatSpecifier; - FormatSpecifierValueResolver m_resolver; -}; -/// @brief Represents single configuration that has representing level, configuration type and a string based value. -/// -/// @detail String based value means any value either its boolean, integer or string itself, it will be embedded inside quotes -/// and will be parsed later. -/// -/// Consider some examples below: -/// * el::Configuration confEnabledInfo(el::Level::Info, el::ConfigurationType::Enabled, "true"); -/// * el::Configuration confMaxLogFileSizeInfo(el::Level::Info, el::ConfigurationType::MaxLogFileSize, "2048"); -/// * el::Configuration confFilenameInfo(el::Level::Info, el::ConfigurationType::Filename, "/var/log/my.log"); -class Configuration : public Loggable { - public: - Configuration(const Configuration& c); - Configuration& operator=(const Configuration& c); - - virtual ~Configuration(void) { - } - - /// @brief Full constructor used to sets value of configuration - Configuration(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Gets level of current configuration - inline Level level(void) const { - return m_level; - } - - /// @brief Gets configuration type of current configuration - inline ConfigurationType configurationType(void) const { - return m_configurationType; - } - - /// @brief Gets string based configuration value - inline const std::string& value(void) const { - return m_value; - } - - /// @brief Set string based configuration value - /// @param value Value to set. Values have to be std::string; For boolean values use "true", "false", for any integral values - /// use them in quotes. They will be parsed when configuring - inline void setValue(const std::string& value) { - m_value = value; - } - - virtual void log(el::base::type::ostream_t& os) const; - - /// @brief Used to find configuration from configuration (pointers) repository. Avoid using it. - class Predicate { - public: - Predicate(Level level, ConfigurationType configurationType); - - bool operator()(const Configuration* conf) const; - - private: - Level m_level; - ConfigurationType m_configurationType; - }; - - private: - Level m_level; - ConfigurationType m_configurationType; - std::string m_value; -}; - -/// @brief Thread-safe Configuration repository -/// -/// @detail This repository represents configurations for all the levels and configuration type mapped to a value. -class Configurations : public base::utils::RegistryWithPred<Configuration, Configuration::Predicate> { - public: - /// @brief Default constructor with empty repository - Configurations(void); - - /// @brief Constructor used to set configurations using configuration file. - /// @param configurationFile Full path to configuration file - /// @param useDefaultsForRemaining Lets you set the remaining configurations to default. - /// @param base If provided, this configuration will be based off existing repository that this argument is pointing to. - /// @see parseFromFile(const std::string&, Configurations* base) - /// @see setRemainingToDefault() - Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true, - Configurations* base = nullptr); - - virtual ~Configurations(void) { - } - - /// @brief Parses configuration from file. - /// @param configurationFile Full path to configuration file - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration file. - /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you - /// do not proceed without successful parse. - bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr); - - /// @brief Parse configurations from configuration string. - /// - /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary - /// new line characters are provided. - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration text. - /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you - /// do not proceed without successful parse. - bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr); - - /// @brief Sets configuration based-off an existing configurations. - /// @param base Pointer to existing configurations. - void setFromBase(Configurations* base); - - /// @brief Determines whether or not specified configuration type exists in the repository. - /// - /// @detail Returns as soon as first level is found. - /// @param configurationType Type of configuration to check existence for. - bool hasConfiguration(ConfigurationType configurationType); - - /// @brief Determines whether or not specified configuration type exists for specified level - /// @param level Level to check - /// @param configurationType Type of configuration to check existence for. - bool hasConfiguration(Level level, ConfigurationType configurationType); - - /// @brief Sets value of configuration for specified level. - /// - /// @detail Any existing configuration for specified level will be replaced. Also note that configuration types - /// ConfigurationType::SubsecondPrecision and ConfigurationType::PerformanceTracking will be ignored if not set for - /// Level::Global because these configurations are not dependant on level. - /// @param level Level to set configuration for (el::Level). - /// @param configurationType Type of configuration (el::ConfigurationType) - /// @param value A string based value. Regardless of what the data type of configuration is, it will always be string - /// from users' point of view. This is then parsed later to be used internally. - /// @see Configuration::setValue(const std::string& value) - /// @see el::Level - /// @see el::ConfigurationType - void set(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Sets single configuration based on other single configuration. - /// @see set(Level level, ConfigurationType configurationType, const std::string& value) - void set(Configuration* conf); - - inline Configuration* get(Level level, ConfigurationType configurationType) { - base::threading::ScopedLock scopedLock(lock()); - return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType); - } - - /// @brief Sets configuration for all levels. - /// @param configurationType Type of configuration - /// @param value String based value - /// @see Configurations::set(Level level, ConfigurationType configurationType, const std::string& value) - inline void setGlobally(ConfigurationType configurationType, const std::string& value) { - setGlobally(configurationType, value, false); - } - - /// @brief Clears repository so that all the configurations are unset - inline void clear(void) { - base::threading::ScopedLock scopedLock(lock()); - unregisterAll(); - } - - /// @brief Gets configuration file used in parsing this configurations. - /// - /// @detail If this repository was set manually or by text this returns empty string. - inline const std::string& configurationFile(void) const { - return m_configurationFile; - } - - /// @brief Sets configurations to "factory based" configurations. - void setToDefault(void); - - /// @brief Lets you set the remaining configurations to default. - /// - /// @detail By remaining, it means that the level/type a configuration does not exist for. - /// This function is useful when you want to minimize chances of failures, e.g, if you have a configuration file that sets - /// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is set to default i.e, - /// true. If you dont do this explicitly (either by calling this function or by using second param in Constructor - /// and try to access a value, an error is thrown - void setRemainingToDefault(void); - - /// @brief Parser used internally to parse configurations from file or text. - /// - /// @detail This class makes use of base::utils::Str. - /// You should not need this unless you are working on some tool for Easylogging++ - class Parser : base::StaticClass { - public: - /// @brief Parses configuration from file. - /// @param configurationFile Full path to configuration file - /// @param sender Sender configurations pointer. Usually 'this' is used from calling class - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration file. - /// @return True if successfully parsed, false otherwise. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you - /// do not proceed without successful parse. - static bool parseFromFile(const std::string& configurationFile, Configurations* sender, - Configurations* base = nullptr); - - /// @brief Parse configurations from configuration string. - /// - /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary - /// new line characters are provided. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you - /// do not proceed without successful parse (This is recommended) - /// @param configurationsString the configuration in plain text format - /// @param sender Sender configurations pointer. Usually 'this' is used from calling class - /// @param base Configurations to base new configuration repository off. This value is used when you want to use - /// existing Configurations to base all the values and then set rest of configuration via configuration text. - /// @return True if successfully parsed, false otherwise. - static bool parseFromText(const std::string& configurationsString, Configurations* sender, - Configurations* base = nullptr); - - private: - friend class el::Loggers; - static void ignoreComments(std::string* line); - static bool isLevel(const std::string& line); - static bool isComment(const std::string& line); - static inline bool isConfig(const std::string& line); - static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel, - Configurations* conf); - }; - - private: - std::string m_configurationFile; - bool m_isFromFile; - friend class el::Loggers; - - /// @brief Unsafely sets configuration if does not already exist - void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Thread unsafe set - void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value); - - /// @brief Sets configurations for all levels including Level::Global if includeGlobalLevel is true - /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) - void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel); - - /// @brief Sets configurations (Unsafely) for all levels including Level::Global if includeGlobalLevel is true - /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) - void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel); -}; - -namespace base { -typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr; -typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap; -typedef std::shared_ptr<base::LogStreamsReferenceMap> LogStreamsReferenceMapPtr; -/// @brief Configurations with data types. -/// -/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations. -/// This is to perform faster while writing logs using correct configurations. -/// -/// This is thread safe and final class containing non-virtual destructor (means nothing should inherit this class) -class TypedConfigurations : public base::threading::ThreadSafe { - public: - /// @brief Constructor to initialize (construct) the object off el::Configurations - /// @param configurations Configurations pointer/reference to base this typed configurations off. - /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference() - TypedConfigurations(Configurations* configurations, LogStreamsReferenceMapPtr logStreamsReference); - - TypedConfigurations(const TypedConfigurations& other); - - virtual ~TypedConfigurations(void) { - } - - const Configurations* configurations(void) const { - return m_configurations; - } - - bool enabled(Level level); - bool toFile(Level level); - const std::string& filename(Level level); - bool toStandardOutput(Level level); - const base::LogFormat& logFormat(Level level); - const base::SubsecondPrecision& subsecondPrecision(Level level = Level::Global); - const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global); - bool performanceTracking(Level level = Level::Global); - base::type::fstream_t* fileStream(Level level); - std::size_t maxLogFileSize(Level level); - std::size_t logFlushThreshold(Level level); - - private: - Configurations* m_configurations; - std::unordered_map<Level, bool> m_enabledMap; - std::unordered_map<Level, bool> m_toFileMap; - std::unordered_map<Level, std::string> m_filenameMap; - std::unordered_map<Level, bool> m_toStandardOutputMap; - std::unordered_map<Level, base::LogFormat> m_logFormatMap; - std::unordered_map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap; - std::unordered_map<Level, bool> m_performanceTrackingMap; - std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap; - std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap; - std::unordered_map<Level, std::size_t> m_logFlushThresholdMap; - LogStreamsReferenceMapPtr m_logStreamsReference = nullptr; - - friend class el::Helpers; - friend class el::base::MessageBuilder; - friend class el::base::Writer; - friend class el::base::DefaultLogDispatchCallback; - friend class el::base::LogDispatcher; - - template <typename Conf_T> - inline Conf_T getConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) { - base::threading::ScopedLock scopedLock(lock()); - return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope - } - - template <typename Conf_T> - inline Conf_T& getConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) { - base::threading::ScopedLock scopedLock(lock()); - return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope - } - - template <typename Conf_T> - Conf_T unsafeGetConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) { - ELPP_UNUSED(confName); - typename std::unordered_map<Level, Conf_T>::const_iterator it = confMap->find(level); - if (it == confMap->end()) { - try { - return confMap->at(Level::Global); - } catch (...) { - ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" - << LevelHelper::convertToString(level) << "]" - << std::endl << "Please ensure you have properly configured logger.", false); - return Conf_T(); - } - } - return it->second; - } - - template <typename Conf_T> - Conf_T& unsafeGetConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) { - ELPP_UNUSED(confName); - typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(level); - if (it == confMap->end()) { - try { - return confMap->at(Level::Global); - } catch (...) { - ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" - << LevelHelper::convertToString(level) << "]" - << std::endl << "Please ensure you have properly configured logger.", false); - } - } - return it->second; - } - - template <typename Conf_T> - void setValue(Level level, const Conf_T& value, std::unordered_map<Level, Conf_T>* confMap, - bool includeGlobalLevel = true) { - // If map is empty and we are allowed to add into generic level (Level::Global), do it! - if (confMap->empty() && includeGlobalLevel) { - confMap->insert(std::make_pair(Level::Global, value)); - return; - } - // If same value exist in generic level already, dont add it to explicit level - typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(Level::Global); - if (it != confMap->end() && it->second == value) { - return; - } - // Now make sure we dont double up values if we really need to add it to explicit level - it = confMap->find(level); - if (it == confMap->end()) { - // Value not found for level, add new - confMap->insert(std::make_pair(level, value)); - } else { - // Value found, just update value - confMap->at(level) = value; - } - } - - void build(Configurations* configurations); - unsigned long getULong(std::string confVal); - std::string resolveFilename(const std::string& filename); - void insertFile(Level level, const std::string& fullFilename); - bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback); - - inline bool validateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) { - base::threading::ScopedLock scopedLock(lock()); - return unsafeValidateFileRolling(level, preRollOutCallback); - } -}; -/// @brief Class that keeps record of current line hit for occasional logging -class HitCounter { - public: - HitCounter(void) : - m_filename(""), - m_lineNumber(0), - m_hitCounts(0) { - } - - HitCounter(const char* filename, base::type::LineNumber lineNumber) : - m_filename(filename), - m_lineNumber(lineNumber), - m_hitCounts(0) { - } - - HitCounter(const HitCounter& hitCounter) : - m_filename(hitCounter.m_filename), - m_lineNumber(hitCounter.m_lineNumber), - m_hitCounts(hitCounter.m_hitCounts) { - } - - HitCounter& operator=(const HitCounter& hitCounter) { - if (&hitCounter != this) { - m_filename = hitCounter.m_filename; - m_lineNumber = hitCounter.m_lineNumber; - m_hitCounts = hitCounter.m_hitCounts; - } - return *this; - } - - virtual ~HitCounter(void) { - } - - /// @brief Resets location of current hit counter - inline void resetLocation(const char* filename, base::type::LineNumber lineNumber) { - m_filename = filename; - m_lineNumber = lineNumber; - } - - /// @brief Validates hit counts and resets it if necessary - inline void validateHitCounts(std::size_t n) { - if (m_hitCounts >= base::consts::kMaxLogPerCounter) { - m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0); - } - ++m_hitCounts; - } - - inline const char* filename(void) const { - return m_filename; - } - - inline base::type::LineNumber lineNumber(void) const { - return m_lineNumber; - } - - inline std::size_t hitCounts(void) const { - return m_hitCounts; - } - - inline void increment(void) { - ++m_hitCounts; - } - - class Predicate { - public: - Predicate(const char* filename, base::type::LineNumber lineNumber) - : m_filename(filename), - m_lineNumber(lineNumber) { - } - inline bool operator()(const HitCounter* counter) { - return ((counter != nullptr) && - (strcmp(counter->m_filename, m_filename) == 0) && - (counter->m_lineNumber == m_lineNumber)); - } - - private: - const char* m_filename; - base::type::LineNumber m_lineNumber; - }; - - private: - const char* m_filename; - base::type::LineNumber m_lineNumber; - std::size_t m_hitCounts; -}; -/// @brief Repository for hit counters used across the application -class RegisteredHitCounters : public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate> { - public: - /// @brief Validates counter for every N, i.e, registers new if does not exist otherwise updates original one - /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned - bool validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n); - - /// @brief Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one - /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned - bool validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n); - - /// @brief Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original one - /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned - bool validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n); - - /// @brief Gets hit counter registered at specified position - inline const base::HitCounter* getCounter(const char* filename, base::type::LineNumber lineNumber) { - base::threading::ScopedLock scopedLock(lock()); - return get(filename, lineNumber); - } -}; -/// @brief Action to be taken for dispatching -enum class DispatchAction : base::type::EnumType { - None = 1, NormalLog = 2, SysLog = 4 -}; -} // namespace base -template <typename T> -class Callback : protected base::threading::ThreadSafe { - public: - Callback(void) : m_enabled(true) {} - inline bool enabled(void) const { - return m_enabled; - } - inline void setEnabled(bool enabled) { - base::threading::ScopedLock scopedLock(lock()); - m_enabled = enabled; - } - protected: - virtual void handle(const T* handlePtr) = 0; - private: - bool m_enabled; -}; -class LogDispatchData { - public: - LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {} - inline const LogMessage* logMessage(void) const { - return m_logMessage; - } - inline base::DispatchAction dispatchAction(void) const { - return m_dispatchAction; - } - inline void setLogMessage(LogMessage* logMessage) { - m_logMessage = logMessage; - } - inline void setDispatchAction(base::DispatchAction dispatchAction) { - m_dispatchAction = dispatchAction; - } - private: - LogMessage* m_logMessage; - base::DispatchAction m_dispatchAction; - friend class base::LogDispatcher; - -}; -class LogDispatchCallback : public Callback<LogDispatchData> { - protected: - virtual void handle(const LogDispatchData* data); - base::threading::Mutex& fileHandle(const LogDispatchData* data); - private: - friend class base::LogDispatcher; - std::unordered_map<std::string, std::unique_ptr<base::threading::Mutex>> m_fileLocks; - base::threading::Mutex m_fileLocksMapLock; -}; -class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> { - private: - friend class base::PerformanceTracker; -}; -class LoggerRegistrationCallback : public Callback<Logger> { - private: - friend class base::RegisteredLoggers; -}; -class LogBuilder : base::NoCopy { - public: - LogBuilder() : m_termSupportsColor(base::utils::OS::termSupportsColor()) {} - virtual ~LogBuilder(void) { - ELPP_INTERNAL_INFO(3, "Destroying log builder...") - } - virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0; - void convertToColoredOutput(base::type::string_t* logLine, Level level); - private: - bool m_termSupportsColor; - friend class el::base::DefaultLogDispatchCallback; -}; -typedef std::shared_ptr<LogBuilder> LogBuilderPtr; -/// @brief Represents a logger holding ID and configurations we need to write logs -/// -/// @detail This class does not write logs itself instead its used by writer to read configurations from. -class Logger : public base::threading::ThreadSafe, public Loggable { - public: - Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference); - Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMapPtr logStreamsReference); - Logger(const Logger& logger); - Logger& operator=(const Logger& logger); - - virtual ~Logger(void) { - base::utils::safeDelete(m_typedConfigurations); - } - - virtual inline void log(el::base::type::ostream_t& os) const { - os << m_id.c_str(); - } - - /// @brief Configures the logger using specified configurations. - void configure(const Configurations& configurations); - - /// @brief Reconfigures logger using existing configurations - void reconfigure(void); - - inline const std::string& id(void) const { - return m_id; - } - - inline const std::string& parentApplicationName(void) const { - return m_parentApplicationName; - } - - inline void setParentApplicationName(const std::string& parentApplicationName) { - m_parentApplicationName = parentApplicationName; - } - - inline Configurations* configurations(void) { - return &m_configurations; - } - - inline base::TypedConfigurations* typedConfigurations(void) { - return m_typedConfigurations; - } - - static bool isValidId(const std::string& id); - - /// @brief Flushes logger to sync all log files for all levels - void flush(void); - - void flush(Level level, base::type::fstream_t* fs); - - inline bool isFlushNeeded(Level level) { - return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level); - } - - inline LogBuilder* logBuilder(void) const { - return m_logBuilder.get(); - } - - inline void setLogBuilder(const LogBuilderPtr& logBuilder) { - m_logBuilder = logBuilder; - } - - inline bool enabled(Level level) const { - return m_typedConfigurations->enabled(level); - } - -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED -# define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\ -template <typename T, typename... Args>\ -inline void FUNCTION_NAME(const char*, const T&, const Args&...);\ -template <typename T>\ -inline void FUNCTION_NAME(const T&); - - template <typename T, typename... Args> - inline void verbose(int, const char*, const T&, const Args&...); - - template <typename T> - inline void verbose(int, const T&); - - LOGGER_LEVEL_WRITERS_SIGNATURES(info) - LOGGER_LEVEL_WRITERS_SIGNATURES(debug) - LOGGER_LEVEL_WRITERS_SIGNATURES(warn) - LOGGER_LEVEL_WRITERS_SIGNATURES(error) - LOGGER_LEVEL_WRITERS_SIGNATURES(fatal) - LOGGER_LEVEL_WRITERS_SIGNATURES(trace) -# undef LOGGER_LEVEL_WRITERS_SIGNATURES -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED - private: - std::string m_id; - base::TypedConfigurations* m_typedConfigurations; - base::type::stringstream_t m_stream; - std::string m_parentApplicationName; - bool m_isConfigured; - Configurations m_configurations; - std::unordered_map<Level, unsigned int> m_unflushedCount; - base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr; - LogBuilderPtr m_logBuilder; - - friend class el::LogMessage; - friend class el::Loggers; - friend class el::Helpers; - friend class el::base::RegisteredLoggers; - friend class el::base::DefaultLogDispatchCallback; - friend class el::base::MessageBuilder; - friend class el::base::Writer; - friend class el::base::PErrorWriter; - friend class el::base::Storage; - friend class el::base::PerformanceTracker; - friend class el::base::LogDispatcher; - - Logger(void); - -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED - template <typename T, typename... Args> - void log_(Level, int, const char*, const T&, const Args&...); - - template <typename T> - inline void log_(Level, int, const T&); - - template <typename T, typename... Args> - void log(Level, const char*, const T&, const Args&...); - - template <typename T> - inline void log(Level, const T&); -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED - - void initUnflushedCount(void); - - inline base::type::stringstream_t& stream(void) { - return m_stream; - } - - void resolveLoggerFormatSpec(void) const; -}; -namespace base { -/// @brief Loggers repository -class RegisteredLoggers : public base::utils::Registry<Logger, std::string> { - public: - explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder); - - virtual ~RegisteredLoggers(void) { - unsafeFlushAll(); - } - - inline void setDefaultConfigurations(const Configurations& configurations) { - base::threading::ScopedLock scopedLock(lock()); - m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations)); - } - - inline Configurations* defaultConfigurations(void) { - return &m_defaultConfigurations; - } - - Logger* get(const std::string& id, bool forceCreation = true); - - template <typename T> - inline bool installLoggerRegistrationCallback(const std::string& id) { - return base::utils::Utils::installCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, - &m_loggerRegistrationCallbacks); - } - - template <typename T> - inline void uninstallLoggerRegistrationCallback(const std::string& id) { - base::utils::Utils::uninstallCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks); - } - - template <typename T> - inline T* loggerRegistrationCallback(const std::string& id) { - return base::utils::Utils::callback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks); - } - - bool remove(const std::string& id); - - inline bool has(const std::string& id) { - return get(id, false) != nullptr; - } - - inline void unregister(Logger*& logger) { - base::threading::ScopedLock scopedLock(lock()); - base::utils::Registry<Logger, std::string>::unregister(logger->id()); - } - - inline LogStreamsReferenceMapPtr logStreamsReference(void) { - return m_logStreamsReference; - } - - inline void flushAll(void) { - base::threading::ScopedLock scopedLock(lock()); - unsafeFlushAll(); - } - - inline void setDefaultLogBuilder(LogBuilderPtr& logBuilderPtr) { - base::threading::ScopedLock scopedLock(lock()); - m_defaultLogBuilder = logBuilderPtr; - } - - private: - LogBuilderPtr m_defaultLogBuilder; - Configurations m_defaultConfigurations; - base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr; - std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks; - friend class el::base::Storage; - - void unsafeFlushAll(void); -}; -/// @brief Represents registries for verbose logging -class VRegistry : base::NoCopy, public base::threading::ThreadSafe { - public: - explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags); - - /// @brief Sets verbose level. Accepted range is 0-9 - void setLevel(base::type::VerboseLevel level); - - inline base::type::VerboseLevel level(void) const { - return m_level; - } - - inline void clearModules(void) { - base::threading::ScopedLock scopedLock(lock()); - m_modules.clear(); - } - - void setModules(const char* modules); - - bool allowed(base::type::VerboseLevel vlevel, const char* file); - - inline const std::unordered_map<std::string, base::type::VerboseLevel>& modules(void) const { - return m_modules; - } - - void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs); - - /// @brief Whether or not vModules enabled - inline bool vModulesEnabled(void) { - return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags); - } - - private: - base::type::VerboseLevel m_level; - base::type::EnumType* m_pFlags; - std::unordered_map<std::string, base::type::VerboseLevel> m_modules; -}; -} // namespace base -class LogMessage { - public: - LogMessage(Level level, const std::string& file, base::type::LineNumber line, const std::string& func, - base::type::VerboseLevel verboseLevel, Logger* logger) : - m_level(level), m_file(file), m_line(line), m_func(func), - m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) { - } - inline Level level(void) const { - return m_level; - } - inline const std::string& file(void) const { - return m_file; - } - inline base::type::LineNumber line(void) const { - return m_line; - } - inline const std::string& func(void) const { - return m_func; - } - inline base::type::VerboseLevel verboseLevel(void) const { - return m_verboseLevel; - } - inline Logger* logger(void) const { - return m_logger; - } - inline const base::type::string_t& message(void) const { - return m_message; - } - private: - Level m_level; - std::string m_file; - base::type::LineNumber m_line; - std::string m_func; - base::type::VerboseLevel m_verboseLevel; - Logger* m_logger; - base::type::string_t m_message; -}; -namespace base { -#if ELPP_ASYNC_LOGGING -class AsyncLogItem { - public: - explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine) - : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {} - virtual ~AsyncLogItem() {} - inline LogMessage* logMessage(void) { - return &m_logMessage; - } - inline LogDispatchData* data(void) { - return &m_dispatchData; - } - inline base::type::string_t logLine(void) { - return m_logLine; - } - private: - LogMessage m_logMessage; - LogDispatchData m_dispatchData; - base::type::string_t m_logLine; -}; -class AsyncLogQueue : public base::threading::ThreadSafe { - public: - virtual ~AsyncLogQueue() { - ELPP_INTERNAL_INFO(6, "~AsyncLogQueue"); - } - - inline AsyncLogItem next(void) { - base::threading::ScopedLock scopedLock(lock()); - AsyncLogItem result = m_queue.front(); - m_queue.pop(); - return result; - } - - inline void push(const AsyncLogItem& item) { - base::threading::ScopedLock scopedLock(lock()); - m_queue.push(item); - } - inline void pop(void) { - base::threading::ScopedLock scopedLock(lock()); - m_queue.pop(); - } - inline AsyncLogItem front(void) { - base::threading::ScopedLock scopedLock(lock()); - return m_queue.front(); - } - inline bool empty(void) { - base::threading::ScopedLock scopedLock(lock()); - return m_queue.empty(); - } - private: - std::queue<AsyncLogItem> m_queue; -}; -class IWorker { - public: - virtual ~IWorker() {} - virtual void start() = 0; -}; -#endif // ELPP_ASYNC_LOGGING -/// @brief Easylogging++ management storage -class Storage : base::NoCopy, public base::threading::ThreadSafe { - public: -#if ELPP_ASYNC_LOGGING - Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker); -#else - explicit Storage(const LogBuilderPtr& defaultLogBuilder); -#endif // ELPP_ASYNC_LOGGING - - virtual ~Storage(void); - - inline bool validateEveryNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t occasion) { - return hitCounters()->validateEveryN(filename, lineNumber, occasion); - } - - inline bool validateAfterNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { - return hitCounters()->validateAfterN(filename, lineNumber, n); - } - - inline bool validateNTimesCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { - return hitCounters()->validateNTimes(filename, lineNumber, n); - } - - inline base::RegisteredHitCounters* hitCounters(void) const { - return m_registeredHitCounters; - } - - inline base::RegisteredLoggers* registeredLoggers(void) const { - return m_registeredLoggers; - } - - inline base::VRegistry* vRegistry(void) const { - return m_vRegistry; - } - -#if ELPP_ASYNC_LOGGING - inline base::AsyncLogQueue* asyncLogQueue(void) const { - return m_asyncLogQueue; - } -#endif // ELPP_ASYNC_LOGGING - - inline const base::utils::CommandLineArgs* commandLineArgs(void) const { - return &m_commandLineArgs; - } - - inline void addFlag(LoggingFlag flag) { - base::utils::addFlag(flag, &m_flags); - } - - inline void removeFlag(LoggingFlag flag) { - base::utils::removeFlag(flag, &m_flags); - } - - inline bool hasFlag(LoggingFlag flag) const { - return base::utils::hasFlag(flag, m_flags); - } - - inline base::type::EnumType flags(void) const { - return m_flags; - } - - inline void setFlags(base::type::EnumType flags) { - m_flags = flags; - } - - inline void setPreRollOutCallback(const PreRollOutCallback& callback) { - m_preRollOutCallback = callback; - } - - inline void unsetPreRollOutCallback(void) { - m_preRollOutCallback = base::defaultPreRollOutCallback; - } - - inline PreRollOutCallback& preRollOutCallback(void) { - return m_preRollOutCallback; - } - - bool hasCustomFormatSpecifier(const char* formatSpecifier); - void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier); - bool uninstallCustomFormatSpecifier(const char* formatSpecifier); - - const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(void) const { - return &m_customFormatSpecifiers; - } - - base::threading::Mutex& customFormatSpecifiersLock() { - return m_customFormatSpecifiersLock; - } - - inline void setLoggingLevel(Level level) { - m_loggingLevel = level; - } - - template <typename T> - inline bool installLogDispatchCallback(const std::string& id) { - return base::utils::Utils::installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks); - } - - template <typename T> - inline void uninstallLogDispatchCallback(const std::string& id) { - base::utils::Utils::uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks); - } - template <typename T> - inline T* logDispatchCallback(const std::string& id) { - return base::utils::Utils::callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks); - } - -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - template <typename T> - inline bool installPerformanceTrackingCallback(const std::string& id) { - return base::utils::Utils::installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, - &m_performanceTrackingCallbacks); - } - - template <typename T> - inline void uninstallPerformanceTrackingCallback(const std::string& id) { - base::utils::Utils::uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id, - &m_performanceTrackingCallbacks); - } - - template <typename T> - inline T* performanceTrackingCallback(const std::string& id) { - return base::utils::Utils::callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks); - } -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - - /// @brief Sets thread name for current thread. Requires std::thread - inline void setThreadName(const std::string& name) { - if (name.empty()) return; - base::threading::ScopedLock scopedLock(m_threadNamesLock); - m_threadNames[base::threading::getCurrentThreadId()] = name; - } - - inline std::string getThreadName(const std::string& threadId) { - base::threading::ScopedLock scopedLock(m_threadNamesLock); - std::unordered_map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId); - if (it == m_threadNames.end()) { - return threadId; - } - return it->second; - } - private: - base::RegisteredHitCounters* m_registeredHitCounters; - base::RegisteredLoggers* m_registeredLoggers; - base::type::EnumType m_flags; - base::VRegistry* m_vRegistry; -#if ELPP_ASYNC_LOGGING - base::AsyncLogQueue* m_asyncLogQueue; - base::IWorker* m_asyncDispatchWorker; -#endif // ELPP_ASYNC_LOGGING - base::utils::CommandLineArgs m_commandLineArgs; - PreRollOutCallback m_preRollOutCallback; - std::unordered_map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks; - std::unordered_map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks; - std::unordered_map<std::string, std::string> m_threadNames; - std::vector<CustomFormatSpecifier> m_customFormatSpecifiers; - base::threading::Mutex m_customFormatSpecifiersLock; - base::threading::Mutex m_threadNamesLock; - Level m_loggingLevel; - - friend class el::Helpers; - friend class el::base::DefaultLogDispatchCallback; - friend class el::LogBuilder; - friend class el::base::MessageBuilder; - friend class el::base::Writer; - friend class el::base::PerformanceTracker; - friend class el::base::LogDispatcher; - - void setApplicationArguments(int argc, char** argv); - - inline void setApplicationArguments(int argc, const char** argv) { - setApplicationArguments(argc, const_cast<char**>(argv)); - } -}; -extern ELPP_EXPORT base::type::StoragePointer elStorage; -#define ELPP el::base::elStorage -class DefaultLogDispatchCallback : public LogDispatchCallback { - protected: - void handle(const LogDispatchData* data); - private: - const LogDispatchData* m_data; - void dispatch(base::type::string_t&& logLine); -}; -#if ELPP_ASYNC_LOGGING -class AsyncLogDispatchCallback : public LogDispatchCallback { - protected: - void handle(const LogDispatchData* data); -}; -class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe { - public: - AsyncDispatchWorker(); - virtual ~AsyncDispatchWorker(); - - bool clean(void); - void emptyQueue(void); - virtual void start(void); - void handle(AsyncLogItem* logItem); - void run(void); - - void setContinueRunning(bool value) { - base::threading::ScopedLock scopedLock(m_continueRunningLock); - m_continueRunning = value; - } - - bool continueRunning(void) const { - return m_continueRunning; - } - private: - std::condition_variable cv; - bool m_continueRunning; - base::threading::Mutex m_continueRunningLock; -}; -#endif // ELPP_ASYNC_LOGGING -} // namespace base -namespace base { -class DefaultLogBuilder : public LogBuilder { - public: - base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const; -}; -/// @brief Dispatches log messages -class LogDispatcher : base::NoCopy { - public: - LogDispatcher(bool proceed, LogMessage* logMessage, base::DispatchAction dispatchAction) : - m_proceed(proceed), - m_logMessage(logMessage), - m_dispatchAction(std::move(dispatchAction)) { - } - - void dispatch(void); - - private: - bool m_proceed; - LogMessage* m_logMessage; - base::DispatchAction m_dispatchAction; -}; -#if defined(ELPP_STL_LOGGING) -/// @brief Workarounds to write some STL logs -/// -/// @detail There is workaround needed to loop through some stl containers. In order to do that, we need iterable containers -/// of same type and provide iterator interface and pass it on to writeIterator(). -/// Remember, this is passed by value in constructor so that we dont change original containers. -/// This operation is as expensive as Big-O(std::min(class_.size(), base::consts::kMaxLogPerContainer)) -namespace workarounds { -/// @brief Abstract IterableContainer template that provides interface for iterable classes of type T -template <typename T, typename Container> -class IterableContainer { - public: - typedef typename Container::iterator iterator; - typedef typename Container::const_iterator const_iterator; - IterableContainer(void) {} - virtual ~IterableContainer(void) {} - iterator begin(void) { - return getContainer().begin(); - } - iterator end(void) { - return getContainer().end(); - } - private: - virtual Container& getContainer(void) = 0; -}; -/// @brief Implements IterableContainer and provides iterable std::priority_queue class -template<typename T, typename Container = std::vector<T>, typename Comparator = std::less<typename Container::value_type>> -class IterablePriorityQueue : public IterableContainer<T, Container>, - public std::priority_queue<T, Container, Comparator> { - public: - IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_) { - std::size_t count_ = 0; - while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { - this->push(queue_.top()); - queue_.pop(); - } - } - private: - inline Container& getContainer(void) { - return this->c; - } -}; -/// @brief Implements IterableContainer and provides iterable std::queue class -template<typename T, typename Container = std::deque<T>> -class IterableQueue : public IterableContainer<T, Container>, public std::queue<T, Container> { - public: - IterableQueue(std::queue<T, Container> queue_) { - std::size_t count_ = 0; - while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { - this->push(queue_.front()); - queue_.pop(); - } - } - private: - inline Container& getContainer(void) { - return this->c; - } -}; -/// @brief Implements IterableContainer and provides iterable std::stack class -template<typename T, typename Container = std::deque<T>> -class IterableStack : public IterableContainer<T, Container>, public std::stack<T, Container> { - public: - IterableStack(std::stack<T, Container> stack_) { - std::size_t count_ = 0; - while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) { - this->push(stack_.top()); - stack_.pop(); - } - } - private: - inline Container& getContainer(void) { - return this->c; - } -}; -} // namespace workarounds -#endif // defined(ELPP_STL_LOGGING) -// Log message builder -class MessageBuilder { - public: - MessageBuilder(void) : m_logger(nullptr), m_containerLogSeparator(ELPP_LITERAL("")) {} - void initialize(Logger* logger); - -# define ELPP_SIMPLE_LOG(LOG_TYPE)\ -MessageBuilder& operator<<(LOG_TYPE msg) {\ -m_logger->stream() << msg;\ -if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\ -m_logger->stream() << " ";\ -}\ -return *this;\ -} - - inline MessageBuilder& operator<<(const std::string& msg) { - return operator<<(msg.c_str()); - } - ELPP_SIMPLE_LOG(char) - ELPP_SIMPLE_LOG(bool) - ELPP_SIMPLE_LOG(signed short) - ELPP_SIMPLE_LOG(unsigned short) - ELPP_SIMPLE_LOG(signed int) - ELPP_SIMPLE_LOG(unsigned int) - ELPP_SIMPLE_LOG(signed long) - ELPP_SIMPLE_LOG(unsigned long) - ELPP_SIMPLE_LOG(float) - ELPP_SIMPLE_LOG(double) - ELPP_SIMPLE_LOG(char*) - ELPP_SIMPLE_LOG(const char*) - ELPP_SIMPLE_LOG(const void*) - ELPP_SIMPLE_LOG(long double) - inline MessageBuilder& operator<<(const std::wstring& msg) { - return operator<<(msg.c_str()); - } - MessageBuilder& operator<<(const wchar_t* msg); - // ostream manipulators - inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) { - m_logger->stream() << OStreamMani; - return *this; - } -#define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \ -template <typename T> \ -inline MessageBuilder& operator<<(const temp<T>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \ -template <typename T1, typename T2> \ -inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \ -template <typename T1, typename T2, typename T3> \ -inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \ -template <typename T1, typename T2, typename T3, typename T4> \ -inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} -#define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \ -template <typename T1, typename T2, typename T3, typename T4, typename T5> \ -inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \ -return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ -} - -#if defined(ELPP_STL_LOGGING) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap) - template <class T, class Container> - inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_) { - base::workarounds::IterableQueue<T, Container> iterableQueue_ = - static_cast<base::workarounds::IterableQueue<T, Container> >(queue_); - return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size()); - } - template <class T, class Container> - inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_) { - base::workarounds::IterableStack<T, Container> iterableStack_ = - static_cast<base::workarounds::IterableStack<T, Container> >(stack_); - return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size()); - } - template <class T, class Container, class Comparator> - inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_) { - base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ = - static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator> >(priorityQueue_); - return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size()); - } - template <class First, class Second> - MessageBuilder& operator<<(const std::pair<First, Second>& pair_) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<First>(pair_.first)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<Second>(pair_.second)); - m_logger->stream() << ELPP_LITERAL(")"); - return *this; - } - template <std::size_t Size> - MessageBuilder& operator<<(const std::bitset<Size>& bitset_) { - m_logger->stream() << ELPP_LITERAL("["); - operator << (bitset_.to_string()); - m_logger->stream() << ELPP_LITERAL("]"); - return *this; - } -# if defined(ELPP_LOG_STD_ARRAY) - template <class T, std::size_t Size> - inline MessageBuilder& operator<<(const std::array<T, Size>& array) { - return writeIterator(array.begin(), array.end(), array.size()); - } -# endif // defined(ELPP_LOG_STD_ARRAY) -# if defined(ELPP_LOG_UNORDERED_MAP) - ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map) - ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap) -# endif // defined(ELPP_LOG_UNORDERED_MAP) -# if defined(ELPP_LOG_UNORDERED_SET) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset) -# endif // defined(ELPP_LOG_UNORDERED_SET) -#endif // defined(ELPP_STL_LOGGING) -#if defined(ELPP_QT_LOGGING) - inline MessageBuilder& operator<<(const QString& msg) { -# if defined(ELPP_UNICODE) - m_logger->stream() << msg.toStdWString(); -# else - m_logger->stream() << msg.toStdString(); -# endif // defined(ELPP_UNICODE) - return *this; - } - inline MessageBuilder& operator<<(const QByteArray& msg) { - return operator << (QString(msg)); - } - inline MessageBuilder& operator<<(const QStringRef& msg) { - return operator<<(msg.toString()); - } - inline MessageBuilder& operator<<(qint64 msg) { -# if defined(ELPP_UNICODE) - m_logger->stream() << QString::number(msg).toStdWString(); -# else - m_logger->stream() << QString::number(msg).toStdString(); -# endif // defined(ELPP_UNICODE) - return *this; - } - inline MessageBuilder& operator<<(quint64 msg) { -# if defined(ELPP_UNICODE) - m_logger->stream() << QString::number(msg).toStdWString(); -# else - m_logger->stream() << QString::number(msg).toStdString(); -# endif // defined(ELPP_UNICODE) - return *this; - } - inline MessageBuilder& operator<<(QChar msg) { - m_logger->stream() << msg.toLatin1(); - return *this; - } - inline MessageBuilder& operator<<(const QLatin1String& msg) { - m_logger->stream() << msg.latin1(); - return *this; - } - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack) - template <typename First, typename Second> - MessageBuilder& operator<<(const QPair<First, Second>& pair_) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<First>(pair_.first)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<Second>(pair_.second)); - m_logger->stream() << ELPP_LITERAL(")"); - return *this; - } - template <typename K, typename V> - MessageBuilder& operator<<(const QMap<K, V>& map_) { - m_logger->stream() << ELPP_LITERAL("["); - QList<K> keys = map_.keys(); - typename QList<K>::const_iterator begin = keys.begin(); - typename QList<K>::const_iterator end = keys.end(); - int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // to prevent warning - for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<K>(*begin)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<V>(map_.value(*begin))); - m_logger->stream() << ELPP_LITERAL(")"); - m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL("")); - } - if (begin != end) { - m_logger->stream() << ELPP_LITERAL("..."); - } - m_logger->stream() << ELPP_LITERAL("]"); - return *this; - } - template <typename K, typename V> - inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_) { - operator << (static_cast<QMap<K, V>>(map_)); - return *this; - } - template <typename K, typename V> - MessageBuilder& operator<<(const QHash<K, V>& hash_) { - m_logger->stream() << ELPP_LITERAL("["); - QList<K> keys = hash_.keys(); - typename QList<K>::const_iterator begin = keys.begin(); - typename QList<K>::const_iterator end = keys.end(); - int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // prevent type warning - for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { - m_logger->stream() << ELPP_LITERAL("("); - operator << (static_cast<K>(*begin)); - m_logger->stream() << ELPP_LITERAL(", "); - operator << (static_cast<V>(hash_.value(*begin))); - m_logger->stream() << ELPP_LITERAL(")"); - m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL("")); - } - if (begin != end) { - m_logger->stream() << ELPP_LITERAL("..."); - } - m_logger->stream() << ELPP_LITERAL("]"); - return *this; - } - template <typename K, typename V> - inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_) { - operator << (static_cast<QHash<K, V>>(multiHash_)); - return *this; - } -#endif // defined(ELPP_QT_LOGGING) -#if defined(ELPP_BOOST_LOGGING) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list) - ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map) - ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set) - ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set) -#endif // defined(ELPP_BOOST_LOGGING) - - /// @brief Macro used internally that can be used externally to make containers easylogging++ friendly - /// - /// @detail This macro expands to write an ostream& operator<< for container. This container is expected to - /// have begin() and end() methods that return respective iterators - /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets - /// @param SizeMethod Method used to get size of container. - /// @param ElementInstance Instance of element to be fed out. Instance name is "elem". See WXELPP_ENABLED macro - /// for an example usage -#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \ -el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\ -const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \ -ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\ -ContainerType::const_iterator elem = container.begin();\ -ContainerType::const_iterator endElem = container.end();\ -std::size_t size_ = container.SizeMethod; \ -ss << ELPP_LITERAL("[");\ -for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \ -ss << ElementInstance;\ -ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\ -}\ -if (elem != endElem) {\ -ss << ELPP_LITERAL("...");\ -}\ -ss << ELPP_LITERAL("]");\ -return ss;\ -} -#if defined(ELPP_WXWIDGETS_LOGGING) - ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector) -# define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem)) -# define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem)) -# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \ -ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")") -#else -# define ELPP_WX_PTR_ENABLED(ContainerType) -# define ELPP_WX_ENABLED(ContainerType) -# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) -#endif // defined(ELPP_WXWIDGETS_LOGGING) - // Other classes - template <class Class> - ELPP_SIMPLE_LOG(const Class&) -#undef ELPP_SIMPLE_LOG -#undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG -#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG - private: - Logger* m_logger; - const base::type::char_t* m_containerLogSeparator; - - template<class Iterator> - MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) { - m_logger->stream() << ELPP_LITERAL("["); - for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) { - operator << (*begin_); - m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeparator : ELPP_LITERAL("")); - } - if (begin_ != end_) { - m_logger->stream() << ELPP_LITERAL("..."); - } - m_logger->stream() << ELPP_LITERAL("]"); - if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { - m_logger->stream() << " "; - } - return *this; - } -}; -/// @brief Writes nothing - Used when certain log is disabled -class NullWriter : base::NoCopy { - public: - NullWriter(void) {} - - // Null manipulator - inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) { - return *this; - } - - template <typename T> - inline NullWriter& operator<<(const T&) { - return *this; - } - - inline operator bool() { - return true; - } -}; -/// @brief Main entry point of each logging -class Writer : base::NoCopy { - public: - Writer(Level level, const char* file, base::type::LineNumber line, - const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, - base::type::VerboseLevel verboseLevel = 0) : - m_msg(nullptr), m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel), - m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) { - } - - Writer(LogMessage* msg, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog) : - m_msg(msg), m_level(msg != nullptr ? msg->level() : Level::Unknown), - m_line(0), m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) { - } - - virtual ~Writer(void) { - processDispatch(); - } - - template <typename T> - inline Writer& operator<<(const T& log) { -#if ELPP_LOGGING_ENABLED - if (m_proceed) { - m_messageBuilder << log; - } -#endif // ELPP_LOGGING_ENABLED - return *this; - } - - inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) { -#if ELPP_LOGGING_ENABLED - if (m_proceed) { - m_messageBuilder << log; - } -#endif // ELPP_LOGGING_ENABLED - return *this; - } - - inline operator bool() { - return true; - } - - Writer& construct(Logger* logger, bool needLock = true); - Writer& construct(int count, const char* loggerIds, ...); - protected: - LogMessage* m_msg; - Level m_level; - const char* m_file; - const base::type::LineNumber m_line; - const char* m_func; - base::type::VerboseLevel m_verboseLevel; - Logger* m_logger; - bool m_proceed; - base::MessageBuilder m_messageBuilder; - base::DispatchAction m_dispatchAction; - std::vector<std::string> m_loggerIds; - friend class el::Helpers; - - void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true); - void processDispatch(); - void triggerDispatch(void); -}; -class PErrorWriter : public base::Writer { - public: - PErrorWriter(Level level, const char* file, base::type::LineNumber line, - const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, - base::type::VerboseLevel verboseLevel = 0) : - base::Writer(level, file, line, func, dispatchAction, verboseLevel) { - } - - virtual ~PErrorWriter(void); -}; -} // namespace base -// Logging from Logger class. Why this is here? Because we have Storage and Writer class available -#if ELPP_VARIADIC_TEMPLATES_SUPPORTED -template <typename T, typename... Args> -void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) { - base::MessageBuilder b; - b.initialize(this); - while (*s) { - if (*s == base::consts::kFormatSpecifierChar) { - if (*(s + 1) == base::consts::kFormatSpecifierChar) { - ++s; - } else { - if (*(s + 1) == base::consts::kFormatSpecifierCharValue) { - ++s; - b << value; - log_(level, vlevel, ++s, args...); - return; - } - } - } - b << *s++; - } - ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false); -} -template <typename T> -void Logger::log_(Level level, int vlevel, const T& log) { - if (level == Level::Verbose) { - if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) { - base::Writer(Level::Verbose, "FILE", 0, "FUNCTION", - base::DispatchAction::NormalLog, vlevel).construct(this, false) << log; - } else { - stream().str(ELPP_LITERAL("")); - releaseLock(); - } - } else { - base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log; - } -} -template <typename T, typename... Args> -inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) { - acquireLock(); // released in Writer! - log_(level, 0, s, value, args...); -} -template <typename T> -inline void Logger::log(Level level, const T& log) { - acquireLock(); // released in Writer! - log_(level, 0, log); -} -# if ELPP_VERBOSE_LOG -template <typename T, typename... Args> -inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) { - acquireLock(); // released in Writer! - log_(el::Level::Verbose, vlevel, s, value, args...); -} -template <typename T> -inline void Logger::verbose(int vlevel, const T& log) { - acquireLock(); // released in Writer! - log_(el::Level::Verbose, vlevel, log); -} -# else -template <typename T, typename... Args> -inline void Logger::verbose(int, const char*, const T&, const Args&...) { - return; -} -template <typename T> -inline void Logger::verbose(int, const T&) { - return; -} -# endif // ELPP_VERBOSE_LOG -# define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\ -template <typename T, typename... Args>\ -inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\ -log(LOG_LEVEL, s, value, args...);\ -}\ -template <typename T>\ -inline void Logger::FUNCTION_NAME(const T& value) {\ -log(LOG_LEVEL, value);\ -} -# define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\ -template <typename T, typename... Args>\ -inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\ -return;\ -}\ -template <typename T>\ -inline void Logger::FUNCTION_NAME(const T&) {\ -return;\ -} - -# if ELPP_INFO_LOG -LOGGER_LEVEL_WRITERS(info, Level::Info) -# else -LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info) -# endif // ELPP_INFO_LOG -# if ELPP_DEBUG_LOG -LOGGER_LEVEL_WRITERS(debug, Level::Debug) -# else -LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug) -# endif // ELPP_DEBUG_LOG -# if ELPP_WARNING_LOG -LOGGER_LEVEL_WRITERS(warn, Level::Warning) -# else -LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning) -# endif // ELPP_WARNING_LOG -# if ELPP_ERROR_LOG -LOGGER_LEVEL_WRITERS(error, Level::Error) -# else -LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error) -# endif // ELPP_ERROR_LOG -# if ELPP_FATAL_LOG -LOGGER_LEVEL_WRITERS(fatal, Level::Fatal) -# else -LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal) -# endif // ELPP_FATAL_LOG -# if ELPP_TRACE_LOG -LOGGER_LEVEL_WRITERS(trace, Level::Trace) -# else -LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace) -# endif // ELPP_TRACE_LOG -# undef LOGGER_LEVEL_WRITERS -# undef LOGGER_LEVEL_WRITERS_DISABLED -#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED -#if ELPP_COMPILER_MSVC -# define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs -# define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__)) -# define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\ -10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -#else -# if ELPP_COMPILER_CLANG -# define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -# else -# define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -# endif // ELPP_COMPILER_CLANG -#endif // ELPP_COMPILER_MSVC -#define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N -#define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \ -ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion) && \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \ -ELPP->validateAfterNCounter(__FILE__, __LINE__, n) && \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \ -ELPP->validateNTimesCounter(__FILE__, __LINE__, n) && \ -writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) -class PerformanceTrackingData { - public: - enum class DataType : base::type::EnumType { - Checkpoint = 1, Complete = 2 - }; - // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*) - explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr), - m_dataType(dataType), m_firstCheckpoint(false), m_file(""), m_line(0), m_func("") {} - inline const std::string* blockName(void) const; - inline const struct timeval* startTime(void) const; - inline const struct timeval* endTime(void) const; - inline const struct timeval* lastCheckpointTime(void) const; - inline const base::PerformanceTracker* performanceTracker(void) const { - return m_performanceTracker; - } - inline PerformanceTrackingData::DataType dataType(void) const { - return m_dataType; - } - inline bool firstCheckpoint(void) const { - return m_firstCheckpoint; - } - inline std::string checkpointId(void) const { - return m_checkpointId; - } - inline const char* file(void) const { - return m_file; - } - inline base::type::LineNumber line(void) const { - return m_line; - } - inline const char* func(void) const { - return m_func; - } - inline const base::type::string_t* formattedTimeTaken() const { - return &m_formattedTimeTaken; - } - inline const std::string& loggerId(void) const; - private: - base::PerformanceTracker* m_performanceTracker; - base::type::string_t m_formattedTimeTaken; - PerformanceTrackingData::DataType m_dataType; - bool m_firstCheckpoint; - std::string m_checkpointId; - const char* m_file; - base::type::LineNumber m_line; - const char* m_func; - inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) { - m_performanceTracker = performanceTracker; - m_firstCheckpoint = firstCheckpoint; - } - - friend class el::base::PerformanceTracker; -}; -namespace base { -/// @brief Represents performanceTracker block of code that conditionally adds performance status to log -/// either when goes outside the scope of when checkpoint() is called -class PerformanceTracker : public base::threading::ThreadSafe, public Loggable { - public: - PerformanceTracker(const std::string& blockName, - base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond, - const std::string& loggerId = std::string(el::base::consts::kPerformanceLoggerId), - bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel); - /// @brief Copy constructor - PerformanceTracker(const PerformanceTracker& t) : - m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog), - m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled), - m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) { - } - virtual ~PerformanceTracker(void); - /// @brief A checkpoint for current performanceTracker block. - void checkpoint(const std::string& id = std::string(), const char* file = __FILE__, - base::type::LineNumber line = __LINE__, - const char* func = ""); - inline Level level(void) const { - return m_level; - } - private: - std::string m_blockName; - base::TimestampUnit m_timestampUnit; - std::string m_loggerId; - bool m_scopedLog; - Level m_level; - bool m_hasChecked; - std::string m_lastCheckpointId; - bool m_enabled; - struct timeval m_startTime, m_endTime, m_lastCheckpointTime; - - PerformanceTracker(void); - - friend class el::PerformanceTrackingData; - friend class base::DefaultPerformanceTrackingCallback; - - const inline base::type::string_t getFormattedTimeTaken() const { - return getFormattedTimeTaken(m_startTime); - } - - const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const; - - virtual inline void log(el::base::type::ostream_t& os) const { - os << getFormattedTimeTaken(); - } -}; -class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback { - protected: - void handle(const PerformanceTrackingData* data) { - m_data = data; - base::type::stringstream_t ss; - if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) { - ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") << - *m_data->formattedTimeTaken() << ELPP_LITERAL("]"); - } else { - ss << ELPP_LITERAL("Performance checkpoint"); - if (!m_data->checkpointId().empty()) { - ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]"); - } - ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") << - *m_data->performanceTracker(); - if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison) - && m_data->performanceTracker()->m_hasChecked) { - ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from "); - if (m_data->performanceTracker()->m_lastCheckpointId.empty()) { - ss << ELPP_LITERAL("last checkpoint"); - } else { - ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'"); - } - ss << ELPP_LITERAL(")]"); - } else { - ss << ELPP_LITERAL("]"); - } - } - el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1, - m_data->loggerId().c_str()) << ss.str(); - } - private: - const PerformanceTrackingData* m_data; -}; -} // namespace base -inline const std::string* PerformanceTrackingData::blockName() const { - return const_cast<const std::string*>(&m_performanceTracker->m_blockName); -} -inline const struct timeval* PerformanceTrackingData::startTime() const { - return const_cast<const struct timeval*>(&m_performanceTracker->m_startTime); -} -inline const struct timeval* PerformanceTrackingData::endTime() const { - return const_cast<const struct timeval*>(&m_performanceTracker->m_endTime); -} -inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const { - return const_cast<const struct timeval*>(&m_performanceTracker->m_lastCheckpointTime); -} -inline const std::string& PerformanceTrackingData::loggerId(void) const { - return m_performanceTracker->m_loggerId; -} -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) -namespace base { -/// @brief Contains some internal debugging tools like crash handler and stack tracer -namespace debug { -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) -class StackTrace : base::NoCopy { - public: - static const unsigned int kMaxStack = 64; - static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew() - class StackTraceEntry { - public: - StackTraceEntry(std::size_t index, const std::string& loc, const std::string& demang, const std::string& hex, - const std::string& addr); - StackTraceEntry(std::size_t index, const std::string& loc) : - m_index(index), - m_location(loc) { - } - std::size_t m_index; - std::string m_location; - std::string m_demangled; - std::string m_hex; - std::string m_addr; - friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si); - - private: - StackTraceEntry(void); - }; - - StackTrace(void) { - generateNew(); - } - - virtual ~StackTrace(void) { - } - - inline std::vector<StackTraceEntry>& getLatestStack(void) { - return m_stack; - } - - friend std::ostream& operator<<(std::ostream& os, const StackTrace& st); - - private: - std::vector<StackTraceEntry> m_stack; - - void generateNew(void); -}; -/// @brief Handles unexpected crashes -class CrashHandler : base::NoCopy { - public: - typedef void (*Handler)(int); - - explicit CrashHandler(bool useDefault); - explicit CrashHandler(const Handler& cHandler) { - setHandler(cHandler); - } - void setHandler(const Handler& cHandler); - - private: - Handler m_handler; -}; -#else -class CrashHandler { - public: - explicit CrashHandler(bool) {} -}; -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) -} // namespace debug -} // namespace base -extern base::debug::CrashHandler elCrashHandler; -#define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \ -el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance) -/// @brief Initializes syslog with process ID, options and facility. calls closelog() on d'tor -class SysLogInitializer { - public: - SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) { -#if defined(ELPP_SYSLOG) - (void)base::consts::kSysLogLoggerId; - openlog(processIdent, options, facility); -#else - ELPP_UNUSED(processIdent); - ELPP_UNUSED(options); - ELPP_UNUSED(facility); -#endif // defined(ELPP_SYSLOG) - } - virtual ~SysLogInitializer(void) { -#if defined(ELPP_SYSLOG) - closelog(); -#endif // defined(ELPP_SYSLOG) - } -}; -#define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac) -/// @brief Static helpers for developers -class Helpers : base::StaticClass { - public: - /// @brief Shares logging repository (base::Storage) - static inline void setStorage(base::type::StoragePointer storage) { - ELPP = storage; - } - /// @return Main storage repository - static inline base::type::StoragePointer storage() { - return ELPP; - } - /// @brief Sets application arguments and figures out whats active for logging and whats not. - static inline void setArgs(int argc, char** argv) { - ELPP->setApplicationArguments(argc, argv); - } - /// @copydoc setArgs(int argc, char** argv) - static inline void setArgs(int argc, const char** argv) { - ELPP->setApplicationArguments(argc, const_cast<char**>(argv)); - } - /// @brief Sets thread name for current thread. Requires std::thread - static inline void setThreadName(const std::string& name) { - ELPP->setThreadName(name); - } - static inline std::string getThreadName() { - return ELPP->getThreadName(base::threading::getCurrentThreadId()); - } -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - /// @brief Overrides default crash handler and installs custom handler. - /// @param crashHandler A functor with no return type that takes single int argument. - /// Handler is a typedef with specification: void (*Handler)(int) - static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) { - el::elCrashHandler.setHandler(crashHandler); - } - /// @brief Abort due to crash with signal in parameter - /// @param sig Crash signal - static void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0); - /// @brief Logs reason of crash as per sig - /// @param sig Crash signal - /// @param stackTraceIfAvailable Includes stack trace if available - /// @param level Logging level - /// @param logger Logger to use for logging - static void logCrashReason(int sig, bool stackTraceIfAvailable = false, - Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId); -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) - /// @brief Installs pre rollout callback, this callback is triggered when log file is about to be rolled out - /// (can be useful for backing up) - static inline void installPreRollOutCallback(const PreRollOutCallback& callback) { - ELPP->setPreRollOutCallback(callback); - } - /// @brief Uninstalls pre rollout callback - static inline void uninstallPreRollOutCallback(void) { - ELPP->unsetPreRollOutCallback(); - } - /// @brief Installs post log dispatch callback, this callback is triggered when log is dispatched - template <typename T> - static inline bool installLogDispatchCallback(const std::string& id) { - return ELPP->installLogDispatchCallback<T>(id); - } - /// @brief Uninstalls log dispatch callback - template <typename T> - static inline void uninstallLogDispatchCallback(const std::string& id) { - ELPP->uninstallLogDispatchCallback<T>(id); - } - template <typename T> - static inline T* logDispatchCallback(const std::string& id) { - return ELPP->logDispatchCallback<T>(id); - } -#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - /// @brief Installs post performance tracking callback, this callback is triggered when performance tracking is finished - template <typename T> - static inline bool installPerformanceTrackingCallback(const std::string& id) { - return ELPP->installPerformanceTrackingCallback<T>(id); - } - /// @brief Uninstalls post performance tracking handler - template <typename T> - static inline void uninstallPerformanceTrackingCallback(const std::string& id) { - ELPP->uninstallPerformanceTrackingCallback<T>(id); - } - template <typename T> - static inline T* performanceTrackingCallback(const std::string& id) { - return ELPP->performanceTrackingCallback<T>(id); - } -#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) - /// @brief Converts template to std::string - useful for loggable classes to log containers within log(std::ostream&) const - template <typename T> - static std::string convertTemplateToStdString(const T& templ) { - el::Logger* logger = - ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId); - if (logger == nullptr) { - return std::string(); - } - base::MessageBuilder b; - b.initialize(logger); - logger->acquireLock(); - b << templ; -#if defined(ELPP_UNICODE) - std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end()); -#else - std::string s = logger->stream().str(); -#endif // defined(ELPP_UNICODE) - logger->stream().str(ELPP_LITERAL("")); - logger->releaseLock(); - return s; - } - /// @brief Returns command line arguments (pointer) provided to easylogging++ - static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) { - return ELPP->commandLineArgs(); - } - /// @brief Reserve space for custom format specifiers for performance - /// @see std::vector::reserve - static inline void reserveCustomFormatSpecifiers(std::size_t size) { - ELPP->m_customFormatSpecifiers.reserve(size); - } - /// @brief Installs user defined format specifier and handler - static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) { - ELPP->installCustomFormatSpecifier(customFormatSpecifier); - } - /// @brief Uninstalls user defined format specifier and handler - static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) { - return ELPP->uninstallCustomFormatSpecifier(formatSpecifier); - } - /// @brief Returns true if custom format specifier is installed - static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) { - return ELPP->hasCustomFormatSpecifier(formatSpecifier); - } - static inline void validateFileRolling(Logger* logger, Level level) { - if (ELPP == nullptr || logger == nullptr) return; - logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback()); - } -}; -/// @brief Static helpers to deal with loggers and their configurations -class Loggers : base::StaticClass { - public: - /// @brief Gets existing or registers new logger - static Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true); - /// @brief Changes default log builder for future loggers - static void setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr); - /// @brief Installs logger registration callback, this callback is triggered when new logger is registered - template <typename T> - static inline bool installLoggerRegistrationCallback(const std::string& id) { - return ELPP->registeredLoggers()->installLoggerRegistrationCallback<T>(id); - } - /// @brief Uninstalls log dispatch callback - template <typename T> - static inline void uninstallLoggerRegistrationCallback(const std::string& id) { - ELPP->registeredLoggers()->uninstallLoggerRegistrationCallback<T>(id); - } - template <typename T> - static inline T* loggerRegistrationCallback(const std::string& id) { - return ELPP->registeredLoggers()->loggerRegistrationCallback<T>(id); - } - /// @brief Unregisters logger - use it only when you know what you are doing, you may unregister - /// loggers initialized / used by third-party libs. - static bool unregisterLogger(const std::string& identity); - /// @brief Whether or not logger with id is registered - static bool hasLogger(const std::string& identity); - /// @brief Reconfigures specified logger with new configurations - static Logger* reconfigureLogger(Logger* logger, const Configurations& configurations); - /// @brief Reconfigures logger with new configurations after looking it up using identity - static Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations); - /// @brief Reconfigures logger's single configuration - static Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType, - const std::string& value); - /// @brief Reconfigures all the existing loggers with new configurations - static void reconfigureAllLoggers(const Configurations& configurations); - /// @brief Reconfigures single configuration for all the loggers - static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) { - reconfigureAllLoggers(Level::Global, configurationType, value); - } - /// @brief Reconfigures single configuration for all the loggers for specified level - static void reconfigureAllLoggers(Level level, ConfigurationType configurationType, - const std::string& value); - /// @brief Sets default configurations. This configuration is used for future (and conditionally for existing) loggers - static void setDefaultConfigurations(const Configurations& configurations, - bool reconfigureExistingLoggers = false); - /// @brief Returns current default - static const Configurations* defaultConfigurations(void); - /// @brief Returns log stream reference pointer if needed by user - static const base::LogStreamsReferenceMapPtr logStreamsReference(void); - /// @brief Default typed configuration based on existing defaultConf - static base::TypedConfigurations defaultTypedConfigurations(void); - /// @brief Populates all logger IDs in current repository. - /// @param [out] targetList List of fill up. - static std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList); - /// @brief Sets configurations from global configuration file. - static void configureFromGlobal(const char* globalConfigurationFilePath); - /// @brief Configures loggers using command line arg. Ensure you have already set command line args, - /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger. - /// If true is returned that does not mean it has been configured successfully, it only means that it - /// has attempted to configure logger using configuration file provided in argument - static bool configureFromArg(const char* argKey); - /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered - static void flushAll(void); - /// @brief Adds logging flag used internally. - static inline void addFlag(LoggingFlag flag) { - ELPP->addFlag(flag); - } - /// @brief Removes logging flag used internally. - static inline void removeFlag(LoggingFlag flag) { - ELPP->removeFlag(flag); - } - /// @brief Determines whether or not certain flag is active - static inline bool hasFlag(LoggingFlag flag) { - return ELPP->hasFlag(flag); - } - /// @brief Adds flag and removes it when scope goes out - class ScopedAddFlag { - public: - ScopedAddFlag(LoggingFlag flag) : m_flag(flag) { - Loggers::addFlag(m_flag); - } - ~ScopedAddFlag(void) { - Loggers::removeFlag(m_flag); - } - private: - LoggingFlag m_flag; - }; - /// @brief Removes flag and add it when scope goes out - class ScopedRemoveFlag { - public: - ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) { - Loggers::removeFlag(m_flag); - } - ~ScopedRemoveFlag(void) { - Loggers::addFlag(m_flag); - } - private: - LoggingFlag m_flag; - }; - /// @brief Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging) - static void setLoggingLevel(Level level) { - ELPP->setLoggingLevel(level); - } - /// @brief Sets verbose level on the fly - static void setVerboseLevel(base::type::VerboseLevel level); - /// @brief Gets current verbose level - static base::type::VerboseLevel verboseLevel(void); - /// @brief Sets vmodules as specified (on the fly) - static void setVModules(const char* modules); - /// @brief Clears vmodules - static void clearVModules(void); -}; -class VersionInfo : base::StaticClass { - public: - /// @brief Current version number - static const std::string version(void); - - /// @brief Release date of current version - static const std::string releaseDate(void); -}; -} // namespace el -#undef VLOG_IS_ON -/// @brief Determines whether verbose logging is on for specified level current file. -#define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__)) -#undef TIMED_BLOCK -#undef TIMED_SCOPE -#undef TIMED_SCOPE_IF -#undef TIMED_FUNC -#undef TIMED_FUNC_IF -#undef ELPP_MIN_UNIT -#if defined(ELPP_PERFORMANCE_MICROSECONDS) -# define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond -#else -# define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond -#endif // (defined(ELPP_PERFORMANCE_MICROSECONDS)) -/// @brief Performance tracked scope. Performance gets written when goes out of scope using -/// 'performance' logger. -/// -/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); -/// @see el::base::PerformanceTracker -/// @see el::base::PerformanceTracker::checkpoint -// Note: Do not surround this definition with null macro because of obj instance -#define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? \ - new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr ) -#define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true) -#define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \ - el::base::type::PerformanceTrackerPtr(new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT)) }; obj.i < 1; ++obj.i) -/// @brief Performance tracked function. Performance gets written when goes out of scope using -/// 'performance' logger. -/// -/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); -/// @see el::base::PerformanceTracker -/// @see el::base::PerformanceTracker::checkpoint -#define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition) -#define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC) -#undef PERFORMANCE_CHECKPOINT -#undef PERFORMANCE_CHECKPOINT_WITH_ID -#define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC) -#define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC) -#undef ELPP_COUNTER -#undef ELPP_COUNTER_POS -/// @brief Gets hit counter for file/line -#define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__)) -/// @brief Gets hit counter position for file/line, -1 if not registered yet -#define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts()) -// Undef levels to support LOG(LEVEL) -#undef INFO -#undef WARNING -#undef DEBUG -#undef ERROR -#undef FATAL -#undef TRACE -#undef VERBOSE -// Undef existing -#undef CINFO -#undef CWARNING -#undef CDEBUG -#undef CFATAL -#undef CERROR -#undef CTRACE -#undef CVERBOSE -#undef CINFO_IF -#undef CWARNING_IF -#undef CDEBUG_IF -#undef CERROR_IF -#undef CFATAL_IF -#undef CTRACE_IF -#undef CVERBOSE_IF -#undef CINFO_EVERY_N -#undef CWARNING_EVERY_N -#undef CDEBUG_EVERY_N -#undef CERROR_EVERY_N -#undef CFATAL_EVERY_N -#undef CTRACE_EVERY_N -#undef CVERBOSE_EVERY_N -#undef CINFO_AFTER_N -#undef CWARNING_AFTER_N -#undef CDEBUG_AFTER_N -#undef CERROR_AFTER_N -#undef CFATAL_AFTER_N -#undef CTRACE_AFTER_N -#undef CVERBOSE_AFTER_N -#undef CINFO_N_TIMES -#undef CWARNING_N_TIMES -#undef CDEBUG_N_TIMES -#undef CERROR_N_TIMES -#undef CFATAL_N_TIMES -#undef CTRACE_N_TIMES -#undef CVERBOSE_N_TIMES -// Normal logs -#if ELPP_INFO_LOG -# define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE(writer, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\ -el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#else -# define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// Conditional logs -#if ELPP_INFO_LOG -# define CINFO_IF(writer, condition_, dispatchAction, ...) \ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_IF(writer, condition_, dispatchAction, ...)\ -ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \ -el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) -#else -# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// Occasional logs -#if ELPP_INFO_LOG -# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\ -ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\ -CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__) -#else -# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// After N logs -#if ELPP_INFO_LOG -# define CINFO_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\ -CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) -#else -# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// N Times logs -#if ELPP_INFO_LOG -# define CINFO_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) -#else -# define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_INFO_LOG -#if ELPP_WARNING_LOG -# define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) -#else -# define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_WARNING_LOG -#if ELPP_DEBUG_LOG -# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) -#else -# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_DEBUG_LOG -#if ELPP_ERROR_LOG -# define CERROR_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) -#else -# define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_ERROR_LOG -#if ELPP_FATAL_LOG -# define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) -#else -# define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_FATAL_LOG -#if ELPP_TRACE_LOG -# define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\ -ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) -#else -# define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_TRACE_LOG -#if ELPP_VERBOSE_LOG -# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\ -CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) -#else -# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() -#endif // ELPP_VERBOSE_LOG -// -// Custom Loggers - Requires (level, dispatchAction, loggerId/s) -// -// undef existing -#undef CLOG -#undef CLOG_VERBOSE -#undef CVLOG -#undef CLOG_IF -#undef CLOG_VERBOSE_IF -#undef CVLOG_IF -#undef CLOG_EVERY_N -#undef CVLOG_EVERY_N -#undef CLOG_AFTER_N -#undef CVLOG_AFTER_N -#undef CLOG_N_TIMES -#undef CVLOG_N_TIMES -// Normal logs -#define CLOG(LEVEL, ...)\ -C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -// Conditional logs -#define CLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_IF(condition, vlevel, ...)\ -CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -// Hit counts based logs -#define CLOG_EVERY_N(n, LEVEL, ...)\ -C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_EVERY_N(n, vlevel, ...)\ -CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CLOG_AFTER_N(n, LEVEL, ...)\ -C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_AFTER_N(n, vlevel, ...)\ -CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CLOG_N_TIMES(n, LEVEL, ...)\ -C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CVLOG_N_TIMES(n, vlevel, ...)\ -CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) -// -// Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros -// -// undef existing -#undef LOG -#undef VLOG -#undef LOG_IF -#undef VLOG_IF -#undef LOG_EVERY_N -#undef VLOG_EVERY_N -#undef LOG_AFTER_N -#undef VLOG_AFTER_N -#undef LOG_N_TIMES -#undef VLOG_N_TIMES -#undef ELPP_CURR_FILE_LOGGER_ID -#if defined(ELPP_DEFAULT_LOGGER) -# define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER -#else -# define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId -#endif -#undef ELPP_TRACE -#define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID) -// Normal logs -#define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Conditional logs -#define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Hit counts based logs -#define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Generic PLOG() -#undef CPLOG -#undef CPLOG_IF -#undef PLOG -#undef PLOG_IF -#undef DCPLOG -#undef DCPLOG_IF -#undef DPLOG -#undef DPLOG_IF -#define CPLOG(LEVEL, ...)\ -C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define CPLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define DCPLOG(LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define DCPLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__) -#define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -// Generic SYSLOG() -#undef CSYSLOG -#undef CSYSLOG_IF -#undef CSYSLOG_EVERY_N -#undef CSYSLOG_AFTER_N -#undef CSYSLOG_N_TIMES -#undef SYSLOG -#undef SYSLOG_IF -#undef SYSLOG_EVERY_N -#undef SYSLOG_AFTER_N -#undef SYSLOG_N_TIMES -#undef DCSYSLOG -#undef DCSYSLOG_IF -#undef DCSYSLOG_EVERY_N -#undef DCSYSLOG_AFTER_N -#undef DCSYSLOG_N_TIMES -#undef DSYSLOG -#undef DSYSLOG_IF -#undef DSYSLOG_EVERY_N -#undef DSYSLOG_AFTER_N -#undef DSYSLOG_N_TIMES -#if defined(ELPP_SYSLOG) -# define CSYSLOG(LEVEL, ...)\ -C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_IF(condition, LEVEL, ...)\ -C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_EVERY_N(n, LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_AFTER_N(n, LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DCSYSLOG_N_TIMES(n, LEVEL, ...)\ -if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) -# define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) -# define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) -#else -# define CSYSLOG(LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() -# define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() -# define SYSLOG(LEVEL) el::base::NullWriter() -# define SYSLOG_IF(condition, LEVEL) el::base::NullWriter() -# define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() -# define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() -# define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() -# define DCSYSLOG(LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() -# define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() -# define DSYSLOG(LEVEL) el::base::NullWriter() -# define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter() -# define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() -# define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() -# define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() -#endif // defined(ELPP_SYSLOG) -// -// Custom Debug Only Loggers - Requires (level, loggerId/s) -// -// undef existing -#undef DCLOG -#undef DCVLOG -#undef DCLOG_IF -#undef DCVLOG_IF -#undef DCLOG_EVERY_N -#undef DCVLOG_EVERY_N -#undef DCLOG_AFTER_N -#undef DCVLOG_AFTER_N -#undef DCLOG_N_TIMES -#undef DCVLOG_N_TIMES -// Normal logs -#define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__) -#define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__) -#define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__) -// Conditional logs -#define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__) -#define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__) -// Hit counts based logs -#define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__) -#define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__) -#define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__) -#define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__) -#define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__) -#define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__) -// -// Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros -// -#if !defined(ELPP_NO_DEBUG_MACROS) -// undef existing -#undef DLOG -#undef DVLOG -#undef DLOG_IF -#undef DVLOG_IF -#undef DLOG_EVERY_N -#undef DVLOG_EVERY_N -#undef DLOG_AFTER_N -#undef DVLOG_AFTER_N -#undef DLOG_N_TIMES -#undef DVLOG_N_TIMES -// Normal logs -#define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Conditional logs -#define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) -// Hit counts based logs -#define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) -#define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) -#endif // defined(ELPP_NO_DEBUG_MACROS) -#if !defined(ELPP_NO_CHECK_MACROS) -// Check macros -#undef CCHECK -#undef CPCHECK -#undef CCHECK_EQ -#undef CCHECK_NE -#undef CCHECK_LT -#undef CCHECK_GT -#undef CCHECK_LE -#undef CCHECK_GE -#undef CCHECK_BOUNDS -#undef CCHECK_NOTNULL -#undef CCHECK_STRCASEEQ -#undef CCHECK_STRCASENE -#undef CHECK -#undef PCHECK -#undef CHECK_EQ -#undef CHECK_NE -#undef CHECK_LT -#undef CHECK_GT -#undef CHECK_LE -#undef CHECK_GE -#undef CHECK_BOUNDS -#undef CHECK_NOTNULL -#undef CHECK_STRCASEEQ -#undef CHECK_STRCASENE -#define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " -#define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " -#define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__) -#define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__) -#define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__) -#define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__) -#define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__) -#define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__) -#define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__) -#define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) -#define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__) -#define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " == " << #str2 << "] " -#define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " != " << #str2 << "] " -#define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " == " << #str2 << "] " -#define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ -<< "Check failed: [" << #str1 << " != " << #str2 << "] " -#define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#undef DCCHECK -#undef DCCHECK_EQ -#undef DCCHECK_NE -#undef DCCHECK_LT -#undef DCCHECK_GT -#undef DCCHECK_LE -#undef DCCHECK_GE -#undef DCCHECK_BOUNDS -#undef DCCHECK_NOTNULL -#undef DCCHECK_STRCASEEQ -#undef DCCHECK_STRCASENE -#undef DCPCHECK -#undef DCHECK -#undef DCHECK_EQ -#undef DCHECK_NE -#undef DCHECK_LT -#undef DCHECK_GT -#undef DCHECK_LE -#undef DCHECK_GE -#undef DCHECK_BOUNDS_ -#undef DCHECK_NOTNULL -#undef DCHECK_STRCASEEQ -#undef DCHECK_STRCASENE -#undef DPCHECK -#define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__) -#define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__) -#define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__) -#define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__) -#define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__) -#define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__) -#define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__) -#define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__) -#define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__) -#define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__) -#define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__) -#define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__) -#define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__) -#define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__) -#define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) -#define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) -#endif // defined(ELPP_NO_CHECK_MACROS) -#if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) -# define ELPP_USE_DEF_CRASH_HANDLER false -#else -# define ELPP_USE_DEF_CRASH_HANDLER true -#endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) -#define ELPP_CRASH_HANDLER_INIT -#define ELPP_INIT_EASYLOGGINGPP(val) \ -namespace el { \ -namespace base { \ -el::base::type::StoragePointer elStorage(val); \ -} \ -el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \ -} - -#if ELPP_ASYNC_LOGGING -# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\ -new el::base::AsyncDispatchWorker())) -#else -# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()))) -#endif // ELPP_ASYNC_LOGGING -#define INITIALIZE_NULL_EASYLOGGINGPP \ -namespace el {\ -namespace base {\ -el::base::type::StoragePointer elStorage;\ -}\ -el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ -} -#define SHARE_EASYLOGGINGPP(initializedStorage)\ -namespace el {\ -namespace base {\ -el::base::type::StoragePointer elStorage(initializedStorage);\ -}\ -el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ -} - -#if defined(ELPP_UNICODE) -# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale("")) -#else -# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv) -#endif // defined(ELPP_UNICODE) -#endif // EASYLOGGINGPP_H diff --git a/third_party/encoding-detect/TextEncodingDetect.cpp b/third_party/encoding-detect/TextEncodingDetect.cpp new file mode 100644 index 00000000..22ae5897 --- /dev/null +++ b/third_party/encoding-detect/TextEncodingDetect.cpp @@ -0,0 +1,313 @@ +// +// Copyright 2015-2016 Jonathan Bennett <[email protected]> +// +// https://www.autoitscript.com +// +// 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. +// + +// Includes +#include "TextEncodingDetect.h" + +using namespace AutoIt::Common; + +static const unsigned char TextEncodingDetect_UTF16_BOM_LE[] = { + (unsigned char)(0xFF), (unsigned char)(0xFE)}; +static const unsigned char TextEncodingDetect_UTF16_BOM_BE[] = { + (unsigned char)(0xFE), (unsigned char)(0xFF)}; +static const unsigned char TextEncodingDetect_UTF8_BOM[] = { + (unsigned char)(0xEF), (unsigned char)(0xBB), (unsigned char)(0xBF)}; + +const unsigned char *TextEncodingDetect::utf16_bom_le_ = + TextEncodingDetect_UTF16_BOM_LE; +const unsigned char *TextEncodingDetect::utf16_bom_be_ = + TextEncodingDetect_UTF16_BOM_BE; +const unsigned char *TextEncodingDetect::utf8_bom_ = + TextEncodingDetect_UTF8_BOM; + +/////////////////////////////////////////////////////////////////////////////// +// Constructor() +// Default constructor +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::TextEncodingDetect() { + // By default, assume nulls can't appear in ANSI/ASCII/UTF8 text files + null_suggests_binary_ = true; + + // Set defaults for utf16 detection based the use of odd/even nulls + utf16_expected_null_percent_ = 70; + utf16_unexpected_null_percent_ = 10; +} + +/////////////////////////////////////////////////////////////////////////////// +// Set the percentages used in utf16 detection using nulls. +/////////////////////////////////////////////////////////////////////////////// + +void TextEncodingDetect::SetUtf16UnexpectedNullPercent(int percent) { + if (percent > 0 && percent < 100) utf16_expected_null_percent_ = percent; +} + +void TextEncodingDetect::SetUtf16ExpectedNullPercent(int percent) { + if (percent > 0 && percent < 100) utf16_unexpected_null_percent_ = percent; +} + +/////////////////////////////////////////////////////////////////////////////// +// Simple function to return the length of the BOM for a particular encoding +// mode. +/////////////////////////////////////////////////////////////////////////////// + +int TextEncodingDetect::GetBOMLengthFromEncodingMode(Encoding encoding) { + int length = 0; + + if (encoding == UTF16_BE_BOM || encoding == UTF16_LE_BOM) + length = 2; + else if (encoding == UTF8_BOM) + length = 3; + + return length; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains a valid BOM and returns the encoding based on it. +// Returns encoding "None" if there is no BOM. +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckBOM( + const unsigned char *pBuffer, size_t size) { + // Check for BOM + if (size >= 2 && pBuffer[0] == utf16_bom_le_[0] && + pBuffer[1] == utf16_bom_le_[1]) { + return UTF16_LE_BOM; + } else if (size >= 2 && pBuffer[0] == utf16_bom_be_[0] && + pBuffer[1] == utf16_bom_be_[1]) { + return UTF16_BE_BOM; + } else if (size >= 3 && pBuffer[0] == utf8_bom_[0] && + pBuffer[1] == utf8_bom_[1] && pBuffer[2] == utf8_bom_[2]) { + return UTF8_BOM; + } else { + return None; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains a valid BOM and returns the encoding based on it. +// If it doesn't contain a BOM it tries to guess what the encoding is or +// "None" if it just looks like binary data. +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::DetectEncoding( + const unsigned char *pBuffer, size_t size) const { + // First check if we have a BOM and return that if so + Encoding encoding = CheckBOM(pBuffer, size); + if (encoding != None) return encoding; + + // Now check for valid UTF8 + encoding = CheckUTF8(pBuffer, size); + if (encoding != None) return encoding; + + // Now try UTF16 + encoding = CheckUTF16NewlineChars(pBuffer, size); + if (encoding != None) return encoding; + + encoding = CheckUTF16ASCII(pBuffer, size); + if (encoding != None) return encoding; + + // ANSI or None (binary) then + if (!DoesContainNulls(pBuffer, size)) + return ANSI; + else { + // Found a null, return based on the preference in null_suggests_binary_ + if (null_suggests_binary_) + return None; + else + return ANSI; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains valid utf8. Returns: +// None - not valid utf8 +// UTF8_NOBOM - valid utf8 encodings and multibyte sequences +// ASCII - Only data in the 0-127 range. +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckUTF8( + const unsigned char *pBuffer, size_t size) const { + // UTF8 Valid sequences + // 0xxxxxxx ASCII + // 110xxxxx 10xxxxxx 2-byte + // 1110xxxx 10xxxxxx 10xxxxxx 3-byte + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4-byte + // + // Width in UTF8 + // Decimal Width + // 0-127 1 byte + // 194-223 2 bytes + // 224-239 3 bytes + // 240-244 4 bytes + // + // Subsequent chars are in the range 128-191 + + bool only_saw_ascii_range = true; + size_t pos = 0; + int more_chars; + + while (pos < size) { + unsigned char ch = pBuffer[pos++]; + + if (ch == 0 && null_suggests_binary_) { + return None; + } else if (ch <= 127) { + // 1 byte + more_chars = 0; + } else if (ch >= 194 && ch <= 223) { + // 2 Byte + more_chars = 1; + } else if (ch >= 224 && ch <= 239) { + // 3 Byte + more_chars = 2; + } else if (ch >= 240 && ch <= 244) { + // 4 Byte + more_chars = 3; + } else { + return None; // Not utf8 + } + + // Check secondary chars are in range if we are expecting any + while (more_chars && pos < size) { + only_saw_ascii_range = false; // Seen non-ascii chars now + + ch = pBuffer[pos++]; + if (ch < 128 || ch > 191) return None; // Not utf8 + + --more_chars; + } + } + + // If we get to here then only valid UTF-8 sequences have been processed + + // If we only saw chars in the range 0-127 then we can't assume UTF8 (the + // caller will need to decide) + if (only_saw_ascii_range) + return ASCII; + else + return UTF8_NOBOM; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains text that looks like utf16 by scanning for +// newline chars that would be present even in non-english text. +// Returns: +// None - not valid utf16 +// UTF16_LE_NOBOM - looks like utf16 le +// UTF16_BE_NOBOM - looks like utf16 be +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckUTF16NewlineChars( + const unsigned char *pBuffer, size_t size) { + if (size < 2) return None; + + // Reduce size by 1 so we don't need to worry about bounds checking for pairs + // of bytes + size--; + + int le_control_chars = 0; + int be_control_chars = 0; + unsigned char ch1, ch2; + + size_t pos = 0; + while (pos < size) { + ch1 = pBuffer[pos++]; + ch2 = pBuffer[pos++]; + + if (ch1 == 0) { + if (ch2 == 0x0a || ch2 == 0x0d) ++be_control_chars; + } else if (ch2 == 0) { + if (ch1 == 0x0a || ch1 == 0x0d) ++le_control_chars; + } + + // If we are getting both LE and BE control chars then this file is not + // utf16 + if (le_control_chars && be_control_chars) return None; + } + + if (le_control_chars) + return UTF16_LE_NOBOM; + else if (be_control_chars) + return UTF16_BE_NOBOM; + else + return None; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains text that looks like utf16. This is done based +// the use of nulls which in ASCII/script like text can be useful to identify. +// Returns: +// None - not valid utf16 +// UTF16_LE_NOBOM - looks like utf16 le +// UTF16_BE_NOBOM - looks like utf16 be +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckUTF16ASCII( + const unsigned char *pBuffer, size_t size) const { + int num_odd_nulls = 0; + int num_even_nulls = 0; + + // Get even nulls + size_t pos = 0; + while (pos < size) { + if (pBuffer[pos] == 0) num_even_nulls++; + + pos += 2; + } + + // Get odd nulls + pos = 1; + while (pos < size) { + if (pBuffer[pos] == 0) num_odd_nulls++; + + pos += 2; + } + + double even_null_threshold = (num_even_nulls * 2.0) / size; + double odd_null_threshold = (num_odd_nulls * 2.0) / size; + double expected_null_threshold = utf16_expected_null_percent_ / 100.0; + double unexpected_null_threshold = utf16_unexpected_null_percent_ / 100.0; + + // Lots of odd nulls, low number of even nulls + if (even_null_threshold < unexpected_null_threshold && + odd_null_threshold > expected_null_threshold) + return UTF16_LE_NOBOM; + + // Lots of even nulls, low number of odd nulls + if (odd_null_threshold < unexpected_null_threshold && + even_null_threshold > expected_null_threshold) + return UTF16_BE_NOBOM; + + // Don't know + return None; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains any nulls. Used to check for binary vs text data. +/////////////////////////////////////////////////////////////////////////////// + +bool TextEncodingDetect::DoesContainNulls(const unsigned char *pBuffer, + size_t size) { + size_t pos = 0; + while (pos < size) { + if (pBuffer[pos++] == 0) return true; + } + + return false; +} diff --git a/third_party/encoding-detect/TextEncodingDetect.h b/third_party/encoding-detect/TextEncodingDetect.h new file mode 100644 index 00000000..6d861716 --- /dev/null +++ b/third_party/encoding-detect/TextEncodingDetect.h @@ -0,0 +1,85 @@ +#pragma once +#ifndef TEXT_ENCODING_DETECT_H_ +#define TEXT_ENCODING_DETECT_H_ + +// +// Copyright 2015 Jonathan Bennett <[email protected]> +// +// https://www.autoitscript.com +// +// 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. +// + +// Includes +#include <stddef.h> + +namespace AutoIt::Common { +class TextEncodingDetect { + public: + enum Encoding { + None, // Unknown or binary + ANSI, // 0-255 + ASCII, // 0-127 + UTF8_BOM, // UTF8 with BOM + UTF8_NOBOM, // UTF8 without BOM + UTF16_LE_BOM, // UTF16 LE with BOM + UTF16_LE_NOBOM, // UTF16 LE without BOM + UTF16_BE_BOM, // UTF16-BE with BOM + UTF16_BE_NOBOM, // UTF16-BE without BOM + }; + + TextEncodingDetect(); + ~TextEncodingDetect() = default; + + static Encoding CheckBOM( + const unsigned char *pBuffer, + size_t size); // Just check if there is a BOM and return + Encoding DetectEncoding(const unsigned char *pBuffer, size_t size) + const; // Check BOM and also guess if there is no BOM + static int GetBOMLengthFromEncodingMode( + Encoding encoding); // Just return the BOM length of a given mode + + void SetNullSuggestsBinary(bool null_suggests_binary) { + null_suggests_binary_ = null_suggests_binary; + } + void SetUtf16UnexpectedNullPercent(int percent); + void SetUtf16ExpectedNullPercent(int percent); + + private: + TextEncodingDetect(const TextEncodingDetect &); + const TextEncodingDetect &operator=(const TextEncodingDetect &); + + static const unsigned char *utf16_bom_le_; + static const unsigned char *utf16_bom_be_; + static const unsigned char *utf8_bom_; + + bool null_suggests_binary_; + int utf16_expected_null_percent_; + int utf16_unexpected_null_percent_; + + Encoding CheckUTF8(const unsigned char *pBuffer, + size_t size) const; // Check for valid UTF8 with no BOM + static Encoding CheckUTF16NewlineChars( + const unsigned char *pBuffer, + size_t size); // Check for valid UTF16 with no BOM via control chars + Encoding CheckUTF16ASCII(const unsigned char *pBuffer, size_t size) + const; // Check for valid UTF16 with no BOM via null distribution + static bool DoesContainNulls(const unsigned char *pBuffer, + size_t size); // Check for nulls +}; + +} // namespace AutoIt::Common + +////////////////////////////////////////////////////////////////////// + +#endif diff --git a/third_party/json b/third_party/json new file mode 160000 +Subproject c6740d7d58a209da8960c961ee07bfb0e841e44 diff --git a/third_party/json/json.hpp b/third_party/json/json.hpp deleted file mode 100644 index 87475ab3..00000000 --- a/third_party/json/json.hpp +++ /dev/null @@ -1,26753 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.10.4 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -Licensed under the MIT License <http://opensource.org/licenses/MIT>. -SPDX-License-Identifier: MIT -Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 10 -#define NLOHMANN_JSON_VERSION_PATCH 4 - -#include <algorithm> // all_of, find, for_each -#include <cstddef> // nullptr_t, ptrdiff_t, size_t -#include <functional> // hash, less -#include <initializer_list> // initializer_list -#ifndef JSON_NO_IO - #include <iosfwd> // istream, ostream -#endif // JSON_NO_IO -#include <iterator> // random_access_iterator_tag -#include <memory> // unique_ptr -#include <numeric> // accumulate -#include <string> // string, stoi, to_string -#include <utility> // declval, forward, move, pair, swap -#include <vector> // vector - -// #include <nlohmann/adl_serializer.hpp> - - -#include <type_traits> -#include <utility> - -// #include <nlohmann/detail/conversions/from_json.hpp> - - -#include <algorithm> // transform -#include <array> // array -#include <forward_list> // forward_list -#include <iterator> // inserter, front_inserter, end -#include <map> // map -#include <string> // string -#include <tuple> // tuple, make_tuple -#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include <unordered_map> // unordered_map -#include <utility> // pair, declval -#include <valarray> // valarray - -// #include <nlohmann/detail/exceptions.hpp> - - -#include <exception> // exception -#include <stdexcept> // runtime_error -#include <string> // to_string -#include <vector> // vector - -// #include <nlohmann/detail/value_t.hpp> - - -#include <array> // array -#include <cstddef> // size_t -#include <cstdint> // uint8_t -#include <string> // string - -namespace nlohmann -{ -namespace detail -{ -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - static constexpr std::array<std::uint8_t, 9> order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast<std::size_t>(lhs); - const auto r_index = static_cast<std::size_t>(rhs); - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -} -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/string_escape.hpp> - - -#include <string> -// #include <nlohmann/detail/macro_scope.hpp> - - -#include <utility> // declval, pair -// #include <nlohmann/thirdparty/hedley/hedley.hpp> - - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson <[email protected]> - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>. - * SPDX-License-Identifier: CC0-1.0 - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) - #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) - #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) - #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include <stdint.h> - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include <stdint.h> - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else - #define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - -// #include <nlohmann/detail/meta/detected.hpp> - - -#include <type_traits> - -// #include <nlohmann/detail/meta/void_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ -template<typename ...Ts> struct make_void -{ - using type = void; -}; -template<typename ...Ts> using void_t = typename make_void<Ts...>::type; -} // namespace detail -} // namespace nlohmann - - -// https://en.cppreference.com/w/cpp/experimental/is_detected -namespace nlohmann -{ -namespace detail -{ -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template<class Default, - class AlwaysVoid, - template<class...> class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template<class Default, template<class...> class Op, class... Args> -struct detector<Default, void_t<Op<Args...>>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op<Args...>; -}; - -template<template<class...> class Op, class... Args> -using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t; - -template<template<class...> class Op, class... Args> -struct is_detected_lazy : is_detected<Op, Args...> { }; - -template<template<class...> class Op, class... Args> -using detected_t = typename detector<nonesuch, void, Op, Args...>::type; - -template<class Default, template<class...> class Op, class... Args> -using detected_or = detector<Default, void, Op, Args...>; - -template<class Default, template<class...> class Op, class... Args> -using detected_or_t = typename detected_or<Default, Op, Args...>::type; - -template<class Expected, template<class...> class Op, class... Args> -using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>; - -template<class To, template<class...> class Op, class... Args> -using is_detected_convertible = - std::is_convertible<detected_t<Op, Args...>, To>; -} // namespace detail -} // namespace nlohmann - - -// This file contains all internal macro definitions -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -// if the user manually specified the used c++ version this is skipped -#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) - #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 - #endif - // the cpp 11 flag is always specified because it is the minimal required version - #define JSON_HAS_CPP_11 -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow to disable exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include <cstdlib> - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow to override assert -#if !defined(JSON_ASSERT) - #include <cassert> // assert - #define JSON_ASSERT(x) assert(x) -#endif - -// allow to access some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) - #define JSON_PRIVATE_UNLESS_TESTED public -#else - #define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template<typename BasicJsonType> \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template<typename BasicJsonType> \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template<template<typename, typename, typename...> class ObjectType, \ - template<typename, typename...> class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template<typename> class AllocatorType, \ - template<typename, typename = void> class JSONSerializer, \ - class BinaryType> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json<ObjectType, ArrayType, StringType, BooleanType, \ - NumberIntegerType, NumberUnsignedType, NumberFloatType, \ - AllocatorType, JSONSerializer, BinaryType> - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - - -// inspired from https://stackoverflow.com/a/26745591 -// allows to call any std function as if (e.g. with begin): -// using std::begin; begin(x); -// -// it allows using the detected idiom to retrieve the return type -// of such an expression -#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ - namespace detail { \ - using std::std_name; \ - \ - template<typename... T> \ - using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \ - } \ - \ - namespace detail2 { \ - struct std_name##_tag \ - { \ - }; \ - \ - template<typename... T> \ - std_name##_tag std_name(T&&...); \ - \ - template<typename... T> \ - using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \ - \ - template<typename... T> \ - struct would_call_std_##std_name \ - { \ - static constexpr auto const value = ::nlohmann::detail:: \ - is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \ - }; \ - } /* namespace detail2 */ \ - \ - template<typename... T> \ - struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \ - { \ - } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 -#endif - - -namespace nlohmann -{ -namespace detail -{ - -/*! -@brief replace all occurrences of a substring by another string - -@param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t -@param[in] f the substring to replace with @a t -@param[in] t the string to replace @a f - -@pre The search string @a f must not be empty. **This precondition is -enforced with an assertion.** - -@since version 2.0.0 -*/ -inline void replace_substring(std::string& s, const std::string& f, - const std::string& t) -{ - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find first occurrence of f - pos != std::string::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find next occurrence of f - {} -} - -/*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ -inline std::string escape(std::string s) -{ - replace_substring(s, "~", "~0"); - replace_substring(s, "/", "~1"); - return s; -} - -/*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ -static void unescape(std::string& s) -{ - replace_substring(s, "~1", "/"); - replace_substring(s, "~0", "~"); -} - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/input/position_t.hpp> - - -#include <cstddef> // size_t - -namespace nlohmann -{ -namespace detail -{ -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ -//////////////// -// exceptions // -//////////////// - -/*! -@brief general exception of the @ref basic_json class - -This class is an extension of `std::exception` objects with a member @a id for -exception ids. It is used as the base class for all exceptions thrown by the -@ref basic_json class. This class can hence be used as "wildcard" to catch -exceptions. - -Subclasses: -- @ref parse_error for exceptions indicating a parse error -- @ref invalid_iterator for exceptions indicating errors with iterators -- @ref type_error for exceptions indicating executing a member function with - a wrong type -- @ref out_of_range for exceptions indicating access out of the defined range -- @ref other_error for exceptions indicating other library errors - -@internal -@note To have nothrow-copy-constructible exceptions, we internally use - `std::runtime_error` which can cope with arbitrary-length error messages. - Intermediate strings are built with static functions and then passed to - the actual constructor. -@endinternal - -@liveexample{The following code shows how arbitrary library exceptions can be -caught.,exception} - -@since version 3.0.0 -*/ -class exception : public std::exception -{ - public: - /// returns the explanatory string - const char* what() const noexcept override - { - return m.what(); - } - - /// the id of the exception - const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) - - protected: - JSON_HEDLEY_NON_NULL(3) - exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} - - static std::string name(const std::string& ename, int id_) - { - return "[json.exception." + ename + "." + std::to_string(id_) + "] "; - } - - template<typename BasicJsonType> - static std::string diagnostics(const BasicJsonType& leaf_element) - { -#if JSON_DIAGNOSTICS - std::vector<std::string> tokens; - for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent) - { - switch (current->m_parent->type()) - { - case value_t::array: - { - for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i) - { - if (¤t->m_parent->m_value.array->operator[](i) == current) - { - tokens.emplace_back(std::to_string(i)); - break; - } - } - break; - } - - case value_t::object: - { - for (const auto& element : *current->m_parent->m_value.object) - { - if (&element.second == current) - { - tokens.emplace_back(element.first.c_str()); - break; - } - } - break; - } - - case value_t::null: // LCOV_EXCL_LINE - case value_t::string: // LCOV_EXCL_LINE - case value_t::boolean: // LCOV_EXCL_LINE - case value_t::number_integer: // LCOV_EXCL_LINE - case value_t::number_unsigned: // LCOV_EXCL_LINE - case value_t::number_float: // LCOV_EXCL_LINE - case value_t::binary: // LCOV_EXCL_LINE - case value_t::discarded: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - break; // LCOV_EXCL_LINE - } - } - - if (tokens.empty()) - { - return ""; - } - - return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, - [](const std::string & a, const std::string & b) - { - return a + "/" + detail::escape(b); - }) + ") "; -#else - static_cast<void>(leaf_element); - return ""; -#endif - } - - private: - /// an exception object as storage for error messages - std::runtime_error m; -}; - -/*! -@brief exception indicating a parse error - -This exception is thrown by the library when a parse error occurs. Parse errors -can occur during the deserialization of JSON text, CBOR, MessagePack, as well -as when using JSON Patch. - -Member @a byte holds the byte index of the last read character in the input -file. - -Exceptions have ids 1xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position. -json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. -json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. -json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. -json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. -json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. -json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. -json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences. -json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number. -json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. -json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. -json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. -json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). -json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed. - -@note For an input with n bytes, 1 is the index of the first character and n+1 - is the index of the terminating null byte or the end of file. This also - holds true when reading a byte vector (CBOR or MessagePack). - -@liveexample{The following code shows how a `parse_error` exception can be -caught.,parse_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class parse_error : public exception -{ - public: - /*! - @brief create a parse error exception - @param[in] id_ the id of the exception - @param[in] pos the position where the error occurred (or with - chars_read_total=0 if the position cannot be - determined) - @param[in] what_arg the explanatory string - @return parse_error object - */ - template<typename BasicJsonType> - static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - position_string(pos) + ": " + exception::diagnostics(context) + what_arg; - return parse_error(id_, pos.chars_read_total, w.c_str()); - } - - template<typename BasicJsonType> - static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("parse_error", id_) + "parse error" + - (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + - ": " + exception::diagnostics(context) + what_arg; - return parse_error(id_, byte_, w.c_str()); - } - - /*! - @brief byte index of the parse error - - The byte index of the last read character in the input file. - - @note For an input with n bytes, 1 is the index of the first character and - n+1 is the index of the terminating null byte or the end of file. - This also holds true when reading a byte vector (CBOR or MessagePack). - */ - const std::size_t byte; - - private: - parse_error(int id_, std::size_t byte_, const char* what_arg) - : exception(id_, what_arg), byte(byte_) {} - - static std::string position_string(const position_t& pos) - { - return " at line " + std::to_string(pos.lines_read + 1) + - ", column " + std::to_string(pos.chars_read_current_line); - } -}; - -/*! -@brief exception indicating errors with iterators - -This exception is thrown if iterators passed to a library function do not match -the expected semantics. - -Exceptions have ids 2xx. - -name / id | example message | description ------------------------------------ | --------------- | ------------------------- -json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. -json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. -json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid. -json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid. -json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range. -json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. -json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to. -json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container. -json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered. -json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin(). - -@liveexample{The following code shows how an `invalid_iterator` exception can be -caught.,invalid_iterator} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class invalid_iterator : public exception -{ - public: - template<typename BasicJsonType> - static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg; - return invalid_iterator(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - invalid_iterator(int id_, const char* what_arg) - : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating executing a member function with a wrong type - -This exception is thrown in case of a type error; that is, a library function is -executed on a JSON value whose type does not match the expected semantics. - -Exceptions have ids 3xx. - -name / id | example message | description ------------------------------ | --------------- | ------------------------- -json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. -json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. -json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. -json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. -json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. -json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types. -json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types. -json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types. -json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types. -json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types. -json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types. -json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined. -json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers. -json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive. -json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. | -json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) | - -@liveexample{The following code shows how a `type_error` exception can be -caught.,type_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class type_error : public exception -{ - public: - template<typename BasicJsonType> - static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg; - return type_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating access out of the defined range - -This exception is thrown in case a library function is called on an input -parameter that exceeds the expected range, for instance in case of array -indices or nonexisting object keys. - -Exceptions have ids 4xx. - -name / id | example message | description -------------------------------- | --------------- | ------------------------- -json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1. -json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. -json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object. -json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. -json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. -json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. -json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) | -json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | - -@liveexample{The following code shows how an `out_of_range` exception can be -caught.,out_of_range} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ -class out_of_range : public exception -{ - public: - template<typename BasicJsonType> - static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg; - return out_of_range(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; - -/*! -@brief exception indicating other library errors - -This exception is thrown in case of errors that cannot be classified with the -other exception types. - -Exceptions have ids 5xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range - -@liveexample{The following code shows how an `other_error` exception can be -caught.,other_error} - -@since version 3.0.0 -*/ -class other_error : public exception -{ - public: - template<typename BasicJsonType> - static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context) - { - std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg; - return other_error(id_, w.c_str()); - } - - private: - JSON_HEDLEY_NON_NULL(3) - other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/meta/cpp_future.hpp> - - -#include <cstddef> // size_t -#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include <utility> // index_sequence, make_index_sequence, index_sequence_for - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ - -template<typename T> -using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type; - -#ifdef JSON_HAS_CPP_14 - -// the following utilities are natively available in C++14 -using std::enable_if_t; -using std::index_sequence; -using std::make_index_sequence; -using std::index_sequence_for; - -#else - -// alias templates to reduce boilerplate -template<bool B, typename T = void> -using enable_if_t = typename std::enable_if<B, T>::type; - -// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h -// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - -//// START OF CODE FROM GOOGLE ABSEIL - -// integer_sequence -// -// Class template representing a compile-time integer sequence. An instantiation -// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its -// type through its template arguments (which is a common need when -// working with C++11 variadic templates). `absl::integer_sequence` is designed -// to be a drop-in replacement for C++14's `std::integer_sequence`. -// -// Example: -// -// template< class T, T... Ints > -// void user_function(integer_sequence<T, Ints...>); -// -// int main() -// { -// // user_function's `T` will be deduced to `int` and `Ints...` -// // will be deduced to `0, 1, 2, 3, 4`. -// user_function(make_integer_sequence<int, 5>()); -// } -template <typename T, T... Ints> -struct integer_sequence -{ - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -// index_sequence -// -// A helper template for an `integer_sequence` of `size_t`, -// `absl::index_sequence` is designed to be a drop-in replacement for C++14's -// `std::index_sequence`. -template <size_t... Ints> -using index_sequence = integer_sequence<size_t, Ints...>; - -namespace utility_internal -{ - -template <typename Seq, size_t SeqSize, size_t Rem> -struct Extend; - -// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. -template <typename T, T... Ints, size_t SeqSize> -struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; -}; - -template <typename T, T... Ints, size_t SeqSize> -struct Extend<integer_sequence<T, Ints...>, SeqSize, 1> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; -}; - -// Recursion helper for 'make_integer_sequence<T, N>'. -// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'. -template <typename T, size_t N> -struct Gen -{ - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; -}; - -template <typename T> -struct Gen<T, 0> -{ - using type = integer_sequence<T>; -}; - -} // namespace utility_internal - -// Compile-time sequences of integers - -// make_integer_sequence -// -// This template alias is equivalent to -// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in -// replacement for C++14's `std::make_integer_sequence`. -template <typename T, T N> -using make_integer_sequence = typename utility_internal::Gen<T, N>::type; - -// make_index_sequence -// -// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, -// and is designed to be a drop-in replacement for C++14's -// `std::make_index_sequence`. -template <size_t N> -using make_index_sequence = make_integer_sequence<size_t, N>; - -// index_sequence_for -// -// Converts a typename pack into an index sequence of the same length, and -// is designed to be a drop-in replacement for C++14's -// `std::index_sequence_for()` -template <typename... Ts> -using index_sequence_for = make_index_sequence<sizeof...(Ts)>; - -//// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) -template<unsigned N> struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template<typename T> -struct static_const -{ - static constexpr T value{}; -}; - -template<typename T> -constexpr T static_const<T>::value; - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/meta/identity_tag.hpp> - - -namespace nlohmann -{ -namespace detail -{ -// dispatching helper struct -template <class T> struct identity_tag {}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/meta/type_traits.hpp> - - -#include <limits> // numeric_limits -#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type -#include <utility> // declval -#include <tuple> // tuple - -// #include <nlohmann/detail/macro_scope.hpp> - - -// #include <nlohmann/detail/iterators/iterator_traits.hpp> - - -#include <iterator> // random_access_iterator_tag - -// #include <nlohmann/detail/meta/void_t.hpp> - -// #include <nlohmann/detail/meta/cpp_future.hpp> - - -namespace nlohmann -{ -namespace detail -{ -template<typename It, typename = void> -struct iterator_types {}; - -template<typename It> -struct iterator_types < - It, - void_t<typename It::difference_type, typename It::value_type, typename It::pointer, - typename It::reference, typename It::iterator_category >> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template<typename T, typename = void> -struct iterator_traits -{ -}; - -template<typename T> -struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> - : iterator_types<T> -{ -}; - -template<typename T> -struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/meta/call_std/begin.hpp> - - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); -} // namespace nlohmann - -// #include <nlohmann/detail/meta/call_std/end.hpp> - - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); -} // namespace nlohmann - -// #include <nlohmann/detail/meta/cpp_future.hpp> - -// #include <nlohmann/detail/meta/detected.hpp> - -// #include <nlohmann/json_fwd.hpp> -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - -#include <cstdint> // int64_t, uint64_t -#include <map> // map -#include <memory> // allocator -#include <string> // string -#include <vector> // vector - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ -/*! -@brief default JSONSerializer template argument - -This serializer ignores the template arguments and uses ADL -([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) -for serialization. -*/ -template<typename T = void, typename SFINAE = void> -struct adl_serializer; - -template<template<typename U, typename V, typename... Args> class ObjectType = - std::map, - template<typename U, typename... Args> class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template<typename U> class AllocatorType = std::allocator, - template<typename T, typename SFINAE = void> class JSONSerializer = - adl_serializer, - class BinaryType = std::vector<std::uint8_t>> -class basic_json; - -/*! -@brief JSON Pointer - -A JSON pointer defines a string syntax for identifying a specific value -within a JSON document. It can be used with functions `at` and -`operator[]`. Furthermore, JSON pointers are the base for JSON patches. - -@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) - -@since version 2.0.0 -*/ -template<typename BasicJsonType> -class json_pointer; - -/*! -@brief default JSON class - -This type is the default specialization of the @ref basic_json class which -uses the standard template types. - -@since version 1.0.0 -*/ -using json = basic_json<>; - -template<class Key, class T, class IgnoredLess, class Allocator> -struct ordered_map; - -/*! -@brief ordered JSON class - -This type preserves the insertion order of object keys. - -@since version 3.9.0 -*/ -using ordered_json = basic_json<nlohmann::ordered_map>; - -} // namespace nlohmann - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -namespace nlohmann -{ -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e. those of the form: decltype(T::member_function(std::declval<T>()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g. to_json(BasicJsonType&, const T&)) - -template<typename> struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template<typename> -class json_ref; - -template<typename> -struct is_json_ref : std::false_type {}; - -template<typename T> -struct is_json_ref<json_ref<T>> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template<typename T> -using mapped_type_t = typename T::mapped_type; - -template<typename T> -using key_type_t = typename T::key_type; - -template<typename T> -using value_type_t = typename T::value_type; - -template<typename T> -using difference_type_t = typename T::difference_type; - -template<typename T> -using pointer_t = typename T::pointer; - -template<typename T> -using reference_t = typename T::reference; - -template<typename T> -using iterator_category_t = typename T::iterator_category; - -template<typename T, typename... Args> -using to_json_function = decltype(T::to_json(std::declval<Args>()...)); - -template<typename T, typename... Args> -using from_json_function = decltype(T::from_json(std::declval<Args>()...)); - -template<typename T, typename U> -using get_template_function = decltype(std::declval<T>().template get<U>()); - -// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists -template<typename BasicJsonType, typename T, typename = void> -struct has_from_json : std::false_type {}; - -// trait checking if j.get<T> is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template <typename BasicJsonType, typename T> -struct is_getable -{ - static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value; -}; - -template<typename BasicJsonType, typename T> -struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> -{ - using serializer = typename BasicJsonType::template json_serializer<T, void>; - - static constexpr bool value = - is_detected_exact<void, from_json_function, serializer, - const BasicJsonType&, T&>::value; -}; - -// This trait checks if JSONSerializer<T>::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template<typename BasicJsonType, typename T, typename = void> -struct has_non_default_from_json : std::false_type {}; - -template<typename BasicJsonType, typename T> -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> -{ - using serializer = typename BasicJsonType::template json_serializer<T, void>; - - static constexpr bool value = - is_detected_exact<T, from_json_function, serializer, - const BasicJsonType&>::value; -}; - -// This trait checks if BasicJsonType::json_serializer<T>::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template<typename BasicJsonType, typename T, typename = void> -struct has_to_json : std::false_type {}; - -template<typename BasicJsonType, typename T> -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >> -{ - using serializer = typename BasicJsonType::template json_serializer<T, void>; - - static constexpr bool value = - is_detected_exact<void, to_json_function, serializer, BasicJsonType&, - T>::value; -}; - - -/////////////////// -// is_ functions // -/////////////////// - -// https://en.cppreference.com/w/cpp/types/conjunction -template<class...> struct conjunction : std::true_type { }; -template<class B1> struct conjunction<B1> : B1 { }; -template<class B1, class... Bn> -struct conjunction<B1, Bn...> -: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {}; - -// https://en.cppreference.com/w/cpp/types/negation -template<class B> struct negation : std::integral_constant < bool, !B::value > { }; - -// Reimplementation of is_constructible and is_default_constructible, due to them being broken for -// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). -// This causes compile errors in e.g. clang 3.5 or gcc 4.9. -template <typename T> -struct is_default_constructible : std::is_default_constructible<T> {}; - -template <typename T1, typename T2> -struct is_default_constructible<std::pair<T1, T2>> - : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {}; - -template <typename T1, typename T2> -struct is_default_constructible<const std::pair<T1, T2>> - : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {}; - -template <typename... Ts> -struct is_default_constructible<std::tuple<Ts...>> - : conjunction<is_default_constructible<Ts>...> {}; - -template <typename... Ts> -struct is_default_constructible<const std::tuple<Ts...>> - : conjunction<is_default_constructible<Ts>...> {}; - - -template <typename T, typename... Args> -struct is_constructible : std::is_constructible<T, Args...> {}; - -template <typename T1, typename T2> -struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {}; - -template <typename T1, typename T2> -struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {}; - -template <typename... Ts> -struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {}; - -template <typename... Ts> -struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {}; - - -template<typename T, typename = void> -struct is_iterator_traits : std::false_type {}; - -template<typename T> -struct is_iterator_traits<iterator_traits<T>> -{ - private: - using traits = iterator_traits<T>; - - public: - static constexpr auto value = - is_detected<value_type_t, traits>::value && - is_detected<difference_type_t, traits>::value && - is_detected<pointer_t, traits>::value && - is_detected<iterator_category_t, traits>::value && - is_detected<reference_t, traits>::value; -}; - -template<typename T> -struct is_range -{ - private: - using t_ref = typename std::add_lvalue_reference<T>::type; - - using iterator = detected_t<result_of_begin, t_ref>; - using sentinel = detected_t<result_of_end, t_ref>; - - // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator - // and https://en.cppreference.com/w/cpp/iterator/sentinel_for - // but reimplementing these would be too much work, as a lot of other concepts are used underneath - static constexpr auto is_iterator_begin = - is_iterator_traits<iterator_traits<iterator>>::value; - - public: - static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin; -}; - -template<typename R> -using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>; - -template<typename T> -using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>; - -// The following implementation of is_complete_type is taken from -// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ -// and is written by Xiang Fan who agreed to using it in this library. - -template<typename T, typename = void> -struct is_complete_type : std::false_type {}; - -template<typename T> -struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {}; - -template<typename BasicJsonType, typename CompatibleObjectType, - typename = void> -struct is_compatible_object_type_impl : std::false_type {}; - -template<typename BasicJsonType, typename CompatibleObjectType> -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&& - is_detected<key_type_t, CompatibleObjectType>::value >> -{ - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible<typename object_t::key_type, - typename CompatibleObjectType::key_type>::value && - is_constructible<typename object_t::mapped_type, - typename CompatibleObjectType::mapped_type>::value; -}; - -template<typename BasicJsonType, typename CompatibleObjectType> -struct is_compatible_object_type - : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {}; - -template<typename BasicJsonType, typename ConstructibleObjectType, - typename = void> -struct is_constructible_object_type_impl : std::false_type {}; - -template<typename BasicJsonType, typename ConstructibleObjectType> -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&& - is_detected<key_type_t, ConstructibleObjectType>::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible<ConstructibleObjectType>::value && - (std::is_move_assignable<ConstructibleObjectType>::value || - std::is_copy_assignable<ConstructibleObjectType>::value) && - (is_constructible<typename ConstructibleObjectType::key_type, - typename object_t::key_type>::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json<BasicJsonType, - typename ConstructibleObjectType::mapped_type>::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template<typename BasicJsonType, typename ConstructibleObjectType> -struct is_constructible_object_type - : is_constructible_object_type_impl<BasicJsonType, - ConstructibleObjectType> {}; - -template<typename BasicJsonType, typename CompatibleStringType> -struct is_compatible_string_type -{ - static constexpr auto value = - is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value; -}; - -template<typename BasicJsonType, typename ConstructibleStringType> -struct is_constructible_string_type -{ - static constexpr auto value = - is_constructible<ConstructibleStringType, - typename BasicJsonType::string_t>::value; -}; - -template<typename BasicJsonType, typename CompatibleArrayType, typename = void> -struct is_compatible_array_type_impl : std::false_type {}; - -template<typename BasicJsonType, typename CompatibleArrayType> -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < - is_detected<iterator_t, CompatibleArrayType>::value&& - is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >> -{ - static constexpr bool value = - is_constructible<BasicJsonType, - range_value_t<CompatibleArrayType>>::value; -}; - -template<typename BasicJsonType, typename CompatibleArrayType> -struct is_compatible_array_type - : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {}; - -template<typename BasicJsonType, typename ConstructibleArrayType, typename = void> -struct is_constructible_array_type_impl : std::false_type {}; - -template<typename BasicJsonType, typename ConstructibleArrayType> -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t<std::is_same<ConstructibleArrayType, - typename BasicJsonType::value_type>::value >> - : std::true_type {}; - -template<typename BasicJsonType, typename ConstructibleArrayType> -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same<ConstructibleArrayType, - typename BasicJsonType::value_type>::value&& - !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&& - is_default_constructible<ConstructibleArrayType>::value&& -(std::is_move_assignable<ConstructibleArrayType>::value || - std::is_copy_assignable<ConstructibleArrayType>::value)&& -is_detected<iterator_t, ConstructibleArrayType>::value&& -is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&& -is_detected<range_value_t, ConstructibleArrayType>::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 -!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&& - is_complete_type < - detected_t<range_value_t, ConstructibleArrayType >>::value >> -{ - using value_type = range_value_t<ConstructibleArrayType>; - - static constexpr bool value = - std::is_same<value_type, - typename BasicJsonType::array_t::value_type>::value || - has_from_json<BasicJsonType, - value_type>::value || - has_non_default_from_json < - BasicJsonType, - value_type >::value; -}; - -template<typename BasicJsonType, typename ConstructibleArrayType> -struct is_constructible_array_type - : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {}; - -template<typename RealIntegerType, typename CompatibleNumberIntegerType, - typename = void> -struct is_compatible_integer_type_impl : std::false_type {}; - -template<typename RealIntegerType, typename CompatibleNumberIntegerType> -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral<RealIntegerType>::value&& - std::is_integral<CompatibleNumberIntegerType>::value&& - !std::is_same<bool, CompatibleNumberIntegerType>::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits<RealIntegerType>; - using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>; - - static constexpr auto value = - is_constructible<RealIntegerType, - CompatibleNumberIntegerType>::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template<typename RealIntegerType, typename CompatibleNumberIntegerType> -struct is_compatible_integer_type - : is_compatible_integer_type_impl<RealIntegerType, - CompatibleNumberIntegerType> {}; - -template<typename BasicJsonType, typename CompatibleType, typename = void> -struct is_compatible_type_impl: std::false_type {}; - -template<typename BasicJsonType, typename CompatibleType> -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t<is_complete_type<CompatibleType>::value >> -{ - static constexpr bool value = - has_to_json<BasicJsonType, CompatibleType>::value; -}; - -template<typename BasicJsonType, typename CompatibleType> -struct is_compatible_type - : is_compatible_type_impl<BasicJsonType, CompatibleType> {}; - -template<typename T1, typename T2> -struct is_constructible_tuple : std::false_type {}; - -template<typename T1, typename... Args> -struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {}; - -// a naive helper to check if a type is an ordered_map (exploits the fact that -// ordered_map inherits capacity() from std::vector) -template <typename T> -struct is_ordered_map -{ - using one = char; - - struct two - { - char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - }; - - template <typename C> static one test( decltype(&C::capacity) ) ; - template <typename C> static two test(...); - - enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) -}; - -// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324) -template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 > -T conditional_static_cast(U value) -{ - return static_cast<T>(value); -} - -template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0> -T conditional_static_cast(U value) -{ - return value; -} - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/value_t.hpp> - - -#ifdef JSON_HAS_CPP_17 - #include <filesystem> -#endif - -namespace nlohmann -{ -namespace detail -{ -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename std::nullptr_t& n) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_null())) - { - JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j)); - } - n = nullptr; -} - -// overloads for basic_json template parameters -template < typename BasicJsonType, typename ArithmeticType, - enable_if_t < std::is_arithmetic<ArithmeticType>::value&& - !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, - int > = 0 > -void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) -{ - switch (static_cast<value_t>(j)) - { - case value_t::number_unsigned: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>()); - break; - } - case value_t::number_integer: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>()); - break; - } - case value_t::number_float: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>()); - break; - } - - case value_t::null: - case value_t::object: - case value_t::array: - case value_t::string: - case value_t::boolean: - case value_t::binary: - case value_t::discarded: - default: - JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j)); - } -} - -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) - { - JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j)); - } - b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>(); -} - -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); - } - s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); -} - -template < - typename BasicJsonType, typename ConstructibleStringType, - enable_if_t < - is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&& - !std::is_same<typename BasicJsonType::string_t, - ConstructibleStringType>::value, - int > = 0 > -void from_json(const BasicJsonType& j, ConstructibleStringType& s) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); - } - - s = *j.template get_ptr<const typename BasicJsonType::string_t*>(); -} - -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) -{ - get_arithmetic_value(j, val); -} - -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) -{ - get_arithmetic_value(j, val); -} - -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) -{ - get_arithmetic_value(j, val); -} - -template<typename BasicJsonType, typename EnumType, - enable_if_t<std::is_enum<EnumType>::value, int> = 0> -void from_json(const BasicJsonType& j, EnumType& e) -{ - typename std::underlying_type<EnumType>::type val; - get_arithmetic_value(j, val); - e = static_cast<EnumType>(val); -} - -// forward_list doesn't have an insert method -template<typename BasicJsonType, typename T, typename Allocator, - enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0> -void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - l.clear(); - std::transform(j.rbegin(), j.rend(), - std::front_inserter(l), [](const BasicJsonType & i) - { - return i.template get<T>(); - }); -} - -// valarray doesn't have an insert method -template<typename BasicJsonType, typename T, - enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0> -void from_json(const BasicJsonType& j, std::valarray<T>& l) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - l.resize(j.size()); - std::transform(j.begin(), j.end(), std::begin(l), - [](const BasicJsonType & elem) - { - return elem.template get<T>(); - }); -} - -template<typename BasicJsonType, typename T, std::size_t N> -auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) --> decltype(j.template get<T>(), void()) -{ - for (std::size_t i = 0; i < N; ++i) - { - arr[i] = j.at(i).template get<T>(); - } -} - -template<typename BasicJsonType> -void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) -{ - arr = *j.template get_ptr<const typename BasicJsonType::array_t*>(); -} - -template<typename BasicJsonType, typename T, std::size_t N> -auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, - priority_tag<2> /*unused*/) --> decltype(j.template get<T>(), void()) -{ - for (std::size_t i = 0; i < N; ++i) - { - arr[i] = j.at(i).template get<T>(); - } -} - -template<typename BasicJsonType, typename ConstructibleArrayType, - enable_if_t< - std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, - int> = 0> -auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) --> decltype( - arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()), - j.template get<typename ConstructibleArrayType::value_type>(), - void()) -{ - using std::end; - - ConstructibleArrayType ret; - ret.reserve(j.size()); - std::transform(j.begin(), j.end(), - std::inserter(ret, end(ret)), [](const BasicJsonType & i) - { - // get<BasicJsonType>() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get<typename ConstructibleArrayType::value_type>(); - }); - arr = std::move(ret); -} - -template<typename BasicJsonType, typename ConstructibleArrayType, - enable_if_t< - std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value, - int> = 0> -void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, - priority_tag<0> /*unused*/) -{ - using std::end; - - ConstructibleArrayType ret; - std::transform( - j.begin(), j.end(), std::inserter(ret, end(ret)), - [](const BasicJsonType & i) - { - // get<BasicJsonType>() returns *this, this won't call a from_json - // method when value_type is BasicJsonType - return i.template get<typename ConstructibleArrayType::value_type>(); - }); - arr = std::move(ret); -} - -template < typename BasicJsonType, typename ConstructibleArrayType, - enable_if_t < - is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&& - !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&& - !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&& - !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&& - !is_basic_json<ConstructibleArrayType>::value, - int > = 0 > -auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) --> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), -j.template get<typename ConstructibleArrayType::value_type>(), -void()) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - - from_json_array_impl(j, arr, priority_tag<3> {}); -} - -template < typename BasicJsonType, typename T, std::size_t... Idx > -std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j, - identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/) -{ - return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } }; -} - -template < typename BasicJsonType, typename T, std::size_t N > -auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag) --> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {})) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - - return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}); -} - -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j)); - } - - bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>(); -} - -template<typename BasicJsonType, typename ConstructibleObjectType, - enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0> -void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j)); - } - - ConstructibleObjectType ret; - const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>(); - using value_type = typename ConstructibleObjectType::value_type; - std::transform( - inner_object->begin(), inner_object->end(), - std::inserter(ret, ret.begin()), - [](typename BasicJsonType::object_t::value_type const & p) - { - return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>()); - }); - obj = std::move(ret); -} - -// overload for arithmetic types, not chosen for basic_json template arguments -// (BooleanType, etc..); note: Is it really necessary to provide explicit -// overloads for boolean_t etc. in case of a custom BooleanType which is not -// an arithmetic type? -template < typename BasicJsonType, typename ArithmeticType, - enable_if_t < - std::is_arithmetic<ArithmeticType>::value&& - !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&& - !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&& - !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&& - !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value, - int > = 0 > -void from_json(const BasicJsonType& j, ArithmeticType& val) -{ - switch (static_cast<value_t>(j)) - { - case value_t::number_unsigned: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>()); - break; - } - case value_t::number_integer: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>()); - break; - } - case value_t::number_float: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>()); - break; - } - case value_t::boolean: - { - val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>()); - break; - } - - case value_t::null: - case value_t::object: - case value_t::array: - case value_t::string: - case value_t::binary: - case value_t::discarded: - default: - JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j)); - } -} - -template<typename BasicJsonType, typename... Args, std::size_t... Idx> -std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/) -{ - return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...); -} - -template < typename BasicJsonType, class A1, class A2 > -std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/) -{ - return {std::forward<BasicJsonType>(j).at(0).template get<A1>(), - std::forward<BasicJsonType>(j).at(1).template get<A2>()}; -} - -template<typename BasicJsonType, typename A1, typename A2> -void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/) -{ - p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {}); -} - -template<typename BasicJsonType, typename... Args> -std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/) -{ - return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {}); -} - -template<typename BasicJsonType, typename... Args> -void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/) -{ - t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {}); -} - -template<typename BasicJsonType, typename TupleRelated> -auto from_json(BasicJsonType&& j, TupleRelated&& t) --> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {})) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - - return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}); -} - -template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, - typename = enable_if_t < !std::is_constructible < - typename BasicJsonType::string_t, Key >::value >> -void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - m.clear(); - for (const auto& p : j) - { - if (JSON_HEDLEY_UNLIKELY(!p.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j)); - } - m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); - } -} - -template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, - typename = enable_if_t < !std::is_constructible < - typename BasicJsonType::string_t, Key >::value >> -void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j)); - } - m.clear(); - for (const auto& p : j) - { - if (JSON_HEDLEY_UNLIKELY(!p.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j)); - } - m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>()); - } -} - -#ifdef JSON_HAS_CPP_17 -template<typename BasicJsonType> -void from_json(const BasicJsonType& j, std::filesystem::path& p) -{ - if (JSON_HEDLEY_UNLIKELY(!j.is_string())) - { - JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j)); - } - p = *j.template get_ptr<const typename BasicJsonType::string_t*>(); -} -#endif - -struct from_json_fn -{ - template<typename BasicJsonType, typename T> - auto operator()(const BasicJsonType& j, T&& val) const - noexcept(noexcept(from_json(j, std::forward<T>(val)))) - -> decltype(from_json(j, std::forward<T>(val))) - { - return from_json(j, std::forward<T>(val)); - } -}; -} // namespace detail - -/// namespace to hold default `from_json` function -/// to see why this is required: -/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) -{ -constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers) -} // namespace -} // namespace nlohmann - -// #include <nlohmann/detail/conversions/to_json.hpp> - - -#include <algorithm> // copy -#include <iterator> // begin, end -#include <string> // string -#include <tuple> // tuple, get -#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type -#include <utility> // move, forward, declval, pair -#include <valarray> // valarray -#include <vector> // vector - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/iterators/iteration_proxy.hpp> - - -#include <cstddef> // size_t -#include <iterator> // input_iterator_tag -#include <string> // string, to_string -#include <tuple> // tuple_size, get, tuple_element -#include <utility> // move - -// #include <nlohmann/detail/meta/type_traits.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ -template<typename string_type> -void int_to_string( string_type& target, std::size_t value ) -{ - // For ADL - using std::to_string; - target = to_string(value); -} -template<typename IteratorType> class iteration_proxy_value -{ - public: - using difference_type = std::ptrdiff_t; - using value_type = iteration_proxy_value; - using pointer = value_type * ; - using reference = value_type & ; - using iterator_category = std::input_iterator_tag; - using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type; - - private: - /// the iterator - IteratorType anchor; - /// an index for arrays (used to create key names) - std::size_t array_index = 0; - /// last stringified array index - mutable std::size_t array_index_last = 0; - /// a string representation of the array index - mutable string_type array_index_str = "0"; - /// an empty string (to return a reference for primitive values) - const string_type empty_str{}; - - public: - explicit iteration_proxy_value(IteratorType it) noexcept - : anchor(std::move(it)) - {} - - /// dereference operator (needed for range-based for) - iteration_proxy_value& operator*() - { - return *this; - } - - /// increment operator (needed for range-based for) - iteration_proxy_value& operator++() - { - ++anchor; - ++array_index; - - return *this; - } - - /// equality operator (needed for InputIterator) - bool operator==(const iteration_proxy_value& o) const - { - return anchor == o.anchor; - } - - /// inequality operator (needed for range-based for) - bool operator!=(const iteration_proxy_value& o) const - { - return anchor != o.anchor; - } - - /// return key of the iterator - const string_type& key() const - { - JSON_ASSERT(anchor.m_object != nullptr); - - switch (anchor.m_object->type()) - { - // use integer array index as key - case value_t::array: - { - if (array_index != array_index_last) - { - int_to_string( array_index_str, array_index ); - array_index_last = array_index; - } - return array_index_str; - } - - // use key from the object - case value_t::object: - return anchor.key(); - - // use an empty key for all primitive types - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return empty_str; - } - } - - /// return value of the iterator - typename IteratorType::reference value() const - { - return anchor.value(); - } -}; - -/// proxy class for the items() function -template<typename IteratorType> class iteration_proxy -{ - private: - /// the container to iterate - typename IteratorType::reference container; - - public: - /// construct iteration proxy from a container - explicit iteration_proxy(typename IteratorType::reference cont) noexcept - : container(cont) {} - - /// return iterator begin (needed for range-based for) - iteration_proxy_value<IteratorType> begin() noexcept - { - return iteration_proxy_value<IteratorType>(container.begin()); - } - - /// return iterator end (needed for range-based for) - iteration_proxy_value<IteratorType> end() noexcept - { - return iteration_proxy_value<IteratorType>(container.end()); - } -}; -// Structured Bindings Support -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0> -auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key()) -{ - return i.key(); -} -// Structured Bindings Support -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0> -auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value()) -{ - return i.value(); -} -} // namespace detail -} // namespace nlohmann - -// The Addition to the STD Namespace is required to add -// Structured Bindings Support to the iteration_proxy_value class -// For further reference see https://blog.tartanllama.xyz/structured-bindings/ -// And see https://github.com/nlohmann/json/pull/1391 -namespace std -{ -#if defined(__clang__) - // Fix: https://github.com/nlohmann/json/issues/1401 - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wmismatched-tags" -#endif -template<typename IteratorType> -class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> - : public std::integral_constant<std::size_t, 2> {}; - -template<std::size_t N, typename IteratorType> -class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> -{ - public: - using type = decltype( - get<N>(std::declval < - ::nlohmann::detail::iteration_proxy_value<IteratorType >> ())); -}; -#if defined(__clang__) - #pragma clang diagnostic pop -#endif -} // namespace std - -// #include <nlohmann/detail/meta/cpp_future.hpp> - -// #include <nlohmann/detail/meta/type_traits.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -#ifdef JSON_HAS_CPP_17 - #include <filesystem> -#endif - -namespace nlohmann -{ -namespace detail -{ -////////////////// -// constructors // -////////////////// - -/* - * Note all external_constructor<>::construct functions need to call - * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an - * allocated value (e.g., a string). See bug issue - * https://github.com/nlohmann/json/issues/2865 for more information. - */ - -template<value_t> struct external_constructor; - -template<> -struct external_constructor<value_t::boolean> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::boolean; - j.m_value = b; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::string> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::string; - j.m_value = s; - j.assert_invariant(); - } - - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::string; - j.m_value = std::move(s); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleStringType, - enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value, - int > = 0 > - static void construct(BasicJsonType& j, const CompatibleStringType& str) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::string; - j.m_value.string = j.template create<typename BasicJsonType::string_t>(str); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::binary> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::binary; - j.m_value = typename BasicJsonType::binary_t(b); - j.assert_invariant(); - } - - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::binary; - j.m_value = typename BasicJsonType::binary_t(std::move(b)); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::number_float> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::number_float; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::number_unsigned> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::number_unsigned; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::number_integer> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::number_integer; - j.m_value = val; - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::array> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = arr; - j.set_parents(); - j.assert_invariant(); - } - - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = std::move(arr); - j.set_parents(); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value, - int > = 0 > - static void construct(BasicJsonType& j, const CompatibleArrayType& arr) - { - using std::begin; - using std::end; - - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr)); - j.set_parents(); - j.assert_invariant(); - } - - template<typename BasicJsonType> - static void construct(BasicJsonType& j, const std::vector<bool>& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = value_t::array; - j.m_value.array->reserve(arr.size()); - for (const bool x : arr) - { - j.m_value.array->push_back(x); - j.set_parent(j.m_value.array->back()); - } - j.assert_invariant(); - } - - template<typename BasicJsonType, typename T, - enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> - static void construct(BasicJsonType& j, const std::valarray<T>& arr) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::array; - j.m_value = value_t::array; - j.m_value.array->resize(arr.size()); - if (arr.size() > 0) - { - std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); - } - j.set_parents(); - j.assert_invariant(); - } -}; - -template<> -struct external_constructor<value_t::object> -{ - template<typename BasicJsonType> - static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::object; - j.m_value = obj; - j.set_parents(); - j.assert_invariant(); - } - - template<typename BasicJsonType> - static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) - { - j.m_value.destroy(j.m_type); - j.m_type = value_t::object; - j.m_value = std::move(obj); - j.set_parents(); - j.assert_invariant(); - } - - template < typename BasicJsonType, typename CompatibleObjectType, - enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 > - static void construct(BasicJsonType& j, const CompatibleObjectType& obj) - { - using std::begin; - using std::end; - - j.m_value.destroy(j.m_type); - j.m_type = value_t::object; - j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj)); - j.set_parents(); - j.assert_invariant(); - } -}; - -///////////// -// to_json // -///////////// - -template<typename BasicJsonType, typename T, - enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0> -void to_json(BasicJsonType& j, T b) noexcept -{ - external_constructor<value_t::boolean>::construct(j, b); -} - -template<typename BasicJsonType, typename CompatibleString, - enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0> -void to_json(BasicJsonType& j, const CompatibleString& s) -{ - external_constructor<value_t::string>::construct(j, s); -} - -template<typename BasicJsonType> -void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) -{ - external_constructor<value_t::string>::construct(j, std::move(s)); -} - -template<typename BasicJsonType, typename FloatType, - enable_if_t<std::is_floating_point<FloatType>::value, int> = 0> -void to_json(BasicJsonType& j, FloatType val) noexcept -{ - external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val)); -} - -template<typename BasicJsonType, typename CompatibleNumberUnsignedType, - enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0> -void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept -{ - external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val)); -} - -template<typename BasicJsonType, typename CompatibleNumberIntegerType, - enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0> -void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept -{ - external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val)); -} - -template<typename BasicJsonType, typename EnumType, - enable_if_t<std::is_enum<EnumType>::value, int> = 0> -void to_json(BasicJsonType& j, EnumType e) noexcept -{ - using underlying_type = typename std::underlying_type<EnumType>::type; - external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e)); -} - -template<typename BasicJsonType> -void to_json(BasicJsonType& j, const std::vector<bool>& e) -{ - external_constructor<value_t::array>::construct(j, e); -} - -template < typename BasicJsonType, typename CompatibleArrayType, - enable_if_t < is_compatible_array_type<BasicJsonType, - CompatibleArrayType>::value&& - !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&& - !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&& - !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&& - !is_basic_json<CompatibleArrayType>::value, - int > = 0 > -void to_json(BasicJsonType& j, const CompatibleArrayType& arr) -{ - external_constructor<value_t::array>::construct(j, arr); -} - -template<typename BasicJsonType> -void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) -{ - external_constructor<value_t::binary>::construct(j, bin); -} - -template<typename BasicJsonType, typename T, - enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0> -void to_json(BasicJsonType& j, const std::valarray<T>& arr) -{ - external_constructor<value_t::array>::construct(j, std::move(arr)); -} - -template<typename BasicJsonType> -void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) -{ - external_constructor<value_t::array>::construct(j, std::move(arr)); -} - -template < typename BasicJsonType, typename CompatibleObjectType, - enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 > -void to_json(BasicJsonType& j, const CompatibleObjectType& obj) -{ - external_constructor<value_t::object>::construct(j, obj); -} - -template<typename BasicJsonType> -void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) -{ - external_constructor<value_t::object>::construct(j, std::move(obj)); -} - -template < - typename BasicJsonType, typename T, std::size_t N, - enable_if_t < !std::is_constructible<typename BasicJsonType::string_t, - const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - int > = 0 > -void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) -{ - external_constructor<value_t::array>::construct(j, arr); -} - -template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 > -void to_json(BasicJsonType& j, const std::pair<T1, T2>& p) -{ - j = { p.first, p.second }; -} - -// for https://github.com/nlohmann/json/pull/1134 -template<typename BasicJsonType, typename T, - enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0> -void to_json(BasicJsonType& j, const T& b) -{ - j = { {b.key(), b.value()} }; -} - -template<typename BasicJsonType, typename Tuple, std::size_t... Idx> -void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/) -{ - j = { std::get<Idx>(t)... }; -} - -template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0> -void to_json(BasicJsonType& j, const T& t) -{ - to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {}); -} - -#ifdef JSON_HAS_CPP_17 -template<typename BasicJsonType> -void to_json(BasicJsonType& j, const std::filesystem::path& p) -{ - j = p.string(); -} -#endif - -struct to_json_fn -{ - template<typename BasicJsonType, typename T> - auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val)))) - -> decltype(to_json(j, std::forward<T>(val)), void()) - { - return to_json(j, std::forward<T>(val)); - } -}; -} // namespace detail - -/// namespace to hold default `to_json` function -/// to see why this is required: -/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) -{ -constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers) -} // namespace -} // namespace nlohmann - -// #include <nlohmann/detail/meta/identity_tag.hpp> - -// #include <nlohmann/detail/meta/type_traits.hpp> - - -namespace nlohmann -{ - -template<typename ValueType, typename> -struct adl_serializer -{ - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @note This function is chosen for default-constructible value types. - - @param[in] j JSON value to read from - @param[in,out] val value to write to - */ - template<typename BasicJsonType, typename TargetType = ValueType> - static auto from_json(BasicJsonType && j, TargetType& val) noexcept( - noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) - -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void()) - { - ::nlohmann::from_json(std::forward<BasicJsonType>(j), val); - } - - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @note This function is chosen for value types which are not default-constructible. - - @param[in] j JSON value to read from - - @return copy of the JSON value, converted to @a ValueType - */ - template<typename BasicJsonType, typename TargetType = ValueType> - static auto from_json(BasicJsonType && j) noexcept( - noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))) - -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})) - { - return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}); - } - - /*! - @brief convert any value type to a JSON value - - This function is usually called by the constructors of the @ref basic_json - class. - - @param[in,out] j JSON value to write to - @param[in] val value to read from - */ - template<typename BasicJsonType, typename TargetType = ValueType> - static auto to_json(BasicJsonType& j, TargetType && val) noexcept( - noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val)))) - -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void()) - { - ::nlohmann::to_json(j, std::forward<TargetType>(val)); - } -}; -} // namespace nlohmann - -// #include <nlohmann/byte_container_with_subtype.hpp> - - -#include <cstdint> // uint8_t, uint64_t -#include <tuple> // tie -#include <utility> // move - -namespace nlohmann -{ - -/*! -@brief an internal type for a backed binary type - -This type extends the template parameter @a BinaryType provided to `basic_json` -with a subtype used by BSON and MessagePack. This type exists so that the user -does not have to specify a type themselves with a specific naming scheme in -order to override the binary type. - -@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by - default) - -@since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0. -*/ -template<typename BinaryType> -class byte_container_with_subtype : public BinaryType -{ - public: - /// the type of the underlying container - using container_type = BinaryType; - /// the type of the subtype - using subtype_type = std::uint64_t; - - byte_container_with_subtype() noexcept(noexcept(container_type())) - : container_type() - {} - - byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) - : container_type(b) - {} - - byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) - : container_type(std::move(b)) - {} - - byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) - : container_type(b) - , m_subtype(subtype_) - , m_has_subtype(true) - {} - - byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) - : container_type(std::move(b)) - , m_subtype(subtype_) - , m_has_subtype(true) - {} - - bool operator==(const byte_container_with_subtype& rhs) const - { - return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) == - std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype); - } - - bool operator!=(const byte_container_with_subtype& rhs) const - { - return !(rhs == *this); - } - - /*! - @brief sets the binary subtype - - Sets the binary subtype of the value, also flags a binary JSON value as - having a subtype, which has implications for serialization. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void set_subtype(subtype_type subtype_) noexcept - { - m_subtype = subtype_; - m_has_subtype = true; - } - - /*! - @brief return the binary subtype - - Returns the numerical subtype of the value if it has a subtype. If it does - not have a subtype, this function will return subtype_type(-1) as a sentinel - value. - - @return the numerical subtype of the binary value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0; fixed return value to properly return - subtype_type(-1) as documented in version 3.10.0 - */ - constexpr subtype_type subtype() const noexcept - { - return m_has_subtype ? m_subtype : subtype_type(-1); - } - - /*! - @brief return whether the value has a subtype - - @return whether the value has a subtype - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - - @since version 3.8.0 - */ - constexpr bool has_subtype() const noexcept - { - return m_has_subtype; - } - - /*! - @brief clears the binary subtype - - Clears the binary subtype and flags the value as not having a subtype, which - has implications for serialization; for instance MessagePack will prefer the - bin family over the ext family. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void clear_subtype() noexcept - { - m_subtype = 0; - m_has_subtype = false; - } - - private: - subtype_type m_subtype = 0; - bool m_has_subtype = false; -}; - -} // namespace nlohmann - -// #include <nlohmann/detail/conversions/from_json.hpp> - -// #include <nlohmann/detail/conversions/to_json.hpp> - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/hash.hpp> - - -#include <cstdint> // uint8_t -#include <cstddef> // size_t -#include <functional> // hash - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ - -// boost::hash_combine -inline std::size_t combine(std::size_t seed, std::size_t h) noexcept -{ - seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); - return seed; -} - -/*! -@brief hash a JSON value - -The hash function tries to rely on std::hash where possible. Furthermore, the -type of the JSON value is taken into account to have different hash values for -null, 0, 0U, and false, etc. - -@tparam BasicJsonType basic_json specialization -@param j JSON value to hash -@return hash value of j -*/ -template<typename BasicJsonType> -std::size_t hash(const BasicJsonType& j) -{ - using string_t = typename BasicJsonType::string_t; - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - - const auto type = static_cast<std::size_t>(j.type()); - switch (j.type()) - { - case BasicJsonType::value_t::null: - case BasicJsonType::value_t::discarded: - { - return combine(type, 0); - } - - case BasicJsonType::value_t::object: - { - auto seed = combine(type, j.size()); - for (const auto& element : j.items()) - { - const auto h = std::hash<string_t> {}(element.key()); - seed = combine(seed, h); - seed = combine(seed, hash(element.value())); - } - return seed; - } - - case BasicJsonType::value_t::array: - { - auto seed = combine(type, j.size()); - for (const auto& element : j) - { - seed = combine(seed, hash(element)); - } - return seed; - } - - case BasicJsonType::value_t::string: - { - const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>()); - return combine(type, h); - } - - case BasicJsonType::value_t::boolean: - { - const auto h = std::hash<bool> {}(j.template get<bool>()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_integer: - { - const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_unsigned: - { - const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>()); - return combine(type, h); - } - - case BasicJsonType::value_t::number_float: - { - const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>()); - return combine(type, h); - } - - case BasicJsonType::value_t::binary: - { - auto seed = combine(type, j.get_binary().size()); - const auto h = std::hash<bool> {}(j.get_binary().has_subtype()); - seed = combine(seed, h); - seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype())); - for (const auto byte : j.get_binary()) - { - seed = combine(seed, std::hash<std::uint8_t> {}(byte)); - } - return seed; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - return 0; // LCOV_EXCL_LINE - } -} - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/input/binary_reader.hpp> - - -#include <algorithm> // generate_n -#include <array> // array -#include <cmath> // ldexp -#include <cstddef> // size_t -#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t -#include <cstdio> // snprintf -#include <cstring> // memcpy -#include <iterator> // back_inserter -#include <limits> // numeric_limits -#include <string> // char_traits, string -#include <utility> // make_pair, move -#include <vector> // vector - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/input/input_adapters.hpp> - - -#include <array> // array -#include <cstddef> // size_t -#include <cstring> // strlen -#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next -#include <memory> // shared_ptr, make_shared, addressof -#include <numeric> // accumulate -#include <string> // string, char_traits -#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer -#include <utility> // pair, declval - -#ifndef JSON_NO_IO - #include <cstdio> // FILE * - #include <istream> // istream -#endif // JSON_NO_IO - -// #include <nlohmann/detail/iterators/iterator_traits.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ -/// the supported input formats -enum class input_format_t { json, cbor, msgpack, ubjson, bson }; - -//////////////////// -// input adapters // -//////////////////// - -#ifndef JSON_NO_IO -/*! -Input adapter for stdio file access. This adapter read only 1 byte and do not use any - buffer. This adapter is a very low level adapter. -*/ -class file_input_adapter -{ - public: - using char_type = char; - - JSON_HEDLEY_NON_NULL(2) - explicit file_input_adapter(std::FILE* f) noexcept - : m_file(f) - {} - - // make class move-only - file_input_adapter(const file_input_adapter&) = delete; - file_input_adapter(file_input_adapter&&) noexcept = default; - file_input_adapter& operator=(const file_input_adapter&) = delete; - file_input_adapter& operator=(file_input_adapter&&) = delete; - ~file_input_adapter() = default; - - std::char_traits<char>::int_type get_character() noexcept - { - return std::fgetc(m_file); - } - - private: - /// the file pointer to read from - std::FILE* m_file; -}; - - -/*! -Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at -beginning of input. Does not support changing the underlying std::streambuf -in mid-input. Maintains underlying std::istream and std::streambuf to support -subsequent use of standard std::istream operations to process any input -characters following those used in parsing the JSON input. Clears the -std::istream flags; any input errors (e.g., EOF) will be detected by the first -subsequent call for input from the std::istream. -*/ -class input_stream_adapter -{ - public: - using char_type = char; - - ~input_stream_adapter() - { - // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags, except eof - if (is != nullptr) - { - is->clear(is->rdstate() & std::ios::eofbit); - } - } - - explicit input_stream_adapter(std::istream& i) - : is(&i), sb(i.rdbuf()) - {} - - // delete because of pointer members - input_stream_adapter(const input_stream_adapter&) = delete; - input_stream_adapter& operator=(input_stream_adapter&) = delete; - input_stream_adapter& operator=(input_stream_adapter&&) = delete; - - input_stream_adapter(input_stream_adapter&& rhs) noexcept - : is(rhs.is), sb(rhs.sb) - { - rhs.is = nullptr; - rhs.sb = nullptr; - } - - // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to - // ensure that std::char_traits<char>::eof() and the character 0xFF do not - // end up as the same value, eg. 0xFFFFFFFF. - std::char_traits<char>::int_type get_character() - { - auto res = sb->sbumpc(); - // set eof manually, as we don't use the istream interface. - if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof())) - { - is->clear(is->rdstate() | std::ios::eofbit); - } - return res; - } - - private: - /// the associated input stream - std::istream* is = nullptr; - std::streambuf* sb = nullptr; -}; -#endif // JSON_NO_IO - -// General-purpose iterator-based adapter. It might not be as fast as -// theoretically possible for some containers, but it is extremely versatile. -template<typename IteratorType> -class iterator_input_adapter -{ - public: - using char_type = typename std::iterator_traits<IteratorType>::value_type; - - iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) - {} - - typename std::char_traits<char_type>::int_type get_character() - { - if (JSON_HEDLEY_LIKELY(current != end)) - { - auto result = std::char_traits<char_type>::to_int_type(*current); - std::advance(current, 1); - return result; - } - - return std::char_traits<char_type>::eof(); - } - - private: - IteratorType current; - IteratorType end; - - template<typename BaseInputAdapter, size_t T> - friend struct wide_string_input_helper; - - bool empty() const - { - return current == end; - } -}; - - -template<typename BaseInputAdapter, size_t T> -struct wide_string_input_helper; - -template<typename BaseInputAdapter> -struct wide_string_input_helper<BaseInputAdapter, 4> -{ - // UTF-32 - static void fill_buffer(BaseInputAdapter& input, - std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, - size_t& utf8_bytes_index, - size_t& utf8_bytes_filled) - { - utf8_bytes_index = 0; - - if (JSON_HEDLEY_UNLIKELY(input.empty())) - { - utf8_bytes[0] = std::char_traits<char>::eof(); - utf8_bytes_filled = 1; - } - else - { - // get the current character - const auto wc = input.get_character(); - - // UTF-32 to UTF-8 encoding - if (wc < 0x80) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); - utf8_bytes_filled = 1; - } - else if (wc <= 0x7FF) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu)); - utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); - utf8_bytes_filled = 2; - } - else if (wc <= 0xFFFF) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu)); - utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); - utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); - utf8_bytes_filled = 3; - } - else if (wc <= 0x10FFFF) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u)); - utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu)); - utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); - utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); - utf8_bytes_filled = 4; - } - else - { - // unknown character - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); - utf8_bytes_filled = 1; - } - } - } -}; - -template<typename BaseInputAdapter> -struct wide_string_input_helper<BaseInputAdapter, 2> -{ - // UTF-16 - static void fill_buffer(BaseInputAdapter& input, - std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, - size_t& utf8_bytes_index, - size_t& utf8_bytes_filled) - { - utf8_bytes_index = 0; - - if (JSON_HEDLEY_UNLIKELY(input.empty())) - { - utf8_bytes[0] = std::char_traits<char>::eof(); - utf8_bytes_filled = 1; - } - else - { - // get the current character - const auto wc = input.get_character(); - - // UTF-16 to UTF-8 encoding - if (wc < 0x80) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); - utf8_bytes_filled = 1; - } - else if (wc <= 0x7FF) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u))); - utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); - utf8_bytes_filled = 2; - } - else if (0xD800 > wc || wc >= 0xE000) - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u))); - utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); - utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); - utf8_bytes_filled = 3; - } - else - { - if (JSON_HEDLEY_UNLIKELY(!input.empty())) - { - const auto wc2 = static_cast<unsigned int>(input.get_character()); - const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u)); - utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); - utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); - utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu)); - utf8_bytes_filled = 4; - } - else - { - utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); - utf8_bytes_filled = 1; - } - } - } - } -}; - -// Wraps another input apdater to convert wide character types into individual bytes. -template<typename BaseInputAdapter, typename WideCharType> -class wide_string_input_adapter -{ - public: - using char_type = char; - - wide_string_input_adapter(BaseInputAdapter base) - : base_adapter(base) {} - - typename std::char_traits<char>::int_type get_character() noexcept - { - // check if buffer needs to be filled - if (utf8_bytes_index == utf8_bytes_filled) - { - fill_buffer<sizeof(WideCharType)>(); - - JSON_ASSERT(utf8_bytes_filled > 0); - JSON_ASSERT(utf8_bytes_index == 0); - } - - // use buffer - JSON_ASSERT(utf8_bytes_filled > 0); - JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); - return utf8_bytes[utf8_bytes_index++]; - } - - private: - BaseInputAdapter base_adapter; - - template<size_t T> - void fill_buffer() - { - wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); - } - - /// a buffer for UTF-8 bytes - std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; - - /// index to the utf8_codes array for the next valid byte - std::size_t utf8_bytes_index = 0; - /// number of valid bytes in the utf8_codes array - std::size_t utf8_bytes_filled = 0; -}; - - -template<typename IteratorType, typename Enable = void> -struct iterator_input_adapter_factory -{ - using iterator_type = IteratorType; - using char_type = typename std::iterator_traits<iterator_type>::value_type; - using adapter_type = iterator_input_adapter<iterator_type>; - - static adapter_type create(IteratorType first, IteratorType last) - { - return adapter_type(std::move(first), std::move(last)); - } -}; - -template<typename T> -struct is_iterator_of_multibyte -{ - using value_type = typename std::iterator_traits<T>::value_type; - enum - { - value = sizeof(value_type) > 1 - }; -}; - -template<typename IteratorType> -struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> -{ - using iterator_type = IteratorType; - using char_type = typename std::iterator_traits<iterator_type>::value_type; - using base_adapter_type = iterator_input_adapter<iterator_type>; - using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>; - - static adapter_type create(IteratorType first, IteratorType last) - { - return adapter_type(base_adapter_type(std::move(first), std::move(last))); - } -}; - -// General purpose iterator-based input -template<typename IteratorType> -typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last) -{ - using factory_type = iterator_input_adapter_factory<IteratorType>; - return factory_type::create(first, last); -} - -// Convenience shorthand from container to iterator -// Enables ADL on begin(container) and end(container) -// Encloses the using declarations in namespace for not to leak them to outside scope - -namespace container_input_adapter_factory_impl -{ - -using std::begin; -using std::end; - -template<typename ContainerType, typename Enable = void> -struct container_input_adapter_factory {}; - -template<typename ContainerType> -struct container_input_adapter_factory< ContainerType, - void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>> - { - using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))); - - static adapter_type create(const ContainerType& container) -{ - return input_adapter(begin(container), end(container)); -} - }; - -} // namespace container_input_adapter_factory_impl - -template<typename ContainerType> -typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container) -{ - return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container); -} - -#ifndef JSON_NO_IO -// Special cases with fast paths -inline file_input_adapter input_adapter(std::FILE* file) -{ - return file_input_adapter(file); -} - -inline input_stream_adapter input_adapter(std::istream& stream) -{ - return input_stream_adapter(stream); -} - -inline input_stream_adapter input_adapter(std::istream&& stream) -{ - return input_stream_adapter(stream); -} -#endif // JSON_NO_IO - -using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>())); - -// Null-delimited strings, and the like. -template < typename CharT, - typename std::enable_if < - std::is_pointer<CharT>::value&& - !std::is_array<CharT>::value&& - std::is_integral<typename std::remove_pointer<CharT>::type>::value&& - sizeof(typename std::remove_pointer<CharT>::type) == 1, - int >::type = 0 > -contiguous_bytes_input_adapter input_adapter(CharT b) -{ - auto length = std::strlen(reinterpret_cast<const char*>(b)); - const auto* ptr = reinterpret_cast<const char*>(b); - return input_adapter(ptr, ptr + length); -} - -template<typename T, std::size_t N> -auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) -{ - return input_adapter(array, array + N); -} - -// This class only handles inputs of input_buffer_adapter type. -// It's required so that expressions like {ptr, len} can be implicitely casted -// to the correct adapter. -class span_input_adapter -{ - public: - template < typename CharT, - typename std::enable_if < - std::is_pointer<CharT>::value&& - std::is_integral<typename std::remove_pointer<CharT>::type>::value&& - sizeof(typename std::remove_pointer<CharT>::type) == 1, - int >::type = 0 > - span_input_adapter(CharT b, std::size_t l) - : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {} - - template<class IteratorType, - typename std::enable_if< - std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, - int>::type = 0> - span_input_adapter(IteratorType first, IteratorType last) - : ia(input_adapter(first, last)) {} - - contiguous_bytes_input_adapter&& get() - { - return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) - } - - private: - contiguous_bytes_input_adapter ia; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/input/json_sax.hpp> - - -#include <cstddef> -#include <string> // string -#include <utility> // move -#include <vector> // vector - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ - -/*! -@brief SAX interface - -This class describes the SAX interface used by @ref nlohmann::json::sax_parse. -Each function is called in different situations while the input is parsed. The -boolean return value informs the parser whether to continue processing the -input. -*/ -template<typename BasicJsonType> -struct json_sax -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - /*! - @brief a null value was read - @return whether parsing should proceed - */ - virtual bool null() = 0; - - /*! - @brief a boolean value was read - @param[in] val boolean value - @return whether parsing should proceed - */ - virtual bool boolean(bool val) = 0; - - /*! - @brief an integer number was read - @param[in] val integer value - @return whether parsing should proceed - */ - virtual bool number_integer(number_integer_t val) = 0; - - /*! - @brief an unsigned integer number was read - @param[in] val unsigned integer value - @return whether parsing should proceed - */ - virtual bool number_unsigned(number_unsigned_t val) = 0; - - /*! - @brief an floating-point number was read - @param[in] val floating-point value - @param[in] s raw token value - @return whether parsing should proceed - */ - virtual bool number_float(number_float_t val, const string_t& s) = 0; - - /*! - @brief a string was read - @param[in] val string value - @return whether parsing should proceed - @note It is safe to move the passed string. - */ - virtual bool string(string_t& val) = 0; - - /*! - @brief a binary string was read - @param[in] val binary value - @return whether parsing should proceed - @note It is safe to move the passed binary. - */ - virtual bool binary(binary_t& val) = 0; - - /*! - @brief the beginning of an object was read - @param[in] elements number of object elements or -1 if unknown - @return whether parsing should proceed - @note binary formats may report the number of elements - */ - virtual bool start_object(std::size_t elements) = 0; - - /*! - @brief an object key was read - @param[in] val object key - @return whether parsing should proceed - @note It is safe to move the passed string. - */ - virtual bool key(string_t& val) = 0; - - /*! - @brief the end of an object was read - @return whether parsing should proceed - */ - virtual bool end_object() = 0; - - /*! - @brief the beginning of an array was read - @param[in] elements number of array elements or -1 if unknown - @return whether parsing should proceed - @note binary formats may report the number of elements - */ - virtual bool start_array(std::size_t elements) = 0; - - /*! - @brief the end of an array was read - @return whether parsing should proceed - */ - virtual bool end_array() = 0; - - /*! - @brief a parse error occurred - @param[in] position the position in the input where the error occurs - @param[in] last_token the last read token - @param[in] ex an exception object describing the error - @return whether parsing should proceed (must return false) - */ - virtual bool parse_error(std::size_t position, - const std::string& last_token, - const detail::exception& ex) = 0; - - json_sax() = default; - json_sax(const json_sax&) = default; - json_sax(json_sax&&) noexcept = default; - json_sax& operator=(const json_sax&) = default; - json_sax& operator=(json_sax&&) noexcept = default; - virtual ~json_sax() = default; -}; - - -namespace detail -{ -/*! -@brief SAX implementation to create a JSON value from SAX events - -This class implements the @ref json_sax interface and processes the SAX events -to create a JSON value which makes it basically a DOM parser. The structure or -hierarchy of the JSON value is managed by the stack `ref_stack` which contains -a pointer to the respective array or object for each recursion depth. - -After successful parsing, the value that is passed by reference to the -constructor contains the parsed value. - -@tparam BasicJsonType the JSON type -*/ -template<typename BasicJsonType> -class json_sax_dom_parser -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - /*! - @param[in,out] r reference to a JSON value that is manipulated while - parsing - @param[in] allow_exceptions_ whether parse errors yield exceptions - */ - explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) - : root(r), allow_exceptions(allow_exceptions_) - {} - - // make class move-only - json_sax_dom_parser(const json_sax_dom_parser&) = delete; - json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; - json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~json_sax_dom_parser() = default; - - bool null() - { - handle_value(nullptr); - return true; - } - - bool boolean(bool val) - { - handle_value(val); - return true; - } - - bool number_integer(number_integer_t val) - { - handle_value(val); - return true; - } - - bool number_unsigned(number_unsigned_t val) - { - handle_value(val); - return true; - } - - bool number_float(number_float_t val, const string_t& /*unused*/) - { - handle_value(val); - return true; - } - - bool string(string_t& val) - { - handle_value(val); - return true; - } - - bool binary(binary_t& val) - { - handle_value(std::move(val)); - return true; - } - - bool start_object(std::size_t len) - { - ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); - - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool key(string_t& val) - { - // add null at given key and store the reference for later - object_element = &(ref_stack.back()->m_value.object->operator[](val)); - return true; - } - - bool end_object() - { - ref_stack.back()->set_parents(); - ref_stack.pop_back(); - return true; - } - - bool start_array(std::size_t len) - { - ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); - - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool end_array() - { - ref_stack.back()->set_parents(); - ref_stack.pop_back(); - return true; - } - - template<class Exception> - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const Exception& ex) - { - errored = true; - static_cast<void>(ex); - if (allow_exceptions) - { - JSON_THROW(ex); - } - return false; - } - - constexpr bool is_errored() const - { - return errored; - } - - private: - /*! - @invariant If the ref stack is empty, then the passed value will be the new - root. - @invariant If the ref stack contains a value, then it is an array or an - object to which we can add elements - */ - template<typename Value> - JSON_HEDLEY_RETURNS_NON_NULL - BasicJsonType* handle_value(Value&& v) - { - if (ref_stack.empty()) - { - root = BasicJsonType(std::forward<Value>(v)); - return &root; - } - - JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); - - if (ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v)); - return &(ref_stack.back()->m_value.array->back()); - } - - JSON_ASSERT(ref_stack.back()->is_object()); - JSON_ASSERT(object_element); - *object_element = BasicJsonType(std::forward<Value>(v)); - return object_element; - } - - /// the parsed JSON value - BasicJsonType& root; - /// stack to model hierarchy of values - std::vector<BasicJsonType*> ref_stack {}; - /// helper to hold the reference for the next object element - BasicJsonType* object_element = nullptr; - /// whether a syntax error occurred - bool errored = false; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; -}; - -template<typename BasicJsonType> -class json_sax_dom_callback_parser -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using parser_callback_t = typename BasicJsonType::parser_callback_t; - using parse_event_t = typename BasicJsonType::parse_event_t; - - json_sax_dom_callback_parser(BasicJsonType& r, - const parser_callback_t cb, - const bool allow_exceptions_ = true) - : root(r), callback(cb), allow_exceptions(allow_exceptions_) - { - keep_stack.push_back(true); - } - - // make class move-only - json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; - json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; - json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~json_sax_dom_callback_parser() = default; - - bool null() - { - handle_value(nullptr); - return true; - } - - bool boolean(bool val) - { - handle_value(val); - return true; - } - - bool number_integer(number_integer_t val) - { - handle_value(val); - return true; - } - - bool number_unsigned(number_unsigned_t val) - { - handle_value(val); - return true; - } - - bool number_float(number_float_t val, const string_t& /*unused*/) - { - handle_value(val); - return true; - } - - bool string(string_t& val) - { - handle_value(val); - return true; - } - - bool binary(binary_t& val) - { - handle_value(std::move(val)); - return true; - } - - bool start_object(std::size_t len) - { - // check callback for object start - const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded); - keep_stack.push_back(keep); - - auto val = handle_value(BasicJsonType::value_t::object, true); - ref_stack.push_back(val.second); - - // check object limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool key(string_t& val) - { - BasicJsonType k = BasicJsonType(val); - - // check callback for key - const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k); - key_keep_stack.push_back(keep); - - // add discarded value at given key and store the reference for later - if (keep && ref_stack.back()) - { - object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded); - } - - return true; - } - - bool end_object() - { - if (ref_stack.back()) - { - if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) - { - // discard object - *ref_stack.back() = discarded; - } - else - { - ref_stack.back()->set_parents(); - } - } - - JSON_ASSERT(!ref_stack.empty()); - JSON_ASSERT(!keep_stack.empty()); - ref_stack.pop_back(); - keep_stack.pop_back(); - - if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) - { - // remove discarded value - for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) - { - if (it->is_discarded()) - { - ref_stack.back()->erase(it); - break; - } - } - } - - return true; - } - - bool start_array(std::size_t len) - { - const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded); - keep_stack.push_back(keep); - - auto val = handle_value(BasicJsonType::value_t::array, true); - ref_stack.push_back(val.second); - - // check array limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) - { - JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back())); - } - - return true; - } - - bool end_array() - { - bool keep = true; - - if (ref_stack.back()) - { - keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); - if (keep) - { - ref_stack.back()->set_parents(); - } - else - { - // discard array - *ref_stack.back() = discarded; - } - } - - JSON_ASSERT(!ref_stack.empty()); - JSON_ASSERT(!keep_stack.empty()); - ref_stack.pop_back(); - keep_stack.pop_back(); - - // remove discarded value - if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->pop_back(); - } - - return true; - } - - template<class Exception> - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, - const Exception& ex) - { - errored = true; - static_cast<void>(ex); - if (allow_exceptions) - { - JSON_THROW(ex); - } - return false; - } - - constexpr bool is_errored() const - { - return errored; - } - - private: - /*! - @param[in] v value to add to the JSON value we build during parsing - @param[in] skip_callback whether we should skip calling the callback - function; this is required after start_array() and - start_object() SAX events, because otherwise we would call the - callback function with an empty array or object, respectively. - - @invariant If the ref stack is empty, then the passed value will be the new - root. - @invariant If the ref stack contains a value, then it is an array or an - object to which we can add elements - - @return pair of boolean (whether value should be kept) and pointer (to the - passed value in the ref_stack hierarchy; nullptr if not kept) - */ - template<typename Value> - std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false) - { - JSON_ASSERT(!keep_stack.empty()); - - // do not handle this value if we know it would be added to a discarded - // container - if (!keep_stack.back()) - { - return {false, nullptr}; - } - - // create value - auto value = BasicJsonType(std::forward<Value>(v)); - - // check callback - const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value); - - // do not handle this value if we just learnt it shall be discarded - if (!keep) - { - return {false, nullptr}; - } - - if (ref_stack.empty()) - { - root = std::move(value); - return {true, &root}; - } - - // skip this value if we already decided to skip the parent - // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) - if (!ref_stack.back()) - { - return {false, nullptr}; - } - - // we now only expect arrays and objects - JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); - - // array - if (ref_stack.back()->is_array()) - { - ref_stack.back()->m_value.array->emplace_back(std::move(value)); - return {true, &(ref_stack.back()->m_value.array->back())}; - } - - // object - JSON_ASSERT(ref_stack.back()->is_object()); - // check if we should store an element for the current key - JSON_ASSERT(!key_keep_stack.empty()); - const bool store_element = key_keep_stack.back(); - key_keep_stack.pop_back(); - - if (!store_element) - { - return {false, nullptr}; - } - - JSON_ASSERT(object_element); - *object_element = std::move(value); - return {true, object_element}; - } - - /// the parsed JSON value - BasicJsonType& root; - /// stack to model hierarchy of values - std::vector<BasicJsonType*> ref_stack {}; - /// stack to manage which values to keep - std::vector<bool> keep_stack {}; - /// stack to manage which object keys to keep - std::vector<bool> key_keep_stack {}; - /// helper to hold the reference for the next object element - BasicJsonType* object_element = nullptr; - /// whether a syntax error occurred - bool errored = false; - /// callback function - const parser_callback_t callback = nullptr; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; - /// a discarded value for the callback - BasicJsonType discarded = BasicJsonType::value_t::discarded; -}; - -template<typename BasicJsonType> -class json_sax_acceptor -{ - public: - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - - bool null() - { - return true; - } - - bool boolean(bool /*unused*/) - { - return true; - } - - bool number_integer(number_integer_t /*unused*/) - { - return true; - } - - bool number_unsigned(number_unsigned_t /*unused*/) - { - return true; - } - - bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) - { - return true; - } - - bool string(string_t& /*unused*/) - { - return true; - } - - bool binary(binary_t& /*unused*/) - { - return true; - } - - bool start_object(std::size_t /*unused*/ = std::size_t(-1)) - { - return true; - } - - bool key(string_t& /*unused*/) - { - return true; - } - - bool end_object() - { - return true; - } - - bool start_array(std::size_t /*unused*/ = std::size_t(-1)) - { - return true; - } - - bool end_array() - { - return true; - } - - bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) - { - return false; - } -}; -} // namespace detail - -} // namespace nlohmann - -// #include <nlohmann/detail/input/lexer.hpp> - - -#include <array> // array -#include <clocale> // localeconv -#include <cstddef> // size_t -#include <cstdio> // snprintf -#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull -#include <initializer_list> // initializer_list -#include <string> // char_traits, string -#include <utility> // move -#include <vector> // vector - -// #include <nlohmann/detail/input/input_adapters.hpp> - -// #include <nlohmann/detail/input/position_t.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ -/////////// -// lexer // -/////////// - -template<typename BasicJsonType> -class lexer_base -{ - public: - /// token types for the parser - enum class token_type - { - uninitialized, ///< indicating the scanner is uninitialized - literal_true, ///< the `true` literal - literal_false, ///< the `false` literal - literal_null, ///< the `null` literal - value_string, ///< a string -- use get_string() for actual value - value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value - value_integer, ///< a signed integer -- use get_number_integer() for actual value - value_float, ///< an floating point number -- use get_number_float() for actual value - begin_array, ///< the character for array begin `[` - begin_object, ///< the character for object begin `{` - end_array, ///< the character for array end `]` - end_object, ///< the character for object end `}` - name_separator, ///< the name separator `:` - value_separator, ///< the value separator `,` - parse_error, ///< indicating a parse error - end_of_input, ///< indicating the end of the input buffer - literal_or_value ///< a literal or the begin of a value (only for diagnostics) - }; - - /// return name of values of type token_type (only used for errors) - JSON_HEDLEY_RETURNS_NON_NULL - JSON_HEDLEY_CONST - static const char* token_type_name(const token_type t) noexcept - { - switch (t) - { - case token_type::uninitialized: - return "<uninitialized>"; - case token_type::literal_true: - return "true literal"; - case token_type::literal_false: - return "false literal"; - case token_type::literal_null: - return "null literal"; - case token_type::value_string: - return "string literal"; - case token_type::value_unsigned: - case token_type::value_integer: - case token_type::value_float: - return "number literal"; - case token_type::begin_array: - return "'['"; - case token_type::begin_object: - return "'{'"; - case token_type::end_array: - return "']'"; - case token_type::end_object: - return "'}'"; - case token_type::name_separator: - return "':'"; - case token_type::value_separator: - return "','"; - case token_type::parse_error: - return "<parse error>"; - case token_type::end_of_input: - return "end of input"; - case token_type::literal_or_value: - return "'[', '{', or a literal"; - // LCOV_EXCL_START - default: // catch non-enum values - return "unknown token"; - // LCOV_EXCL_STOP - } - } -}; -/*! -@brief lexical analysis - -This class organizes the lexical analysis during JSON deserialization. -*/ -template<typename BasicJsonType, typename InputAdapterType> -class lexer : public lexer_base<BasicJsonType> -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using char_type = typename InputAdapterType::char_type; - using char_int_type = typename std::char_traits<char_type>::int_type; - - public: - using token_type = typename lexer_base<BasicJsonType>::token_type; - - explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept - : ia(std::move(adapter)) - , ignore_comments(ignore_comments_) - , decimal_point_char(static_cast<char_int_type>(get_decimal_point())) - {} - - // delete because of pointer members - lexer(const lexer&) = delete; - lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - lexer& operator=(lexer&) = delete; - lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~lexer() = default; - - private: - ///////////////////// - // locales - ///////////////////// - - /// return the locale-dependent decimal point - JSON_HEDLEY_PURE - static char get_decimal_point() noexcept - { - const auto* loc = localeconv(); - JSON_ASSERT(loc != nullptr); - return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); - } - - ///////////////////// - // scan functions - ///////////////////// - - /*! - @brief get codepoint from 4 hex characters following `\u` - - For input "\u c1 c2 c3 c4" the codepoint is: - (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 - = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) - - Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' - must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The - conversion is done by subtracting the offset (0x30, 0x37, and 0x57) - between the ASCII value of the character and the desired integer value. - - @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or - non-hex character) - */ - int get_codepoint() - { - // this function only makes sense after reading `\u` - JSON_ASSERT(current == 'u'); - int codepoint = 0; - - const auto factors = { 12u, 8u, 4u, 0u }; - for (const auto factor : factors) - { - get(); - - if (current >= '0' && current <= '9') - { - codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor); - } - else if (current >= 'A' && current <= 'F') - { - codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor); - } - else if (current >= 'a' && current <= 'f') - { - codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor); - } - else - { - return -1; - } - } - - JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF); - return codepoint; - } - - /*! - @brief check if the next byte(s) are inside a given range - - Adds the current byte and, for each passed range, reads a new byte and - checks if it is inside the range. If a violation was detected, set up an - error message and return false. Otherwise, return true. - - @param[in] ranges list of integers; interpreted as list of pairs of - inclusive lower and upper bound, respectively - - @pre The passed list @a ranges must have 2, 4, or 6 elements; that is, - 1, 2, or 3 pairs. This precondition is enforced by an assertion. - - @return true if and only if no range violation was detected - */ - bool next_byte_in_range(std::initializer_list<char_int_type> ranges) - { - JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6); - add(current); - - for (auto range = ranges.begin(); range != ranges.end(); ++range) - { - get(); - if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) - { - add(current); - } - else - { - error_message = "invalid string: ill-formed UTF-8 byte"; - return false; - } - } - - return true; - } - - /*! - @brief scan a string literal - - This function scans a string according to Sect. 7 of RFC 8259. While - scanning, bytes are escaped and copied into buffer token_buffer. Then the - function returns successfully, token_buffer is *not* null-terminated (as it - may contain \0 bytes), and token_buffer.size() is the number of bytes in the - string. - - @return token_type::value_string if string could be successfully scanned, - token_type::parse_error otherwise - - @note In case of errors, variable error_message contains a textual - description. - */ - token_type scan_string() - { - // reset token_buffer (ignore opening quote) - reset(); - - // we entered the function by reading an open quote - JSON_ASSERT(current == '\"'); - - while (true) - { - // get next character - switch (get()) - { - // end of file while parsing string - case std::char_traits<char_type>::eof(): - { - error_message = "invalid string: missing closing quote"; - return token_type::parse_error; - } - - // closing quote - case '\"': - { - return token_type::value_string; - } - - // escapes - case '\\': - { - switch (get()) - { - // quotation mark - case '\"': - add('\"'); - break; - // reverse solidus - case '\\': - add('\\'); - break; - // solidus - case '/': - add('/'); - break; - // backspace - case 'b': - add('\b'); - break; - // form feed - case 'f': - add('\f'); - break; - // line feed - case 'n': - add('\n'); - break; - // carriage return - case 'r': - add('\r'); - break; - // tab - case 't': - add('\t'); - break; - - // unicode escapes - case 'u': - { - const int codepoint1 = get_codepoint(); - int codepoint = codepoint1; // start with codepoint1 - - if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1)) - { - error_message = "invalid string: '\\u' must be followed by 4 hex digits"; - return token_type::parse_error; - } - - // check if code point is a high surrogate - if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF) - { - // expect next \uxxxx entry - if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u')) - { - const int codepoint2 = get_codepoint(); - - if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1)) - { - error_message = "invalid string: '\\u' must be followed by 4 hex digits"; - return token_type::parse_error; - } - - // check if codepoint2 is a low surrogate - if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF)) - { - // overwrite codepoint - codepoint = static_cast<int>( - // high surrogate occupies the most significant 22 bits - (static_cast<unsigned int>(codepoint1) << 10u) - // low surrogate occupies the least significant 15 bits - + static_cast<unsigned int>(codepoint2) - // there is still the 0xD800, 0xDC00 and 0x10000 noise - // in the result so we have to subtract with: - // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 - - 0x35FDC00u); - } - else - { - error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; - return token_type::parse_error; - } - } - else - { - error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; - return token_type::parse_error; - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF)) - { - error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; - return token_type::parse_error; - } - } - - // result of the above calculation yields a proper codepoint - JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF); - - // translate codepoint into bytes - if (codepoint < 0x80) - { - // 1-byte characters: 0xxxxxxx (ASCII) - add(static_cast<char_int_type>(codepoint)); - } - else if (codepoint <= 0x7FF) - { - // 2-byte characters: 110xxxxx 10xxxxxx - add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u))); - add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu))); - } - else if (codepoint <= 0xFFFF) - { - // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx - add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u))); - add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu))); - add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu))); - } - else - { - // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u))); - add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu))); - add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu))); - add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu))); - } - - break; - } - - // other characters after escape - default: - error_message = "invalid string: forbidden character after backslash"; - return token_type::parse_error; - } - - break; - } - - // invalid control characters - case 0x00: - { - error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000"; - return token_type::parse_error; - } - - case 0x01: - { - error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001"; - return token_type::parse_error; - } - - case 0x02: - { - error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002"; - return token_type::parse_error; - } - - case 0x03: - { - error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003"; - return token_type::parse_error; - } - - case 0x04: - { - error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004"; - return token_type::parse_error; - } - - case 0x05: - { - error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005"; - return token_type::parse_error; - } - - case 0x06: - { - error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006"; - return token_type::parse_error; - } - - case 0x07: - { - error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007"; - return token_type::parse_error; - } - - case 0x08: - { - error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b"; - return token_type::parse_error; - } - - case 0x09: - { - error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t"; - return token_type::parse_error; - } - - case 0x0A: - { - error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n"; - return token_type::parse_error; - } - - case 0x0B: - { - error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B"; - return token_type::parse_error; - } - - case 0x0C: - { - error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f"; - return token_type::parse_error; - } - - case 0x0D: - { - error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r"; - return token_type::parse_error; - } - - case 0x0E: - { - error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E"; - return token_type::parse_error; - } - - case 0x0F: - { - error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F"; - return token_type::parse_error; - } - - case 0x10: - { - error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010"; - return token_type::parse_error; - } - - case 0x11: - { - error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011"; - return token_type::parse_error; - } - - case 0x12: - { - error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012"; - return token_type::parse_error; - } - - case 0x13: - { - error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013"; - return token_type::parse_error; - } - - case 0x14: - { - error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014"; - return token_type::parse_error; - } - - case 0x15: - { - error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015"; - return token_type::parse_error; - } - - case 0x16: - { - error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016"; - return token_type::parse_error; - } - - case 0x17: - { - error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017"; - return token_type::parse_error; - } - - case 0x18: - { - error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018"; - return token_type::parse_error; - } - - case 0x19: - { - error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019"; - return token_type::parse_error; - } - - case 0x1A: - { - error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A"; - return token_type::parse_error; - } - - case 0x1B: - { - error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B"; - return token_type::parse_error; - } - - case 0x1C: - { - error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C"; - return token_type::parse_error; - } - - case 0x1D: - { - error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D"; - return token_type::parse_error; - } - - case 0x1E: - { - error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E"; - return token_type::parse_error; - } - - case 0x1F: - { - error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F"; - return token_type::parse_error; - } - - // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace)) - case 0x20: - case 0x21: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - { - add(current); - break; - } - - // U+0080..U+07FF: bytes C2..DF 80..BF - case 0xC2: - case 0xC3: - case 0xC4: - case 0xC5: - case 0xC6: - case 0xC7: - case 0xC8: - case 0xC9: - case 0xCA: - case 0xCB: - case 0xCC: - case 0xCD: - case 0xCE: - case 0xCF: - case 0xD0: - case 0xD1: - case 0xD2: - case 0xD3: - case 0xD4: - case 0xD5: - case 0xD6: - case 0xD7: - case 0xD8: - case 0xD9: - case 0xDA: - case 0xDB: - case 0xDC: - case 0xDD: - case 0xDE: - case 0xDF: - { - if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF}))) - { - return token_type::parse_error; - } - break; - } - - // U+0800..U+0FFF: bytes E0 A0..BF 80..BF - case 0xE0: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF - // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - case 0xE8: - case 0xE9: - case 0xEA: - case 0xEB: - case 0xEC: - case 0xEE: - case 0xEF: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+D000..U+D7FF: bytes ED 80..9F 80..BF - case 0xED: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF - case 0xF0: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF - case 0xF1: - case 0xF2: - case 0xF3: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF - case 0xF4: - { - if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) - { - return token_type::parse_error; - } - break; - } - - // remaining bytes (80..C1 and F5..FF) are ill-formed - default: - { - error_message = "invalid string: ill-formed UTF-8 byte"; - return token_type::parse_error; - } - } - } - } - - /*! - * @brief scan a comment - * @return whether comment could be scanned successfully - */ - bool scan_comment() - { - switch (get()) - { - // single-line comments skip input until a newline or EOF is read - case '/': - { - while (true) - { - switch (get()) - { - case '\n': - case '\r': - case std::char_traits<char_type>::eof(): - case '\0': - return true; - - default: - break; - } - } - } - - // multi-line comments skip input until */ is read - case '*': - { - while (true) - { - switch (get()) - { - case std::char_traits<char_type>::eof(): - case '\0': - { - error_message = "invalid comment; missing closing '*/'"; - return false; - } - - case '*': - { - switch (get()) - { - case '/': - return true; - - default: - { - unget(); - continue; - } - } - } - - default: - continue; - } - } - } - - // unexpected character after reading '/' - default: - { - error_message = "invalid comment; expecting '/' or '*' after '/'"; - return false; - } - } - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(float& f, const char* str, char** endptr) noexcept - { - f = std::strtof(str, endptr); - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(double& f, const char* str, char** endptr) noexcept - { - f = std::strtod(str, endptr); - } - - JSON_HEDLEY_NON_NULL(2) - static void strtof(long double& f, const char* str, char** endptr) noexcept - { - f = std::strtold(str, endptr); - } - - /*! - @brief scan a number literal - - This function scans a string according to Sect. 6 of RFC 8259. - - The function is realized with a deterministic finite state machine derived - from the grammar described in RFC 8259. Starting in state "init", the - input is read and used to determined the next state. Only state "done" - accepts the number. State "error" is a trap state to model errors. In the - table below, "anything" means any character but the ones listed before. - - state | 0 | 1-9 | e E | + | - | . | anything - ---------|----------|----------|----------|---------|---------|----------|----------- - init | zero | any1 | [error] | [error] | minus | [error] | [error] - minus | zero | any1 | [error] | [error] | [error] | [error] | [error] - zero | done | done | exponent | done | done | decimal1 | done - any1 | any1 | any1 | exponent | done | done | decimal1 | done - decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error] - decimal2 | decimal2 | decimal2 | exponent | done | done | done | done - exponent | any2 | any2 | [error] | sign | sign | [error] | [error] - sign | any2 | any2 | [error] | [error] | [error] | [error] | [error] - any2 | any2 | any2 | done | done | done | done | done - - The state machine is realized with one label per state (prefixed with - "scan_number_") and `goto` statements between them. The state machine - contains cycles, but any cycle can be left when EOF is read. Therefore, - the function is guaranteed to terminate. - - During scanning, the read bytes are stored in token_buffer. This string is - then converted to a signed integer, an unsigned integer, or a - floating-point number. - - @return token_type::value_unsigned, token_type::value_integer, or - token_type::value_float if number could be successfully scanned, - token_type::parse_error otherwise - - @note The scanner is independent of the current locale. Internally, the - locale's decimal point is used instead of `.` to work with the - locale-dependent converters. - */ - token_type scan_number() // lgtm [cpp/use-of-goto] - { - // reset token_buffer to store the number's bytes - reset(); - - // the type of the parsed number; initially set to unsigned; will be - // changed if minus sign, decimal point or exponent is read - token_type number_type = token_type::value_unsigned; - - // state (init): we just found out we need to scan a number - switch (current) - { - case '-': - { - add(current); - goto scan_number_minus; - } - - case '0': - { - add(current); - goto scan_number_zero; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - // all other characters are rejected outside scan_number() - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - -scan_number_minus: - // state: we just parsed a leading minus sign - number_type = token_type::value_integer; - switch (get()) - { - case '0': - { - add(current); - goto scan_number_zero; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - default: - { - error_message = "invalid number; expected digit after '-'"; - return token_type::parse_error; - } - } - -scan_number_zero: - // state: we just parse a zero (maybe with a leading minus sign) - switch (get()) - { - case '.': - { - add(decimal_point_char); - goto scan_number_decimal1; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_any1: - // state: we just parsed a number 0-9 (maybe with a leading minus sign) - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any1; - } - - case '.': - { - add(decimal_point_char); - goto scan_number_decimal1; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_decimal1: - // state: we just parsed a decimal point - number_type = token_type::value_float; - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_decimal2; - } - - default: - { - error_message = "invalid number; expected digit after '.'"; - return token_type::parse_error; - } - } - -scan_number_decimal2: - // we just parsed at least one number after a decimal point - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_decimal2; - } - - case 'e': - case 'E': - { - add(current); - goto scan_number_exponent; - } - - default: - goto scan_number_done; - } - -scan_number_exponent: - // we just parsed an exponent - number_type = token_type::value_float; - switch (get()) - { - case '+': - case '-': - { - add(current); - goto scan_number_sign; - } - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - { - error_message = - "invalid number; expected '+', '-', or digit after exponent"; - return token_type::parse_error; - } - } - -scan_number_sign: - // we just parsed an exponent sign - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - { - error_message = "invalid number; expected digit after exponent sign"; - return token_type::parse_error; - } - } - -scan_number_any2: - // we just parsed a number after the exponent or exponent sign - switch (get()) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - add(current); - goto scan_number_any2; - } - - default: - goto scan_number_done; - } - -scan_number_done: - // unget the character after the number (we only read it to know that - // we are done scanning a number) - unget(); - - char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - errno = 0; - - // try to parse integers first and fall back to floats - if (number_type == token_type::value_unsigned) - { - const auto x = std::strtoull(token_buffer.data(), &endptr, 10); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - if (errno == 0) - { - value_unsigned = static_cast<number_unsigned_t>(x); - if (value_unsigned == x) - { - return token_type::value_unsigned; - } - } - } - else if (number_type == token_type::value_integer) - { - const auto x = std::strtoll(token_buffer.data(), &endptr, 10); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - if (errno == 0) - { - value_integer = static_cast<number_integer_t>(x); - if (value_integer == x) - { - return token_type::value_integer; - } - } - } - - // this code is reached if we parse a floating-point number or if an - // integer conversion above failed - strtof(value_float, token_buffer.data(), &endptr); - - // we checked the number format before - JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); - - return token_type::value_float; - } - - /*! - @param[in] literal_text the literal text to expect - @param[in] length the length of the passed literal text - @param[in] return_type the token type to return on success - */ - JSON_HEDLEY_NON_NULL(2) - token_type scan_literal(const char_type* literal_text, const std::size_t length, - token_type return_type) - { - JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]); - for (std::size_t i = 1; i < length; ++i) - { - if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i])) - { - error_message = "invalid literal"; - return token_type::parse_error; - } - } - return return_type; - } - - ///////////////////// - // input management - ///////////////////// - - /// reset token_buffer; current character is beginning of token - void reset() noexcept - { - token_buffer.clear(); - token_string.clear(); - token_string.push_back(std::char_traits<char_type>::to_char_type(current)); - } - - /* - @brief get next character from the input - - This function provides the interface to the used input adapter. It does - not throw in case the input reached EOF, but returns a - `std::char_traits<char>::eof()` in that case. Stores the scanned characters - for use in error messages. - - @return character read from the input - */ - char_int_type get() - { - ++position.chars_read_total; - ++position.chars_read_current_line; - - if (next_unget) - { - // just reset the next_unget variable and work with current - next_unget = false; - } - else - { - current = ia.get_character(); - } - - if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof())) - { - token_string.push_back(std::char_traits<char_type>::to_char_type(current)); - } - - if (current == '\n') - { - ++position.lines_read; - position.chars_read_current_line = 0; - } - - return current; - } - - /*! - @brief unget current character (read it again on next get) - - We implement unget by setting variable next_unget to true. The input is not - changed - we just simulate ungetting by modifying chars_read_total, - chars_read_current_line, and token_string. The next call to get() will - behave as if the unget character is read again. - */ - void unget() - { - next_unget = true; - - --position.chars_read_total; - - // in case we "unget" a newline, we have to also decrement the lines_read - if (position.chars_read_current_line == 0) - { - if (position.lines_read > 0) - { - --position.lines_read; - } - } - else - { - --position.chars_read_current_line; - } - - if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof())) - { - JSON_ASSERT(!token_string.empty()); - token_string.pop_back(); - } - } - - /// add a character to token_buffer - void add(char_int_type c) - { - token_buffer.push_back(static_cast<typename string_t::value_type>(c)); - } - - public: - ///////////////////// - // value getters - ///////////////////// - - /// return integer value - constexpr number_integer_t get_number_integer() const noexcept - { - return value_integer; - } - - /// return unsigned integer value - constexpr number_unsigned_t get_number_unsigned() const noexcept - { - return value_unsigned; - } - - /// return floating-point value - constexpr number_float_t get_number_float() const noexcept - { - return value_float; - } - - /// return current string value (implicitly resets the token; useful only once) - string_t& get_string() - { - return token_buffer; - } - - ///////////////////// - // diagnostics - ///////////////////// - - /// return position of last read token - constexpr position_t get_position() const noexcept - { - return position; - } - - /// return the last read token (for errors only). Will never contain EOF - /// (an arbitrary value that is not a valid char value, often -1), because - /// 255 may legitimately occur. May contain NUL, which should be escaped. - std::string get_token_string() const - { - // escape control characters - std::string result; - for (const auto c : token_string) - { - if (static_cast<unsigned char>(c) <= '\x1F') - { - // escape control characters - std::array<char, 9> cs{{}}; - (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - result += cs.data(); - } - else - { - // add character as is - result.push_back(static_cast<std::string::value_type>(c)); - } - } - - return result; - } - - /// return syntax error message - JSON_HEDLEY_RETURNS_NON_NULL - constexpr const char* get_error_message() const noexcept - { - return error_message; - } - - ///////////////////// - // actual scanner - ///////////////////// - - /*! - @brief skip the UTF-8 byte order mark - @return true iff there is no BOM or the correct BOM has been skipped - */ - bool skip_bom() - { - if (get() == 0xEF) - { - // check if we completely parse the BOM - return get() == 0xBB && get() == 0xBF; - } - - // the first character is not the beginning of the BOM; unget it to - // process is later - unget(); - return true; - } - - void skip_whitespace() - { - do - { - get(); - } - while (current == ' ' || current == '\t' || current == '\n' || current == '\r'); - } - - token_type scan() - { - // initially, skip the BOM - if (position.chars_read_total == 0 && !skip_bom()) - { - error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; - return token_type::parse_error; - } - - // read next character and ignore whitespace - skip_whitespace(); - - // ignore comments - while (ignore_comments && current == '/') - { - if (!scan_comment()) - { - return token_type::parse_error; - } - - // skip following whitespace - skip_whitespace(); - } - - switch (current) - { - // structural characters - case '[': - return token_type::begin_array; - case ']': - return token_type::end_array; - case '{': - return token_type::begin_object; - case '}': - return token_type::end_object; - case ':': - return token_type::name_separator; - case ',': - return token_type::value_separator; - - // literals - case 't': - { - std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; - return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); - } - case 'f': - { - std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; - return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); - } - case 'n': - { - std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; - return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); - } - - // string - case '\"': - return scan_string(); - - // number - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return scan_number(); - - // end of input (the null byte is needed when parsing from - // string literals) - case '\0': - case std::char_traits<char_type>::eof(): - return token_type::end_of_input; - - // error - default: - error_message = "invalid literal"; - return token_type::parse_error; - } - } - - private: - /// input adapter - InputAdapterType ia; - - /// whether comments should be ignored (true) or signaled as errors (false) - const bool ignore_comments = false; - - /// the current character - char_int_type current = std::char_traits<char_type>::eof(); - - /// whether the next get() call should just return current - bool next_unget = false; - - /// the start position of the current token - position_t position {}; - - /// raw input token string (for error messages) - std::vector<char_type> token_string {}; - - /// buffer for variable-length tokens (numbers, strings) - string_t token_buffer {}; - - /// a description of occurred lexer errors - const char* error_message = ""; - - // number values - number_integer_t value_integer = 0; - number_unsigned_t value_unsigned = 0; - number_float_t value_float = 0; - - /// the decimal point - const char_int_type decimal_point_char = '.'; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/meta/is_sax.hpp> - - -#include <cstdint> // size_t -#include <utility> // declval -#include <string> // string - -// #include <nlohmann/detail/meta/detected.hpp> - -// #include <nlohmann/detail/meta/type_traits.hpp> - - -namespace nlohmann -{ -namespace detail -{ -template<typename T> -using null_function_t = decltype(std::declval<T&>().null()); - -template<typename T> -using boolean_function_t = - decltype(std::declval<T&>().boolean(std::declval<bool>())); - -template<typename T, typename Integer> -using number_integer_function_t = - decltype(std::declval<T&>().number_integer(std::declval<Integer>())); - -template<typename T, typename Unsigned> -using number_unsigned_function_t = - decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>())); - -template<typename T, typename Float, typename String> -using number_float_function_t = decltype(std::declval<T&>().number_float( - std::declval<Float>(), std::declval<const String&>())); - -template<typename T, typename String> -using string_function_t = - decltype(std::declval<T&>().string(std::declval<String&>())); - -template<typename T, typename Binary> -using binary_function_t = - decltype(std::declval<T&>().binary(std::declval<Binary&>())); - -template<typename T> -using start_object_function_t = - decltype(std::declval<T&>().start_object(std::declval<std::size_t>())); - -template<typename T, typename String> -using key_function_t = - decltype(std::declval<T&>().key(std::declval<String&>())); - -template<typename T> -using end_object_function_t = decltype(std::declval<T&>().end_object()); - -template<typename T> -using start_array_function_t = - decltype(std::declval<T&>().start_array(std::declval<std::size_t>())); - -template<typename T> -using end_array_function_t = decltype(std::declval<T&>().end_array()); - -template<typename T, typename Exception> -using parse_error_function_t = decltype(std::declval<T&>().parse_error( - std::declval<std::size_t>(), std::declval<const std::string&>(), - std::declval<const Exception&>())); - -template<typename SAX, typename BasicJsonType> -struct is_sax -{ - private: - static_assert(is_basic_json<BasicJsonType>::value, - "BasicJsonType must be of type basic_json<...>"); - - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using exception_t = typename BasicJsonType::exception; - - public: - static constexpr bool value = - is_detected_exact<bool, null_function_t, SAX>::value && - is_detected_exact<bool, boolean_function_t, SAX>::value && - is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value && - is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value && - is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value && - is_detected_exact<bool, string_function_t, SAX, string_t>::value && - is_detected_exact<bool, binary_function_t, SAX, binary_t>::value && - is_detected_exact<bool, start_object_function_t, SAX>::value && - is_detected_exact<bool, key_function_t, SAX, string_t>::value && - is_detected_exact<bool, end_object_function_t, SAX>::value && - is_detected_exact<bool, start_array_function_t, SAX>::value && - is_detected_exact<bool, end_array_function_t, SAX>::value && - is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value; -}; - -template<typename SAX, typename BasicJsonType> -struct is_sax_static_asserts -{ - private: - static_assert(is_basic_json<BasicJsonType>::value, - "BasicJsonType must be of type basic_json<...>"); - - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using exception_t = typename BasicJsonType::exception; - - public: - static_assert(is_detected_exact<bool, null_function_t, SAX>::value, - "Missing/invalid function: bool null()"); - static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert( - is_detected_exact<bool, number_integer_function_t, SAX, - number_integer_t>::value, - "Missing/invalid function: bool number_integer(number_integer_t)"); - static_assert( - is_detected_exact<bool, number_unsigned_function_t, SAX, - number_unsigned_t>::value, - "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); - static_assert(is_detected_exact<bool, number_float_function_t, SAX, - number_float_t, string_t>::value, - "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); - static_assert( - is_detected_exact<bool, string_function_t, SAX, string_t>::value, - "Missing/invalid function: bool string(string_t&)"); - static_assert( - is_detected_exact<bool, binary_function_t, SAX, binary_t>::value, - "Missing/invalid function: bool binary(binary_t&)"); - static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value, - "Missing/invalid function: bool start_object(std::size_t)"); - static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value, - "Missing/invalid function: bool key(string_t&)"); - static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value, - "Missing/invalid function: bool end_object()"); - static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value, - "Missing/invalid function: bool start_array(std::size_t)"); - static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value, - "Missing/invalid function: bool end_array()"); - static_assert( - is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value, - "Missing/invalid function: bool parse_error(std::size_t, const " - "std::string&, const exception&)"); -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/meta/type_traits.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ - -/// how to treat CBOR tags -enum class cbor_tag_handler_t -{ - error, ///< throw a parse_error exception in case of a tag - ignore, ///< ignore tags - store ///< store tags as binary type -}; - -/*! -@brief determine system byte order - -@return true if and only if system's byte order is little endian - -@note from https://stackoverflow.com/a/1001328/266378 -*/ -static inline bool little_endianess(int num = 1) noexcept -{ - return *reinterpret_cast<char*>(&num) == 1; -} - - -/////////////////// -// binary reader // -/////////////////// - -/*! -@brief deserialization of CBOR, MessagePack, and UBJSON values -*/ -template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>> -class binary_reader -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using json_sax_t = SAX; - using char_type = typename InputAdapterType::char_type; - using char_int_type = typename std::char_traits<char_type>::int_type; - - public: - /*! - @brief create a binary reader - - @param[in] adapter input adapter to read from - */ - explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter)) - { - (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; - } - - // make class move-only - binary_reader(const binary_reader&) = delete; - binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - binary_reader& operator=(const binary_reader&) = delete; - binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) - ~binary_reader() = default; - - /*! - @param[in] format the binary format to parse - @param[in] sax_ a SAX event processor - @param[in] strict whether to expect the input to be consumed completed - @param[in] tag_handler how to treat CBOR tags - - @return whether parsing was successful - */ - JSON_HEDLEY_NON_NULL(3) - bool sax_parse(const input_format_t format, - json_sax_t* sax_, - const bool strict = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - sax = sax_; - bool result = false; - - switch (format) - { - case input_format_t::bson: - result = parse_bson_internal(); - break; - - case input_format_t::cbor: - result = parse_cbor_internal(true, tag_handler); - break; - - case input_format_t::msgpack: - result = parse_msgpack_internal(); - break; - - case input_format_t::ubjson: - result = parse_ubjson_internal(); - break; - - case input_format_t::json: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - - // strict mode: next byte must be EOF - if (result && strict) - { - if (format == input_format_t::ubjson) - { - get_ignore_noop(); - } - else - { - get(); - } - - if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof())) - { - return sax->parse_error(chars_read, get_token_string(), - parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType())); - } - } - - return result; - } - - private: - ////////// - // BSON // - ////////// - - /*! - @brief Reads in a BSON-object and passes it to the SAX-parser. - @return whether a valid BSON-value was passed to the SAX parser - */ - bool parse_bson_internal() - { - std::int32_t document_size{}; - get_number<std::int32_t, true>(input_format_t::bson, document_size); - - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) - { - return false; - } - - return sax->end_object(); - } - - /*! - @brief Parses a C-style string from the BSON input. - @param[in,out] result A reference to the string variable where the read - string is to be stored. - @return `true` if the \x00-byte indicating the end of the string was - encountered before the EOF; false` indicates an unexpected EOF. - */ - bool get_bson_cstr(string_t& result) - { - auto out = std::back_inserter(result); - while (true) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) - { - return false; - } - if (current == 0x00) - { - return true; - } - *out++ = static_cast<typename string_t::value_type>(current); - } - } - - /*! - @brief Parses a zero-terminated string of length @a len from the BSON - input. - @param[in] len The length (including the zero-byte at the end) of the - string to be read. - @param[in,out] result A reference to the string variable where the read - string is to be stored. - @tparam NumberType The type of the length @a len - @pre len >= 1 - @return `true` if the string was successfully parsed - */ - template<typename NumberType> - bool get_bson_string(const NumberType len, string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(len < 1)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType())); - } - - return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof(); - } - - /*! - @brief Parses a byte array input of length @a len from the BSON input. - @param[in] len The length of the byte array to be read. - @param[in,out] result A reference to the binary variable where the read - array is to be stored. - @tparam NumberType The type of the length @a len - @pre len >= 0 - @return `true` if the byte array was successfully parsed - */ - template<typename NumberType> - bool get_bson_binary(const NumberType len, binary_t& result) - { - if (JSON_HEDLEY_UNLIKELY(len < 0)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType())); - } - - // All BSON binary values have a subtype - std::uint8_t subtype{}; - get_number<std::uint8_t>(input_format_t::bson, subtype); - result.set_subtype(subtype); - - return get_binary(input_format_t::bson, len, result); - } - - /*! - @brief Read a BSON document element of the given @a element_type. - @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html - @param[in] element_type_parse_position The position in the input stream, - where the `element_type` was read. - @warning Not all BSON element types are supported yet. An unsupported - @a element_type will give rise to a parse_error.114: - Unsupported BSON record type 0x... - @return whether a valid BSON-object/array was passed to the SAX parser - */ - bool parse_bson_element_internal(const char_int_type element_type, - const std::size_t element_type_parse_position) - { - switch (element_type) - { - case 0x01: // double - { - double number{}; - return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - case 0x02: // string - { - std::int32_t len{}; - string_t value; - return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); - } - - case 0x03: // object - { - return parse_bson_internal(); - } - - case 0x04: // array - { - return parse_bson_array(); - } - - case 0x05: // binary - { - std::int32_t len{}; - binary_t value; - return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); - } - - case 0x08: // boolean - { - return sax->boolean(get() != 0); - } - - case 0x0A: // null - { - return sax->null(); - } - - case 0x10: // int32 - { - std::int32_t value{}; - return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value); - } - - case 0x12: // int64 - { - std::int64_t value{}; - return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value); - } - - default: // anything else not supported (yet) - { - std::array<char, 3> cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType())); - } - } - } - - /*! - @brief Read a BSON element list (as specified in the BSON-spec) - - The same binary layout is used for objects and arrays, hence it must be - indicated with the argument @a is_array which one is expected - (true --> array, false --> object). - - @param[in] is_array Determines if the element list being read is to be - treated as an object (@a is_array == false), or as an - array (@a is_array == true). - @return whether a valid BSON-object/array was passed to the SAX parser - */ - bool parse_bson_element_list(const bool is_array) - { - string_t key; - - while (auto element_type = get()) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) - { - return false; - } - - const std::size_t element_type_parse_position = chars_read; - if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) - { - return false; - } - - if (!is_array && !sax->key(key)) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) - { - return false; - } - - // get_bson_cstr only appends - key.clear(); - } - - return true; - } - - /*! - @brief Reads an array from the BSON input and passes it to the SAX-parser. - @return whether a valid BSON-array was passed to the SAX parser - */ - bool parse_bson_array() - { - std::int32_t document_size{}; - get_number<std::int32_t, true>(input_format_t::bson, document_size); - - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) - { - return false; - } - - return sax->end_array(); - } - - ////////// - // CBOR // - ////////// - - /*! - @param[in] get_char whether a new character should be retrieved from the - input (true) or whether the last read character should - be considered instead (false) - @param[in] tag_handler how CBOR tags should be treated - - @return whether a valid CBOR value was passed to the SAX parser - */ - bool parse_cbor_internal(const bool get_char, - const cbor_tag_handler_t tag_handler) - { - switch (get_char ? get() : current) - { - // EOF - case std::char_traits<char_type>::eof(): - return unexpect_eof(input_format_t::cbor, "value"); - - // Integer 0x00..0x17 (0..23) - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - return sax->number_unsigned(static_cast<number_unsigned_t>(current)); - - case 0x18: // Unsigned integer (one-byte uint8_t follows) - { - std::uint8_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x19: // Unsigned integer (two-byte uint16_t follows) - { - std::uint16_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x1A: // Unsigned integer (four-byte uint32_t follows) - { - std::uint32_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - case 0x1B: // Unsigned integer (eight-byte uint64_t follows) - { - std::uint64_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); - } - - // Negative integer -1-0x00..-1-0x17 (-1..-24) - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current)); - - case 0x38: // Negative integer (one-byte uint8_t follows) - { - std::uint8_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number); - } - - case 0x39: // Negative integer -1-n (two-byte uint16_t follows) - { - std::uint16_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number); - } - - case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) - { - std::uint32_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number); - } - - case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) - { - std::uint64_t number{}; - return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - - static_cast<number_integer_t>(number)); - } - - // Binary data (0x00..0x17 bytes follow) - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: // Binary data (one-byte uint8_t for n follows) - case 0x59: // Binary data (two-byte uint16_t for n follow) - case 0x5A: // Binary data (four-byte uint32_t for n follow) - case 0x5B: // Binary data (eight-byte uint64_t for n follow) - case 0x5F: // Binary data (indefinite length) - { - binary_t b; - return get_cbor_binary(b) && sax->binary(b); - } - - // UTF-8 string (0x00..0x17 bytes follow) - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: // UTF-8 string (one-byte uint8_t for n follows) - case 0x79: // UTF-8 string (two-byte uint16_t for n follow) - case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) - case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) - case 0x7F: // UTF-8 string (indefinite length) - { - string_t s; - return get_cbor_string(s) && sax->string(s); - } - - // array (0x00..0x17 data items follow) - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8E: - case 0x8F: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler); - - case 0x98: // array (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler); - } - - case 0x99: // array (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler); - } - - case 0x9A: // array (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler); - } - - case 0x9B: // array (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler); - } - - case 0x9F: // array (indefinite length) - return get_cbor_array(std::size_t(-1), tag_handler); - - // map (0x00..0x17 pairs of data items follow) - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler); - - case 0xB8: // map (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler); - } - - case 0xB9: // map (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler); - } - - case 0xBA: // map (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler); - } - - case 0xBB: // map (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler); - } - - case 0xBF: // map (indefinite length) - return get_cbor_object(std::size_t(-1), tag_handler); - - case 0xC6: // tagged item - case 0xC7: - case 0xC8: - case 0xC9: - case 0xCA: - case 0xCB: - case 0xCC: - case 0xCD: - case 0xCE: - case 0xCF: - case 0xD0: - case 0xD1: - case 0xD2: - case 0xD3: - case 0xD4: - case 0xD8: // tagged item (1 bytes follow) - case 0xD9: // tagged item (2 bytes follow) - case 0xDA: // tagged item (4 bytes follow) - case 0xDB: // tagged item (8 bytes follow) - { - switch (tag_handler) - { - case cbor_tag_handler_t::error: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - - case cbor_tag_handler_t::ignore: - { - // ignore binary subtype - switch (current) - { - case 0xD8: - { - std::uint8_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - case 0xD9: - { - std::uint16_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - case 0xDA: - { - std::uint32_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - case 0xDB: - { - std::uint64_t subtype_to_ignore{}; - get_number(input_format_t::cbor, subtype_to_ignore); - break; - } - default: - break; - } - return parse_cbor_internal(true, tag_handler); - } - - case cbor_tag_handler_t::store: - { - binary_t b; - // use binary subtype and store in binary container - switch (current) - { - case 0xD8: - { - std::uint8_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); - break; - } - case 0xD9: - { - std::uint16_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); - break; - } - case 0xDA: - { - std::uint32_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); - break; - } - case 0xDB: - { - std::uint64_t subtype{}; - get_number(input_format_t::cbor, subtype); - b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); - break; - } - default: - return parse_cbor_internal(true, tag_handler); - } - get(); - return get_cbor_binary(b) && sax->binary(b); - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE - } - } - - case 0xF4: // false - return sax->boolean(false); - - case 0xF5: // true - return sax->boolean(true); - - case 0xF6: // null - return sax->null(); - - case 0xF9: // Half-Precision Float (two-byte IEEE 754) - { - const auto byte1_raw = get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) - { - return false; - } - const auto byte2_raw = get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) - { - return false; - } - - const auto byte1 = static_cast<unsigned char>(byte1_raw); - const auto byte2 = static_cast<unsigned char>(byte2_raw); - - // code from RFC 7049, Appendix D, Figure 3: - // As half-precision floating-point numbers were only added - // to IEEE 754 in 2008, today's programming platforms often - // still only have limited support for them. It is very - // easy to include at least decoding support for them even - // without such support. An example of a small decoder for - // half-precision floating-point numbers in the C language - // is shown in Fig. 3. - const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2); - const double val = [&half] - { - const int exp = (half >> 10u) & 0x1Fu; - const unsigned int mant = half & 0x3FFu; - JSON_ASSERT(0 <= exp&& exp <= 32); - JSON_ASSERT(mant <= 1024); - switch (exp) - { - case 0: - return std::ldexp(mant, -24); - case 31: - return (mant == 0) - ? std::numeric_limits<double>::infinity() - : std::numeric_limits<double>::quiet_NaN(); - default: - return std::ldexp(mant + 1024, exp - 25); - } - }(); - return sax->number_float((half & 0x8000u) != 0 - ? static_cast<number_float_t>(-val) - : static_cast<number_float_t>(val), ""); - } - - case 0xFA: // Single-Precision Float (four-byte IEEE 754) - { - float number{}; - return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - case 0xFB: // Double-Precision Float (eight-byte IEEE 754) - { - double number{}; - return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - default: // anything else (0xFF is handled inside the other types) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - } - } - - /*! - @brief reads a CBOR string - - This function first reads starting bytes to determine the expected - string length and then copies this number of bytes into a string. - Additionally, CBOR's strings with indefinite lengths are supported. - - @param[out] result created string - - @return whether string creation completed - */ - bool get_cbor_string(string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) - { - return false; - } - - switch (current) - { - // UTF-8 string (0x00..0x17 bytes follow) - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - { - return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result); - } - - case 0x78: // UTF-8 string (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x79: // UTF-8 string (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); - } - - case 0x7F: // UTF-8 string (indefinite length) - { - while (get() != 0xFF) - { - string_t chunk; - if (!get_cbor_string(chunk)) - { - return false; - } - result.append(chunk); - } - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType())); - } - } - } - - /*! - @brief reads a CBOR byte array - - This function first reads starting bytes to determine the expected - byte array length and then copies this number of bytes into the byte array. - Additionally, CBOR's byte arrays with indefinite lengths are supported. - - @param[out] result created byte array - - @return whether byte array creation completed - */ - bool get_cbor_binary(binary_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) - { - return false; - } - - switch (current) - { - // Binary data (0x00..0x17 bytes follow) - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - { - return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result); - } - - case 0x58: // Binary data (one-byte uint8_t for n follows) - { - std::uint8_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x59: // Binary data (two-byte uint16_t for n follow) - { - std::uint16_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5A: // Binary data (four-byte uint32_t for n follow) - { - std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5B: // Binary data (eight-byte uint64_t for n follow) - { - std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && - get_binary(input_format_t::cbor, len, result); - } - - case 0x5F: // Binary data (indefinite length) - { - while (get() != 0xFF) - { - binary_t chunk; - if (!get_cbor_binary(chunk)) - { - return false; - } - result.insert(result.end(), chunk.begin(), chunk.end()); - } - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType())); - } - } - } - - /*! - @param[in] len the length of the array or std::size_t(-1) for an - array of indefinite size - @param[in] tag_handler how CBOR tags should be treated - @return whether array creation completed - */ - bool get_cbor_array(const std::size_t len, - const cbor_tag_handler_t tag_handler) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) - { - return false; - } - - if (len != std::size_t(-1)) - { - for (std::size_t i = 0; i < len; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - } - } - else - { - while (get() != 0xFF) - { - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) - { - return false; - } - } - } - - return sax->end_array(); - } - - /*! - @param[in] len the length of the object or std::size_t(-1) for an - object of indefinite size - @param[in] tag_handler how CBOR tags should be treated - @return whether object creation completed - */ - bool get_cbor_object(const std::size_t len, - const cbor_tag_handler_t tag_handler) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) - { - return false; - } - - if (len != 0) - { - string_t key; - if (len != std::size_t(-1)) - { - for (std::size_t i = 0; i < len; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - key.clear(); - } - } - else - { - while (get() != 0xFF) - { - if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) - { - return false; - } - key.clear(); - } - } - } - - return sax->end_object(); - } - - ///////////// - // MsgPack // - ///////////// - - /*! - @return whether a valid MessagePack value was passed to the SAX parser - */ - bool parse_msgpack_internal() - { - switch (get()) - { - // EOF - case std::char_traits<char_type>::eof(): - return unexpect_eof(input_format_t::msgpack, "value"); - - // positive fixint - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4A: - case 0x4B: - case 0x4C: - case 0x4D: - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - return sax->number_unsigned(static_cast<number_unsigned_t>(current)); - - // fixmap - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x8E: - case 0x8F: - return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); - - // fixarray - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9A: - case 0x9B: - case 0x9C: - case 0x9D: - case 0x9E: - case 0x9F: - return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); - - // fixstr - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - case 0xD9: // str 8 - case 0xDA: // str 16 - case 0xDB: // str 32 - { - string_t s; - return get_msgpack_string(s) && sax->string(s); - } - - case 0xC0: // nil - return sax->null(); - - case 0xC2: // false - return sax->boolean(false); - - case 0xC3: // true - return sax->boolean(true); - - case 0xC4: // bin 8 - case 0xC5: // bin 16 - case 0xC6: // bin 32 - case 0xC7: // ext 8 - case 0xC8: // ext 16 - case 0xC9: // ext 32 - case 0xD4: // fixext 1 - case 0xD5: // fixext 2 - case 0xD6: // fixext 4 - case 0xD7: // fixext 8 - case 0xD8: // fixext 16 - { - binary_t b; - return get_msgpack_binary(b) && sax->binary(b); - } - - case 0xCA: // float 32 - { - float number{}; - return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - case 0xCB: // float 64 - { - double number{}; - return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - case 0xCC: // uint 8 - { - std::uint8_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCD: // uint 16 - { - std::uint16_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCE: // uint 32 - { - std::uint32_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xCF: // uint 64 - { - std::uint64_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); - } - - case 0xD0: // int 8 - { - std::int8_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD1: // int 16 - { - std::int16_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD2: // int 32 - { - std::int32_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xD3: // int 64 - { - std::int64_t number{}; - return get_number(input_format_t::msgpack, number) && sax->number_integer(number); - } - - case 0xDC: // array 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len)); - } - - case 0xDD: // array 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len)); - } - - case 0xDE: // map 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len)); - } - - case 0xDF: // map 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len)); - } - - // negative fixint - case 0xE0: - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - case 0xE8: - case 0xE9: - case 0xEA: - case 0xEB: - case 0xEC: - case 0xED: - case 0xEE: - case 0xEF: - case 0xF0: - case 0xF1: - case 0xF2: - case 0xF3: - case 0xF4: - case 0xF5: - case 0xF6: - case 0xF7: - case 0xF8: - case 0xF9: - case 0xFA: - case 0xFB: - case 0xFC: - case 0xFD: - case 0xFE: - case 0xFF: - return sax->number_integer(static_cast<std::int8_t>(current)); - - default: // anything else - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - } - } - - /*! - @brief reads a MessagePack string - - This function first reads starting bytes to determine the expected - string length and then copies this number of bytes into a string. - - @param[out] result created string - - @return whether string creation completed - */ - bool get_msgpack_string(string_t& result) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) - { - return false; - } - - switch (current) - { - // fixstr - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - case 0xA4: - case 0xA5: - case 0xA6: - case 0xA7: - case 0xA8: - case 0xA9: - case 0xAA: - case 0xAB: - case 0xAC: - case 0xAD: - case 0xAE: - case 0xAF: - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - { - return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result); - } - - case 0xD9: // str 8 - { - std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - case 0xDA: // str 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - case 0xDB: // str 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType())); - } - } - } - - /*! - @brief reads a MessagePack byte array - - This function first reads starting bytes to determine the expected - byte array length and then copies this number of bytes into a byte array. - - @param[out] result created byte array - - @return whether byte array creation completed - */ - bool get_msgpack_binary(binary_t& result) - { - // helper function to set the subtype - auto assign_and_return_true = [&result](std::int8_t subtype) - { - result.set_subtype(static_cast<std::uint8_t>(subtype)); - return true; - }; - - switch (current) - { - case 0xC4: // bin 8 - { - std::uint8_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC5: // bin 16 - { - std::uint16_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC6: // bin 32 - { - std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && - get_binary(input_format_t::msgpack, len, result); - } - - case 0xC7: // ext 8 - { - std::uint8_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xC8: // ext 16 - { - std::uint16_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xC9: // ext 32 - { - std::uint32_t len{}; - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, len) && - get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, len, result) && - assign_and_return_true(subtype); - } - - case 0xD4: // fixext 1 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 1, result) && - assign_and_return_true(subtype); - } - - case 0xD5: // fixext 2 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 2, result) && - assign_and_return_true(subtype); - } - - case 0xD6: // fixext 4 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 4, result) && - assign_and_return_true(subtype); - } - - case 0xD7: // fixext 8 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 8, result) && - assign_and_return_true(subtype); - } - - case 0xD8: // fixext 16 - { - std::int8_t subtype{}; - return get_number(input_format_t::msgpack, subtype) && - get_binary(input_format_t::msgpack, 16, result) && - assign_and_return_true(subtype); - } - - default: // LCOV_EXCL_LINE - return false; // LCOV_EXCL_LINE - } - } - - /*! - @param[in] len the length of the array - @return whether array creation completed - */ - bool get_msgpack_array(const std::size_t len) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) - { - return false; - } - - for (std::size_t i = 0; i < len; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) - { - return false; - } - } - - return sax->end_array(); - } - - /*! - @param[in] len the length of the object - @return whether object creation completed - */ - bool get_msgpack_object(const std::size_t len) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) - { - return false; - } - - string_t key; - for (std::size_t i = 0; i < len; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) - { - return false; - } - - if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) - { - return false; - } - key.clear(); - } - - return sax->end_object(); - } - - //////////// - // UBJSON // - //////////// - - /*! - @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead - - @return whether a valid UBJSON value was passed to the SAX parser - */ - bool parse_ubjson_internal(const bool get_char = true) - { - return get_ubjson_value(get_char ? get_ignore_noop() : current); - } - - /*! - @brief reads a UBJSON string - - This function is either called after reading the 'S' byte explicitly - indicating a string, or in case of an object key where the 'S' byte can be - left out. - - @param[out] result created string - @param[in] get_char whether a new character should be retrieved from the - input (true, default) or whether the last read - character should be considered instead - - @return whether string creation completed - */ - bool get_ubjson_string(string_t& result, const bool get_char = true) - { - if (get_char) - { - get(); // TODO(niels): may we ignore N here? - } - - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) - { - return false; - } - - switch (current) - { - case 'U': - { - std::uint8_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'i': - { - std::int8_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'I': - { - std::int16_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'l': - { - std::int32_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - case 'L': - { - std::int64_t len{}; - return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result); - } - - default: - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType())); - } - } - - /*! - @param[out] result determined size - @return whether size determination completed - */ - bool get_ubjson_size_value(std::size_t& result) - { - switch (get_ignore_noop()) - { - case 'U': - { - std::uint8_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast<std::size_t>(number); - return true; - } - - case 'i': - { - std::int8_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char - return true; - } - - case 'I': - { - std::int16_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast<std::size_t>(number); - return true; - } - - case 'l': - { - std::int32_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast<std::size_t>(number); - return true; - } - - case 'L': - { - std::int64_t number{}; - if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number))) - { - return false; - } - result = static_cast<std::size_t>(number); - return true; - } - - default: - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType())); - } - } - } - - /*! - @brief determine the type and size for a container - - In the optimized UBJSON format, a type and a size can be provided to allow - for a more compact representation. - - @param[out] result pair of the size and the type - - @return whether pair creation completed - */ - bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result) - { - result.first = string_t::npos; // size - result.second = 0; // type - - get_ignore_noop(); - - if (current == '$') - { - result.second = get(); // must not ignore 'N', because 'N' maybe the type - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type"))) - { - return false; - } - - get_ignore_noop(); - if (JSON_HEDLEY_UNLIKELY(current != '#')) - { - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value"))) - { - return false; - } - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType())); - } - - return get_ubjson_size_value(result.first); - } - - if (current == '#') - { - return get_ubjson_size_value(result.first); - } - - return true; - } - - /*! - @param prefix the previously read or set type prefix - @return whether value creation completed - */ - bool get_ubjson_value(const char_int_type prefix) - { - switch (prefix) - { - case std::char_traits<char_type>::eof(): // EOF - return unexpect_eof(input_format_t::ubjson, "value"); - - case 'T': // true - return sax->boolean(true); - case 'F': // false - return sax->boolean(false); - - case 'Z': // null - return sax->null(); - - case 'U': - { - std::uint8_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number); - } - - case 'i': - { - std::int8_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'I': - { - std::int16_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'l': - { - std::int32_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'L': - { - std::int64_t number{}; - return get_number(input_format_t::ubjson, number) && sax->number_integer(number); - } - - case 'd': - { - float number{}; - return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - case 'D': - { - double number{}; - return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), ""); - } - - case 'H': - { - return get_ubjson_high_precision_number(); - } - - case 'C': // char - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char"))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(current > 127)) - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType())); - } - string_t s(1, static_cast<typename string_t::value_type>(current)); - return sax->string(s); - } - - case 'S': // string - { - string_t s; - return get_ubjson_string(s) && sax->string(s); - } - - case '[': // array - return get_ubjson_array(); - - case '{': // object - return get_ubjson_object(); - - default: // anything else - { - auto last_token = get_token_string(); - return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType())); - } - } - } - - /*! - @return whether array creation completed - */ - bool get_ubjson_array() - { - std::pair<std::size_t, char_int_type> size_and_type; - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) - { - return false; - } - - if (size_and_type.first != string_t::npos) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) - { - return false; - } - - if (size_and_type.second != 0) - { - if (size_and_type.second != 'N') - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) - { - return false; - } - } - } - } - else - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - } - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - while (current != ']') - { - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) - { - return false; - } - get_ignore_noop(); - } - } - - return sax->end_array(); - } - - /*! - @return whether object creation completed - */ - bool get_ubjson_object() - { - std::pair<std::size_t, char_int_type> size_and_type; - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) - { - return false; - } - - string_t key; - if (size_and_type.first != string_t::npos) - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) - { - return false; - } - - if (size_and_type.second != 0) - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) - { - return false; - } - key.clear(); - } - } - else - { - for (std::size_t i = 0; i < size_and_type.first; ++i) - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - key.clear(); - } - } - } - else - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - while (current != '}') - { - if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) - { - return false; - } - if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) - { - return false; - } - get_ignore_noop(); - key.clear(); - } - } - - return sax->end_object(); - } - - // Note, no reader for UBJSON binary types is implemented because they do - // not exist - - bool get_ubjson_high_precision_number() - { - // get size of following number string - std::size_t size{}; - auto res = get_ubjson_size_value(size); - if (JSON_HEDLEY_UNLIKELY(!res)) - { - return res; - } - - // get number string - std::vector<char> number_vector; - for (std::size_t i = 0; i < size; ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number"))) - { - return false; - } - number_vector.push_back(static_cast<char>(current)); - } - - // parse number string - using ia_type = decltype(detail::input_adapter(number_vector)); - auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false); - const auto result_number = number_lexer.scan(); - const auto number_string = number_lexer.get_token_string(); - const auto result_remainder = number_lexer.scan(); - - using token_type = typename detail::lexer_base<BasicJsonType>::token_type; - - if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) - { - return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType())); - } - - switch (result_number) - { - case token_type::value_integer: - return sax->number_integer(number_lexer.get_number_integer()); - case token_type::value_unsigned: - return sax->number_unsigned(number_lexer.get_number_unsigned()); - case token_type::value_float: - return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); - case token_type::uninitialized: - case token_type::literal_true: - case token_type::literal_false: - case token_type::literal_null: - case token_type::value_string: - case token_type::begin_array: - case token_type::begin_object: - case token_type::end_array: - case token_type::end_object: - case token_type::name_separator: - case token_type::value_separator: - case token_type::parse_error: - case token_type::end_of_input: - case token_type::literal_or_value: - default: - return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType())); - } - } - - /////////////////////// - // Utility functions // - /////////////////////// - - /*! - @brief get next character from the input - - This function provides the interface to the used input adapter. It does - not throw in case the input reached EOF, but returns a -'ve valued - `std::char_traits<char_type>::eof()` in that case. - - @return character read from the input - */ - char_int_type get() - { - ++chars_read; - return current = ia.get_character(); - } - - /*! - @return character read from the input after ignoring all 'N' entries - */ - char_int_type get_ignore_noop() - { - do - { - get(); - } - while (current == 'N'); - - return current; - } - - /* - @brief read a number from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[out] result number of type @a NumberType - - @return whether conversion completed - - @note This function needs to respect the system's endianess, because - bytes in CBOR, MessagePack, and UBJSON are stored in network order - (big endian) and therefore need reordering on little endian systems. - */ - template<typename NumberType, bool InputIsLittleEndian = false> - bool get_number(const input_format_t format, NumberType& result) - { - // step 1: read input into array with system's byte order - std::array<std::uint8_t, sizeof(NumberType)> vec{}; - for (std::size_t i = 0; i < sizeof(NumberType); ++i) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) - { - return false; - } - - // reverse byte order prior to conversion if necessary - if (is_little_endian != InputIsLittleEndian) - { - vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current); - } - else - { - vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE - } - } - - // step 2: convert array into number of type T and return - std::memcpy(&result, vec.data(), sizeof(NumberType)); - return true; - } - - /*! - @brief create a string by reading characters from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[in] len number of characters to read - @param[out] result string created by reading @a len bytes - - @return whether string creation completed - - @note We can not reserve @a len bytes for the result, because @a len - may be too large. Usually, @ref unexpect_eof() detects the end of - the input before we run out of string memory. - */ - template<typename NumberType> - bool get_string(const input_format_t format, - const NumberType len, - string_t& result) - { - bool success = true; - for (NumberType i = 0; i < len; i++) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) - { - success = false; - break; - } - result.push_back(static_cast<typename string_t::value_type>(current)); - } - return success; - } - - /*! - @brief create a byte array by reading bytes from the input - - @tparam NumberType the type of the number - @param[in] format the current format (for diagnostics) - @param[in] len number of bytes to read - @param[out] result byte array created by reading @a len bytes - - @return whether byte array creation completed - - @note We can not reserve @a len bytes for the result, because @a len - may be too large. Usually, @ref unexpect_eof() detects the end of - the input before we run out of memory. - */ - template<typename NumberType> - bool get_binary(const input_format_t format, - const NumberType len, - binary_t& result) - { - bool success = true; - for (NumberType i = 0; i < len; i++) - { - get(); - if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) - { - success = false; - break; - } - result.push_back(static_cast<std::uint8_t>(current)); - } - return success; - } - - /*! - @param[in] format the current format (for diagnostics) - @param[in] context further context information (for diagnostics) - @return whether the last read character is not EOF - */ - JSON_HEDLEY_NON_NULL(3) - bool unexpect_eof(const input_format_t format, const char* context) const - { - if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof())) - { - return sax->parse_error(chars_read, "<end of file>", - parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType())); - } - return true; - } - - /*! - @return a string representation of the last read byte - */ - std::string get_token_string() const - { - std::array<char, 3> cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - return std::string{cr.data()}; - } - - /*! - @param[in] format the current format - @param[in] detail a detailed error message - @param[in] context further context information - @return a message string to use in the parse_error exceptions - */ - std::string exception_message(const input_format_t format, - const std::string& detail, - const std::string& context) const - { - std::string error_msg = "syntax error while parsing "; - - switch (format) - { - case input_format_t::cbor: - error_msg += "CBOR"; - break; - - case input_format_t::msgpack: - error_msg += "MessagePack"; - break; - - case input_format_t::ubjson: - error_msg += "UBJSON"; - break; - - case input_format_t::bson: - error_msg += "BSON"; - break; - - case input_format_t::json: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - - return error_msg + " " + context + ": " + detail; - } - - private: - /// input adapter - InputAdapterType ia; - - /// the current character - char_int_type current = std::char_traits<char_type>::eof(); - - /// the number of characters read - std::size_t chars_read = 0; - - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); - - /// the SAX parser - json_sax_t* sax = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/input/input_adapters.hpp> - -// #include <nlohmann/detail/input/lexer.hpp> - -// #include <nlohmann/detail/input/parser.hpp> - - -#include <cmath> // isfinite -#include <cstdint> // uint8_t -#include <functional> // function -#include <string> // string -#include <utility> // move -#include <vector> // vector - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/input/input_adapters.hpp> - -// #include <nlohmann/detail/input/json_sax.hpp> - -// #include <nlohmann/detail/input/lexer.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/meta/is_sax.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ -//////////// -// parser // -//////////// - -enum class parse_event_t : std::uint8_t -{ - /// the parser read `{` and started to process a JSON object - object_start, - /// the parser read `}` and finished processing a JSON object - object_end, - /// the parser read `[` and started to process a JSON array - array_start, - /// the parser read `]` and finished processing a JSON array - array_end, - /// the parser read a key of a value in an object - key, - /// the parser finished reading a JSON value - value -}; - -template<typename BasicJsonType> -using parser_callback_t = - std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>; - -/*! -@brief syntax analysis - -This class implements a recursive descent parser. -*/ -template<typename BasicJsonType, typename InputAdapterType> -class parser -{ - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using number_float_t = typename BasicJsonType::number_float_t; - using string_t = typename BasicJsonType::string_t; - using lexer_t = lexer<BasicJsonType, InputAdapterType>; - using token_type = typename lexer_t::token_type; - - public: - /// a parser reading from an input adapter - explicit parser(InputAdapterType&& adapter, - const parser_callback_t<BasicJsonType> cb = nullptr, - const bool allow_exceptions_ = true, - const bool skip_comments = false) - : callback(cb) - , m_lexer(std::move(adapter), skip_comments) - , allow_exceptions(allow_exceptions_) - { - // read first token - get_token(); - } - - /*! - @brief public parser interface - - @param[in] strict whether to expect the last token to be EOF - @param[in,out] result parsed JSON value - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ - void parse(const bool strict, BasicJsonType& result) - { - if (callback) - { - json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions); - sax_parse_internal(&sdp); - - // in strict mode, input must be completely read - if (strict && (get_token() != token_type::end_of_input)) - { - sdp.parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), - exception_message(token_type::end_of_input, "value"), BasicJsonType())); - } - - // in case of an error, return discarded value - if (sdp.is_errored()) - { - result = value_t::discarded; - return; - } - - // set top-level value to null if it was discarded by the callback - // function - if (result.is_discarded()) - { - result = nullptr; - } - } - else - { - json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions); - sax_parse_internal(&sdp); - - // in strict mode, input must be completely read - if (strict && (get_token() != token_type::end_of_input)) - { - sdp.parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType())); - } - - // in case of an error, return discarded value - if (sdp.is_errored()) - { - result = value_t::discarded; - return; - } - } - - result.assert_invariant(); - } - - /*! - @brief public accept interface - - @param[in] strict whether to expect the last token to be EOF - @return whether the input is a proper JSON text - */ - bool accept(const bool strict = true) - { - json_sax_acceptor<BasicJsonType> sax_acceptor; - return sax_parse(&sax_acceptor, strict); - } - - template<typename SAX> - JSON_HEDLEY_NON_NULL(2) - bool sax_parse(SAX* sax, const bool strict = true) - { - (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; - const bool result = sax_parse_internal(sax); - - // strict mode: next byte must be EOF - if (result && strict && (get_token() != token_type::end_of_input)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType())); - } - - return result; - } - - private: - template<typename SAX> - JSON_HEDLEY_NON_NULL(2) - bool sax_parse_internal(SAX* sax) - { - // stack to remember the hierarchy of structured values we are parsing - // true = array; false = object - std::vector<bool> states; - // value to avoid a goto (see comment where set to true) - bool skip_to_state_evaluation = false; - - while (true) - { - if (!skip_to_state_evaluation) - { - // invariant: get_token() was called before each iteration - switch (last_token) - { - case token_type::begin_object: - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) - { - return false; - } - - // closing } -> we are done - if (get_token() == token_type::end_object) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) - { - return false; - } - break; - } - - // parse key - if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType())); - } - if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) - { - return false; - } - - // parse separator (:) - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType())); - } - - // remember we are now inside an object - states.push_back(false); - - // parse values - get_token(); - continue; - } - - case token_type::begin_array: - { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) - { - return false; - } - - // closing ] -> we are done - if (get_token() == token_type::end_array) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) - { - return false; - } - break; - } - - // remember we are now inside an array - states.push_back(true); - - // parse values (no need to call get_token) - continue; - } - - case token_type::value_float: - { - const auto res = m_lexer.get_number_float(); - - if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType())); - } - - if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) - { - return false; - } - - break; - } - - case token_type::literal_false: - { - if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) - { - return false; - } - break; - } - - case token_type::literal_null: - { - if (JSON_HEDLEY_UNLIKELY(!sax->null())) - { - return false; - } - break; - } - - case token_type::literal_true: - { - if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) - { - return false; - } - break; - } - - case token_type::value_integer: - { - if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) - { - return false; - } - break; - } - - case token_type::value_string: - { - if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) - { - return false; - } - break; - } - - case token_type::value_unsigned: - { - if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) - { - return false; - } - break; - } - - case token_type::parse_error: - { - // using "uninitialized" to avoid "expected" message - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType())); - } - - case token_type::uninitialized: - case token_type::end_array: - case token_type::end_object: - case token_type::name_separator: - case token_type::value_separator: - case token_type::end_of_input: - case token_type::literal_or_value: - default: // the last token was unexpected - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType())); - } - } - } - else - { - skip_to_state_evaluation = false; - } - - // we reached this line after we successfully parsed a value - if (states.empty()) - { - // empty stack: we reached the end of the hierarchy: done - return true; - } - - if (states.back()) // array - { - // comma -> next value - if (get_token() == token_type::value_separator) - { - // parse a new value - get_token(); - continue; - } - - // closing ] - if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) - { - return false; - } - - // We are done with this array. Before we can parse a - // new value, we need to evaluate the new state first. - // By setting skip_to_state_evaluation to false, we - // are effectively jumping to the beginning of this if. - JSON_ASSERT(!states.empty()); - states.pop_back(); - skip_to_state_evaluation = true; - continue; - } - - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType())); - } - - // states.back() is false -> object - - // comma -> next value - if (get_token() == token_type::value_separator) - { - // parse key - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType())); - } - - if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) - { - return false; - } - - // parse separator (:) - if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) - { - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType())); - } - - // parse values - get_token(); - continue; - } - - // closing } - if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) - { - if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) - { - return false; - } - - // We are done with this object. Before we can parse a - // new value, we need to evaluate the new state first. - // By setting skip_to_state_evaluation to false, we - // are effectively jumping to the beginning of this if. - JSON_ASSERT(!states.empty()); - states.pop_back(); - skip_to_state_evaluation = true; - continue; - } - - return sax->parse_error(m_lexer.get_position(), - m_lexer.get_token_string(), - parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType())); - } - } - - /// get next token from lexer - token_type get_token() - { - return last_token = m_lexer.scan(); - } - - std::string exception_message(const token_type expected, const std::string& context) - { - std::string error_msg = "syntax error "; - - if (!context.empty()) - { - error_msg += "while parsing " + context + " "; - } - - error_msg += "- "; - - if (last_token == token_type::parse_error) - { - error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + - m_lexer.get_token_string() + "'"; - } - else - { - error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token)); - } - - if (expected != token_type::uninitialized) - { - error_msg += "; expected " + std::string(lexer_t::token_type_name(expected)); - } - - return error_msg; - } - - private: - /// callback function - const parser_callback_t<BasicJsonType> callback = nullptr; - /// the type of the last read token - token_type last_token = token_type::uninitialized; - /// the lexer - lexer_t m_lexer; - /// whether to throw exceptions in case of errors - const bool allow_exceptions = true; -}; - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/iterators/internal_iterator.hpp> - - -// #include <nlohmann/detail/iterators/primitive_iterator.hpp> - - -#include <cstddef> // ptrdiff_t -#include <limits> // numeric_limits - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ -/* -@brief an iterator for primitive JSON types - -This class models an iterator for primitive JSON types (boolean, number, -string). It's only purpose is to allow the iterator/const_iterator classes -to "iterate" over primitive values. Internally, the iterator is modeled by -a `difference_type` variable. Value begin_value (`0`) models the begin, -end_value (`1`) models past the end. -*/ -class primitive_iterator_t -{ - private: - using difference_type = std::ptrdiff_t; - static constexpr difference_type begin_value = 0; - static constexpr difference_type end_value = begin_value + 1; - - JSON_PRIVATE_UNLESS_TESTED: - /// iterator as signed integer type - difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)(); - - public: - constexpr difference_type get_value() const noexcept - { - return m_it; - } - - /// set iterator to a defined beginning - void set_begin() noexcept - { - m_it = begin_value; - } - - /// set iterator to a defined past the end - void set_end() noexcept - { - m_it = end_value; - } - - /// return whether the iterator can be dereferenced - constexpr bool is_begin() const noexcept - { - return m_it == begin_value; - } - - /// return whether the iterator is at end - constexpr bool is_end() const noexcept - { - return m_it == end_value; - } - - friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it == rhs.m_it; - } - - friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it < rhs.m_it; - } - - primitive_iterator_t operator+(difference_type n) noexcept - { - auto result = *this; - result += n; - return result; - } - - friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept - { - return lhs.m_it - rhs.m_it; - } - - primitive_iterator_t& operator++() noexcept - { - ++m_it; - return *this; - } - - primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type) - { - auto result = *this; - ++m_it; - return result; - } - - primitive_iterator_t& operator--() noexcept - { - --m_it; - return *this; - } - - primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type) - { - auto result = *this; - --m_it; - return result; - } - - primitive_iterator_t& operator+=(difference_type n) noexcept - { - m_it += n; - return *this; - } - - primitive_iterator_t& operator-=(difference_type n) noexcept - { - m_it -= n; - return *this; - } -}; -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -/*! -@brief an iterator value - -@note This structure could easily be a union, but MSVC currently does not allow -unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. -*/ -template<typename BasicJsonType> struct internal_iterator -{ - /// iterator for JSON objects - typename BasicJsonType::object_t::iterator object_iterator {}; - /// iterator for JSON arrays - typename BasicJsonType::array_t::iterator array_iterator {}; - /// generic iterator for all other types - primitive_iterator_t primitive_iterator {}; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/iterators/iter_impl.hpp> - - -#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next -#include <type_traits> // conditional, is_const, remove_const - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/iterators/internal_iterator.hpp> - -// #include <nlohmann/detail/iterators/primitive_iterator.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/meta/cpp_future.hpp> - -// #include <nlohmann/detail/meta/type_traits.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ -// forward declare, to be able to friend it later on -template<typename IteratorType> class iteration_proxy; -template<typename IteratorType> class iteration_proxy_value; - -/*! -@brief a template for a bidirectional iterator for the @ref basic_json class -This class implements a both iterators (iterator and const_iterator) for the -@ref basic_json class. -@note An iterator is called *initialized* when a pointer to a JSON value has - been set (e.g., by a constructor or a copy assignment). If the iterator is - default-constructed, it is *uninitialized* and most methods are undefined. - **The library uses assertions to detect calls on uninitialized iterators.** -@requirement The class satisfies the following concept requirements: -- -[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): - The iterator that can be moved can be moved in both directions (i.e. - incremented and decremented). -@since version 1.0.0, simplified in version 2.0.9, change to bidirectional - iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) -*/ -template<typename BasicJsonType> -class iter_impl -{ - /// the iterator with BasicJsonType of different const-ness - using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>; - /// allow basic_json to access private members - friend other_iter_impl; - friend BasicJsonType; - friend iteration_proxy<iter_impl>; - friend iteration_proxy_value<iter_impl>; - - using object_t = typename BasicJsonType::object_t; - using array_t = typename BasicJsonType::array_t; - // make sure BasicJsonType is basic_json or const basic_json - static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value, - "iter_impl only accepts (const) basic_json"); - - public: - - /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. - /// The C++ Standard has never required user-defined iterators to derive from std::iterator. - /// A user-defined iterator should provide publicly accessible typedefs named - /// iterator_category, value_type, difference_type, pointer, and reference. - /// Note that value_type is required to be non-const, even for constant iterators. - using iterator_category = std::bidirectional_iterator_tag; - - /// the type of the values when the iterator is dereferenced - using value_type = typename BasicJsonType::value_type; - /// a type to represent differences between iterators - using difference_type = typename BasicJsonType::difference_type; - /// defines a pointer to the type iterated over (value_type) - using pointer = typename std::conditional<std::is_const<BasicJsonType>::value, - typename BasicJsonType::const_pointer, - typename BasicJsonType::pointer>::type; - /// defines a reference to the type iterated over (value_type) - using reference = - typename std::conditional<std::is_const<BasicJsonType>::value, - typename BasicJsonType::const_reference, - typename BasicJsonType::reference>::type; - - iter_impl() = default; - ~iter_impl() = default; - iter_impl(iter_impl&&) noexcept = default; - iter_impl& operator=(iter_impl&&) noexcept = default; - - /*! - @brief constructor for a given JSON instance - @param[in] object pointer to a JSON object for this iterator - @pre object != nullptr - @post The iterator is initialized; i.e. `m_object != nullptr`. - */ - explicit iter_impl(pointer object) noexcept : m_object(object) - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = typename object_t::iterator(); - break; - } - - case value_t::array: - { - m_it.array_iterator = typename array_t::iterator(); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator = primitive_iterator_t(); - break; - } - } - } - - /*! - @note The conventional copy constructor and copy assignment are implicitly - defined. Combined with the following converting constructor and - assignment, they support: (1) copy from iterator to iterator, (2) - copy from const iterator to const iterator, and (3) conversion from - iterator to const iterator. However conversion from const iterator - to iterator is not defined. - */ - - /*! - @brief const copy constructor - @param[in] other const iterator to copy from - @note This copy constructor had to be defined explicitly to circumvent a bug - occurring on msvc v19.0 compiler (VS 2015) debug build. For more - information refer to: https://github.com/nlohmann/json/issues/1608 - */ - iter_impl(const iter_impl<const BasicJsonType>& other) noexcept - : m_object(other.m_object), m_it(other.m_it) - {} - - /*! - @brief converting assignment - @param[in] other const iterator to copy from - @return const/non-const iterator - @note It is not checked whether @a other is initialized. - */ - iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept - { - if (&other != this) - { - m_object = other.m_object; - m_it = other.m_it; - } - return *this; - } - - /*! - @brief converting constructor - @param[in] other non-const iterator to copy from - @note It is not checked whether @a other is initialized. - */ - iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept - : m_object(other.m_object), m_it(other.m_it) - {} - - /*! - @brief converting assignment - @param[in] other non-const iterator to copy from - @return const/non-const iterator - @note It is not checked whether @a other is initialized. - */ - iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp) - { - m_object = other.m_object; - m_it = other.m_it; - return *this; - } - - JSON_PRIVATE_UNLESS_TESTED: - /*! - @brief set the iterator to the first value - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - void set_begin() noexcept - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = m_object->m_value.object->begin(); - break; - } - - case value_t::array: - { - m_it.array_iterator = m_object->m_value.array->begin(); - break; - } - - case value_t::null: - { - // set to end so begin()==end() is true: null is empty - m_it.primitive_iterator.set_end(); - break; - } - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator.set_begin(); - break; - } - } - } - - /*! - @brief set the iterator past the last value - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - void set_end() noexcept - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - m_it.object_iterator = m_object->m_value.object->end(); - break; - } - - case value_t::array: - { - m_it.array_iterator = m_object->m_value.array->end(); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator.set_end(); - break; - } - } - } - - public: - /*! - @brief return a reference to the value pointed to by the iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference operator*() const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); - return m_it.object_iterator->second; - } - - case value_t::array: - { - JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); - return *m_it.array_iterator; - } - - case value_t::null: - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) - { - return *m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - } - } - } - - /*! - @brief dereference the iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - pointer operator->() const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end()); - return &(m_it.object_iterator->second); - } - - case value_t::array: - { - JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end()); - return &*m_it.array_iterator; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) - { - return m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - } - } - } - - /*! - @brief post-increment (it++) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl const operator++(int) // NOLINT(readability-const-return-type) - { - auto result = *this; - ++(*this); - return result; - } - - /*! - @brief pre-increment (++it) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator++() - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - std::advance(m_it.object_iterator, 1); - break; - } - - case value_t::array: - { - std::advance(m_it.array_iterator, 1); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - ++m_it.primitive_iterator; - break; - } - } - - return *this; - } - - /*! - @brief post-decrement (it--) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl const operator--(int) // NOLINT(readability-const-return-type) - { - auto result = *this; - --(*this); - return result; - } - - /*! - @brief pre-decrement (--it) - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator--() - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - { - std::advance(m_it.object_iterator, -1); - break; - } - - case value_t::array: - { - std::advance(m_it.array_iterator, -1); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - --m_it.primitive_iterator; - break; - } - } - - return *this; - } - - /*! - @brief comparison: equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr > - bool operator==(const IterImpl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object)); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - return (m_it.object_iterator == other.m_it.object_iterator); - - case value_t::array: - return (m_it.array_iterator == other.m_it.array_iterator); - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return (m_it.primitive_iterator == other.m_it.primitive_iterator); - } - } - - /*! - @brief comparison: not equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr > - bool operator!=(const IterImpl& other) const - { - return !operator==(other); - } - - /*! - @brief comparison: smaller - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator<(const iter_impl& other) const - { - // if objects are not the same, the comparison is undefined - if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) - { - JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object)); - } - - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object)); - - case value_t::array: - return (m_it.array_iterator < other.m_it.array_iterator); - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return (m_it.primitive_iterator < other.m_it.primitive_iterator); - } - } - - /*! - @brief comparison: less than or equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator<=(const iter_impl& other) const - { - return !other.operator < (*this); - } - - /*! - @brief comparison: greater than - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator>(const iter_impl& other) const - { - return !operator<=(other); - } - - /*! - @brief comparison: greater than or equal - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - bool operator>=(const iter_impl& other) const - { - return !operator<(other); - } - - /*! - @brief add to iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator+=(difference_type i) - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object)); - - case value_t::array: - { - std::advance(m_it.array_iterator, i); - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - m_it.primitive_iterator += i; - break; - } - } - - return *this; - } - - /*! - @brief subtract from iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl& operator-=(difference_type i) - { - return operator+=(-i); - } - - /*! - @brief add to iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl operator+(difference_type i) const - { - auto result = *this; - result += i; - return result; - } - - /*! - @brief addition of distance and iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - friend iter_impl operator+(difference_type i, const iter_impl& it) - { - auto result = it; - result += i; - return result; - } - - /*! - @brief subtract from iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - iter_impl operator-(difference_type i) const - { - auto result = *this; - result -= i; - return result; - } - - /*! - @brief return difference - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - difference_type operator-(const iter_impl& other) const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object)); - - case value_t::array: - return m_it.array_iterator - other.m_it.array_iterator; - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - return m_it.primitive_iterator - other.m_it.primitive_iterator; - } - } - - /*! - @brief access to successor - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference operator[](difference_type n) const - { - JSON_ASSERT(m_object != nullptr); - - switch (m_object->m_type) - { - case value_t::object: - JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object)); - - case value_t::array: - return *std::next(m_it.array_iterator, n); - - case value_t::null: - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) - { - return *m_object; - } - - JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object)); - } - } - } - - /*! - @brief return the key of an object iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - const typename object_t::key_type& key() const - { - JSON_ASSERT(m_object != nullptr); - - if (JSON_HEDLEY_LIKELY(m_object->is_object())) - { - return m_it.object_iterator->first; - } - - JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object)); - } - - /*! - @brief return the value of an iterator - @pre The iterator is initialized; i.e. `m_object != nullptr`. - */ - reference value() const - { - return operator*(); - } - - JSON_PRIVATE_UNLESS_TESTED: - /// associated JSON instance - pointer m_object = nullptr; - /// the actual iterator of the associated instance - internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {}; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/iterators/iteration_proxy.hpp> - -// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp> - - -#include <cstddef> // ptrdiff_t -#include <iterator> // reverse_iterator -#include <utility> // declval - -namespace nlohmann -{ -namespace detail -{ -////////////////////// -// reverse_iterator // -////////////////////// - -/*! -@brief a template for a reverse iterator class - -@tparam Base the base iterator type to reverse. Valid types are @ref -iterator (to create @ref reverse_iterator) and @ref const_iterator (to -create @ref const_reverse_iterator). - -@requirement The class satisfies the following concept requirements: -- -[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): - The iterator that can be moved can be moved in both directions (i.e. - incremented and decremented). -- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): - It is possible to write to the pointed-to element (only if @a Base is - @ref iterator). - -@since version 1.0.0 -*/ -template<typename Base> -class json_reverse_iterator : public std::reverse_iterator<Base> -{ - public: - using difference_type = std::ptrdiff_t; - /// shortcut to the reverse iterator adapter - using base_iterator = std::reverse_iterator<Base>; - /// the reference type for the pointed-to element - using reference = typename Base::reference; - - /// create reverse iterator from iterator - explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept - : base_iterator(it) {} - - /// create reverse iterator from base class - explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} - - /// post-increment (it++) - json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type) - { - return static_cast<json_reverse_iterator>(base_iterator::operator++(1)); - } - - /// pre-increment (++it) - json_reverse_iterator& operator++() - { - return static_cast<json_reverse_iterator&>(base_iterator::operator++()); - } - - /// post-decrement (it--) - json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type) - { - return static_cast<json_reverse_iterator>(base_iterator::operator--(1)); - } - - /// pre-decrement (--it) - json_reverse_iterator& operator--() - { - return static_cast<json_reverse_iterator&>(base_iterator::operator--()); - } - - /// add to iterator - json_reverse_iterator& operator+=(difference_type i) - { - return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i)); - } - - /// add to iterator - json_reverse_iterator operator+(difference_type i) const - { - return static_cast<json_reverse_iterator>(base_iterator::operator+(i)); - } - - /// subtract from iterator - json_reverse_iterator operator-(difference_type i) const - { - return static_cast<json_reverse_iterator>(base_iterator::operator-(i)); - } - - /// return difference - difference_type operator-(const json_reverse_iterator& other) const - { - return base_iterator(*this) - base_iterator(other); - } - - /// access to successor - reference operator[](difference_type n) const - { - return *(this->operator+(n)); - } - - /// return the key of an object iterator - auto key() const -> decltype(std::declval<Base>().key()) - { - auto it = --this->base(); - return it.key(); - } - - /// return the value of an iterator - reference value() const - { - auto it = --this->base(); - return it.operator * (); - } -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/iterators/primitive_iterator.hpp> - -// #include <nlohmann/detail/json_pointer.hpp> - - -#include <algorithm> // all_of -#include <cctype> // isdigit -#include <limits> // max -#include <numeric> // accumulate -#include <string> // string -#include <utility> // move -#include <vector> // vector - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/string_escape.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -template<typename BasicJsonType> -class json_pointer -{ - // allow basic_json to access private members - NLOHMANN_BASIC_JSON_TPL_DECLARATION - friend class basic_json; - - public: - /*! - @brief create JSON pointer - - Create a JSON pointer according to the syntax described in - [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). - - @param[in] s string representing the JSON pointer; if omitted, the empty - string is assumed which references the whole JSON value - - @throw parse_error.107 if the given JSON pointer @a s is nonempty and does - not begin with a slash (`/`); see example below - - @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is - not followed by `0` (representing `~`) or `1` (representing `/`); see - example below - - @liveexample{The example shows the construction several valid JSON pointers - as well as the exceptional behavior.,json_pointer} - - @since version 2.0.0 - */ - explicit json_pointer(const std::string& s = "") - : reference_tokens(split(s)) - {} - - /*! - @brief return a string representation of the JSON pointer - - @invariant For each JSON pointer `ptr`, it holds: - @code {.cpp} - ptr == json_pointer(ptr.to_string()); - @endcode - - @return a string representation of the JSON pointer - - @liveexample{The example shows the result of `to_string`.,json_pointer__to_string} - - @since version 2.0.0 - */ - std::string to_string() const - { - return std::accumulate(reference_tokens.begin(), reference_tokens.end(), - std::string{}, - [](const std::string & a, const std::string & b) - { - return a + "/" + detail::escape(b); - }); - } - - /// @copydoc to_string() - operator std::string() const - { - return to_string(); - } - - /*! - @brief append another JSON pointer at the end of this JSON pointer - - @param[in] ptr JSON pointer to append - @return JSON pointer with @a ptr appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::string) to append a reference token - @sa see @ref operator/=(std::size_t) to append an array index - @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(const json_pointer& ptr) - { - reference_tokens.insert(reference_tokens.end(), - ptr.reference_tokens.begin(), - ptr.reference_tokens.end()); - return *this; - } - - /*! - @brief append an unescaped reference token at the end of this JSON pointer - - @param[in] token reference token to append - @return JSON pointer with @a token appended without escaping @a token - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - @sa see @ref operator/=(std::size_t) to append an array index - @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(std::string token) - { - push_back(std::move(token)); - return *this; - } - - /*! - @brief append an array index at the end of this JSON pointer - - @param[in] array_idx array index to append - @return JSON pointer with @a array_idx appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - @sa see @ref operator/=(std::string) to append a reference token - @sa see @ref operator/(const json_pointer&, std::string) for a binary operator - - @since version 3.6.0 - */ - json_pointer& operator/=(std::size_t array_idx) - { - return *this /= std::to_string(array_idx); - } - - /*! - @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer - - @param[in] lhs JSON pointer - @param[in] rhs JSON pointer - @return a new JSON pointer with @a rhs appended to @a lhs - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a lhs and @a rhs. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& lhs, - const json_pointer& rhs) - { - return json_pointer(lhs) /= rhs; - } - - /*! - @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] token reference token - @return a new JSON pointer with unescaped @a token appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::string) to append a reference token - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param) - { - return json_pointer(ptr) /= std::move(token); - } - - /*! - @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] array_idx array index - @return a new JSON pointer with @a array_idx appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::size_t) to append an array index - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx) - { - return json_pointer(ptr) /= array_idx; - } - - /*! - @brief returns the parent of this JSON pointer - - @return parent of this JSON pointer; in case this JSON pointer is the root, - the root itself is returned - - @complexity Linear in the length of the JSON pointer. - - @liveexample{The example shows the result of `parent_pointer` for different - JSON Pointers.,json_pointer__parent_pointer} - - @since version 3.6.0 - */ - json_pointer parent_pointer() const - { - if (empty()) - { - return *this; - } - - json_pointer res = *this; - res.pop_back(); - return res; - } - - /*! - @brief remove last reference token - - @pre not `empty()` - - @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ - void pop_back() - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType())); - } - - reference_tokens.pop_back(); - } - - /*! - @brief return last reference token - - @pre not `empty()` - @return last reference token - - @liveexample{The example shows the usage of `back`.,json_pointer__back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ - const std::string& back() const - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType())); - } - - return reference_tokens.back(); - } - - /*! - @brief append an unescaped token at the end of the reference pointer - - @param[in] token token to add - - @complexity Amortized constant. - - @liveexample{The example shows the result of `push_back` for different - JSON Pointers.,json_pointer__push_back} - - @since version 3.6.0 - */ - void push_back(const std::string& token) - { - reference_tokens.push_back(token); - } - - /// @copydoc push_back(const std::string&) - void push_back(std::string&& token) - { - reference_tokens.push_back(std::move(token)); - } - - /*! - @brief return whether pointer points to the root document - - @return true iff the JSON pointer points to the root document - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example shows the result of `empty` for different JSON - Pointers.,json_pointer__empty} - - @since version 3.6.0 - */ - bool empty() const noexcept - { - return reference_tokens.empty(); - } - - private: - /*! - @param[in] s reference token to be converted into an array index - - @return integer representation of @a s - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index begins not with a digit - @throw out_of_range.404 if string @a s could not be converted to an integer - @throw out_of_range.410 if an array index exceeds size_type - */ - static typename BasicJsonType::size_type array_index(const std::string& s) - { - using size_type = typename BasicJsonType::size_type; - - // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) - { - JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType())); - } - - // error condition (cf. RFC 6901, Sect. 4) - if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) - { - JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType())); - } - - std::size_t processed_chars = 0; - unsigned long long res = 0; // NOLINT(runtime/int) - JSON_TRY - { - res = std::stoull(s, &processed_chars); - } - JSON_CATCH(std::out_of_range&) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType())); - } - - // check if the string was completely read - if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size())) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType())); - } - - // only triggered on special platforms (like 32bit), see also - // https://github.com/nlohmann/json/pull/2203 - if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int) - { - JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE - } - - return static_cast<size_type>(res); - } - - JSON_PRIVATE_UNLESS_TESTED: - json_pointer top() const - { - if (JSON_HEDLEY_UNLIKELY(empty())) - { - JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType())); - } - - json_pointer result = *this; - result.reference_tokens = {reference_tokens[0]}; - return result; - } - - private: - /*! - @brief create and return a reference to the pointed to value - - @complexity Linear in the number of reference tokens. - - @throw parse_error.109 if array index is not a number - @throw type_error.313 if value cannot be unflattened - */ - BasicJsonType& get_and_create(BasicJsonType& j) const - { - auto* result = &j; - - // in case no reference tokens exist, return a reference to the JSON value - // j which will be overwritten by a primitive value - for (const auto& reference_token : reference_tokens) - { - switch (result->type()) - { - case detail::value_t::null: - { - if (reference_token == "0") - { - // start a new array if reference token is 0 - result = &result->operator[](0); - } - else - { - // start a new object otherwise - result = &result->operator[](reference_token); - } - break; - } - - case detail::value_t::object: - { - // create an entry in the object - result = &result->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - // create an entry in the array - result = &result->operator[](array_index(reference_token)); - break; - } - - /* - The following code is only reached if there exists a reference - token _and_ the current value is primitive. In this case, we have - an error situation, because primitive values may only occur as - single value; that is, with an empty list of reference tokens. - */ - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j)); - } - } - - return *result; - } - - /*! - @brief return a reference to the pointed to value - - @note This version does not throw if a value is not present, but tries to - create nested values instead. For instance, calling this function - with pointer `"/this/that"` on a null value is equivalent to calling - `operator[]("this").operator[]("that")` on that value, effectively - changing the null value to an object. - - @param[in] ptr a JSON value - - @return reference to the JSON value pointed to by the JSON pointer - - @complexity Linear in the length of the JSON pointer. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - BasicJsonType& get_unchecked(BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - // convert null values to arrays or objects before continuing - if (ptr->is_null()) - { - // check if reference token is a number - const bool nums = - std::all_of(reference_token.begin(), reference_token.end(), - [](const unsigned char x) - { - return std::isdigit(x); - }); - - // change value to array for numbers or "-" or to object otherwise - *ptr = (nums || reference_token == "-") - ? detail::value_t::array - : detail::value_t::object; - } - - switch (ptr->type()) - { - case detail::value_t::object: - { - // use unchecked object access - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (reference_token == "-") - { - // explicitly treat "-" as index beyond the end - ptr = &ptr->operator[](ptr->m_value.array->size()); - } - else - { - // convert array index to number; unchecked access - ptr = &ptr->operator[](array_index(reference_token)); - } - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - BasicJsonType& get_checked(BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // note: at performs range check - ptr = &ptr->at(reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range", *ptr)); - } - - // note: at performs range check - ptr = &ptr->at(array_index(reference_token)); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @brief return a const reference to the pointed to value - - @param[in] ptr a JSON value - - @return const reference to the JSON value pointed to by the JSON - pointer - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // use unchecked object access - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" cannot be used for const access - JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr)); - } - - // use unchecked array access - ptr = &ptr->operator[](array_index(reference_token)); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - */ - const BasicJsonType& get_checked(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - // note: at performs range check - ptr = &ptr->at(reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - JSON_THROW(detail::out_of_range::create(402, - "array index '-' (" + std::to_string(ptr->m_value.array->size()) + - ") is out of range", *ptr)); - } - - // note: at performs range check - ptr = &ptr->at(array_index(reference_token)); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr)); - } - } - - return *ptr; - } - - /*! - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - */ - bool contains(const BasicJsonType* ptr) const - { - for (const auto& reference_token : reference_tokens) - { - switch (ptr->type()) - { - case detail::value_t::object: - { - if (!ptr->contains(reference_token)) - { - // we did not find the key in the object - return false; - } - - ptr = &ptr->operator[](reference_token); - break; - } - - case detail::value_t::array: - { - if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) - { - // "-" always fails the range check - return false; - } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) - { - // invalid char - return false; - } - if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) - { - if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) - { - // first char should be between '1' and '9' - return false; - } - for (std::size_t i = 1; i < reference_token.size(); i++) - { - if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) - { - // other char should be between '0' and '9' - return false; - } - } - } - - const auto idx = array_index(reference_token); - if (idx >= ptr->size()) - { - // index out of range - return false; - } - - ptr = &ptr->operator[](idx); - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - { - // we do not expect primitive values if there is still a - // reference token to process - return false; - } - } - } - - // no reference token left means we found a primitive value - return true; - } - - /*! - @brief split the string input to reference tokens - - @note This function is only called by the json_pointer constructor. - All exceptions below are documented there. - - @throw parse_error.107 if the pointer is not empty or begins with '/' - @throw parse_error.108 if character '~' is not followed by '0' or '1' - */ - static std::vector<std::string> split(const std::string& reference_string) - { - std::vector<std::string> result; - - // special case: empty reference string -> no reference tokens - if (reference_string.empty()) - { - return result; - } - - // check if nonempty reference string begins with slash - if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) - { - JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType())); - } - - // extract the reference tokens: - // - slash: position of the last read slash (or end of string) - // - start: position after the previous slash - for ( - // search for the first slash after the first character - std::size_t slash = reference_string.find_first_of('/', 1), - // set the beginning of the first reference token - start = 1; - // we can stop if start == 0 (if slash == std::string::npos) - start != 0; - // set the beginning of the next reference token - // (will eventually be 0 if slash == std::string::npos) - start = (slash == std::string::npos) ? 0 : slash + 1, - // find next slash - slash = reference_string.find_first_of('/', start)) - { - // use the text between the beginning of the reference token - // (start) and the last slash (slash). - auto reference_token = reference_string.substr(start, slash - start); - - // check reference tokens are properly escaped - for (std::size_t pos = reference_token.find_first_of('~'); - pos != std::string::npos; - pos = reference_token.find_first_of('~', pos + 1)) - { - JSON_ASSERT(reference_token[pos] == '~'); - - // ~ must be followed by 0 or 1 - if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || - (reference_token[pos + 1] != '0' && - reference_token[pos + 1] != '1'))) - { - JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType())); - } - } - - // finally, store the reference token - detail::unescape(reference_token); - result.push_back(reference_token); - } - - return result; - } - - private: - /*! - @param[in] reference_string the reference string to the current value - @param[in] value the value to consider - @param[in,out] result the result object to insert values to - - @note Empty objects or arrays are flattened to `null`. - */ - static void flatten(const std::string& reference_string, - const BasicJsonType& value, - BasicJsonType& result) - { - switch (value.type()) - { - case detail::value_t::array: - { - if (value.m_value.array->empty()) - { - // flatten empty array as null - result[reference_string] = nullptr; - } - else - { - // iterate array and use index as reference string - for (std::size_t i = 0; i < value.m_value.array->size(); ++i) - { - flatten(reference_string + "/" + std::to_string(i), - value.m_value.array->operator[](i), result); - } - } - break; - } - - case detail::value_t::object: - { - if (value.m_value.object->empty()) - { - // flatten empty object as null - result[reference_string] = nullptr; - } - else - { - // iterate object and use keys as reference string - for (const auto& element : *value.m_value.object) - { - flatten(reference_string + "/" + detail::escape(element.first), element.second, result); - } - } - break; - } - - case detail::value_t::null: - case detail::value_t::string: - case detail::value_t::boolean: - case detail::value_t::number_integer: - case detail::value_t::number_unsigned: - case detail::value_t::number_float: - case detail::value_t::binary: - case detail::value_t::discarded: - default: - { - // add primitive value with its reference string - result[reference_string] = value; - break; - } - } - } - - /*! - @param[in] value flattened JSON - - @return unflattened JSON - - @throw parse_error.109 if array index is not a number - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - @throw type_error.313 if value cannot be unflattened - */ - static BasicJsonType - unflatten(const BasicJsonType& value) - { - if (JSON_HEDLEY_UNLIKELY(!value.is_object())) - { - JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value)); - } - - BasicJsonType result; - - // iterate the JSON object values - for (const auto& element : *value.m_value.object) - { - if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) - { - JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second)); - } - - // assign value to reference pointed to by JSON pointer; Note that if - // the JSON pointer is "" (i.e., points to the whole value), function - // get_and_create returns a reference to result itself. An assignment - // will then create a primitive value. - json_pointer(element.first).get_and_create(result) = element.second; - } - - return result; - } - - /*! - @brief compares two JSON pointers for equality - - @param[in] lhs JSON pointer to compare - @param[in] rhs JSON pointer to compare - @return whether @a lhs is equal to @a rhs - - @complexity Linear in the length of the JSON pointer - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - */ - friend bool operator==(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return lhs.reference_tokens == rhs.reference_tokens; - } - - /*! - @brief compares two JSON pointers for inequality - - @param[in] lhs JSON pointer to compare - @param[in] rhs JSON pointer to compare - @return whether @a lhs is not equal @a rhs - - @complexity Linear in the length of the JSON pointer - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - */ - friend bool operator!=(json_pointer const& lhs, - json_pointer const& rhs) noexcept - { - return !(lhs == rhs); - } - - /// the reference tokens - std::vector<std::string> reference_tokens; -}; -} // namespace nlohmann - -// #include <nlohmann/detail/json_ref.hpp> - - -#include <initializer_list> -#include <utility> - -// #include <nlohmann/detail/meta/type_traits.hpp> - - -namespace nlohmann -{ -namespace detail -{ -template<typename BasicJsonType> -class json_ref -{ - public: - using value_type = BasicJsonType; - - json_ref(value_type&& value) - : owned_value(std::move(value)) - {} - - json_ref(const value_type& value) - : value_ref(&value) - {} - - json_ref(std::initializer_list<json_ref> init) - : owned_value(init) - {} - - template < - class... Args, - enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 > - json_ref(Args && ... args) - : owned_value(std::forward<Args>(args)...) - {} - - // class should be movable only - json_ref(json_ref&&) noexcept = default; - json_ref(const json_ref&) = delete; - json_ref& operator=(const json_ref&) = delete; - json_ref& operator=(json_ref&&) = delete; - ~json_ref() = default; - - value_type moved_or_copied() const - { - if (value_ref == nullptr) - { - return std::move(owned_value); - } - return *value_ref; - } - - value_type const& operator*() const - { - return value_ref ? *value_ref : owned_value; - } - - value_type const* operator->() const - { - return &** this; - } - - private: - mutable value_type owned_value = nullptr; - value_type const* value_ref = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/string_escape.hpp> - -// #include <nlohmann/detail/meta/cpp_future.hpp> - -// #include <nlohmann/detail/meta/type_traits.hpp> - -// #include <nlohmann/detail/output/binary_writer.hpp> - - -#include <algorithm> // reverse -#include <array> // array -#include <cmath> // isnan, isinf -#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t -#include <cstring> // memcpy -#include <limits> // numeric_limits -#include <string> // string -#include <utility> // move - -// #include <nlohmann/detail/input/binary_reader.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/output/output_adapters.hpp> - - -#include <algorithm> // copy -#include <cstddef> // size_t -#include <iterator> // back_inserter -#include <memory> // shared_ptr, make_shared -#include <string> // basic_string -#include <vector> // vector - -#ifndef JSON_NO_IO - #include <ios> // streamsize - #include <ostream> // basic_ostream -#endif // JSON_NO_IO - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ -/// abstract output adapter interface -template<typename CharType> struct output_adapter_protocol -{ - virtual void write_character(CharType c) = 0; - virtual void write_characters(const CharType* s, std::size_t length) = 0; - virtual ~output_adapter_protocol() = default; - - output_adapter_protocol() = default; - output_adapter_protocol(const output_adapter_protocol&) = default; - output_adapter_protocol(output_adapter_protocol&&) noexcept = default; - output_adapter_protocol& operator=(const output_adapter_protocol&) = default; - output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default; -}; - -/// a type to simplify interfaces -template<typename CharType> -using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>; - -/// output adapter for byte vectors -template<typename CharType, typename AllocatorType = std::allocator<CharType>> -class output_vector_adapter : public output_adapter_protocol<CharType> -{ - public: - explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept - : v(vec) - {} - - void write_character(CharType c) override - { - v.push_back(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - std::copy(s, s + length, std::back_inserter(v)); - } - - private: - std::vector<CharType, AllocatorType>& v; -}; - -#ifndef JSON_NO_IO -/// output adapter for output streams -template<typename CharType> -class output_stream_adapter : public output_adapter_protocol<CharType> -{ - public: - explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept - : stream(s) - {} - - void write_character(CharType c) override - { - stream.put(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - stream.write(s, static_cast<std::streamsize>(length)); - } - - private: - std::basic_ostream<CharType>& stream; -}; -#endif // JSON_NO_IO - -/// output adapter for basic_string -template<typename CharType, typename StringType = std::basic_string<CharType>> -class output_string_adapter : public output_adapter_protocol<CharType> -{ - public: - explicit output_string_adapter(StringType& s) noexcept - : str(s) - {} - - void write_character(CharType c) override - { - str.push_back(c); - } - - JSON_HEDLEY_NON_NULL(2) - void write_characters(const CharType* s, std::size_t length) override - { - str.append(s, length); - } - - private: - StringType& str; -}; - -template<typename CharType, typename StringType = std::basic_string<CharType>> -class output_adapter -{ - public: - template<typename AllocatorType = std::allocator<CharType>> - output_adapter(std::vector<CharType, AllocatorType>& vec) - : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {} - -#ifndef JSON_NO_IO - output_adapter(std::basic_ostream<CharType>& s) - : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {} -#endif // JSON_NO_IO - - output_adapter(StringType& s) - : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {} - - operator output_adapter_t<CharType>() - { - return oa; - } - - private: - output_adapter_t<CharType> oa = nullptr; -}; -} // namespace detail -} // namespace nlohmann - - -namespace nlohmann -{ -namespace detail -{ -/////////////////// -// binary writer // -/////////////////// - -/*! -@brief serialization to CBOR and MessagePack values -*/ -template<typename BasicJsonType, typename CharType> -class binary_writer -{ - using string_t = typename BasicJsonType::string_t; - using binary_t = typename BasicJsonType::binary_t; - using number_float_t = typename BasicJsonType::number_float_t; - - public: - /*! - @brief create a binary writer - - @param[in] adapter output adapter to write to - */ - explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter)) - { - JSON_ASSERT(oa); - } - - /*! - @param[in] j JSON value to serialize - @pre j.type() == value_t::object - */ - void write_bson(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::object: - { - write_bson_object(*j.m_value.object); - break; - } - - case value_t::null: - case value_t::array: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j)); - } - } - } - - /*! - @param[in] j JSON value to serialize - */ - void write_cbor(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::null: - { - oa->write_character(to_char_type(0xF6)); - break; - } - - case value_t::boolean: - { - oa->write_character(j.m_value.boolean - ? to_char_type(0xF5) - : to_char_type(0xF4)); - break; - } - - case value_t::number_integer: - { - if (j.m_value.number_integer >= 0) - { - // CBOR does not differentiate between positive signed - // integers and unsigned integers. Therefore, we used the - // code from the value_t::number_unsigned case here. - if (j.m_value.number_integer <= 0x17) - { - write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0x18)); - write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0x19)); - write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0x1A)); - write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); - } - else - { - oa->write_character(to_char_type(0x1B)); - write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); - } - } - else - { - // The conversions below encode the sign in the first - // byte, and the value is converted to a positive number. - const auto positive_number = -1 - j.m_value.number_integer; - if (j.m_value.number_integer >= -24) - { - write_number(static_cast<std::uint8_t>(0x20 + positive_number)); - } - else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0x38)); - write_number(static_cast<std::uint8_t>(positive_number)); - } - else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0x39)); - write_number(static_cast<std::uint16_t>(positive_number)); - } - else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0x3A)); - write_number(static_cast<std::uint32_t>(positive_number)); - } - else - { - oa->write_character(to_char_type(0x3B)); - write_number(static_cast<std::uint64_t>(positive_number)); - } - } - break; - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned <= 0x17) - { - write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0x18)); - write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0x19)); - write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0x1A)); - write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned)); - } - else - { - oa->write_character(to_char_type(0x1B)); - write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned)); - } - break; - } - - case value_t::number_float: - { - if (std::isnan(j.m_value.number_float)) - { - // NaN is 0xf97e00 in CBOR - oa->write_character(to_char_type(0xF9)); - oa->write_character(to_char_type(0x7E)); - oa->write_character(to_char_type(0x00)); - } - else if (std::isinf(j.m_value.number_float)) - { - // Infinity is 0xf97c00, -Infinity is 0xf9fc00 - oa->write_character(to_char_type(0xf9)); - oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC)); - oa->write_character(to_char_type(0x00)); - } - else - { - write_compact_float(j.m_value.number_float, detail::input_format_t::cbor); - } - break; - } - - case value_t::string: - { - // step 1: write control byte and the string length - const auto N = j.m_value.string->size(); - if (N <= 0x17) - { - write_number(static_cast<std::uint8_t>(0x60 + N)); - } - else if (N <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0x78)); - write_number(static_cast<std::uint8_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0x79)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0x7A)); - write_number(static_cast<std::uint32_t>(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits<std::uint64_t>::max)()) - { - oa->write_character(to_char_type(0x7B)); - write_number(static_cast<std::uint64_t>(N)); - } - // LCOV_EXCL_STOP - - // step 2: write the string - oa->write_characters( - reinterpret_cast<const CharType*>(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - // step 1: write control byte and the array size - const auto N = j.m_value.array->size(); - if (N <= 0x17) - { - write_number(static_cast<std::uint8_t>(0x80 + N)); - } - else if (N <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0x98)); - write_number(static_cast<std::uint8_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0x99)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0x9A)); - write_number(static_cast<std::uint32_t>(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits<std::uint64_t>::max)()) - { - oa->write_character(to_char_type(0x9B)); - write_number(static_cast<std::uint64_t>(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - for (const auto& el : *j.m_value.array) - { - write_cbor(el); - } - break; - } - - case value_t::binary: - { - if (j.m_value.binary->has_subtype()) - { - if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)()) - { - write_number(static_cast<std::uint8_t>(0xd8)); - write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype())); - } - else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)()) - { - write_number(static_cast<std::uint8_t>(0xd9)); - write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype())); - } - else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)()) - { - write_number(static_cast<std::uint8_t>(0xda)); - write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype())); - } - else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)()) - { - write_number(static_cast<std::uint8_t>(0xdb)); - write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype())); - } - } - - // step 1: write control byte and the binary array size - const auto N = j.m_value.binary->size(); - if (N <= 0x17) - { - write_number(static_cast<std::uint8_t>(0x40 + N)); - } - else if (N <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0x58)); - write_number(static_cast<std::uint8_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0x59)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0x5A)); - write_number(static_cast<std::uint32_t>(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits<std::uint64_t>::max)()) - { - oa->write_character(to_char_type(0x5B)); - write_number(static_cast<std::uint64_t>(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - oa->write_characters( - reinterpret_cast<const CharType*>(j.m_value.binary->data()), - N); - - break; - } - - case value_t::object: - { - // step 1: write control byte and the object size - const auto N = j.m_value.object->size(); - if (N <= 0x17) - { - write_number(static_cast<std::uint8_t>(0xA0 + N)); - } - else if (N <= (std::numeric_limits<std::uint8_t>::max)()) - { - oa->write_character(to_char_type(0xB8)); - write_number(static_cast<std::uint8_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - oa->write_character(to_char_type(0xB9)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - oa->write_character(to_char_type(0xBA)); - write_number(static_cast<std::uint32_t>(N)); - } - // LCOV_EXCL_START - else if (N <= (std::numeric_limits<std::uint64_t>::max)()) - { - oa->write_character(to_char_type(0xBB)); - write_number(static_cast<std::uint64_t>(N)); - } - // LCOV_EXCL_STOP - - // step 2: write each element - for (const auto& el : *j.m_value.object) - { - write_cbor(el.first); - write_cbor(el.second); - } - break; - } - - case value_t::discarded: - default: - break; - } - } - - /*! - @param[in] j JSON value to serialize - */ - void write_msgpack(const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::null: // nil - { - oa->write_character(to_char_type(0xC0)); - break; - } - - case value_t::boolean: // true and false - { - oa->write_character(j.m_value.boolean - ? to_char_type(0xC3) - : to_char_type(0xC2)); - break; - } - - case value_t::number_integer: - { - if (j.m_value.number_integer >= 0) - { - // MessagePack does not differentiate between positive - // signed integers and unsigned integers. Therefore, we used - // the code from the value_t::number_unsigned case here. - if (j.m_value.number_unsigned < 128) - { - // positive fixnum - write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) - { - // uint 8 - oa->write_character(to_char_type(0xCC)); - write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) - { - // uint 16 - oa->write_character(to_char_type(0xCD)); - write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) - { - // uint 32 - oa->write_character(to_char_type(0xCE)); - write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) - { - // uint 64 - oa->write_character(to_char_type(0xCF)); - write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); - } - } - else - { - if (j.m_value.number_integer >= -32) - { - // negative fixnum - write_number(static_cast<std::int8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() && - j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)()) - { - // int 8 - oa->write_character(to_char_type(0xD0)); - write_number(static_cast<std::int8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() && - j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)()) - { - // int 16 - oa->write_character(to_char_type(0xD1)); - write_number(static_cast<std::int16_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() && - j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)()) - { - // int 32 - oa->write_character(to_char_type(0xD2)); - write_number(static_cast<std::int32_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() && - j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)()) - { - // int 64 - oa->write_character(to_char_type(0xD3)); - write_number(static_cast<std::int64_t>(j.m_value.number_integer)); - } - } - break; - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned < 128) - { - // positive fixnum - write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)()) - { - // uint 8 - oa->write_character(to_char_type(0xCC)); - write_number(static_cast<std::uint8_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)()) - { - // uint 16 - oa->write_character(to_char_type(0xCD)); - write_number(static_cast<std::uint16_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)()) - { - // uint 32 - oa->write_character(to_char_type(0xCE)); - write_number(static_cast<std::uint32_t>(j.m_value.number_integer)); - } - else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)()) - { - // uint 64 - oa->write_character(to_char_type(0xCF)); - write_number(static_cast<std::uint64_t>(j.m_value.number_integer)); - } - break; - } - - case value_t::number_float: - { - write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack); - break; - } - - case value_t::string: - { - // step 1: write control byte and the string length - const auto N = j.m_value.string->size(); - if (N <= 31) - { - // fixstr - write_number(static_cast<std::uint8_t>(0xA0 | N)); - } - else if (N <= (std::numeric_limits<std::uint8_t>::max)()) - { - // str 8 - oa->write_character(to_char_type(0xD9)); - write_number(static_cast<std::uint8_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - // str 16 - oa->write_character(to_char_type(0xDA)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - // str 32 - oa->write_character(to_char_type(0xDB)); - write_number(static_cast<std::uint32_t>(N)); - } - - // step 2: write the string - oa->write_characters( - reinterpret_cast<const CharType*>(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - // step 1: write control byte and the array size - const auto N = j.m_value.array->size(); - if (N <= 15) - { - // fixarray - write_number(static_cast<std::uint8_t>(0x90 | N)); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - // array 16 - oa->write_character(to_char_type(0xDC)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - // array 32 - oa->write_character(to_char_type(0xDD)); - write_number(static_cast<std::uint32_t>(N)); - } - - // step 2: write each element - for (const auto& el : *j.m_value.array) - { - write_msgpack(el); - } - break; - } - - case value_t::binary: - { - // step 0: determine if the binary type has a set subtype to - // determine whether or not to use the ext or fixext types - const bool use_ext = j.m_value.binary->has_subtype(); - - // step 1: write control byte and the byte string length - const auto N = j.m_value.binary->size(); - if (N <= (std::numeric_limits<std::uint8_t>::max)()) - { - std::uint8_t output_type{}; - bool fixed = true; - if (use_ext) - { - switch (N) - { - case 1: - output_type = 0xD4; // fixext 1 - break; - case 2: - output_type = 0xD5; // fixext 2 - break; - case 4: - output_type = 0xD6; // fixext 4 - break; - case 8: - output_type = 0xD7; // fixext 8 - break; - case 16: - output_type = 0xD8; // fixext 16 - break; - default: - output_type = 0xC7; // ext 8 - fixed = false; - break; - } - - } - else - { - output_type = 0xC4; // bin 8 - fixed = false; - } - - oa->write_character(to_char_type(output_type)); - if (!fixed) - { - write_number(static_cast<std::uint8_t>(N)); - } - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - std::uint8_t output_type = use_ext - ? 0xC8 // ext 16 - : 0xC5; // bin 16 - - oa->write_character(to_char_type(output_type)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - std::uint8_t output_type = use_ext - ? 0xC9 // ext 32 - : 0xC6; // bin 32 - - oa->write_character(to_char_type(output_type)); - write_number(static_cast<std::uint32_t>(N)); - } - - // step 1.5: if this is an ext type, write the subtype - if (use_ext) - { - write_number(static_cast<std::int8_t>(j.m_value.binary->subtype())); - } - - // step 2: write the byte string - oa->write_characters( - reinterpret_cast<const CharType*>(j.m_value.binary->data()), - N); - - break; - } - - case value_t::object: - { - // step 1: write control byte and the object size - const auto N = j.m_value.object->size(); - if (N <= 15) - { - // fixmap - write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF))); - } - else if (N <= (std::numeric_limits<std::uint16_t>::max)()) - { - // map 16 - oa->write_character(to_char_type(0xDE)); - write_number(static_cast<std::uint16_t>(N)); - } - else if (N <= (std::numeric_limits<std::uint32_t>::max)()) - { - // map 32 - oa->write_character(to_char_type(0xDF)); - write_number(static_cast<std::uint32_t>(N)); - } - - // step 2: write each element - for (const auto& el : *j.m_value.object) - { - write_msgpack(el.first); - write_msgpack(el.second); - } - break; - } - - case value_t::discarded: - default: - break; - } - } - - /*! - @param[in] j JSON value to serialize - @param[in] use_count whether to use '#' prefixes (optimized format) - @param[in] use_type whether to use '$' prefixes (optimized format) - @param[in] add_prefix whether prefixes need to be used for this value - */ - void write_ubjson(const BasicJsonType& j, const bool use_count, - const bool use_type, const bool add_prefix = true) - { - switch (j.type()) - { - case value_t::null: - { - if (add_prefix) - { - oa->write_character(to_char_type('Z')); - } - break; - } - - case value_t::boolean: - { - if (add_prefix) - { - oa->write_character(j.m_value.boolean - ? to_char_type('T') - : to_char_type('F')); - } - break; - } - - case value_t::number_integer: - { - write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix); - break; - } - - case value_t::number_unsigned: - { - write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix); - break; - } - - case value_t::number_float: - { - write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix); - break; - } - - case value_t::string: - { - if (add_prefix) - { - oa->write_character(to_char_type('S')); - } - write_number_with_ubjson_prefix(j.m_value.string->size(), true); - oa->write_characters( - reinterpret_cast<const CharType*>(j.m_value.string->c_str()), - j.m_value.string->size()); - break; - } - - case value_t::array: - { - if (add_prefix) - { - oa->write_character(to_char_type('[')); - } - - bool prefix_required = true; - if (use_type && !j.m_value.array->empty()) - { - JSON_ASSERT(use_count); - const CharType first_prefix = ubjson_prefix(j.front()); - const bool same_prefix = std::all_of(j.begin() + 1, j.end(), - [this, first_prefix](const BasicJsonType & v) - { - return ubjson_prefix(v) == first_prefix; - }); - - if (same_prefix) - { - prefix_required = false; - oa->write_character(to_char_type('$')); - oa->write_character(first_prefix); - } - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.array->size(), true); - } - - for (const auto& el : *j.m_value.array) - { - write_ubjson(el, use_count, use_type, prefix_required); - } - - if (!use_count) - { - oa->write_character(to_char_type(']')); - } - - break; - } - - case value_t::binary: - { - if (add_prefix) - { - oa->write_character(to_char_type('[')); - } - - if (use_type && !j.m_value.binary->empty()) - { - JSON_ASSERT(use_count); - oa->write_character(to_char_type('$')); - oa->write_character('U'); - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.binary->size(), true); - } - - if (use_type) - { - oa->write_characters( - reinterpret_cast<const CharType*>(j.m_value.binary->data()), - j.m_value.binary->size()); - } - else - { - for (size_t i = 0; i < j.m_value.binary->size(); ++i) - { - oa->write_character(to_char_type('U')); - oa->write_character(j.m_value.binary->data()[i]); - } - } - - if (!use_count) - { - oa->write_character(to_char_type(']')); - } - - break; - } - - case value_t::object: - { - if (add_prefix) - { - oa->write_character(to_char_type('{')); - } - - bool prefix_required = true; - if (use_type && !j.m_value.object->empty()) - { - JSON_ASSERT(use_count); - const CharType first_prefix = ubjson_prefix(j.front()); - const bool same_prefix = std::all_of(j.begin(), j.end(), - [this, first_prefix](const BasicJsonType & v) - { - return ubjson_prefix(v) == first_prefix; - }); - - if (same_prefix) - { - prefix_required = false; - oa->write_character(to_char_type('$')); - oa->write_character(first_prefix); - } - } - - if (use_count) - { - oa->write_character(to_char_type('#')); - write_number_with_ubjson_prefix(j.m_value.object->size(), true); - } - - for (const auto& el : *j.m_value.object) - { - write_number_with_ubjson_prefix(el.first.size(), true); - oa->write_characters( - reinterpret_cast<const CharType*>(el.first.c_str()), - el.first.size()); - write_ubjson(el.second, use_count, use_type, prefix_required); - } - - if (!use_count) - { - oa->write_character(to_char_type('}')); - } - - break; - } - - case value_t::discarded: - default: - break; - } - } - - private: - ////////// - // BSON // - ////////// - - /*! - @return The size of a BSON document entry header, including the id marker - and the entry name size (and its null-terminator). - */ - static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j) - { - const auto it = name.find(static_cast<typename string_t::value_type>(0)); - if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos)) - { - JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j)); - static_cast<void>(j); - } - - return /*id*/ 1ul + name.size() + /*zero-terminator*/1u; - } - - /*! - @brief Writes the given @a element_type and @a name to the output adapter - */ - void write_bson_entry_header(const string_t& name, - const std::uint8_t element_type) - { - oa->write_character(to_char_type(element_type)); // boolean - oa->write_characters( - reinterpret_cast<const CharType*>(name.c_str()), - name.size() + 1u); - } - - /*! - @brief Writes a BSON element with key @a name and boolean value @a value - */ - void write_bson_boolean(const string_t& name, - const bool value) - { - write_bson_entry_header(name, 0x08); - oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00)); - } - - /*! - @brief Writes a BSON element with key @a name and double value @a value - */ - void write_bson_double(const string_t& name, - const double value) - { - write_bson_entry_header(name, 0x01); - write_number<double, true>(value); - } - - /*! - @return The size of the BSON-encoded string in @a value - */ - static std::size_t calc_bson_string_size(const string_t& value) - { - return sizeof(std::int32_t) + value.size() + 1ul; - } - - /*! - @brief Writes a BSON element with key @a name and string value @a value - */ - void write_bson_string(const string_t& name, - const string_t& value) - { - write_bson_entry_header(name, 0x02); - - write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul)); - oa->write_characters( - reinterpret_cast<const CharType*>(value.c_str()), - value.size() + 1); - } - - /*! - @brief Writes a BSON element with key @a name and null value - */ - void write_bson_null(const string_t& name) - { - write_bson_entry_header(name, 0x0A); - } - - /*! - @return The size of the BSON-encoded integer @a value - */ - static std::size_t calc_bson_integer_size(const std::int64_t value) - { - return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)() - ? sizeof(std::int32_t) - : sizeof(std::int64_t); - } - - /*! - @brief Writes a BSON element with key @a name and integer @a value - */ - void write_bson_integer(const string_t& name, - const std::int64_t value) - { - if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()) - { - write_bson_entry_header(name, 0x10); // int32 - write_number<std::int32_t, true>(static_cast<std::int32_t>(value)); - } - else - { - write_bson_entry_header(name, 0x12); // int64 - write_number<std::int64_t, true>(static_cast<std::int64_t>(value)); - } - } - - /*! - @return The size of the BSON-encoded unsigned integer in @a j - */ - static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept - { - return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) - ? sizeof(std::int32_t) - : sizeof(std::int64_t); - } - - /*! - @brief Writes a BSON element with key @a name and unsigned @a value - */ - void write_bson_unsigned(const string_t& name, - const BasicJsonType& j) - { - if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) - { - write_bson_entry_header(name, 0x10 /* int32 */); - write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned)); - } - else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) - { - write_bson_entry_header(name, 0x12 /* int64 */); - write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned)); - } - else - { - JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j)); - } - } - - /*! - @brief Writes a BSON element with key @a name and object @a value - */ - void write_bson_object_entry(const string_t& name, - const typename BasicJsonType::object_t& value) - { - write_bson_entry_header(name, 0x03); // object - write_bson_object(value); - } - - /*! - @return The size of the BSON-encoded array @a value - */ - static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value) - { - std::size_t array_index = 0ul; - - const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) - { - return result + calc_bson_element_size(std::to_string(array_index++), el); - }); - - return sizeof(std::int32_t) + embedded_document_size + 1ul; - } - - /*! - @return The size of the BSON-encoded binary array @a value - */ - static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value) - { - return sizeof(std::int32_t) + value.size() + 1ul; - } - - /*! - @brief Writes a BSON element with key @a name and array @a value - */ - void write_bson_array(const string_t& name, - const typename BasicJsonType::array_t& value) - { - write_bson_entry_header(name, 0x04); // array - write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value))); - - std::size_t array_index = 0ul; - - for (const auto& el : value) - { - write_bson_element(std::to_string(array_index++), el); - } - - oa->write_character(to_char_type(0x00)); - } - - /*! - @brief Writes a BSON element with key @a name and binary value @a value - */ - void write_bson_binary(const string_t& name, - const binary_t& value) - { - write_bson_entry_header(name, 0x05); - - write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size())); - write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00)); - - oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size()); - } - - /*! - @brief Calculates the size necessary to serialize the JSON value @a j with its @a name - @return The calculated size for the BSON document entry for @a j with the given @a name. - */ - static std::size_t calc_bson_element_size(const string_t& name, - const BasicJsonType& j) - { - const auto header_size = calc_bson_entry_header_size(name, j); - switch (j.type()) - { - case value_t::object: - return header_size + calc_bson_object_size(*j.m_value.object); - - case value_t::array: - return header_size + calc_bson_array_size(*j.m_value.array); - - case value_t::binary: - return header_size + calc_bson_binary_size(*j.m_value.binary); - - case value_t::boolean: - return header_size + 1ul; - - case value_t::number_float: - return header_size + 8ul; - - case value_t::number_integer: - return header_size + calc_bson_integer_size(j.m_value.number_integer); - - case value_t::number_unsigned: - return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned); - - case value_t::string: - return header_size + calc_bson_string_size(*j.m_value.string); - - case value_t::null: - return header_size + 0ul; - - // LCOV_EXCL_START - case value_t::discarded: - default: - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) - return 0ul; - // LCOV_EXCL_STOP - } - } - - /*! - @brief Serializes the JSON value @a j to BSON and associates it with the - key @a name. - @param name The name to associate with the JSON entity @a j within the - current BSON document - */ - void write_bson_element(const string_t& name, - const BasicJsonType& j) - { - switch (j.type()) - { - case value_t::object: - return write_bson_object_entry(name, *j.m_value.object); - - case value_t::array: - return write_bson_array(name, *j.m_value.array); - - case value_t::binary: - return write_bson_binary(name, *j.m_value.binary); - - case value_t::boolean: - return write_bson_boolean(name, j.m_value.boolean); - - case value_t::number_float: - return write_bson_double(name, j.m_value.number_float); - - case value_t::number_integer: - return write_bson_integer(name, j.m_value.number_integer); - - case value_t::number_unsigned: - return write_bson_unsigned(name, j); - - case value_t::string: - return write_bson_string(name, *j.m_value.string); - - case value_t::null: - return write_bson_null(name); - - // LCOV_EXCL_START - case value_t::discarded: - default: - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) - return; - // LCOV_EXCL_STOP - } - } - - /*! - @brief Calculates the size of the BSON serialization of the given - JSON-object @a j. - @param[in] value JSON value to serialize - @pre value.type() == value_t::object - */ - static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value) - { - std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0), - [](size_t result, const typename BasicJsonType::object_t::value_type & el) - { - return result += calc_bson_element_size(el.first, el.second); - }); - - return sizeof(std::int32_t) + document_size + 1ul; - } - - /*! - @param[in] value JSON value to serialize - @pre value.type() == value_t::object - */ - void write_bson_object(const typename BasicJsonType::object_t& value) - { - write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value))); - - for (const auto& el : value) - { - write_bson_element(el.first, el.second); - } - - oa->write_character(to_char_type(0x00)); - } - - ////////// - // CBOR // - ////////// - - static constexpr CharType get_cbor_float_prefix(float /*unused*/) - { - return to_char_type(0xFA); // Single-Precision Float - } - - static constexpr CharType get_cbor_float_prefix(double /*unused*/) - { - return to_char_type(0xFB); // Double-Precision Float - } - - ///////////// - // MsgPack // - ///////////// - - static constexpr CharType get_msgpack_float_prefix(float /*unused*/) - { - return to_char_type(0xCA); // float 32 - } - - static constexpr CharType get_msgpack_float_prefix(double /*unused*/) - { - return to_char_type(0xCB); // float 64 - } - - //////////// - // UBJSON // - //////////// - - // UBJSON: write number (floating point) - template<typename NumberType, typename std::enable_if< - std::is_floating_point<NumberType>::value, int>::type = 0> - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if (add_prefix) - { - oa->write_character(get_ubjson_float_prefix(n)); - } - write_number(n); - } - - // UBJSON: write number (unsigned integer) - template<typename NumberType, typename std::enable_if< - std::is_unsigned<NumberType>::value, int>::type = 0> - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('i')); // int8 - } - write_number(static_cast<std::uint8_t>(n)); - } - else if (n <= (std::numeric_limits<std::uint8_t>::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('U')); // uint8 - } - write_number(static_cast<std::uint8_t>(n)); - } - else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('I')); // int16 - } - write_number(static_cast<std::int16_t>(n)); - } - else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('l')); // int32 - } - write_number(static_cast<std::int32_t>(n)); - } - else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('L')); // int64 - } - write_number(static_cast<std::int64_t>(n)); - } - else - { - if (add_prefix) - { - oa->write_character(to_char_type('H')); // high-precision number - } - - const auto number = BasicJsonType(n).dump(); - write_number_with_ubjson_prefix(number.size(), true); - for (std::size_t i = 0; i < number.size(); ++i) - { - oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i]))); - } - } - } - - // UBJSON: write number (signed integer) - template < typename NumberType, typename std::enable_if < - std::is_signed<NumberType>::value&& - !std::is_floating_point<NumberType>::value, int >::type = 0 > - void write_number_with_ubjson_prefix(const NumberType n, - const bool add_prefix) - { - if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('i')); // int8 - } - write_number(static_cast<std::int8_t>(n)); - } - else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)())) - { - if (add_prefix) - { - oa->write_character(to_char_type('U')); // uint8 - } - write_number(static_cast<std::uint8_t>(n)); - } - else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('I')); // int16 - } - write_number(static_cast<std::int16_t>(n)); - } - else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('l')); // int32 - } - write_number(static_cast<std::int32_t>(n)); - } - else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)()) - { - if (add_prefix) - { - oa->write_character(to_char_type('L')); // int64 - } - write_number(static_cast<std::int64_t>(n)); - } - // LCOV_EXCL_START - else - { - if (add_prefix) - { - oa->write_character(to_char_type('H')); // high-precision number - } - - const auto number = BasicJsonType(n).dump(); - write_number_with_ubjson_prefix(number.size(), true); - for (std::size_t i = 0; i < number.size(); ++i) - { - oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i]))); - } - } - // LCOV_EXCL_STOP - } - - /*! - @brief determine the type prefix of container values - */ - CharType ubjson_prefix(const BasicJsonType& j) const noexcept - { - switch (j.type()) - { - case value_t::null: - return 'Z'; - - case value_t::boolean: - return j.m_value.boolean ? 'T' : 'F'; - - case value_t::number_integer: - { - if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)()) - { - return 'i'; - } - if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)()) - { - return 'U'; - } - if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)()) - { - return 'I'; - } - if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)()) - { - return 'l'; - } - if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)()) - { - return 'L'; - } - // anything else is treated as high-precision number - return 'H'; // LCOV_EXCL_LINE - } - - case value_t::number_unsigned: - { - if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)())) - { - return 'i'; - } - if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)())) - { - return 'U'; - } - if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)())) - { - return 'I'; - } - if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)())) - { - return 'l'; - } - if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)())) - { - return 'L'; - } - // anything else is treated as high-precision number - return 'H'; // LCOV_EXCL_LINE - } - - case value_t::number_float: - return get_ubjson_float_prefix(j.m_value.number_float); - - case value_t::string: - return 'S'; - - case value_t::array: // fallthrough - case value_t::binary: - return '['; - - case value_t::object: - return '{'; - - case value_t::discarded: - default: // discarded values - return 'N'; - } - } - - static constexpr CharType get_ubjson_float_prefix(float /*unused*/) - { - return 'd'; // float 32 - } - - static constexpr CharType get_ubjson_float_prefix(double /*unused*/) - { - return 'D'; // float 64 - } - - /////////////////////// - // Utility functions // - /////////////////////// - - /* - @brief write a number to output input - @param[in] n number of type @a NumberType - @tparam NumberType the type of the number - @tparam OutputIsLittleEndian Set to true if output data is - required to be little endian - - @note This function needs to respect the system's endianess, because bytes - in CBOR, MessagePack, and UBJSON are stored in network order (big - endian) and therefore need reordering on little endian systems. - */ - template<typename NumberType, bool OutputIsLittleEndian = false> - void write_number(const NumberType n) - { - // step 1: write number to array of length NumberType - std::array<CharType, sizeof(NumberType)> vec{}; - std::memcpy(vec.data(), &n, sizeof(NumberType)); - - // step 2: write array to output (with possible reordering) - if (is_little_endian != OutputIsLittleEndian) - { - // reverse byte order prior to conversion if necessary - std::reverse(vec.begin(), vec.end()); - } - - oa->write_characters(vec.data(), sizeof(NumberType)); - } - - void write_compact_float(const number_float_t n, detail::input_format_t format) - { -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) && - static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) && - static_cast<double>(static_cast<float>(n)) == static_cast<double>(n)) - { - oa->write_character(format == detail::input_format_t::cbor - ? get_cbor_float_prefix(static_cast<float>(n)) - : get_msgpack_float_prefix(static_cast<float>(n))); - write_number(static_cast<float>(n)); - } - else - { - oa->write_character(format == detail::input_format_t::cbor - ? get_cbor_float_prefix(n) - : get_msgpack_float_prefix(n)); - write_number(n); - } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - } - - public: - // The following to_char_type functions are implement the conversion - // between uint8_t and CharType. In case CharType is not unsigned, - // such a conversion is required to allow values greater than 128. - // See <https://github.com/nlohmann/json/issues/1286> for a discussion. - template < typename C = CharType, - enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr > - static constexpr CharType to_char_type(std::uint8_t x) noexcept - { - return *reinterpret_cast<char*>(&x); - } - - template < typename C = CharType, - enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr > - static CharType to_char_type(std::uint8_t x) noexcept - { - static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); - static_assert(std::is_trivial<CharType>::value, "CharType must be trivial"); - CharType result; - std::memcpy(&result, &x, sizeof(x)); - return result; - } - - template<typename C = CharType, - enable_if_t<std::is_unsigned<C>::value>* = nullptr> - static constexpr CharType to_char_type(std::uint8_t x) noexcept - { - return x; - } - - template < typename InputCharType, typename C = CharType, - enable_if_t < - std::is_signed<C>::value && - std::is_signed<char>::value && - std::is_same<char, typename std::remove_cv<InputCharType>::type>::value - > * = nullptr > - static constexpr CharType to_char_type(InputCharType x) noexcept - { - return x; - } - - private: - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); - - /// the output - output_adapter_t<CharType> oa = nullptr; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/output/output_adapters.hpp> - -// #include <nlohmann/detail/output/serializer.hpp> - - -#include <algorithm> // reverse, remove, fill, find, none_of -#include <array> // array -#include <clocale> // localeconv, lconv -#include <cmath> // labs, isfinite, isnan, signbit -#include <cstddef> // size_t, ptrdiff_t -#include <cstdint> // uint8_t -#include <cstdio> // snprintf -#include <limits> // numeric_limits -#include <string> // string, char_traits -#include <type_traits> // is_same -#include <utility> // move - -// #include <nlohmann/detail/conversions/to_chars.hpp> - - -#include <array> // array -#include <cmath> // signbit, isfinite -#include <cstdint> // intN_t, uintN_t -#include <cstring> // memcpy, memmove -#include <limits> // numeric_limits -#include <type_traits> // conditional - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ -namespace detail -{ - -/*! -@brief implements the Grisu2 algorithm for binary to decimal floating-point -conversion. - -This implementation is a slightly modified version of the reference -implementation which may be obtained from -http://florian.loitsch.com/publications (bench.tar.gz). - -The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch. - -For a detailed description of the algorithm see: - -[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with - Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming - Language Design and Implementation, PLDI 2010 -[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", - Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language - Design and Implementation, PLDI 1996 -*/ -namespace dtoa_impl -{ - -template<typename Target, typename Source> -Target reinterpret_bits(const Source source) -{ - static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); - - Target target; - std::memcpy(&target, &source, sizeof(Source)); - return target; -} - -struct diyfp // f * 2^e -{ - static constexpr int kPrecision = 64; // = q - - std::uint64_t f = 0; - int e = 0; - - constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} - - /*! - @brief returns x - y - @pre x.e == y.e and x.f >= y.f - */ - static diyfp sub(const diyfp& x, const diyfp& y) noexcept - { - JSON_ASSERT(x.e == y.e); - JSON_ASSERT(x.f >= y.f); - - return {x.f - y.f, x.e}; - } - - /*! - @brief returns x * y - @note The result is rounded. (Only the upper q bits are returned.) - */ - static diyfp mul(const diyfp& x, const diyfp& y) noexcept - { - static_assert(kPrecision == 64, "internal error"); - - // Computes: - // f = round((x.f * y.f) / 2^q) - // e = x.e + y.e + q - - // Emulate the 64-bit * 64-bit multiplication: - // - // p = u * v - // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) - // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi ) - // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 ) - // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) - // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3) - // = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) - // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) - // - // (Since Q might be larger than 2^32 - 1) - // - // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) - // - // (Q_hi + H does not overflow a 64-bit int) - // - // = p_lo + 2^64 p_hi - - const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; - const std::uint64_t u_hi = x.f >> 32u; - const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; - const std::uint64_t v_hi = y.f >> 32u; - - const std::uint64_t p0 = u_lo * v_lo; - const std::uint64_t p1 = u_lo * v_hi; - const std::uint64_t p2 = u_hi * v_lo; - const std::uint64_t p3 = u_hi * v_hi; - - const std::uint64_t p0_hi = p0 >> 32u; - const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; - const std::uint64_t p1_hi = p1 >> 32u; - const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; - const std::uint64_t p2_hi = p2 >> 32u; - - std::uint64_t Q = p0_hi + p1_lo + p2_lo; - - // The full product might now be computed as - // - // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) - // p_lo = p0_lo + (Q << 32) - // - // But in this particular case here, the full p_lo is not required. - // Effectively we only need to add the highest bit in p_lo to p_hi (and - // Q_hi + 1 does not overflow). - - Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up - - const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); - - return {h, x.e + y.e + 64}; - } - - /*! - @brief normalize x such that the significand is >= 2^(q-1) - @pre x.f != 0 - */ - static diyfp normalize(diyfp x) noexcept - { - JSON_ASSERT(x.f != 0); - - while ((x.f >> 63u) == 0) - { - x.f <<= 1u; - x.e--; - } - - return x; - } - - /*! - @brief normalize x such that the result has the exponent E - @pre e >= x.e and the upper e - x.e bits of x.f must be zero. - */ - static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept - { - const int delta = x.e - target_exponent; - - JSON_ASSERT(delta >= 0); - JSON_ASSERT(((x.f << delta) >> delta) == x.f); - - return {x.f << delta, target_exponent}; - } -}; - -struct boundaries -{ - diyfp w; - diyfp minus; - diyfp plus; -}; - -/*! -Compute the (normalized) diyfp representing the input number 'value' and its -boundaries. - -@pre value must be finite and positive -*/ -template<typename FloatType> -boundaries compute_boundaries(FloatType value) -{ - JSON_ASSERT(std::isfinite(value)); - JSON_ASSERT(value > 0); - - // Convert the IEEE representation into a diyfp. - // - // If v is denormal: - // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) - // If v is normalized: - // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) - - static_assert(std::numeric_limits<FloatType>::is_iec559, - "internal error: dtoa_short requires an IEEE-754 floating-point implementation"); - - constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit) - constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1); - constexpr int kMinExp = 1 - kBias; - constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1) - - using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type; - - const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value)); - const std::uint64_t E = bits >> (kPrecision - 1); - const std::uint64_t F = bits & (kHiddenBit - 1); - - const bool is_denormal = E == 0; - const diyfp v = is_denormal - ? diyfp(F, kMinExp) - : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias); - - // Compute the boundaries m- and m+ of the floating-point value - // v = f * 2^e. - // - // Determine v- and v+, the floating-point predecessor and successor if v, - // respectively. - // - // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) - // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) - // - // v+ = v + 2^e - // - // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ - // between m- and m+ round to v, regardless of how the input rounding - // algorithm breaks ties. - // - // ---+-------------+-------------+-------------+-------------+--- (A) - // v- m- v m+ v+ - // - // -----------------+------+------+-------------+-------------+--- (B) - // v- m- v m+ v+ - - const bool lower_boundary_is_closer = F == 0 && E > 1; - const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); - const diyfp m_minus = lower_boundary_is_closer - ? diyfp(4 * v.f - 1, v.e - 2) // (B) - : diyfp(2 * v.f - 1, v.e - 1); // (A) - - // Determine the normalized w+ = m+. - const diyfp w_plus = diyfp::normalize(m_plus); - - // Determine w- = m- such that e_(w-) = e_(w+). - const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); - - return {diyfp::normalize(v), w_minus, w_plus}; -} - -// Given normalized diyfp w, Grisu needs to find a (normalized) cached -// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies -// within a certain range [alpha, gamma] (Definition 3.2 from [1]) -// -// alpha <= e = e_c + e_w + q <= gamma -// -// or -// -// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q -// <= f_c * f_w * 2^gamma -// -// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies -// -// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma -// -// or -// -// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) -// -// The choice of (alpha,gamma) determines the size of the table and the form of -// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well -// in practice: -// -// The idea is to cut the number c * w = f * 2^e into two parts, which can be -// processed independently: An integral part p1, and a fractional part p2: -// -// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e -// = (f div 2^-e) + (f mod 2^-e) * 2^e -// = p1 + p2 * 2^e -// -// The conversion of p1 into decimal form requires a series of divisions and -// modulos by (a power of) 10. These operations are faster for 32-bit than for -// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be -// achieved by choosing -// -// -e >= 32 or e <= -32 := gamma -// -// In order to convert the fractional part -// -// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... -// -// into decimal form, the fraction is repeatedly multiplied by 10 and the digits -// d[-i] are extracted in order: -// -// (10 * p2) div 2^-e = d[-1] -// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... -// -// The multiplication by 10 must not overflow. It is sufficient to choose -// -// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. -// -// Since p2 = f mod 2^-e < 2^-e, -// -// -e <= 60 or e >= -60 := alpha - -constexpr int kAlpha = -60; -constexpr int kGamma = -32; - -struct cached_power // c = f * 2^e ~= 10^k -{ - std::uint64_t f; - int e; - int k; -}; - -/*! -For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached -power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c -satisfies (Definition 3.2 from [1]) - - alpha <= e_c + e + q <= gamma. -*/ -inline cached_power get_cached_power_for_binary_exponent(int e) -{ - // Now - // - // alpha <= e_c + e + q <= gamma (1) - // ==> f_c * 2^alpha <= c * 2^e * 2^q - // - // and since the c's are normalized, 2^(q-1) <= f_c, - // - // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) - // ==> 2^(alpha - e - 1) <= c - // - // If c were an exact power of ten, i.e. c = 10^k, one may determine k as - // - // k = ceil( log_10( 2^(alpha - e - 1) ) ) - // = ceil( (alpha - e - 1) * log_10(2) ) - // - // From the paper: - // "In theory the result of the procedure could be wrong since c is rounded, - // and the computation itself is approximated [...]. In practice, however, - // this simple function is sufficient." - // - // For IEEE double precision floating-point numbers converted into - // normalized diyfp's w = f * 2^e, with q = 64, - // - // e >= -1022 (min IEEE exponent) - // -52 (p - 1) - // -52 (p - 1, possibly normalize denormal IEEE numbers) - // -11 (normalize the diyfp) - // = -1137 - // - // and - // - // e <= +1023 (max IEEE exponent) - // -52 (p - 1) - // -11 (normalize the diyfp) - // = 960 - // - // This binary exponent range [-1137,960] results in a decimal exponent - // range [-307,324]. One does not need to store a cached power for each - // k in this range. For each such k it suffices to find a cached power - // such that the exponent of the product lies in [alpha,gamma]. - // This implies that the difference of the decimal exponents of adjacent - // table entries must be less than or equal to - // - // floor( (gamma - alpha) * log_10(2) ) = 8. - // - // (A smaller distance gamma-alpha would require a larger table.) - - // NB: - // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. - - constexpr int kCachedPowersMinDecExp = -300; - constexpr int kCachedPowersDecStep = 8; - - static constexpr std::array<cached_power, 79> kCachedPowers = - { - { - { 0xAB70FE17C79AC6CA, -1060, -300 }, - { 0xFF77B1FCBEBCDC4F, -1034, -292 }, - { 0xBE5691EF416BD60C, -1007, -284 }, - { 0x8DD01FAD907FFC3C, -980, -276 }, - { 0xD3515C2831559A83, -954, -268 }, - { 0x9D71AC8FADA6C9B5, -927, -260 }, - { 0xEA9C227723EE8BCB, -901, -252 }, - { 0xAECC49914078536D, -874, -244 }, - { 0x823C12795DB6CE57, -847, -236 }, - { 0xC21094364DFB5637, -821, -228 }, - { 0x9096EA6F3848984F, -794, -220 }, - { 0xD77485CB25823AC7, -768, -212 }, - { 0xA086CFCD97BF97F4, -741, -204 }, - { 0xEF340A98172AACE5, -715, -196 }, - { 0xB23867FB2A35B28E, -688, -188 }, - { 0x84C8D4DFD2C63F3B, -661, -180 }, - { 0xC5DD44271AD3CDBA, -635, -172 }, - { 0x936B9FCEBB25C996, -608, -164 }, - { 0xDBAC6C247D62A584, -582, -156 }, - { 0xA3AB66580D5FDAF6, -555, -148 }, - { 0xF3E2F893DEC3F126, -529, -140 }, - { 0xB5B5ADA8AAFF80B8, -502, -132 }, - { 0x87625F056C7C4A8B, -475, -124 }, - { 0xC9BCFF6034C13053, -449, -116 }, - { 0x964E858C91BA2655, -422, -108 }, - { 0xDFF9772470297EBD, -396, -100 }, - { 0xA6DFBD9FB8E5B88F, -369, -92 }, - { 0xF8A95FCF88747D94, -343, -84 }, - { 0xB94470938FA89BCF, -316, -76 }, - { 0x8A08F0F8BF0F156B, -289, -68 }, - { 0xCDB02555653131B6, -263, -60 }, - { 0x993FE2C6D07B7FAC, -236, -52 }, - { 0xE45C10C42A2B3B06, -210, -44 }, - { 0xAA242499697392D3, -183, -36 }, - { 0xFD87B5F28300CA0E, -157, -28 }, - { 0xBCE5086492111AEB, -130, -20 }, - { 0x8CBCCC096F5088CC, -103, -12 }, - { 0xD1B71758E219652C, -77, -4 }, - { 0x9C40000000000000, -50, 4 }, - { 0xE8D4A51000000000, -24, 12 }, - { 0xAD78EBC5AC620000, 3, 20 }, - { 0x813F3978F8940984, 30, 28 }, - { 0xC097CE7BC90715B3, 56, 36 }, - { 0x8F7E32CE7BEA5C70, 83, 44 }, - { 0xD5D238A4ABE98068, 109, 52 }, - { 0x9F4F2726179A2245, 136, 60 }, - { 0xED63A231D4C4FB27, 162, 68 }, - { 0xB0DE65388CC8ADA8, 189, 76 }, - { 0x83C7088E1AAB65DB, 216, 84 }, - { 0xC45D1DF942711D9A, 242, 92 }, - { 0x924D692CA61BE758, 269, 100 }, - { 0xDA01EE641A708DEA, 295, 108 }, - { 0xA26DA3999AEF774A, 322, 116 }, - { 0xF209787BB47D6B85, 348, 124 }, - { 0xB454E4A179DD1877, 375, 132 }, - { 0x865B86925B9BC5C2, 402, 140 }, - { 0xC83553C5C8965D3D, 428, 148 }, - { 0x952AB45CFA97A0B3, 455, 156 }, - { 0xDE469FBD99A05FE3, 481, 164 }, - { 0xA59BC234DB398C25, 508, 172 }, - { 0xF6C69A72A3989F5C, 534, 180 }, - { 0xB7DCBF5354E9BECE, 561, 188 }, - { 0x88FCF317F22241E2, 588, 196 }, - { 0xCC20CE9BD35C78A5, 614, 204 }, - { 0x98165AF37B2153DF, 641, 212 }, - { 0xE2A0B5DC971F303A, 667, 220 }, - { 0xA8D9D1535CE3B396, 694, 228 }, - { 0xFB9B7CD9A4A7443C, 720, 236 }, - { 0xBB764C4CA7A44410, 747, 244 }, - { 0x8BAB8EEFB6409C1A, 774, 252 }, - { 0xD01FEF10A657842C, 800, 260 }, - { 0x9B10A4E5E9913129, 827, 268 }, - { 0xE7109BFBA19C0C9D, 853, 276 }, - { 0xAC2820D9623BF429, 880, 284 }, - { 0x80444B5E7AA7CF85, 907, 292 }, - { 0xBF21E44003ACDD2D, 933, 300 }, - { 0x8E679C2F5E44FF8F, 960, 308 }, - { 0xD433179D9C8CB841, 986, 316 }, - { 0x9E19DB92B4E31BA9, 1013, 324 }, - } - }; - - // This computation gives exactly the same results for k as - // k = ceil((kAlpha - e - 1) * 0.30102999566398114) - // for |e| <= 1500, but doesn't require floating-point operations. - // NB: log_10(2) ~= 78913 / 2^18 - JSON_ASSERT(e >= -1500); - JSON_ASSERT(e <= 1500); - const int f = kAlpha - e - 1; - const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0); - - const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; - JSON_ASSERT(index >= 0); - JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size()); - - const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)]; - JSON_ASSERT(kAlpha <= cached.e + e + 64); - JSON_ASSERT(kGamma >= cached.e + e + 64); - - return cached; -} - -/*! -For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. -For n == 0, returns 1 and sets pow10 := 1. -*/ -inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10) -{ - // LCOV_EXCL_START - if (n >= 1000000000) - { - pow10 = 1000000000; - return 10; - } - // LCOV_EXCL_STOP - if (n >= 100000000) - { - pow10 = 100000000; - return 9; - } - if (n >= 10000000) - { - pow10 = 10000000; - return 8; - } - if (n >= 1000000) - { - pow10 = 1000000; - return 7; - } - if (n >= 100000) - { - pow10 = 100000; - return 6; - } - if (n >= 10000) - { - pow10 = 10000; - return 5; - } - if (n >= 1000) - { - pow10 = 1000; - return 4; - } - if (n >= 100) - { - pow10 = 100; - return 3; - } - if (n >= 10) - { - pow10 = 10; - return 2; - } - - pow10 = 1; - return 1; -} - -inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, - std::uint64_t rest, std::uint64_t ten_k) -{ - JSON_ASSERT(len >= 1); - JSON_ASSERT(dist <= delta); - JSON_ASSERT(rest <= delta); - JSON_ASSERT(ten_k > 0); - - // <--------------------------- delta ----> - // <---- dist ---------> - // --------------[------------------+-------------------]-------------- - // M- w M+ - // - // ten_k - // <------> - // <---- rest ----> - // --------------[------------------+----+--------------]-------------- - // w V - // = buf * 10^k - // - // ten_k represents a unit-in-the-last-place in the decimal representation - // stored in buf. - // Decrement buf by ten_k while this takes buf closer to w. - - // The tests are written in this order to avoid overflow in unsigned - // integer arithmetic. - - while (rest < dist - && delta - rest >= ten_k - && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) - { - JSON_ASSERT(buf[len - 1] != '0'); - buf[len - 1]--; - rest += ten_k; - } -} - -/*! -Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. -M- and M+ must be normalized and share the same exponent -60 <= e <= -32. -*/ -inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, - diyfp M_minus, diyfp w, diyfp M_plus) -{ - static_assert(kAlpha >= -60, "internal error"); - static_assert(kGamma <= -32, "internal error"); - - // Generates the digits (and the exponent) of a decimal floating-point - // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's - // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma. - // - // <--------------------------- delta ----> - // <---- dist ---------> - // --------------[------------------+-------------------]-------------- - // M- w M+ - // - // Grisu2 generates the digits of M+ from left to right and stops as soon as - // V is in [M-,M+]. - - JSON_ASSERT(M_plus.e >= kAlpha); - JSON_ASSERT(M_plus.e <= kGamma); - - std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e) - std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e) - - // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): - // - // M+ = f * 2^e - // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e - // = ((p1 ) * 2^-e + (p2 )) * 2^e - // = p1 + p2 * 2^e - - const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); - - auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) - std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e - - // 1) - // - // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] - - JSON_ASSERT(p1 > 0); - - std::uint32_t pow10{}; - const int k = find_largest_pow10(p1, pow10); - - // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) - // - // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) - // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) - // - // M+ = p1 + p2 * 2^e - // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e - // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e - // = d[k-1] * 10^(k-1) + ( rest) * 2^e - // - // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) - // - // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] - // - // but stop as soon as - // - // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e - - int n = k; - while (n > 0) - { - // Invariants: - // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) - // pow10 = 10^(n-1) <= p1 < 10^n - // - const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) - const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) - // - // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e - // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) - // - JSON_ASSERT(d <= 9); - buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d - // - // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) - // - p1 = r; - n--; - // - // M+ = buffer * 10^n + (p1 + p2 * 2^e) - // pow10 = 10^n - // - - // Now check if enough digits have been generated. - // Compute - // - // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e - // - // Note: - // Since rest and delta share the same exponent e, it suffices to - // compare the significands. - const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; - if (rest <= delta) - { - // V = buffer * 10^n, with M- <= V <= M+. - - decimal_exponent += n; - - // We may now just stop. But instead look if the buffer could be - // decremented to bring V closer to w. - // - // pow10 = 10^n is now 1 ulp in the decimal representation V. - // The rounding procedure works with diyfp's with an implicit - // exponent of e. - // - // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e - // - const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; - grisu2_round(buffer, length, dist, delta, rest, ten_n); - - return; - } - - pow10 /= 10; - // - // pow10 = 10^(n-1) <= p1 < 10^n - // Invariants restored. - } - - // 2) - // - // The digits of the integral part have been generated: - // - // M+ = d[k-1]...d[1]d[0] + p2 * 2^e - // = buffer + p2 * 2^e - // - // Now generate the digits of the fractional part p2 * 2^e. - // - // Note: - // No decimal point is generated: the exponent is adjusted instead. - // - // p2 actually represents the fraction - // - // p2 * 2^e - // = p2 / 2^-e - // = d[-1] / 10^1 + d[-2] / 10^2 + ... - // - // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) - // - // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m - // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) - // - // using - // - // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) - // = ( d) * 2^-e + ( r) - // - // or - // 10^m * p2 * 2^e = d + r * 2^e - // - // i.e. - // - // M+ = buffer + p2 * 2^e - // = buffer + 10^-m * (d + r * 2^e) - // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e - // - // and stop as soon as 10^-m * r * 2^e <= delta * 2^e - - JSON_ASSERT(p2 > delta); - - int m = 0; - for (;;) - { - // Invariant: - // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e - // = buffer * 10^-m + 10^-m * (p2 ) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e - // - JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10); - p2 *= 10; - const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e - const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e - // - // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e - // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) - // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e - // - JSON_ASSERT(d <= 9); - buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d - // - // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e - // - p2 = r; - m++; - // - // M+ = buffer * 10^-m + 10^-m * p2 * 2^e - // Invariant restored. - - // Check if enough digits have been generated. - // - // 10^-m * p2 * 2^e <= delta * 2^e - // p2 * 2^e <= 10^m * delta * 2^e - // p2 <= 10^m * delta - delta *= 10; - dist *= 10; - if (p2 <= delta) - { - break; - } - } - - // V = buffer * 10^-m, with M- <= V <= M+. - - decimal_exponent -= m; - - // 1 ulp in the decimal representation is now 10^-m. - // Since delta and dist are now scaled by 10^m, we need to do the - // same with ulp in order to keep the units in sync. - // - // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e - // - const std::uint64_t ten_m = one.f; - grisu2_round(buffer, length, dist, delta, p2, ten_m); - - // By construction this algorithm generates the shortest possible decimal - // number (Loitsch, Theorem 6.2) which rounds back to w. - // For an input number of precision p, at least - // - // N = 1 + ceil(p * log_10(2)) - // - // decimal digits are sufficient to identify all binary floating-point - // numbers (Matula, "In-and-Out conversions"). - // This implies that the algorithm does not produce more than N decimal - // digits. - // - // N = 17 for p = 53 (IEEE double precision) - // N = 9 for p = 24 (IEEE single precision) -} - -/*! -v = buf * 10^decimal_exponent -len is the length of the buffer (number of decimal digits) -The buffer must be large enough, i.e. >= max_digits10. -*/ -JSON_HEDLEY_NON_NULL(1) -inline void grisu2(char* buf, int& len, int& decimal_exponent, - diyfp m_minus, diyfp v, diyfp m_plus) -{ - JSON_ASSERT(m_plus.e == m_minus.e); - JSON_ASSERT(m_plus.e == v.e); - - // --------(-----------------------+-----------------------)-------- (A) - // m- v m+ - // - // --------------------(-----------+-----------------------)-------- (B) - // m- v m+ - // - // First scale v (and m- and m+) such that the exponent is in the range - // [alpha, gamma]. - - const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); - - const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k - - // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] - const diyfp w = diyfp::mul(v, c_minus_k); - const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); - const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); - - // ----(---+---)---------------(---+---)---------------(---+---)---- - // w- w w+ - // = c*m- = c*v = c*m+ - // - // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and - // w+ are now off by a small amount. - // In fact: - // - // w - v * 10^k < 1 ulp - // - // To account for this inaccuracy, add resp. subtract 1 ulp. - // - // --------+---[---------------(---+---)---------------]---+-------- - // w- M- w M+ w+ - // - // Now any number in [M-, M+] (bounds included) will round to w when input, - // regardless of how the input rounding algorithm breaks ties. - // - // And digit_gen generates the shortest possible such number in [M-, M+]. - // Note that this does not mean that Grisu2 always generates the shortest - // possible number in the interval (m-, m+). - const diyfp M_minus(w_minus.f + 1, w_minus.e); - const diyfp M_plus (w_plus.f - 1, w_plus.e ); - - decimal_exponent = -cached.k; // = -(-k) = k - - grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); -} - -/*! -v = buf * 10^decimal_exponent -len is the length of the buffer (number of decimal digits) -The buffer must be large enough, i.e. >= max_digits10. -*/ -template<typename FloatType> -JSON_HEDLEY_NON_NULL(1) -void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) -{ - static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3, - "internal error: not enough precision"); - - JSON_ASSERT(std::isfinite(value)); - JSON_ASSERT(value > 0); - - // If the neighbors (and boundaries) of 'value' are always computed for double-precision - // numbers, all float's can be recovered using strtod (and strtof). However, the resulting - // decimal representations are not exactly "short". - // - // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) - // says "value is converted to a string as if by std::sprintf in the default ("C") locale" - // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars' - // does. - // On the other hand, the documentation for 'std::to_chars' requires that "parsing the - // representation using the corresponding std::from_chars function recovers value exactly". That - // indicates that single precision floating-point numbers should be recovered using - // 'std::strtof'. - // - // NB: If the neighbors are computed for single-precision numbers, there is a single float - // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision - // value is off by 1 ulp. -#if 0 - const boundaries w = compute_boundaries(static_cast<double>(value)); -#else - const boundaries w = compute_boundaries(value); -#endif - - grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); -} - -/*! -@brief appends a decimal representation of e to buf -@return a pointer to the element following the exponent. -@pre -1000 < e < 1000 -*/ -JSON_HEDLEY_NON_NULL(1) -JSON_HEDLEY_RETURNS_NON_NULL -inline char* append_exponent(char* buf, int e) -{ - JSON_ASSERT(e > -1000); - JSON_ASSERT(e < 1000); - - if (e < 0) - { - e = -e; - *buf++ = '-'; - } - else - { - *buf++ = '+'; - } - - auto k = static_cast<std::uint32_t>(e); - if (k < 10) - { - // Always print at least two digits in the exponent. - // This is for compatibility with printf("%g"). - *buf++ = '0'; - *buf++ = static_cast<char>('0' + k); - } - else if (k < 100) - { - *buf++ = static_cast<char>('0' + k / 10); - k %= 10; - *buf++ = static_cast<char>('0' + k); - } - else - { - *buf++ = static_cast<char>('0' + k / 100); - k %= 100; - *buf++ = static_cast<char>('0' + k / 10); - k %= 10; - *buf++ = static_cast<char>('0' + k); - } - - return buf; -} - -/*! -@brief prettify v = buf * 10^decimal_exponent - -If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point -notation. Otherwise it will be printed in exponential notation. - -@pre min_exp < 0 -@pre max_exp > 0 -*/ -JSON_HEDLEY_NON_NULL(1) -JSON_HEDLEY_RETURNS_NON_NULL -inline char* format_buffer(char* buf, int len, int decimal_exponent, - int min_exp, int max_exp) -{ - JSON_ASSERT(min_exp < 0); - JSON_ASSERT(max_exp > 0); - - const int k = len; - const int n = len + decimal_exponent; - - // v = buf * 10^(n-k) - // k is the length of the buffer (number of decimal digits) - // n is the position of the decimal point relative to the start of the buffer. - - if (k <= n && n <= max_exp) - { - // digits[000] - // len <= max_exp + 2 - - std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k)); - // Make it look like a floating-point number (#362, #378) - buf[n + 0] = '.'; - buf[n + 1] = '0'; - return buf + (static_cast<size_t>(n) + 2); - } - - if (0 < n && n <= max_exp) - { - // dig.its - // len <= max_digits10 + 1 - - JSON_ASSERT(k > n); - - std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n)); - buf[n] = '.'; - return buf + (static_cast<size_t>(k) + 1U); - } - - if (min_exp < n && n <= 0) - { - // 0.[000]digits - // len <= 2 + (-min_exp - 1) + max_digits10 - - std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k)); - buf[0] = '0'; - buf[1] = '.'; - std::memset(buf + 2, '0', static_cast<size_t>(-n)); - return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k)); - } - - if (k == 1) - { - // dE+123 - // len <= 1 + 5 - - buf += 1; - } - else - { - // d.igitsE+123 - // len <= max_digits10 + 1 + 5 - - std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1); - buf[1] = '.'; - buf += 1 + static_cast<size_t>(k); - } - - *buf++ = 'e'; - return append_exponent(buf, n - 1); -} - -} // namespace dtoa_impl - -/*! -@brief generates a decimal representation of the floating-point number value in [first, last). - -The format of the resulting decimal representation is similar to printf's %g -format. Returns an iterator pointing past-the-end of the decimal representation. - -@note The input number must be finite, i.e. NaN's and Inf's are not supported. -@note The buffer must be large enough. -@note The result is NOT null-terminated. -*/ -template<typename FloatType> -JSON_HEDLEY_NON_NULL(1, 2) -JSON_HEDLEY_RETURNS_NON_NULL -char* to_chars(char* first, const char* last, FloatType value) -{ - static_cast<void>(last); // maybe unused - fix warning - JSON_ASSERT(std::isfinite(value)); - - // Use signbit(value) instead of (value < 0) since signbit works for -0. - if (std::signbit(value)) - { - value = -value; - *first++ = '-'; - } - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (value == 0) // +-0 - { - *first++ = '0'; - // Make it look like a floating-point number (#362, #378) - *first++ = '.'; - *first++ = '0'; - return first; - } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10); - - // Compute v = buffer * 10^decimal_exponent. - // The decimal digits are stored in the buffer, which needs to be interpreted - // as an unsigned decimal integer. - // len is the length of the buffer, i.e. the number of decimal digits. - int len = 0; - int decimal_exponent = 0; - dtoa_impl::grisu2(first, len, decimal_exponent, value); - - JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10); - - // Format the buffer like printf("%.*g", prec, value) - constexpr int kMinExp = -4; - // Use digits10 here to increase compatibility with version 2. - constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10; - - JSON_ASSERT(last - first >= kMaxExp + 2); - JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10); - JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6); - - return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp); -} - -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/exceptions.hpp> - -// #include <nlohmann/detail/macro_scope.hpp> - -// #include <nlohmann/detail/meta/cpp_future.hpp> - -// #include <nlohmann/detail/output/binary_writer.hpp> - -// #include <nlohmann/detail/output/output_adapters.hpp> - -// #include <nlohmann/detail/value_t.hpp> - - -namespace nlohmann -{ -namespace detail -{ -/////////////////// -// serialization // -/////////////////// - -/// how to treat decoding errors -enum class error_handler_t -{ - strict, ///< throw a type_error exception in case of invalid UTF-8 - replace, ///< replace invalid UTF-8 sequences with U+FFFD - ignore ///< ignore invalid UTF-8 sequences -}; - -template<typename BasicJsonType> -class serializer -{ - using string_t = typename BasicJsonType::string_t; - using number_float_t = typename BasicJsonType::number_float_t; - using number_integer_t = typename BasicJsonType::number_integer_t; - using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using binary_char_t = typename BasicJsonType::binary_t::value_type; - static constexpr std::uint8_t UTF8_ACCEPT = 0; - static constexpr std::uint8_t UTF8_REJECT = 1; - - public: - /*! - @param[in] s output stream to serialize to - @param[in] ichar indentation character to use - @param[in] error_handler_ how to react on decoding errors - */ - serializer(output_adapter_t<char> s, const char ichar, - error_handler_t error_handler_ = error_handler_t::strict) - : o(std::move(s)) - , loc(std::localeconv()) - , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep))) - , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point))) - , indent_char(ichar) - , indent_string(512, indent_char) - , error_handler(error_handler_) - {} - - // delete because of pointer members - serializer(const serializer&) = delete; - serializer& operator=(const serializer&) = delete; - serializer(serializer&&) = delete; - serializer& operator=(serializer&&) = delete; - ~serializer() = default; - - /*! - @brief internal implementation of the serialization function - - This function is called by the public member function dump and organizes - the serialization internally. The indentation level is propagated as - additional parameter. In case of arrays and objects, the function is - called recursively. - - - strings and object keys are escaped using `escape_string()` - - integer numbers are converted implicitly via `operator<<` - - floating-point numbers are converted to a string using `"%g"` format - - binary values are serialized as objects containing the subtype and the - byte array - - @param[in] val value to serialize - @param[in] pretty_print whether the output shall be pretty-printed - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] indent_step the indent level - @param[in] current_indent the current indent level (only used internally) - */ - void dump(const BasicJsonType& val, - const bool pretty_print, - const bool ensure_ascii, - const unsigned int indent_step, - const unsigned int current_indent = 0) - { - switch (val.m_type) - { - case value_t::object: - { - if (val.m_value.object->empty()) - { - o->write_characters("{}", 2); - return; - } - - if (pretty_print) - { - o->write_characters("{\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - // first n-1 elements - auto i = val.m_value.object->cbegin(); - for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) - { - o->write_characters(indent_string.c_str(), new_indent); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\": ", 3); - dump(i->second, true, ensure_ascii, indent_step, new_indent); - o->write_characters(",\n", 2); - } - - // last element - JSON_ASSERT(i != val.m_value.object->cend()); - JSON_ASSERT(std::next(i) == val.m_value.object->cend()); - o->write_characters(indent_string.c_str(), new_indent); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\": ", 3); - dump(i->second, true, ensure_ascii, indent_step, new_indent); - - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character('}'); - } - else - { - o->write_character('{'); - - // first n-1 elements - auto i = val.m_value.object->cbegin(); - for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) - { - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\":", 2); - dump(i->second, false, ensure_ascii, indent_step, current_indent); - o->write_character(','); - } - - // last element - JSON_ASSERT(i != val.m_value.object->cend()); - JSON_ASSERT(std::next(i) == val.m_value.object->cend()); - o->write_character('\"'); - dump_escaped(i->first, ensure_ascii); - o->write_characters("\":", 2); - dump(i->second, false, ensure_ascii, indent_step, current_indent); - - o->write_character('}'); - } - - return; - } - - case value_t::array: - { - if (val.m_value.array->empty()) - { - o->write_characters("[]", 2); - return; - } - - if (pretty_print) - { - o->write_characters("[\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - // first n-1 elements - for (auto i = val.m_value.array->cbegin(); - i != val.m_value.array->cend() - 1; ++i) - { - o->write_characters(indent_string.c_str(), new_indent); - dump(*i, true, ensure_ascii, indent_step, new_indent); - o->write_characters(",\n", 2); - } - - // last element - JSON_ASSERT(!val.m_value.array->empty()); - o->write_characters(indent_string.c_str(), new_indent); - dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent); - - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character(']'); - } - else - { - o->write_character('['); - - // first n-1 elements - for (auto i = val.m_value.array->cbegin(); - i != val.m_value.array->cend() - 1; ++i) - { - dump(*i, false, ensure_ascii, indent_step, current_indent); - o->write_character(','); - } - - // last element - JSON_ASSERT(!val.m_value.array->empty()); - dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent); - - o->write_character(']'); - } - - return; - } - - case value_t::string: - { - o->write_character('\"'); - dump_escaped(*val.m_value.string, ensure_ascii); - o->write_character('\"'); - return; - } - - case value_t::binary: - { - if (pretty_print) - { - o->write_characters("{\n", 2); - - // variable to hold indentation for recursive calls - const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize(indent_string.size() * 2, ' '); - } - - o->write_characters(indent_string.c_str(), new_indent); - - o->write_characters("\"bytes\": [", 10); - - if (!val.m_value.binary->empty()) - { - for (auto i = val.m_value.binary->cbegin(); - i != val.m_value.binary->cend() - 1; ++i) - { - dump_integer(*i); - o->write_characters(", ", 2); - } - dump_integer(val.m_value.binary->back()); - } - - o->write_characters("],\n", 3); - o->write_characters(indent_string.c_str(), new_indent); - - o->write_characters("\"subtype\": ", 11); - if (val.m_value.binary->has_subtype()) - { - dump_integer(val.m_value.binary->subtype()); - } - else - { - o->write_characters("null", 4); - } - o->write_character('\n'); - o->write_characters(indent_string.c_str(), current_indent); - o->write_character('}'); - } - else - { - o->write_characters("{\"bytes\":[", 10); - - if (!val.m_value.binary->empty()) - { - for (auto i = val.m_value.binary->cbegin(); - i != val.m_value.binary->cend() - 1; ++i) - { - dump_integer(*i); - o->write_character(','); - } - dump_integer(val.m_value.binary->back()); - } - - o->write_characters("],\"subtype\":", 12); - if (val.m_value.binary->has_subtype()) - { - dump_integer(val.m_value.binary->subtype()); - o->write_character('}'); - } - else - { - o->write_characters("null}", 5); - } - } - return; - } - - case value_t::boolean: - { - if (val.m_value.boolean) - { - o->write_characters("true", 4); - } - else - { - o->write_characters("false", 5); - } - return; - } - - case value_t::number_integer: - { - dump_integer(val.m_value.number_integer); - return; - } - - case value_t::number_unsigned: - { - dump_integer(val.m_value.number_unsigned); - return; - } - - case value_t::number_float: - { - dump_float(val.m_value.number_float); - return; - } - - case value_t::discarded: - { - o->write_characters("<discarded>", 11); - return; - } - - case value_t::null: - { - o->write_characters("null", 4); - return; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - } - - JSON_PRIVATE_UNLESS_TESTED: - /*! - @brief dump escaped string - - Escape a string by replacing certain special characters by a sequence of an - escape character (backslash) and another character and other control - characters by a sequence of "\u" followed by a four-digit hex - representation. The escaped string is written to output stream @a o. - - @param[in] s the string to escape - @param[in] ensure_ascii whether to escape non-ASCII characters with - \uXXXX sequences - - @complexity Linear in the length of string @a s. - */ - void dump_escaped(const string_t& s, const bool ensure_ascii) - { - std::uint32_t codepoint{}; - std::uint8_t state = UTF8_ACCEPT; - std::size_t bytes = 0; // number of bytes written to string_buffer - - // number of bytes written at the point of the last valid byte - std::size_t bytes_after_last_accept = 0; - std::size_t undumped_chars = 0; - - for (std::size_t i = 0; i < s.size(); ++i) - { - const auto byte = static_cast<std::uint8_t>(s[i]); - - switch (decode(state, codepoint, byte)) - { - case UTF8_ACCEPT: // decode found a new code point - { - switch (codepoint) - { - case 0x08: // backspace - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'b'; - break; - } - - case 0x09: // horizontal tab - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 't'; - break; - } - - case 0x0A: // newline - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'n'; - break; - } - - case 0x0C: // formfeed - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'f'; - break; - } - - case 0x0D: // carriage return - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'r'; - break; - } - - case 0x22: // quotation mark - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\"'; - break; - } - - case 0x5C: // reverse solidus - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = '\\'; - break; - } - - default: - { - // escape control characters (0x00..0x1F) or, if - // ensure_ascii parameter is used, non-ASCII characters - if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F))) - { - if (codepoint <= 0xFFFF) - { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", - static_cast<std::uint16_t>(codepoint)); - bytes += 6; - } - else - { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", - static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)), - static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))); - bytes += 12; - } - } - else - { - // copy byte to buffer (all previous bytes - // been copied have in default case above) - string_buffer[bytes++] = s[i]; - } - break; - } - } - - // write buffer and reset index; there must be 13 bytes - // left, as this is the maximal number of bytes to be - // written ("\uxxxx\uxxxx\0") for one code point - if (string_buffer.size() - bytes < 13) - { - o->write_characters(string_buffer.data(), bytes); - bytes = 0; - } - - // remember the byte position of this accept - bytes_after_last_accept = bytes; - undumped_chars = 0; - break; - } - - case UTF8_REJECT: // decode found invalid UTF-8 byte - { - switch (error_handler) - { - case error_handler_t::strict: - { - std::string sn(9, '\0'); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(&sn[0], sn.size(), "%.2X", byte); - JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType())); - } - - case error_handler_t::ignore: - case error_handler_t::replace: - { - // in case we saw this character the first time, we - // would like to read it again, because the byte - // may be OK for itself, but just not OK for the - // previous sequence - if (undumped_chars > 0) - { - --i; - } - - // reset length buffer to the last accepted index; - // thus removing/ignoring the invalid characters - bytes = bytes_after_last_accept; - - if (error_handler == error_handler_t::replace) - { - // add a replacement character - if (ensure_ascii) - { - string_buffer[bytes++] = '\\'; - string_buffer[bytes++] = 'u'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'f'; - string_buffer[bytes++] = 'd'; - } - else - { - string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF'); - string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF'); - string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD'); - } - - // write buffer and reset index; there must be 13 bytes - // left, as this is the maximal number of bytes to be - // written ("\uxxxx\uxxxx\0") for one code point - if (string_buffer.size() - bytes < 13) - { - o->write_characters(string_buffer.data(), bytes); - bytes = 0; - } - - bytes_after_last_accept = bytes; - } - - undumped_chars = 0; - - // continue processing the string - state = UTF8_ACCEPT; - break; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - break; - } - - default: // decode found yet incomplete multi-byte code point - { - if (!ensure_ascii) - { - // code point will not be escaped - copy byte to buffer - string_buffer[bytes++] = s[i]; - } - ++undumped_chars; - break; - } - } - } - - // we finished processing the string - if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT)) - { - // write buffer - if (bytes > 0) - { - o->write_characters(string_buffer.data(), bytes); - } - } - else - { - // we finish reading, but do not accept: string was incomplete - switch (error_handler) - { - case error_handler_t::strict: - { - std::string sn(9, '\0'); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back())); - JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType())); - } - - case error_handler_t::ignore: - { - // write all accepted bytes - o->write_characters(string_buffer.data(), bytes_after_last_accept); - break; - } - - case error_handler_t::replace: - { - // write all accepted bytes - o->write_characters(string_buffer.data(), bytes_after_last_accept); - // add a replacement character - if (ensure_ascii) - { - o->write_characters("\\ufffd", 6); - } - else - { - o->write_characters("\xEF\xBF\xBD", 3); - } - break; - } - - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - } - } - - private: - /*! - @brief count digits - - Count the number of decimal (base 10) digits for an input unsigned integer. - - @param[in] x unsigned integer number to count its digits - @return number of decimal digits - */ - inline unsigned int count_digits(number_unsigned_t x) noexcept - { - unsigned int n_digits = 1; - for (;;) - { - if (x < 10) - { - return n_digits; - } - if (x < 100) - { - return n_digits + 1; - } - if (x < 1000) - { - return n_digits + 2; - } - if (x < 10000) - { - return n_digits + 3; - } - x = x / 10000u; - n_digits += 4; - } - } - - /*! - @brief dump an integer - - Dump a given integer to output stream @a o. Works internally with - @a number_buffer. - - @param[in] x integer number (signed or unsigned) to dump - @tparam NumberType either @a number_integer_t or @a number_unsigned_t - */ - template < typename NumberType, detail::enable_if_t < - std::is_integral<NumberType>::value || - std::is_same<NumberType, number_unsigned_t>::value || - std::is_same<NumberType, number_integer_t>::value || - std::is_same<NumberType, binary_char_t>::value, - int > = 0 > - void dump_integer(NumberType x) - { - static constexpr std::array<std::array<char, 2>, 100> digits_to_99 - { - { - {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}}, - {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}}, - {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}}, - {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}}, - {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}}, - {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}}, - {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}}, - {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}}, - {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}}, - {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}}, - } - }; - - // special case for "0" - if (x == 0) - { - o->write_character('0'); - return; - } - - // use a pointer to fill the buffer - auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg) - - const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755 - number_unsigned_t abs_value; - - unsigned int n_chars{}; - - if (is_negative) - { - *buffer_ptr = '-'; - abs_value = remove_sign(static_cast<number_integer_t>(x)); - - // account one more byte for the minus sign - n_chars = 1 + count_digits(abs_value); - } - else - { - abs_value = static_cast<number_unsigned_t>(x); - n_chars = count_digits(abs_value); - } - - // spare 1 byte for '\0' - JSON_ASSERT(n_chars < number_buffer.size() - 1); - - // jump to the end to generate the string from backward - // so we later avoid reversing the result - buffer_ptr += n_chars; - - // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu - // See: https://www.youtube.com/watch?v=o4-CwDo2zpg - while (abs_value >= 100) - { - const auto digits_index = static_cast<unsigned>((abs_value % 100)); - abs_value /= 100; - *(--buffer_ptr) = digits_to_99[digits_index][1]; - *(--buffer_ptr) = digits_to_99[digits_index][0]; - } - - if (abs_value >= 10) - { - const auto digits_index = static_cast<unsigned>(abs_value); - *(--buffer_ptr) = digits_to_99[digits_index][1]; - *(--buffer_ptr) = digits_to_99[digits_index][0]; - } - else - { - *(--buffer_ptr) = static_cast<char>('0' + abs_value); - } - - o->write_characters(number_buffer.data(), n_chars); - } - - /*! - @brief dump a floating-point number - - Dump a given floating-point number to output stream @a o. Works internally - with @a number_buffer. - - @param[in] x floating-point number to dump - */ - void dump_float(number_float_t x) - { - // NaN / inf - if (!std::isfinite(x)) - { - o->write_characters("null", 4); - return; - } - - // If number_float_t is an IEEE-754 single or double precision number, - // use the Grisu2 algorithm to produce short numbers which are - // guaranteed to round-trip, using strtof and strtod, resp. - // - // NB: The test below works if <long double> == <double>. - static constexpr bool is_ieee_single_or_double - = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) || - (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024); - - dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>()); - } - - void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/) - { - auto* begin = number_buffer.data(); - auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x); - - o->write_characters(begin, static_cast<size_t>(end - begin)); - } - - void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/) - { - // get number of digits for a float -> text -> float round-trip - static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10; - - // the actual conversion - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x); - - // negative value indicates an error - JSON_ASSERT(len > 0); - // check if buffer was large enough - JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size()); - - // erase thousands separator - if (thousands_sep != '\0') - { - // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081 - const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep); - std::fill(end, number_buffer.end(), '\0'); - JSON_ASSERT((end - number_buffer.begin()) <= len); - len = (end - number_buffer.begin()); - } - - // convert decimal point to '.' - if (decimal_point != '\0' && decimal_point != '.') - { - // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081 - const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point); - if (dec_pos != number_buffer.end()) - { - *dec_pos = '.'; - } - } - - o->write_characters(number_buffer.data(), static_cast<std::size_t>(len)); - - // determine if need to append ".0" - const bool value_is_int_like = - std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, - [](char c) - { - return c == '.' || c == 'e'; - }); - - if (value_is_int_like) - { - o->write_characters(".0", 2); - } - } - - /*! - @brief check whether a string is UTF-8 encoded - - The function checks each byte of a string whether it is UTF-8 encoded. The - result of the check is stored in the @a state parameter. The function must - be called initially with state 0 (accept). State 1 means the string must - be rejected, because the current byte is not allowed. If the string is - completely processed, but the state is non-zero, the string ended - prematurely; that is, the last byte indicated more bytes should have - followed. - - @param[in,out] state the state of the decoding - @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT) - @param[in] byte next byte to decode - @return new state - - @note The function has been edited: a std::array is used. - - @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <[email protected]> - @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - */ - static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept - { - static const std::array<std::uint8_t, 400> utf8d = - { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF - 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF - 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF - 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF - 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2 - 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4 - 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6 - 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8 - } - }; - - JSON_ASSERT(byte < utf8d.size()); - const std::uint8_t type = utf8d[byte]; - - codep = (state != UTF8_ACCEPT) - ? (byte & 0x3fu) | (codep << 6u) - : (0xFFu >> type) & (byte); - - std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type); - JSON_ASSERT(index < 400); - state = utf8d[index]; - return state; - } - - /* - * Overload to make the compiler happy while it is instantiating - * dump_integer for number_unsigned_t. - * Must never be called. - */ - number_unsigned_t remove_sign(number_unsigned_t x) - { - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - return x; // LCOV_EXCL_LINE - } - - /* - * Helper function for dump_integer - * - * This function takes a negative signed integer and returns its absolute - * value as unsigned integer. The plus/minus shuffling is necessary as we can - * not directly remove the sign of an arbitrary signed integer as the - * absolute values of INT_MIN and INT_MAX are usually not the same. See - * #1708 for details. - */ - inline number_unsigned_t remove_sign(number_integer_t x) noexcept - { - JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression) - return static_cast<number_unsigned_t>(-(x + 1)) + 1; - } - - private: - /// the output of the serializer - output_adapter_t<char> o = nullptr; - - /// a (hopefully) large enough character buffer - std::array<char, 64> number_buffer{{}}; - - /// the locale - const std::lconv* loc = nullptr; - /// the locale's thousand separator character - const char thousands_sep = '\0'; - /// the locale's decimal point character - const char decimal_point = '\0'; - - /// string buffer - std::array<char, 512> string_buffer{{}}; - - /// the indentation character - const char indent_char; - /// the indentation string - string_t indent_string; - - /// error_handler how to react on decoding errors - const error_handler_t error_handler; -}; -} // namespace detail -} // namespace nlohmann - -// #include <nlohmann/detail/value_t.hpp> - -// #include <nlohmann/json_fwd.hpp> - -// #include <nlohmann/ordered_map.hpp> - - -#include <functional> // less -#include <initializer_list> // initializer_list -#include <iterator> // input_iterator_tag, iterator_traits -#include <memory> // allocator -#include <stdexcept> // for out_of_range -#include <type_traits> // enable_if, is_convertible -#include <utility> // pair -#include <vector> // vector - -// #include <nlohmann/detail/macro_scope.hpp> - - -namespace nlohmann -{ - -/// ordered_map: a minimal map-like container that preserves insertion order -/// for use within nlohmann::basic_json<ordered_map> -template <class Key, class T, class IgnoredLess = std::less<Key>, - class Allocator = std::allocator<std::pair<const Key, T>>> - struct ordered_map : std::vector<std::pair<const Key, T>, Allocator> -{ - using key_type = Key; - using mapped_type = T; - using Container = std::vector<std::pair<const Key, T>, Allocator>; - using typename Container::iterator; - using typename Container::const_iterator; - using typename Container::size_type; - using typename Container::value_type; - - // Explicit constructors instead of `using Container::Container` - // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) - ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {} - template <class It> - ordered_map(It first, It last, const Allocator& alloc = Allocator()) - : Container{first, last, alloc} {} - ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() ) - : Container{init, alloc} {} - - std::pair<iterator, bool> emplace(const key_type& key, T&& t) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return {it, false}; - } - } - Container::emplace_back(key, t); - return {--this->end(), true}; - } - - T& operator[](const Key& key) - { - return emplace(key, T{}).first->second; - } - - const T& operator[](const Key& key) const - { - return at(key); - } - - T& at(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it->second; - } - } - - JSON_THROW(std::out_of_range("key not found")); - } - - const T& at(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it->second; - } - } - - JSON_THROW(std::out_of_range("key not found")); - } - - size_type erase(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) - { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; - } - Container::pop_back(); - return 1; - } - } - return 0; - } - - iterator erase(iterator pos) - { - auto it = pos; - - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) - { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; - } - Container::pop_back(); - return pos; - } - - size_type count(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return 1; - } - } - return 0; - } - - iterator find(const Key& key) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it; - } - } - return Container::end(); - } - - const_iterator find(const Key& key) const - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == key) - { - return it; - } - } - return Container::end(); - } - - std::pair<iterator, bool> insert( value_type&& value ) - { - return emplace(value.first, std::move(value.second)); - } - - std::pair<iterator, bool> insert( const value_type& value ) - { - for (auto it = this->begin(); it != this->end(); ++it) - { - if (it->first == value.first) - { - return {it, false}; - } - } - Container::push_back(value); - return {--this->end(), true}; - } - - template<typename InputIt> - using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category, - std::input_iterator_tag>::value>::type; - - template<typename InputIt, typename = require_input_iter<InputIt>> - void insert(InputIt first, InputIt last) - { - for (auto it = first; it != last; ++it) - { - insert(*it); - } - } -}; - -} // namespace nlohmann - - -#if defined(JSON_HAS_CPP_17) - #include <string_view> -#endif - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ - -/*! -@brief a class to store JSON values - -@tparam ObjectType type for JSON objects (`std::map` by default; will be used -in @ref object_t) -@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used -in @ref array_t) -@tparam StringType type for JSON strings and object keys (`std::string` by -default; will be used in @ref string_t) -@tparam BooleanType type for JSON booleans (`bool` by default; will be used -in @ref boolean_t) -@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by -default; will be used in @ref number_integer_t) -@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c -`uint64_t` by default; will be used in @ref number_unsigned_t) -@tparam NumberFloatType type for JSON floating-point numbers (`double` by -default; will be used in @ref number_float_t) -@tparam BinaryType type for packed binary data for compatibility with binary -serialization formats (`std::vector<std::uint8_t>` by default; will be used in -@ref binary_t) -@tparam AllocatorType type of the allocator to use (`std::allocator` by -default) -@tparam JSONSerializer the serializer to resolve internal calls to `to_json()` -and `from_json()` (@ref adl_serializer by default) - -@requirement The class satisfies the following concept requirements: -- Basic - - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): - JSON values can be default constructed. The result will be a JSON null - value. - - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): - A JSON value can be constructed from an rvalue argument. - - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): - A JSON value can be copy-constructed from an lvalue expression. - - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): - A JSON value van be assigned from an rvalue argument. - - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): - A JSON value can be copy-assigned from an lvalue expression. - - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): - JSON values can be destructed. -- Layout - - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): - JSON values have - [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): - All non-static data members are private and standard layout types, the - class has no virtual functions or (virtual) base classes. -- Library-wide - - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): - JSON values can be compared with `==`, see @ref - operator==(const_reference,const_reference). - - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): - JSON values can be compared with `<`, see @ref - operator<(const_reference,const_reference). - - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): - Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of - other compatible types, using unqualified function call @ref swap(). - - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): - JSON values can be compared against `std::nullptr_t` objects which are used - to model the `null` value. -- Container - - [Container](https://en.cppreference.com/w/cpp/named_req/Container): - JSON values can be used like STL containers and provide iterator access. - - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer); - JSON values can be used like STL containers and provide reverse iterator - access. - -@invariant The member variables @a m_value and @a m_type have the following -relationship: -- If `m_type == value_t::object`, then `m_value.object != nullptr`. -- If `m_type == value_t::array`, then `m_value.array != nullptr`. -- If `m_type == value_t::string`, then `m_value.string != nullptr`. -The invariants are checked by member function assert_invariant(). - -@internal -@note ObjectType trick from https://stackoverflow.com/a/9860911 -@endinternal - -@see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange -Format](https://tools.ietf.org/html/rfc8259) - -@since version 1.0.0 - -@nosubgrouping -*/ -NLOHMANN_BASIC_JSON_TPL_DECLARATION -class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) -{ - private: - template<detail::value_t> friend struct detail::external_constructor; - friend ::nlohmann::json_pointer<basic_json>; - - template<typename BasicJsonType, typename InputType> - friend class ::nlohmann::detail::parser; - friend ::nlohmann::detail::serializer<basic_json>; - template<typename BasicJsonType> - friend class ::nlohmann::detail::iter_impl; - template<typename BasicJsonType, typename CharType> - friend class ::nlohmann::detail::binary_writer; - template<typename BasicJsonType, typename InputType, typename SAX> - friend class ::nlohmann::detail::binary_reader; - template<typename BasicJsonType> - friend class ::nlohmann::detail::json_sax_dom_parser; - template<typename BasicJsonType> - friend class ::nlohmann::detail::json_sax_dom_callback_parser; - friend class ::nlohmann::detail::exception; - - /// workaround type for MSVC - using basic_json_t = NLOHMANN_BASIC_JSON_TPL; - - JSON_PRIVATE_UNLESS_TESTED: - // convenience aliases for types residing in namespace detail; - using lexer = ::nlohmann::detail::lexer_base<basic_json>; - - template<typename InputAdapterType> - static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser( - InputAdapterType adapter, - detail::parser_callback_t<basic_json>cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false - ) - { - return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), - std::move(cb), allow_exceptions, ignore_comments); - } - - private: - using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t; - template<typename BasicJsonType> - using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>; - template<typename BasicJsonType> - using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>; - template<typename Iterator> - using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>; - template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>; - - template<typename CharType> - using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>; - - template<typename InputType> - using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>; - template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>; - - JSON_PRIVATE_UNLESS_TESTED: - using serializer = ::nlohmann::detail::serializer<basic_json>; - - public: - using value_t = detail::value_t; - /// JSON Pointer, see @ref nlohmann::json_pointer - using json_pointer = ::nlohmann::json_pointer<basic_json>; - template<typename T, typename SFINAE> - using json_serializer = JSONSerializer<T, SFINAE>; - /// how to treat decoding errors - using error_handler_t = detail::error_handler_t; - /// how to treat CBOR tags - using cbor_tag_handler_t = detail::cbor_tag_handler_t; - /// helper type for initializer lists of basic_json values - using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>; - - using input_format_t = detail::input_format_t; - /// SAX interface type, see @ref nlohmann::json_sax - using json_sax_t = json_sax<basic_json>; - - //////////////// - // exceptions // - //////////////// - - /// @name exceptions - /// Classes to implement user-defined exceptions. - /// @{ - - /// @copydoc detail::exception - using exception = detail::exception; - /// @copydoc detail::parse_error - using parse_error = detail::parse_error; - /// @copydoc detail::invalid_iterator - using invalid_iterator = detail::invalid_iterator; - /// @copydoc detail::type_error - using type_error = detail::type_error; - /// @copydoc detail::out_of_range - using out_of_range = detail::out_of_range; - /// @copydoc detail::other_error - using other_error = detail::other_error; - - /// @} - - - ///////////////////// - // container types // - ///////////////////// - - /// @name container types - /// The canonic container types to use @ref basic_json like any other STL - /// container. - /// @{ - - /// the type of elements in a basic_json container - using value_type = basic_json; - - /// the type of an element reference - using reference = value_type&; - /// the type of an element const reference - using const_reference = const value_type&; - - /// a type to represent differences between iterators - using difference_type = std::ptrdiff_t; - /// a type to represent container sizes - using size_type = std::size_t; - - /// the allocator type - using allocator_type = AllocatorType<basic_json>; - - /// the type of an element pointer - using pointer = typename std::allocator_traits<allocator_type>::pointer; - /// the type of an element const pointer - using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer; - - /// an iterator for a basic_json container - using iterator = iter_impl<basic_json>; - /// a const iterator for a basic_json container - using const_iterator = iter_impl<const basic_json>; - /// a reverse iterator for a basic_json container - using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>; - /// a const reverse iterator for a basic_json container - using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>; - - /// @} - - - /*! - @brief returns the allocator associated with the container - */ - static allocator_type get_allocator() - { - return allocator_type(); - } - - /*! - @brief returns version information on the library - - This function returns a JSON object with information about the library, - including the version number and information on the platform and compiler. - - @return JSON object holding version information - key | description - ----------- | --------------- - `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). - `copyright` | The copyright line for the library as string. - `name` | The name of the library as string. - `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. - `url` | The URL of the project as string. - `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). - - @liveexample{The following code shows an example output of the `meta()` - function.,meta} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @complexity Constant. - - @since 2.1.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json meta() - { - basic_json result; - - result["copyright"] = "(C) 2013-2021 Niels Lohmann"; - result["name"] = "JSON for Modern C++"; - result["url"] = "https://github.com/nlohmann/json"; - result["version"]["string"] = - std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." + - std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." + - std::to_string(NLOHMANN_JSON_VERSION_PATCH); - result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR; - result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR; - result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH; - -#ifdef _WIN32 - result["platform"] = "win32"; -#elif defined __linux__ - result["platform"] = "linux"; -#elif defined __APPLE__ - result["platform"] = "apple"; -#elif defined __unix__ - result["platform"] = "unix"; -#else - result["platform"] = "unknown"; -#endif - -#if defined(__ICC) || defined(__INTEL_COMPILER) - result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}}; -#elif defined(__clang__) - result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}}; -#elif defined(__GNUC__) || defined(__GNUG__) - result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}}; -#elif defined(__HP_cc) || defined(__HP_aCC) - result["compiler"] = "hp" -#elif defined(__IBMCPP__) - result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}}; -#elif defined(_MSC_VER) - result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}}; -#elif defined(__PGI) - result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}}; -#elif defined(__SUNPRO_CC) - result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}}; -#else - result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}}; -#endif - -#ifdef __cplusplus - result["compiler"]["c++"] = std::to_string(__cplusplus); -#else - result["compiler"]["c++"] = "unknown"; -#endif - return result; - } - - - /////////////////////////// - // JSON value data types // - /////////////////////////// - - /// @name JSON value data types - /// The data types to store a JSON value. These types are derived from - /// the template arguments passed to class @ref basic_json. - /// @{ - -#if defined(JSON_HAS_CPP_14) - // Use transparent comparator if possible, combined with perfect forwarding - // on find() and count() calls prevents unnecessary string construction. - using object_comparator_t = std::less<>; -#else - using object_comparator_t = std::less<StringType>; -#endif - - /*! - @brief a type for an object - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: - > An object is an unordered collection of zero or more name/value pairs, - > where a name is a string and a value is a string, number, boolean, null, - > object, or array. - - To store objects in C++, a type is defined by the template parameters - described below. - - @tparam ObjectType the container to store objects (e.g., `std::map` or - `std::unordered_map`) - @tparam StringType the type of the keys or names (e.g., `std::string`). - The comparison function `std::less<StringType>` is used to order elements - inside the container. - @tparam AllocatorType the allocator to use for objects (e.g., - `std::allocator`) - - #### Default type - - With the default values for @a ObjectType (`std::map`), @a StringType - (`std::string`), and @a AllocatorType (`std::allocator`), the default - value for @a object_t is: - - @code {.cpp} - std::map< - std::string, // key_type - basic_json, // value_type - std::less<std::string>, // key_compare - std::allocator<std::pair<const std::string, basic_json>> // allocator_type - > - @endcode - - #### Behavior - - The choice of @a object_t influences the behavior of the JSON class. With - the default type, objects have the following behavior: - - - When all names are unique, objects will be interoperable in the sense - that all software implementations receiving that object will agree on - the name-value mappings. - - When the names within an object are not unique, it is unspecified which - one of the values for a given key will be chosen. For instance, - `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or - `{"key": 2}`. - - Internally, name/value pairs are stored in lexicographical order of the - names. Objects will also be serialized (see @ref dump) in this order. - For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored - and serialized as `{"a": 2, "b": 1}`. - - When comparing objects, the order of the name/value pairs is irrelevant. - This makes objects interoperable in the sense that they will not be - affected by these differences. For instance, `{"b": 1, "a": 2}` and - `{"a": 2, "b": 1}` will be treated as equal. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the object's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON object. - - #### Storage - - Objects are stored as pointers in a @ref basic_json type. That is, for any - access to object values, a pointer of type `object_t*` must be - dereferenced. - - @sa see @ref array_t -- type for an array value - - @since version 1.0.0 - - @note The order name/value pairs are added to the object is *not* - preserved by the library. Therefore, iterating an object may return - name/value pairs in a different order than they were originally stored. In - fact, keys will be traversed in alphabetical order as `std::map` with - `std::less` is used by default. Please note this behavior conforms to [RFC - 8259](https://tools.ietf.org/html/rfc8259), because any order implements the - specified "unordered" nature of JSON objects. - */ - using object_t = ObjectType<StringType, - basic_json, - object_comparator_t, - AllocatorType<std::pair<const StringType, - basic_json>>>; - - /*! - @brief a type for an array - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: - > An array is an ordered sequence of zero or more values. - - To store objects in C++, a type is defined by the template parameters - explained below. - - @tparam ArrayType container type to store arrays (e.g., `std::vector` or - `std::list`) - @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`) - - #### Default type - - With the default values for @a ArrayType (`std::vector`) and @a - AllocatorType (`std::allocator`), the default value for @a array_t is: - - @code {.cpp} - std::vector< - basic_json, // value_type - std::allocator<basic_json> // allocator_type - > - @endcode - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the array's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON array. - - #### Storage - - Arrays are stored as pointers in a @ref basic_json type. That is, for any - access to array values, a pointer of type `array_t*` must be dereferenced. - - @sa see @ref object_t -- type for an object value - - @since version 1.0.0 - */ - using array_t = ArrayType<basic_json, AllocatorType<basic_json>>; - - /*! - @brief a type for a string - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: - > A string is a sequence of zero or more Unicode characters. - - To store objects in C++, a type is defined by the template parameter - described below. Unicode values are split by the JSON class into - byte-sized characters during deserialization. - - @tparam StringType the container to store strings (e.g., `std::string`). - Note this container is used for keys/names in objects, see @ref object_t. - - #### Default type - - With the default values for @a StringType (`std::string`), the default - value for @a string_t is: - - @code {.cpp} - std::string - @endcode - - #### Encoding - - Strings are stored in UTF-8 encoding. Therefore, functions like - `std::string::size()` or `std::string::length()` return the number of - bytes in the string rather than the number of characters or glyphs. - - #### String comparison - - [RFC 8259](https://tools.ietf.org/html/rfc8259) states: - > Software implementations are typically required to test names of object - > members for equality. Implementations that transform the textual - > representation into sequences of Unicode code units and then perform the - > comparison numerically, code unit by code unit, are interoperable in the - > sense that implementations will agree in all cases on equality or - > inequality of two strings. For example, implementations that compare - > strings with escaped characters unconverted may incorrectly find that - > `"a\\b"` and `"a\u005Cb"` are not equal. - - This implementation is interoperable as it does compare strings code unit - by code unit. - - #### Storage - - String values are stored as pointers in a @ref basic_json type. That is, - for any access to string values, a pointer of type `string_t*` must be - dereferenced. - - @since version 1.0.0 - */ - using string_t = StringType; - - /*! - @brief a type for a boolean - - [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a - type which differentiates the two literals `true` and `false`. - - To store objects in C++, a type is defined by the template parameter @a - BooleanType which chooses the type to use. - - #### Default type - - With the default values for @a BooleanType (`bool`), the default value for - @a boolean_t is: - - @code {.cpp} - bool - @endcode - - #### Storage - - Boolean values are stored directly inside a @ref basic_json type. - - @since version 1.0.0 - */ - using boolean_t = BooleanType; - - /*! - @brief a type for a number (integer) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store integer numbers in C++, a type is defined by the template - parameter @a NumberIntegerType which chooses the type to use. - - #### Default type - - With the default values for @a NumberIntegerType (`int64_t`), the default - value for @a number_integer_t is: - - @code {.cpp} - int64_t - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in integer literals lead to an interpretation as octal - number. Internally, the value will be stored as decimal number. For - instance, the C++ integer literal `010` will be serialized to `8`. - During deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `9223372036854775807` (INT64_MAX) and the minimal integer number - that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers - that are out of range will yield over/underflow when used in a - constructor. During deserialization, too large or small integer numbers - will be automatically be stored as @ref number_unsigned_t or @ref - number_float_t. - - [RFC 8259](https://tools.ietf.org/html/rfc8259) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense - > that implementations will agree exactly on their numeric values. - - As this range is a subrange of the exactly supported range [INT64_MIN, - INT64_MAX], this class's integer type is interoperable. - - #### Storage - - Integer number values are stored directly inside a @ref basic_json type. - - @sa see @ref number_float_t -- type for number values (floating-point) - - @sa see @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ - using number_integer_t = NumberIntegerType; - - /*! - @brief a type for a number (unsigned) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store unsigned integer numbers in C++, a type is defined by the - template parameter @a NumberUnsignedType which chooses the type to use. - - #### Default type - - With the default values for @a NumberUnsignedType (`uint64_t`), the - default value for @a number_unsigned_t is: - - @code {.cpp} - uint64_t - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in integer literals lead to an interpretation as octal - number. Internally, the value will be stored as decimal number. For - instance, the C++ integer literal `010` will be serialized to `8`. - During deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `18446744073709551615` (UINT64_MAX) and the minimal integer - number that can be stored is `0`. Integer numbers that are out of range - will yield over/underflow when used in a constructor. During - deserialization, too large or small integer numbers will be automatically - be stored as @ref number_integer_t or @ref number_float_t. - - [RFC 8259](https://tools.ietf.org/html/rfc8259) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense - > that implementations will agree exactly on their numeric values. - - As this range is a subrange (when considered in conjunction with the - number_integer_t type) of the exactly supported range [0, UINT64_MAX], - this class's integer type is interoperable. - - #### Storage - - Integer number values are stored directly inside a @ref basic_json type. - - @sa see @ref number_float_t -- type for number values (floating-point) - @sa see @ref number_integer_t -- type for number values (integer) - - @since version 2.0.0 - */ - using number_unsigned_t = NumberUnsignedType; - - /*! - @brief a type for a number (floating-point) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store floating-point numbers in C++, a type is defined by the template - parameter @a NumberFloatType which chooses the type to use. - - #### Default type - - With the default values for @a NumberFloatType (`double`), the default - value for @a number_float_t is: - - @code {.cpp} - double - @endcode - - #### Default behavior - - - The restrictions about leading zeros is not enforced in C++. Instead, - leading zeros in floating-point literals will be ignored. Internally, - the value will be stored as decimal number. For instance, the C++ - floating-point literal `01.2` will be serialized to `1.2`. During - deserialization, leading zeros yield an error. - - Not-a-number (NaN) values will be serialized to `null`. - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) states: - > This specification allows implementations to set limits on the range and - > precision of numbers accepted. Since software that implements IEEE - > 754-2008 binary64 (double precision) numbers is generally available and - > widely used, good interoperability can be achieved by implementations - > that expect no more precision or range than these provide, in the sense - > that implementations will approximate JSON numbers within the expected - > precision. - - This implementation does exactly follow this approach, as it uses double - precision floating-point numbers. Note values smaller than - `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` - will be stored as NaN internally and be serialized to `null`. - - #### Storage - - Floating-point number values are stored directly inside a @ref basic_json - type. - - @sa see @ref number_integer_t -- type for number values (integer) - - @sa see @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ - using number_float_t = NumberFloatType; - - /*! - @brief a type for a packed binary type - - This type is a type designed to carry binary data that appears in various - serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and - BSON's generic binary subtype. This type is NOT a part of standard JSON and - exists solely for compatibility with these binary types. As such, it is - simply defined as an ordered sequence of zero or more byte values. - - Additionally, as an implementation detail, the subtype of the binary data is - carried around as a `std::uint8_t`, which is compatible with both of the - binary data formats that use binary subtyping, (though the specific - numbering is incompatible with each other, and it is up to the user to - translate between them). - - [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type - as: - > Major type 2: a byte string. The string's length in bytes is represented - > following the rules for positive integers (major type 0). - - [MessagePack's documentation on the bin type - family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) - describes this type as: - > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes - > in addition to the size of the byte array. - - [BSON's specifications](http://bsonspec.org/spec.html) describe several - binary types; however, this type is intended to represent the generic binary - type which has the description: - > Generic binary subtype - This is the most commonly used binary subtype and - > should be the 'default' for drivers and tools. - - None of these impose any limitations on the internal representation other - than the basic unit of storage be some type of array whose parts are - decomposable into bytes. - - The default representation of this binary format is a - `std::vector<std::uint8_t>`, which is a very common way to represent a byte - array in modern C++. - - #### Default type - - The default values for @a BinaryType is `std::vector<std::uint8_t>` - - #### Storage - - Binary Arrays are stored as pointers in a @ref basic_json type. That is, - for any access to array values, a pointer of the type `binary_t*` must be - dereferenced. - - #### Notes on subtypes - - - CBOR - - Binary values are represented as byte strings. Subtypes are serialized - as tagged values. - - MessagePack - - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, - or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8) - is used. For other sizes, the ext family (ext8, ext16, ext32) is used. - The subtype is then added as singed 8-bit integer. - - If no subtype is given, the bin family (bin8, bin16, bin32) is used. - - BSON - - If a subtype is given, it is used and added as unsigned 8-bit integer. - - If no subtype is given, the generic binary subtype 0x00 is used. - - @sa see @ref binary -- create a binary array - - @since version 3.8.0 - */ - using binary_t = nlohmann::byte_container_with_subtype<BinaryType>; - /// @} - - private: - - /// helper for exception-safe object creation - template<typename T, typename... Args> - JSON_HEDLEY_RETURNS_NON_NULL - static T* create(Args&& ... args) - { - AllocatorType<T> alloc; - using AllocatorTraits = std::allocator_traits<AllocatorType<T>>; - - auto deleter = [&](T * obj) - { - AllocatorTraits::deallocate(alloc, obj, 1); - }; - std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter); - AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...); - JSON_ASSERT(obj != nullptr); - return obj.release(); - } - - //////////////////////// - // JSON value storage // - //////////////////////// - - JSON_PRIVATE_UNLESS_TESTED: - /*! - @brief a JSON value - - The actual storage for a JSON value of the @ref basic_json class. This - union combines the different storage types for the JSON value types - defined in @ref value_t. - - JSON type | value_t type | used type - --------- | --------------- | ------------------------ - object | object | pointer to @ref object_t - array | array | pointer to @ref array_t - string | string | pointer to @ref string_t - boolean | boolean | @ref boolean_t - number | number_integer | @ref number_integer_t - number | number_unsigned | @ref number_unsigned_t - number | number_float | @ref number_float_t - binary | binary | pointer to @ref binary_t - null | null | *no value is stored* - - @note Variable-length types (objects, arrays, and strings) are stored as - pointers. The size of the union should not exceed 64 bits if the default - value types are used. - - @since version 1.0.0 - */ - union json_value - { - /// object (stored with pointer to save storage) - object_t* object; - /// array (stored with pointer to save storage) - array_t* array; - /// string (stored with pointer to save storage) - string_t* string; - /// binary (stored with pointer to save storage) - binary_t* binary; - /// boolean - boolean_t boolean; - /// number (integer) - number_integer_t number_integer; - /// number (unsigned integer) - number_unsigned_t number_unsigned; - /// number (floating-point) - number_float_t number_float; - - /// default constructor (for null values) - json_value() = default; - /// constructor for booleans - json_value(boolean_t v) noexcept : boolean(v) {} - /// constructor for numbers (integer) - json_value(number_integer_t v) noexcept : number_integer(v) {} - /// constructor for numbers (unsigned) - json_value(number_unsigned_t v) noexcept : number_unsigned(v) {} - /// constructor for numbers (floating-point) - json_value(number_float_t v) noexcept : number_float(v) {} - /// constructor for empty values of a given type - json_value(value_t t) - { - switch (t) - { - case value_t::object: - { - object = create<object_t>(); - break; - } - - case value_t::array: - { - array = create<array_t>(); - break; - } - - case value_t::string: - { - string = create<string_t>(""); - break; - } - - case value_t::binary: - { - binary = create<binary_t>(); - break; - } - - case value_t::boolean: - { - boolean = boolean_t(false); - break; - } - - case value_t::number_integer: - { - number_integer = number_integer_t(0); - break; - } - - case value_t::number_unsigned: - { - number_unsigned = number_unsigned_t(0); - break; - } - - case value_t::number_float: - { - number_float = number_float_t(0.0); - break; - } - - case value_t::null: - { - object = nullptr; // silence warning, see #821 - break; - } - - case value_t::discarded: - default: - { - object = nullptr; // silence warning, see #821 - if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) - { - JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE - } - break; - } - } - } - - /// constructor for strings - json_value(const string_t& value) - { - string = create<string_t>(value); - } - - /// constructor for rvalue strings - json_value(string_t&& value) - { - string = create<string_t>(std::move(value)); - } - - /// constructor for objects - json_value(const object_t& value) - { - object = create<object_t>(value); - } - - /// constructor for rvalue objects - json_value(object_t&& value) - { - object = create<object_t>(std::move(value)); - } - - /// constructor for arrays - json_value(const array_t& value) - { - array = create<array_t>(value); - } - - /// constructor for rvalue arrays - json_value(array_t&& value) - { - array = create<array_t>(std::move(value)); - } - - /// constructor for binary arrays - json_value(const typename binary_t::container_type& value) - { - binary = create<binary_t>(value); - } - - /// constructor for rvalue binary arrays - json_value(typename binary_t::container_type&& value) - { - binary = create<binary_t>(std::move(value)); - } - - /// constructor for binary arrays (internal type) - json_value(const binary_t& value) - { - binary = create<binary_t>(value); - } - - /// constructor for rvalue binary arrays (internal type) - json_value(binary_t&& value) - { - binary = create<binary_t>(std::move(value)); - } - - void destroy(value_t t) - { - if (t == value_t::array || t == value_t::object) - { - // flatten the current json_value to a heap-allocated stack - std::vector<basic_json> stack; - - // move the top-level items to stack - if (t == value_t::array) - { - stack.reserve(array->size()); - std::move(array->begin(), array->end(), std::back_inserter(stack)); - } - else - { - stack.reserve(object->size()); - for (auto&& it : *object) - { - stack.push_back(std::move(it.second)); - } - } - - while (!stack.empty()) - { - // move the last item to local variable to be processed - basic_json current_item(std::move(stack.back())); - stack.pop_back(); - - // if current_item is array/object, move - // its children to the stack to be processed later - if (current_item.is_array()) - { - std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack)); - - current_item.m_value.array->clear(); - } - else if (current_item.is_object()) - { - for (auto&& it : *current_item.m_value.object) - { - stack.push_back(std::move(it.second)); - } - - current_item.m_value.object->clear(); - } - - // it's now safe that current_item get destructed - // since it doesn't have any children - } - } - - switch (t) - { - case value_t::object: - { - AllocatorType<object_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, object); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1); - break; - } - - case value_t::array: - { - AllocatorType<array_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, array); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1); - break; - } - - case value_t::string: - { - AllocatorType<string_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, string); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1); - break; - } - - case value_t::binary: - { - AllocatorType<binary_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, binary); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1); - break; - } - - case value_t::null: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::discarded: - default: - { - break; - } - } - } - }; - - private: - /*! - @brief checks the class invariants - - This function asserts the class invariants. It needs to be called at the - end of every constructor to make sure that created objects respect the - invariant. Furthermore, it has to be called each time the type of a JSON - value is changed, because the invariant expresses a relationship between - @a m_type and @a m_value. - - Furthermore, the parent relation is checked for arrays and objects: If - @a check_parents true and the value is an array or object, then the - container's elements must have the current value as parent. - - @param[in] check_parents whether the parent relation should be checked. - The value is true by default and should only be set to false - during destruction of objects when the invariant does not - need to hold. - */ - void assert_invariant(bool check_parents = true) const noexcept - { - JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr); - JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr); - JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr); - JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr); - -#if JSON_DIAGNOSTICS - JSON_TRY - { - // cppcheck-suppress assertWithSideEffect - JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j) - { - return j.m_parent == this; - })); - } - JSON_CATCH(...) {} // LCOV_EXCL_LINE -#endif - static_cast<void>(check_parents); - } - - void set_parents() - { -#if JSON_DIAGNOSTICS - switch (m_type) - { - case value_t::array: - { - for (auto& element : *m_value.array) - { - element.m_parent = this; - } - break; - } - - case value_t::object: - { - for (auto& element : *m_value.object) - { - element.second.m_parent = this; - } - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - break; - } -#endif - } - - iterator set_parents(iterator it, typename iterator::difference_type count) - { -#if JSON_DIAGNOSTICS - for (typename iterator::difference_type i = 0; i < count; ++i) - { - (it + i)->m_parent = this; - } -#else - static_cast<void>(count); -#endif - return it; - } - - reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1)) - { -#if JSON_DIAGNOSTICS - if (old_capacity != std::size_t(-1)) - { - // see https://github.com/nlohmann/json/issues/2838 - JSON_ASSERT(type() == value_t::array); - if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) - { - // capacity has changed: update all parents - set_parents(); - return j; - } - } - - // ordered_json uses a vector internally, so pointers could have - // been invalidated; see https://github.com/nlohmann/json/issues/2962 -#ifdef JSON_HEDLEY_MSVC_VERSION -#pragma warning(push ) -#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr -#endif - if (detail::is_ordered_map<object_t>::value) - { - set_parents(); - return j; - } -#ifdef JSON_HEDLEY_MSVC_VERSION -#pragma warning( pop ) -#endif - - j.m_parent = this; -#else - static_cast<void>(j); - static_cast<void>(old_capacity); -#endif - return j; - } - - public: - ////////////////////////// - // JSON parser callback // - ////////////////////////// - - /*! - @brief parser event types - - The parser callback distinguishes the following events: - - `object_start`: the parser read `{` and started to process a JSON object - - `key`: the parser read a key of a value in an object - - `object_end`: the parser read `}` and finished processing a JSON object - - `array_start`: the parser read `[` and started to process a JSON array - - `array_end`: the parser read `]` and finished processing a JSON array - - `value`: the parser finished reading a JSON value - - @image html callback_events.png "Example when certain parse events are triggered" - - @sa see @ref parser_callback_t for more information and examples - */ - using parse_event_t = detail::parse_event_t; - - /*! - @brief per-element parser callback type - - With a parser callback function, the result of parsing a JSON text can be - influenced. When passed to @ref parse, it is called on certain events - (passed as @ref parse_event_t via parameter @a event) with a set recursion - depth @a depth and context JSON value @a parsed. The return value of the - callback function is a boolean indicating whether the element that emitted - the callback shall be kept or not. - - We distinguish six scenarios (determined by the event type) in which the - callback function can be called. The following table describes the values - of the parameters @a depth, @a event, and @a parsed. - - parameter @a event | description | parameter @a depth | parameter @a parsed - ------------------ | ----------- | ------------------ | ------------------- - parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded - parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key - parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object - parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded - parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array - parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value - - @image html callback_events.png "Example when certain parse events are triggered" - - Discarding a value (i.e., returning `false`) has different effects - depending on the context in which function was called: - - - Discarded values in structured types are skipped. That is, the parser - will behave as if the discarded value was never read. - - In case a value outside a structured type is skipped, it is replaced - with `null`. This case happens if the top-level element is skipped. - - @param[in] depth the depth of the recursion during parsing - - @param[in] event an event of type parse_event_t indicating the context in - the callback function has been called - - @param[in,out] parsed the current intermediate parse result; note that - writing to this value has no effect for parse_event_t::key events - - @return Whether the JSON value which called the function during parsing - should be kept (`true`) or not (`false`). In the latter case, it is either - skipped completely or replaced by an empty discarded object. - - @sa see @ref parse for examples - - @since version 1.0.0 - */ - using parser_callback_t = detail::parser_callback_t<basic_json>; - - ////////////////// - // constructors // - ////////////////// - - /// @name constructors and destructors - /// Constructors of class @ref basic_json, copy/move constructor, copy - /// assignment, static functions creating objects, and the destructor. - /// @{ - - /*! - @brief create an empty value with a given type - - Create an empty JSON value with a given type. The value will be default - initialized with an empty value which depends on the type: - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - object | `{}` - array | `[]` - binary | empty array - - @param[in] v the type of the value to create - - @complexity Constant. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows the constructor for different @ref - value_t values,basic_json__value_t} - - @sa see @ref clear() -- restores the postcondition of this constructor - - @since version 1.0.0 - */ - basic_json(const value_t v) - : m_type(v), m_value(v) - { - assert_invariant(); - } - - /*! - @brief create a null object - - Create a `null` JSON value. It either takes a null pointer as parameter - (explicitly creating `null`) or no parameter (implicitly creating `null`). - The passed null pointer itself is not read -- it is only used to choose - the right constructor. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @liveexample{The following code shows the constructor with and without a - null pointer parameter.,basic_json__nullptr_t} - - @since version 1.0.0 - */ - basic_json(std::nullptr_t = nullptr) noexcept - : basic_json(value_t::null) - { - assert_invariant(); - } - - /*! - @brief create a JSON value - - This is a "catch all" constructor for all compatible JSON types; that is, - types for which a `to_json()` method exists. The constructor forwards the - parameter @a val to that method (to `json_serializer<U>::to_json` method - with `U = uncvref_t<CompatibleType>`, to be exact). - - Template type @a CompatibleType includes, but is not limited to, the - following types: - - **arrays**: @ref array_t and all kinds of compatible containers such as - `std::vector`, `std::deque`, `std::list`, `std::forward_list`, - `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, - `std::multiset`, and `std::unordered_multiset` with a `value_type` from - which a @ref basic_json value can be constructed. - - **objects**: @ref object_t and all kinds of compatible associative - containers such as `std::map`, `std::unordered_map`, `std::multimap`, - and `std::unordered_multimap` with a `key_type` compatible to - @ref string_t and a `value_type` from which a @ref basic_json value can - be constructed. - - **strings**: @ref string_t, string literals, and all compatible string - containers can be used. - - **numbers**: @ref number_integer_t, @ref number_unsigned_t, - @ref number_float_t, and all convertible number types such as `int`, - `size_t`, `int64_t`, `float` or `double` can be used. - - **boolean**: @ref boolean_t / `bool` can be used. - - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used, - unfortunately because string literals cannot be distinguished from binary - character arrays by the C++ type system, all types compatible with `const - char*` will be directed to the string constructor instead. This is both - for backwards compatibility, and due to the fact that a binary type is not - a standard JSON type. - - See the examples below. - - @tparam CompatibleType a type such that: - - @a CompatibleType is not derived from `std::istream`, - - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move - constructors), - - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments) - - @a CompatibleType is not a @ref basic_json nested type (e.g., - @ref json_pointer, @ref iterator, etc ...) - - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method - - @tparam U = `uncvref_t<CompatibleType>` - - @param[in] val the value to be forwarded to the respective constructor - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety Depends on the called constructor. For types directly - supported by the library (i.e., all types for which no `to_json()` function - was provided), strong guarantee holds: if an exception is thrown, there are - no changes to any JSON value. - - @liveexample{The following code shows the constructor with several - compatible types.,basic_json__CompatibleType} - - @since version 2.1.0 - */ - template < typename CompatibleType, - typename U = detail::uncvref_t<CompatibleType>, - detail::enable_if_t < - !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 > - basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape) - JSONSerializer<U>::to_json(std::declval<basic_json_t&>(), - std::forward<CompatibleType>(val)))) - { - JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val)); - set_parents(); - assert_invariant(); - } - - /*! - @brief create a JSON value from an existing one - - This is a constructor for existing @ref basic_json types. - It does not hijack copy/move constructors, since the parameter has different - template arguments than the current ones. - - The constructor tries to convert the internal @ref m_value of the parameter. - - @tparam BasicJsonType a type such that: - - @a BasicJsonType is a @ref basic_json type. - - @a BasicJsonType has different template arguments than @ref basic_json_t. - - @param[in] val the @ref basic_json value to be converted. - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety Depends on the called constructor. For types directly - supported by the library (i.e., all types for which no `to_json()` function - was provided), strong guarantee holds: if an exception is thrown, there are - no changes to any JSON value. - - @since version 3.2.0 - */ - template < typename BasicJsonType, - detail::enable_if_t < - detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 > - basic_json(const BasicJsonType& val) - { - using other_boolean_t = typename BasicJsonType::boolean_t; - using other_number_float_t = typename BasicJsonType::number_float_t; - using other_number_integer_t = typename BasicJsonType::number_integer_t; - using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using other_string_t = typename BasicJsonType::string_t; - using other_object_t = typename BasicJsonType::object_t; - using other_array_t = typename BasicJsonType::array_t; - using other_binary_t = typename BasicJsonType::binary_t; - - switch (val.type()) - { - case value_t::boolean: - JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>()); - break; - case value_t::number_float: - JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>()); - break; - case value_t::number_integer: - JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>()); - break; - case value_t::number_unsigned: - JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>()); - break; - case value_t::string: - JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>()); - break; - case value_t::object: - JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>()); - break; - case value_t::array: - JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>()); - break; - case value_t::binary: - JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>()); - break; - case value_t::null: - *this = nullptr; - break; - case value_t::discarded: - m_type = value_t::discarded; - break; - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - set_parents(); - assert_invariant(); - } - - /*! - @brief create a container (array or object) from an initializer list - - Creates a JSON value of type array or object from the passed initializer - list @a init. In case @a type_deduction is `true` (default), the type of - the JSON value to be created is deducted from the initializer list @a init - according to the following rules: - - 1. If the list is empty, an empty JSON object value `{}` is created. - 2. If the list consists of pairs whose first element is a string, a JSON - object value is created where the first elements of the pairs are - treated as keys and the second elements are as values. - 3. In all other cases, an array is created. - - The rules aim to create the best fit between a C++ initializer list and - JSON values. The rationale is as follows: - - 1. The empty initializer list is written as `{}` which is exactly an empty - JSON object. - 2. C++ has no way of describing mapped types other than to list a list of - pairs. As JSON requires that keys must be of type string, rule 2 is the - weakest constraint one can pose on initializer lists to interpret them - as an object. - 3. In all other cases, the initializer list could not be interpreted as - JSON object type, so interpreting it as JSON array type is safe. - - With the rules described above, the following JSON values cannot be - expressed by an initializer list: - - - the empty array (`[]`): use @ref array(initializer_list_t) - with an empty initializer list in this case - - arrays whose elements satisfy rule 2: use @ref - array(initializer_list_t) with the same initializer list - in this case - - @note When used without parentheses around an empty initializer list, @ref - basic_json() is called instead of this function, yielding the JSON null - value. - - @param[in] init initializer list with JSON values - - @param[in] type_deduction internal parameter; when set to `true`, the type - of the JSON value is deducted from the initializer list @a init; when set - to `false`, the type provided via @a manual_type is forced. This mode is - used by the functions @ref array(initializer_list_t) and - @ref object(initializer_list_t). - - @param[in] manual_type internal parameter; when @a type_deduction is set - to `false`, the created JSON value will use the provided type (only @ref - value_t::array and @ref value_t::object are valid); when @a type_deduction - is set to `true`, this parameter has no effect - - @throw type_error.301 if @a type_deduction is `false`, @a manual_type is - `value_t::object`, but @a init contains an element which is not a pair - whose first element is a string. In this case, the constructor could not - create an object. If @a type_deduction would have be `true`, an array - would have been created. See @ref object(initializer_list_t) - for an example. - - @complexity Linear in the size of the initializer list @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows how JSON values are created from - initializer lists.,basic_json__list_init_t} - - @sa see @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - @sa see @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ - basic_json(initializer_list_t init, - bool type_deduction = true, - value_t manual_type = value_t::array) - { - // check if each element is an array with two elements whose first - // element is a string - bool is_an_object = std::all_of(init.begin(), init.end(), - [](const detail::json_ref<basic_json>& element_ref) - { - return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string(); - }); - - // adjust type if type deduction is not wanted - if (!type_deduction) - { - // if array is wanted, do not create an object though possible - if (manual_type == value_t::array) - { - is_an_object = false; - } - - // if object is wanted but impossible, throw an exception - if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object)) - { - JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json())); - } - } - - if (is_an_object) - { - // the initializer list is a list of pairs -> create object - m_type = value_t::object; - m_value = value_t::object; - - for (auto& element_ref : init) - { - auto element = element_ref.moved_or_copied(); - m_value.object->emplace( - std::move(*((*element.m_value.array)[0].m_value.string)), - std::move((*element.m_value.array)[1])); - } - } - else - { - // the initializer list describes an array -> create array - m_type = value_t::array; - m_value.array = create<array_t>(init.begin(), init.end()); - } - - set_parents(); - assert_invariant(); - } - - /*! - @brief explicitly create a binary array (without subtype) - - Creates a JSON binary array value from a given binary container. Binary - values are part of various binary formats, such as CBOR, MessagePack, and - BSON. This constructor is used to create a value for serialization to those - formats. - - @note Note, this function exists because of the difficulty in correctly - specifying the correct template overload in the standard value ctor, as both - JSON arrays and JSON binary arrays are backed with some form of a - `std::vector`. Because JSON binary arrays are a non-standard extension it - was decided that it would be best to prevent automatic initialization of a - binary array type, for backwards compatibility and so it does not happen on - accident. - - @param[in] init container containing bytes to use as binary type - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(const typename binary_t::container_type& init) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = init; - return res; - } - - /*! - @brief explicitly create a binary array (with subtype) - - Creates a JSON binary array value from a given binary container. Binary - values are part of various binary formats, such as CBOR, MessagePack, and - BSON. This constructor is used to create a value for serialization to those - formats. - - @note Note, this function exists because of the difficulty in correctly - specifying the correct template overload in the standard value ctor, as both - JSON arrays and JSON binary arrays are backed with some form of a - `std::vector`. Because JSON binary arrays are a non-standard extension it - was decided that it would be best to prevent automatic initialization of a - binary array type, for backwards compatibility and so it does not happen on - accident. - - @param[in] init container containing bytes to use as binary type - @param[in] subtype subtype to use in MessagePack and BSON - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = binary_t(init, subtype); - return res; - } - - /// @copydoc binary(const typename binary_t::container_type&) - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(typename binary_t::container_type&& init) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = std::move(init); - return res; - } - - /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type) - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype) - { - auto res = basic_json(); - res.m_type = value_t::binary; - res.m_value = binary_t(std::move(init), subtype); - return res; - } - - /*! - @brief explicitly create an array from an initializer list - - Creates a JSON array value from a given initializer list. That is, given a - list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the - initializer list is empty, the empty array `[]` is created. - - @note This function is only needed to express two edge cases that cannot - be realized with the initializer list constructor (@ref - basic_json(initializer_list_t, bool, value_t)). These cases - are: - 1. creating an array whose elements are all pairs whose first element is a - string -- in this case, the initializer list constructor would create an - object, taking the first elements as keys - 2. creating an empty array -- passing the empty initializer list to the - initializer list constructor yields an empty object - - @param[in] init initializer list with JSON values to create an array from - (optional) - - @return JSON array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `array` - function.,array} - - @sa see @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa see @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json array(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::array); - } - - /*! - @brief explicitly create an object from an initializer list - - Creates a JSON object value from a given initializer list. The initializer - lists elements must be pairs, and their first elements must be strings. If - the initializer list is empty, the empty object `{}` is created. - - @note This function is only added for symmetry reasons. In contrast to the - related function @ref array(initializer_list_t), there are - no cases which can only be expressed by this function. That is, any - initializer list @a init can also be passed to the initializer list - constructor @ref basic_json(initializer_list_t, bool, value_t). - - @param[in] init initializer list to create an object from (optional) - - @return JSON object value - - @throw type_error.301 if @a init is not a list of pairs whose first - elements are strings. In this case, no object can be created. When such a - value is passed to @ref basic_json(initializer_list_t, bool, value_t), - an array would have been created from the passed initializer list @a init. - See example below. - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `object` - function.,object} - - @sa see @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa see @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json object(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::object); - } - - /*! - @brief construct an array with count copies of given value - - Constructs a JSON array value by creating @a cnt copies of a passed value. - In case @a cnt is `0`, an empty array is created. - - @param[in] cnt the number of JSON copies of @a val to create - @param[in] val the JSON value to copy - - @post `std::distance(begin(),end()) == cnt` holds. - - @complexity Linear in @a cnt. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows examples for the @ref - basic_json(size_type\, const basic_json&) - constructor.,basic_json__size_type_basic_json} - - @since version 1.0.0 - */ - basic_json(size_type cnt, const basic_json& val) - : m_type(value_t::array) - { - m_value.array = create<array_t>(cnt, val); - set_parents(); - assert_invariant(); - } - - /*! - @brief construct a JSON container given an iterator range - - Constructs the JSON value with the contents of the range `[first, last)`. - The semantics depends on the different types a JSON value can have: - - In case of a null type, invalid_iterator.206 is thrown. - - In case of other primitive types (number, boolean, or string), @a first - must be `begin()` and @a last must be `end()`. In this case, the value is - copied. Otherwise, invalid_iterator.204 is thrown. - - In case of structured types (array, object), the constructor behaves as - similar versions for `std::vector` or `std::map`; that is, a JSON array - or object is constructed from the values in the range. - - @tparam InputIT an input iterator type (@ref iterator or @ref - const_iterator) - - @param[in] first begin of the range to copy from (included) - @param[in] last end of the range to copy from (excluded) - - @pre Iterators @a first and @a last must be initialized. **This - precondition is enforced with an assertion (see warning).** If - assertions are switched off, a violation of this precondition yields - undefined behavior. - - @pre Range `[first, last)` is valid. Usually, this precondition cannot be - checked efficiently. Only certain edge cases are detected; see the - description of the exceptions below. A violation of this precondition - yields undefined behavior. - - @warning A precondition is enforced with a runtime assertion that will - result in calling `std::abort` if this precondition is not met. - Assertions can be disabled by defining `NDEBUG` at compile time. - See https://en.cppreference.com/w/cpp/error/assert for more - information. - - @throw invalid_iterator.201 if iterators @a first and @a last are not - compatible (i.e., do not belong to the same JSON value). In this case, - the range `[first, last)` is undefined. - @throw invalid_iterator.204 if iterators @a first and @a last belong to a - primitive type (number, boolean, or string), but @a first does not point - to the first element any more. In this case, the range `[first, last)` is - undefined. See example code below. - @throw invalid_iterator.206 if iterators @a first and @a last belong to a - null value. In this case, the range `[first, last)` is undefined. - - @complexity Linear in distance between @a first and @a last. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows several ways to create JSON values by - specifying a subrange with iterators.,basic_json__InputIt_InputIt} - - @since version 1.0.0 - */ - template < class InputIT, typename std::enable_if < - std::is_same<InputIT, typename basic_json_t::iterator>::value || - std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 > - basic_json(InputIT first, InputIT last) - { - JSON_ASSERT(first.m_object != nullptr); - JSON_ASSERT(last.m_object != nullptr); - - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json())); - } - - // copy type from first iterator - m_type = first.m_object->m_type; - - // check if iterator range is complete for primitive values - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - { - if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) - { - JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object)); - } - break; - } - - case value_t::null: - case value_t::object: - case value_t::array: - case value_t::binary: - case value_t::discarded: - default: - break; - } - - switch (m_type) - { - case value_t::number_integer: - { - m_value.number_integer = first.m_object->m_value.number_integer; - break; - } - - case value_t::number_unsigned: - { - m_value.number_unsigned = first.m_object->m_value.number_unsigned; - break; - } - - case value_t::number_float: - { - m_value.number_float = first.m_object->m_value.number_float; - break; - } - - case value_t::boolean: - { - m_value.boolean = first.m_object->m_value.boolean; - break; - } - - case value_t::string: - { - m_value = *first.m_object->m_value.string; - break; - } - - case value_t::object: - { - m_value.object = create<object_t>(first.m_it.object_iterator, - last.m_it.object_iterator); - break; - } - - case value_t::array: - { - m_value.array = create<array_t>(first.m_it.array_iterator, - last.m_it.array_iterator); - break; - } - - case value_t::binary: - { - m_value = *first.m_object->m_value.binary; - break; - } - - case value_t::null: - case value_t::discarded: - default: - JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object)); - } - - set_parents(); - assert_invariant(); - } - - - /////////////////////////////////////// - // other constructors and destructor // - /////////////////////////////////////// - - template<typename JsonRef, - detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>, - std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 > - basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {} - - /*! - @brief copy constructor - - Creates a copy of a given JSON value. - - @param[in] other the JSON value to copy - - @post `*this == other` - - @complexity Linear in the size of @a other. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - As postcondition, it holds: `other == basic_json(other)`. - - @liveexample{The following code shows an example for the copy - constructor.,basic_json__basic_json} - - @since version 1.0.0 - */ - basic_json(const basic_json& other) - : m_type(other.m_type) - { - // check of passed value is valid - other.assert_invariant(); - - switch (m_type) - { - case value_t::object: - { - m_value = *other.m_value.object; - break; - } - - case value_t::array: - { - m_value = *other.m_value.array; - break; - } - - case value_t::string: - { - m_value = *other.m_value.string; - break; - } - - case value_t::boolean: - { - m_value = other.m_value.boolean; - break; - } - - case value_t::number_integer: - { - m_value = other.m_value.number_integer; - break; - } - - case value_t::number_unsigned: - { - m_value = other.m_value.number_unsigned; - break; - } - - case value_t::number_float: - { - m_value = other.m_value.number_float; - break; - } - - case value_t::binary: - { - m_value = *other.m_value.binary; - break; - } - - case value_t::null: - case value_t::discarded: - default: - break; - } - - set_parents(); - assert_invariant(); - } - - /*! - @brief move constructor - - Move constructor. Constructs a JSON value with the contents of the given - value @a other using move semantics. It "steals" the resources from @a - other and leaves it as JSON null value. - - @param[in,out] other value to move to this object - - @post `*this` has the same value as @a other before the call. - @post @a other is a JSON null value. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @requirement This function helps `basic_json` satisfying the - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible) - requirements. - - @liveexample{The code below shows the move constructor explicitly called - via std::move.,basic_json__moveconstructor} - - @since version 1.0.0 - */ - basic_json(basic_json&& other) noexcept - : m_type(std::move(other.m_type)), - m_value(std::move(other.m_value)) - { - // check that passed value is valid - other.assert_invariant(false); - - // invalidate payload - other.m_type = value_t::null; - other.m_value = {}; - - set_parents(); - assert_invariant(); - } - - /*! - @brief copy assignment - - Copy assignment operator. Copies a JSON value via the "copy and swap" - strategy: It is expressed in terms of the copy constructor, destructor, - and the `swap()` member function. - - @param[in] other value to copy from - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - @liveexample{The code below shows and example for the copy assignment. It - creates a copy of value `a` which is then swapped with `b`. Finally\, the - copy of `a` (which is the null value after the swap) is - destroyed.,basic_json__copyassignment} - - @since version 1.0.0 - */ - basic_json& operator=(basic_json other) noexcept ( - std::is_nothrow_move_constructible<value_t>::value&& - std::is_nothrow_move_assignable<value_t>::value&& - std::is_nothrow_move_constructible<json_value>::value&& - std::is_nothrow_move_assignable<json_value>::value - ) - { - // check that passed value is valid - other.assert_invariant(); - - using std::swap; - swap(m_type, other.m_type); - swap(m_value, other.m_value); - - set_parents(); - assert_invariant(); - return *this; - } - - /*! - @brief destructor - - Destroys the JSON value and frees all allocated memory. - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - All stored elements are destroyed and all memory is freed. - - @since version 1.0.0 - */ - ~basic_json() noexcept - { - assert_invariant(false); - m_value.destroy(m_type); - } - - /// @} - - public: - /////////////////////// - // object inspection // - /////////////////////// - - /// @name object inspection - /// Functions to inspect the type of a JSON value. - /// @{ - - /*! - @brief serialization - - Serialization function for JSON values. The function tries to mimic - Python's `json.dumps()` function, and currently supports its @a indent - and @a ensure_ascii parameters. - - @param[in] indent If indent is nonnegative, then array elements and object - members will be pretty-printed with that indent level. An indent level of - `0` will only insert newlines. `-1` (the default) selects the most compact - representation. - @param[in] indent_char The character to use for indentation if @a indent is - greater than `0`. The default is ` ` (space). - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] error_handler how to react on decoding errors; there are three - possible values: `strict` (throws and exception in case a decoding error - occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD), - and `ignore` (ignore invalid UTF-8 sequences during serialization; all - bytes are copied to the output unchanged). - - @return string containing the serialization of the JSON value - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded and @a error_handler is set to strict - - @note Binary values are serialized as object containing two keys: - - "bytes": an array of bytes as integers - - "subtype": the subtype as integer or "null" if the binary has no subtype - - @complexity Linear. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @liveexample{The following example shows the effect of different @a indent\, - @a indent_char\, and @a ensure_ascii parameters to the result of the - serialization.,dump} - - @see https://docs.python.org/2/library/json.html#json.dump - - @since version 1.0.0; indentation character @a indent_char, option - @a ensure_ascii and exceptions added in version 3.0.0; error - handlers added in version 3.4.0; serialization of binary values added - in version 3.8.0. - */ - string_t dump(const int indent = -1, - const char indent_char = ' ', - const bool ensure_ascii = false, - const error_handler_t error_handler = error_handler_t::strict) const - { - string_t result; - serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler); - - if (indent >= 0) - { - s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent)); - } - else - { - s.dump(*this, false, ensure_ascii, 0); - } - - return result; - } - - /*! - @brief return the type of the JSON value (explicit) - - Return the type of the JSON value as a value from the @ref value_t - enumeration. - - @return the type of the JSON value - Value type | return value - ------------------------- | ------------------------- - null | value_t::null - boolean | value_t::boolean - string | value_t::string - number (integer) | value_t::number_integer - number (unsigned integer) | value_t::number_unsigned - number (floating-point) | value_t::number_float - object | value_t::object - array | value_t::array - binary | value_t::binary - discarded | value_t::discarded - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `type()` for all JSON - types.,type} - - @sa see @ref operator value_t() -- return the type of the JSON value (implicit) - @sa see @ref type_name() -- return the type as string - - @since version 1.0.0 - */ - constexpr value_t type() const noexcept - { - return m_type; - } - - /*! - @brief return whether type is primitive - - This function returns true if and only if the JSON type is primitive - (string, number, boolean, or null). - - @return `true` if type is primitive (string, number, boolean, or null), - `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_primitive()` for all JSON - types.,is_primitive} - - @sa see @ref is_structured() -- returns whether JSON value is structured - @sa see @ref is_null() -- returns whether JSON value is `null` - @sa see @ref is_string() -- returns whether JSON value is a string - @sa see @ref is_boolean() -- returns whether JSON value is a boolean - @sa see @ref is_number() -- returns whether JSON value is a number - @sa see @ref is_binary() -- returns whether JSON value is a binary array - - @since version 1.0.0 - */ - constexpr bool is_primitive() const noexcept - { - return is_null() || is_string() || is_boolean() || is_number() || is_binary(); - } - - /*! - @brief return whether type is structured - - This function returns true if and only if the JSON type is structured - (array or object). - - @return `true` if type is structured (array or object), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_structured()` for all JSON - types.,is_structured} - - @sa see @ref is_primitive() -- returns whether value is primitive - @sa see @ref is_array() -- returns whether value is an array - @sa see @ref is_object() -- returns whether value is an object - - @since version 1.0.0 - */ - constexpr bool is_structured() const noexcept - { - return is_array() || is_object(); - } - - /*! - @brief return whether value is null - - This function returns true if and only if the JSON value is null. - - @return `true` if type is null, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_null()` for all JSON - types.,is_null} - - @since version 1.0.0 - */ - constexpr bool is_null() const noexcept - { - return m_type == value_t::null; - } - - /*! - @brief return whether value is a boolean - - This function returns true if and only if the JSON value is a boolean. - - @return `true` if type is boolean, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_boolean()` for all JSON - types.,is_boolean} - - @since version 1.0.0 - */ - constexpr bool is_boolean() const noexcept - { - return m_type == value_t::boolean; - } - - /*! - @brief return whether value is a number - - This function returns true if and only if the JSON value is a number. This - includes both integer (signed and unsigned) and floating-point values. - - @return `true` if type is number (regardless whether integer, unsigned - integer or floating-type), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number()` for all JSON - types.,is_number} - - @sa see @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ - constexpr bool is_number() const noexcept - { - return is_number_integer() || is_number_float(); - } - - /*! - @brief return whether value is an integer number - - This function returns true if and only if the JSON value is a signed or - unsigned integer number. This excludes floating-point values. - - @return `true` if type is an integer or unsigned integer number, `false` - otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_integer()` for all - JSON types.,is_number_integer} - - @sa see @ref is_number() -- check if value is a number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ - constexpr bool is_number_integer() const noexcept - { - return m_type == value_t::number_integer || m_type == value_t::number_unsigned; - } - - /*! - @brief return whether value is an unsigned integer number - - This function returns true if and only if the JSON value is an unsigned - integer number. This excludes floating-point and signed integer values. - - @return `true` if type is an unsigned integer number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_unsigned()` for all - JSON types.,is_number_unsigned} - - @sa see @ref is_number() -- check if value is a number - @sa see @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 2.0.0 - */ - constexpr bool is_number_unsigned() const noexcept - { - return m_type == value_t::number_unsigned; - } - - /*! - @brief return whether value is a floating-point number - - This function returns true if and only if the JSON value is a - floating-point number. This excludes signed and unsigned integer values. - - @return `true` if type is a floating-point number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_float()` for all - JSON types.,is_number_float} - - @sa see @ref is_number() -- check if value is number - @sa see @ref is_number_integer() -- check if value is an integer number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - - @since version 1.0.0 - */ - constexpr bool is_number_float() const noexcept - { - return m_type == value_t::number_float; - } - - /*! - @brief return whether value is an object - - This function returns true if and only if the JSON value is an object. - - @return `true` if type is object, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_object()` for all JSON - types.,is_object} - - @since version 1.0.0 - */ - constexpr bool is_object() const noexcept - { - return m_type == value_t::object; - } - - /*! - @brief return whether value is an array - - This function returns true if and only if the JSON value is an array. - - @return `true` if type is array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_array()` for all JSON - types.,is_array} - - @since version 1.0.0 - */ - constexpr bool is_array() const noexcept - { - return m_type == value_t::array; - } - - /*! - @brief return whether value is a string - - This function returns true if and only if the JSON value is a string. - - @return `true` if type is string, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_string()` for all JSON - types.,is_string} - - @since version 1.0.0 - */ - constexpr bool is_string() const noexcept - { - return m_type == value_t::string; - } - - /*! - @brief return whether value is a binary array - - This function returns true if and only if the JSON value is a binary array. - - @return `true` if type is binary array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_binary()` for all JSON - types.,is_binary} - - @since version 3.8.0 - */ - constexpr bool is_binary() const noexcept - { - return m_type == value_t::binary; - } - - /*! - @brief return whether value is discarded - - This function returns true if and only if the JSON value was discarded - during parsing with a callback function (see @ref parser_callback_t). - - @note This function will always be `false` for JSON values after parsing. - That is, discarded values can only occur during parsing, but will be - removed when inside a structured value or replaced by null in other cases. - - @return `true` if type is discarded, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_discarded()` for all JSON - types.,is_discarded} - - @since version 1.0.0 - */ - constexpr bool is_discarded() const noexcept - { - return m_type == value_t::discarded; - } - - /*! - @brief return the type of the JSON value (implicit) - - Implicitly return the type of the JSON value as a value from the @ref - value_t enumeration. - - @return the type of the JSON value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies the @ref value_t operator for - all JSON types.,operator__value_t} - - @sa see @ref type() -- return the type of the JSON value (explicit) - @sa see @ref type_name() -- return the type as string - - @since version 1.0.0 - */ - constexpr operator value_t() const noexcept - { - return m_type; - } - - /// @} - - private: - ////////////////// - // value access // - ////////////////// - - /// get a boolean (explicit) - boolean_t get_impl(boolean_t* /*unused*/) const - { - if (JSON_HEDLEY_LIKELY(is_boolean())) - { - return m_value.boolean; - } - - JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this)); - } - - /// get a pointer to the value (object) - object_t* get_impl_ptr(object_t* /*unused*/) noexcept - { - return is_object() ? m_value.object : nullptr; - } - - /// get a pointer to the value (object) - constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept - { - return is_object() ? m_value.object : nullptr; - } - - /// get a pointer to the value (array) - array_t* get_impl_ptr(array_t* /*unused*/) noexcept - { - return is_array() ? m_value.array : nullptr; - } - - /// get a pointer to the value (array) - constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept - { - return is_array() ? m_value.array : nullptr; - } - - /// get a pointer to the value (string) - string_t* get_impl_ptr(string_t* /*unused*/) noexcept - { - return is_string() ? m_value.string : nullptr; - } - - /// get a pointer to the value (string) - constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept - { - return is_string() ? m_value.string : nullptr; - } - - /// get a pointer to the value (boolean) - boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept - { - return is_boolean() ? &m_value.boolean : nullptr; - } - - /// get a pointer to the value (boolean) - constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept - { - return is_boolean() ? &m_value.boolean : nullptr; - } - - /// get a pointer to the value (integer number) - number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept - { - return is_number_integer() ? &m_value.number_integer : nullptr; - } - - /// get a pointer to the value (integer number) - constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept - { - return is_number_integer() ? &m_value.number_integer : nullptr; - } - - /// get a pointer to the value (unsigned number) - number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept - { - return is_number_unsigned() ? &m_value.number_unsigned : nullptr; - } - - /// get a pointer to the value (unsigned number) - constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept - { - return is_number_unsigned() ? &m_value.number_unsigned : nullptr; - } - - /// get a pointer to the value (floating-point number) - number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept - { - return is_number_float() ? &m_value.number_float : nullptr; - } - - /// get a pointer to the value (floating-point number) - constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept - { - return is_number_float() ? &m_value.number_float : nullptr; - } - - /// get a pointer to the value (binary) - binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept - { - return is_binary() ? m_value.binary : nullptr; - } - - /// get a pointer to the value (binary) - constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept - { - return is_binary() ? m_value.binary : nullptr; - } - - /*! - @brief helper function to implement get_ref() - - This function helps to implement get_ref() without code duplication for - const and non-const overloads - - @tparam ThisType will be deduced as `basic_json` or `const basic_json` - - @throw type_error.303 if ReferenceType does not match underlying value - type of the current JSON - */ - template<typename ReferenceType, typename ThisType> - static ReferenceType get_ref_impl(ThisType& obj) - { - // delegate the call to get_ptr<>() - auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>(); - - if (JSON_HEDLEY_LIKELY(ptr != nullptr)) - { - return *ptr; - } - - JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj)); - } - - public: - /// @name value access - /// Direct access to the stored value of a JSON value. - /// @{ - - /*! - @brief get a pointer value (implicit) - - Implicit pointer access to the internally stored JSON value. No copies are - made. - - @warning Writing data to the pointee of the result yields an undefined - state. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. Enforced by a static - assertion. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{The example below shows how pointers to internal values of a - JSON value can be requested. Note that no type conversions are made and a - `nullptr` is returned if the value and the requested pointer type does not - match.,get_ptr} - - @since version 1.0.0 - */ - template<typename PointerType, typename std::enable_if< - std::is_pointer<PointerType>::value, int>::type = 0> - auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>())) - { - // delegate the call to get_impl_ptr<>() - return get_impl_ptr(static_cast<PointerType>(nullptr)); - } - - /*! - @brief get a pointer value (implicit) - @copydoc get_ptr() - */ - template < typename PointerType, typename std::enable_if < - std::is_pointer<PointerType>::value&& - std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 > - constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>())) - { - // delegate the call to get_impl_ptr<>() const - return get_impl_ptr(static_cast<PointerType>(nullptr)); - } - - private: - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value - which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). - The value is converted by calling the @ref json_serializer<ValueType> - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType ret; - JSONSerializer<ValueType>::from_json(*this, ret); - return ret; - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer<ValueType> has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @ref json_serializer<ValueType> does not have a `from_json()` method of - the form `ValueType from_json(const basic_json&)` - - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @a ValueType - - @throw what @ref json_serializer<ValueType> `from_json()` method throws - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector<short>`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map<std::string\, - json>`.,get__ValueType_const} - - @since version 2.1.0 - */ - template < typename ValueType, - detail::enable_if_t < - detail::is_default_constructible<ValueType>::value&& - detail::has_from_json<basic_json_t, ValueType>::value, - int > = 0 > - ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept( - JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>()))) - { - auto ret = ValueType(); - JSONSerializer<ValueType>::from_json(*this, ret); - return ret; - } - - /*! - @brief get a value (explicit); special case - - Explicit type conversion between the JSON value and a compatible value - which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). - The value is converted by calling the @ref json_serializer<ValueType> - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - return JSONSerializer<ValueType>::from_json(*this); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json and - - @ref json_serializer<ValueType> has a `from_json()` method of the form - `ValueType from_json(const basic_json&)` - - @note If @ref json_serializer<ValueType> has both overloads of - `from_json()`, this one is chosen. - - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @a ValueType - - @throw what @ref json_serializer<ValueType> `from_json()` method throws - - @since version 2.1.0 - */ - template < typename ValueType, - detail::enable_if_t < - detail::has_non_default_from_json<basic_json_t, ValueType>::value, - int > = 0 > - ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept( - JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>()))) - { - return JSONSerializer<ValueType>::from_json(*this); - } - - /*! - @brief get special-case overload - - This overloads converts the current @ref basic_json in a different - @ref basic_json type - - @tparam BasicJsonType == @ref basic_json - - @return a copy of *this, converted into @a BasicJsonType - - @complexity Depending on the implementation of the called `from_json()` - method. - - @since version 3.2.0 - */ - template < typename BasicJsonType, - detail::enable_if_t < - detail::is_basic_json<BasicJsonType>::value, - int > = 0 > - BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const - { - return *this; - } - - /*! - @brief get special-case overload - - This overloads avoids a lot of template boilerplate, it can be seen as the - identity method - - @tparam BasicJsonType == @ref basic_json - - @return a copy of *this - - @complexity Constant. - - @since version 2.1.0 - */ - template<typename BasicJsonType, - detail::enable_if_t< - std::is_same<BasicJsonType, basic_json_t>::value, - int> = 0> - basic_json get_impl(detail::priority_tag<3> /*unused*/) const - { - return *this; - } - - /*! - @brief get a pointer value (explicit) - @copydoc get() - */ - template<typename PointerType, - detail::enable_if_t< - std::is_pointer<PointerType>::value, - int> = 0> - constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept - -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>()) - { - // delegate the call to get_ptr - return get_ptr<PointerType>(); - } - - public: - /*! - @brief get a (pointer) value (explicit) - - Performs explicit type conversion between the JSON value and a compatible value if required. - - - If the requested type is a pointer to the internally stored JSON value that pointer is returned. - No copies are made. - - - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible - from the current @ref basic_json. - - - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()` - method. - - @tparam ValueTypeCV the provided value type - @tparam ValueType the returned value type - - @return copy of the JSON value, converted to @tparam ValueType if necessary - - @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required - - @since version 2.1.0 - */ - template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>> -#if defined(JSON_HAS_CPP_14) - constexpr -#endif - auto get() const noexcept( - noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))) - -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})) - { - // we cannot static_assert on ValueTypeCV being non-const, because - // there is support for get<const basic_json_t>(), which is why we - // still need the uncvref - static_assert(!std::is_reference<ValueTypeCV>::value, - "get() cannot be used with reference types, you might want to use get_ref()"); - return get_impl<ValueType>(detail::priority_tag<4> {}); - } - - /*! - @brief get a pointer value (explicit) - - Explicit pointer access to the internally stored JSON value. No copies are - made. - - @warning The pointer becomes invalid if the underlying JSON object - changes. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{The example below shows how pointers to internal values of a - JSON value can be requested. Note that no type conversions are made and a - `nullptr` is returned if the value and the requested pointer type does not - match.,get__PointerType} - - @sa see @ref get_ptr() for explicit pointer-member access - - @since version 1.0.0 - */ - template<typename PointerType, typename std::enable_if< - std::is_pointer<PointerType>::value, int>::type = 0> - auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>()) - { - // delegate the call to get_ptr - return get_ptr<PointerType>(); - } - - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value. - The value is filled into the input parameter by calling the @ref json_serializer<ValueType> - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType v; - JSONSerializer<ValueType>::from_json(*this, v); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer<ValueType> has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @tparam ValueType the input parameter type. - - @return the input parameter, allowing chaining calls. - - @throw what @ref json_serializer<ValueType> `from_json()` method throws - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector<short>`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map<std::string\, - json>`.,get_to} - - @since version 3.3.0 - */ - template < typename ValueType, - detail::enable_if_t < - !detail::is_basic_json<ValueType>::value&& - detail::has_from_json<basic_json_t, ValueType>::value, - int > = 0 > - ValueType & get_to(ValueType& v) const noexcept(noexcept( - JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v))) - { - JSONSerializer<ValueType>::from_json(*this, v); - return v; - } - - // specialization to allow to call get_to with a basic_json value - // see https://github.com/nlohmann/json/issues/2175 - template<typename ValueType, - detail::enable_if_t < - detail::is_basic_json<ValueType>::value, - int> = 0> - ValueType & get_to(ValueType& v) const - { - v = *this; - return v; - } - - template < - typename T, std::size_t N, - typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - detail::enable_if_t < - detail::has_from_json<basic_json_t, Array>::value, int > = 0 > - Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - noexcept(noexcept(JSONSerializer<Array>::from_json( - std::declval<const basic_json_t&>(), v))) - { - JSONSerializer<Array>::from_json(*this, v); - return v; - } - - /*! - @brief get a reference value (implicit) - - Implicit reference access to the internally stored JSON value. No copies - are made. - - @warning Writing data to the referee of the result yields an undefined - state. - - @tparam ReferenceType reference type; must be a reference to @ref array_t, - @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or - @ref number_float_t. Enforced by static assertion. - - @return reference to the internally stored JSON value if the requested - reference type @a ReferenceType fits to the JSON value; throws - type_error.303 otherwise - - @throw type_error.303 in case passed type @a ReferenceType is incompatible - with the stored JSON value; see example below - - @complexity Constant. - - @liveexample{The example shows several calls to `get_ref()`.,get_ref} - - @since version 1.1.0 - */ - template<typename ReferenceType, typename std::enable_if< - std::is_reference<ReferenceType>::value, int>::type = 0> - ReferenceType get_ref() - { - // delegate call to get_ref_impl - return get_ref_impl<ReferenceType>(*this); - } - - /*! - @brief get a reference value (implicit) - @copydoc get_ref() - */ - template < typename ReferenceType, typename std::enable_if < - std::is_reference<ReferenceType>::value&& - std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 > - ReferenceType get_ref() const - { - // delegate call to get_ref_impl - return get_ref_impl<ReferenceType>(*this); - } - - /*! - @brief get a value (implicit) - - Implicit type conversion between the JSON value and a compatible value. - The call is realized by calling @ref get() const. - - @tparam ValueType non-pointer type compatible to the JSON value, for - instance `int` for JSON integer numbers, `bool` for JSON booleans, or - `std::vector` types for JSON arrays. The character type of @ref string_t - as well as an initializer list of this type is excluded to avoid - ambiguities as these types implicitly convert to `std::string`. - - @return copy of the JSON value, converted to type @a ValueType - - @throw type_error.302 in case passed type @a ValueType is incompatible - to the JSON value type (e.g., the JSON value is of type boolean, but a - string is requested); see example below - - @complexity Linear in the size of the JSON value. - - @liveexample{The example below shows several conversions from JSON values - to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector<short>`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map<std::string\, - json>`.,operator__ValueType} - - @since version 1.0.0 - */ - template < typename ValueType, typename std::enable_if < - detail::conjunction < - detail::negation<std::is_pointer<ValueType>>, - detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>, - detail::negation<std::is_same<ValueType, typename string_t::value_type>>, - detail::negation<detail::is_basic_json<ValueType>>, - detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>, - -#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914)) - detail::negation<std::is_same<ValueType, std::string_view>>, -#endif - detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType> - >::value, int >::type = 0 > - JSON_EXPLICIT operator ValueType() const - { - // delegate the call to get<>() const - return get<ValueType>(); - } - - /*! - @return reference to the binary value - - @throw type_error.302 if the value is not binary - - @sa see @ref is_binary() to check if the value is binary - - @since version 3.8.0 - */ - binary_t& get_binary() - { - if (!is_binary()) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this)); - } - - return *get_ptr<binary_t*>(); - } - - /// @copydoc get_binary() - const binary_t& get_binary() const - { - if (!is_binary()) - { - JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this)); - } - - return *get_ptr<const binary_t*>(); - } - - /// @} - - - //////////////////// - // element access // - //////////////////// - - /// @name element access - /// Access to the JSON value. - /// @{ - - /*! - @brief access specified array element with bounds checking - - Returns a reference to the element at specified location @a idx, with - bounds checking. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.304 if the JSON value is not an array; in this case, - calling `at` with an index makes no sense. See example below. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__size_type} - */ - reference at(size_type idx) - { - // at only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - JSON_TRY - { - return set_parent(m_value.array->at(idx)); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified array element with bounds checking - - Returns a const reference to the element at specified location @a idx, - with bounds checking. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.304 if the JSON value is not an array; in this case, - calling `at` with an index makes no sense. See example below. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__size_type_const} - */ - const_reference at(size_type idx) const - { - // at only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - JSON_TRY - { - return m_value.array->at(idx); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified object element with bounds checking - - Returns a reference to the element at with specified key @a key, with - bounds checking. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.304 if the JSON value is not an object; in this case, - calling `at` with a key makes no sense. See example below. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__object_t_key_type} - */ - reference at(const typename object_t::key_type& key) - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_TRY - { - return set_parent(m_value.object->at(key)); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified object element with bounds checking - - Returns a const reference to the element at with specified key @a key, - with bounds checking. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @throw type_error.304 if the JSON value is not an object; in this case, - calling `at` with a key makes no sense. See example below. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__object_t_key_type_const} - */ - const_reference at(const typename object_t::key_type& key) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_TRY - { - return m_value.object->at(key); - } - JSON_CATCH (std::out_of_range&) - { - // create better exception explanation - JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this)); - } - } - else - { - JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief access specified array element - - Returns a reference to the element at specified location @a idx. - - @note If @a idx is beyond the range of the array (i.e., `idx >= size()`), - then the array is silently filled up with `null` values to make `idx` a - valid reference to the last stored element. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array or null; in that - cases, using the [] operator with an index makes no sense. - - @complexity Constant if @a idx is in the range of the array. Otherwise - linear in `idx - size()`. - - @liveexample{The example below shows how array elements can be read and - written using `[]` operator. Note the addition of `null` - values.,operatorarray__size_type} - - @since version 1.0.0 - */ - reference operator[](size_type idx) - { - // implicitly convert null value to an empty array - if (is_null()) - { - m_type = value_t::array; - m_value.array = create<array_t>(); - assert_invariant(); - } - - // operator[] only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // fill up array with null values if given idx is outside range - if (idx >= m_value.array->size()) - { -#if JSON_DIAGNOSTICS - // remember array size & capacity before resizing - const auto old_size = m_value.array->size(); - const auto old_capacity = m_value.array->capacity(); -#endif - m_value.array->resize(idx + 1); - -#if JSON_DIAGNOSTICS - if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) - { - // capacity has changed: update all parents - set_parents(); - } - else - { - // set parent for values added above - set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size)); - } -#endif - assert_invariant(); - } - - return m_value.array->operator[](idx); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified array element - - Returns a const reference to the element at specified location @a idx. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array; in that case, - using the [] operator with an index makes no sense. - - @complexity Constant. - - @liveexample{The example below shows how array elements can be read using - the `[]` operator.,operatorarray__size_type_const} - - @since version 1.0.0 - */ - const_reference operator[](size_type idx) const - { - // const operator[] only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - return m_value.array->operator[](idx); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a key is not found in the object, then it is silently added to - the object and filled with a `null` value to make `key` a valid reference. - In case the value was `null` before, it is converted to an object. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - */ - reference operator[](const typename object_t::key_type& key) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create<object_t>(); - assert_invariant(); - } - - // operator[] only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return set_parent(m_value.object->operator[](key)); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - */ - const_reference operator[](const typename object_t::key_type& key) const - { - // const operator[] only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_ASSERT(m_value.object->find(key) != m_value.object->end()); - return m_value.object->find(key)->second; - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a key is not found in the object, then it is silently added to - the object and filled with a `null` value to make `key` a valid reference. - In case the value was `null` before, it is converted to an object. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.1.0 - */ - template<typename T> - JSON_HEDLEY_NON_NULL(2) - reference operator[](T* key) - { - // implicitly convert null to object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return set_parent(m_value.object->operator[](key)); - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.1.0 - */ - template<typename T> - JSON_HEDLEY_NON_NULL(2) - const_reference operator[](T* key) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - JSON_ASSERT(m_value.object->find(key) != m_value.object->end()); - return m_value.object->find(key)->second; - } - - JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); - } - - /*! - @brief access specified object element with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(key); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const typename object_t::key_type&), this function - does not throw if the given key @a key was not found. - - @note Unlike @ref operator[](const typename object_t::key_type& key), this - function does not implicitly add an element to the position defined by @a - key. This function is furthermore also applicable to const objects. - - @param[in] key key of the element to access - @param[in] default_value the value to return if @a key is not found - - @tparam ValueType type compatible to JSON values, for instance `int` for - JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for - JSON arrays. Note the type of the expected value at @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a key - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - - @since version 1.0.0 - */ - // using std::is_convertible in a std::enable_if will fail when using explicit conversions - template < class ValueType, typename std::enable_if < - detail::is_getable<basic_json_t, ValueType>::value - && !std::is_same<value_t, ValueType>::value, int >::type = 0 > - ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - // if key is found, return value and given default value otherwise - const auto it = find(key); - if (it != end()) - { - return it->template get<ValueType>(); - } - - return default_value; - } - - JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this)); - } - - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const - */ - string_t value(const typename object_t::key_type& key, const char* default_value) const - { - return value(key, string_t(default_value)); - } - - /*! - @brief access specified object element via JSON Pointer with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(ptr); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const json_pointer&), this function does not throw - if the given key @a key was not found. - - @param[in] ptr a JSON pointer to the element to access - @param[in] default_value the value to return if @a ptr found no value - - @tparam ValueType type compatible to JSON values, for instance `int` for - JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for - JSON arrays. Note the type of the expected value at @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a ptr - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value_ptr} - - @sa see @ref operator[](const json_pointer&) for unchecked access by reference - - @since version 2.0.2 - */ - template<class ValueType, typename std::enable_if< - detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0> - ValueType value(const json_pointer& ptr, const ValueType& default_value) const - { - // at only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - // if pointer resolves a value, return it or use default value - JSON_TRY - { - return ptr.get_checked(this).template get<ValueType>(); - } - JSON_INTERNAL_CATCH (out_of_range&) - { - return default_value; - } - } - - JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this)); - } - - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const json_pointer&, ValueType) const - */ - JSON_HEDLEY_NON_NULL(3) - string_t value(const json_pointer& ptr, const char* default_value) const - { - return value(ptr, string_t(default_value)); - } - - /*! - @brief access the first element - - Returns a reference to the first element in the container. For a JSON - container `c`, the expression `c.front()` is equivalent to `*c.begin()`. - - @return In case of a structured type (array or object), a reference to the - first element is returned. In case of number, string, boolean, or binary - values, a reference to the value is returned. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on `null` value - - @liveexample{The following code shows an example for `front()`.,front} - - @sa see @ref back() -- access the last element - - @since version 1.0.0 - */ - reference front() - { - return *begin(); - } - - /*! - @copydoc basic_json::front() - */ - const_reference front() const - { - return *cbegin(); - } - - /*! - @brief access the last element - - Returns a reference to the last element in the container. For a JSON - container `c`, the expression `c.back()` is equivalent to - @code {.cpp} - auto tmp = c.end(); - --tmp; - return *tmp; - @endcode - - @return In case of a structured type (array or object), a reference to the - last element is returned. In case of number, string, boolean, or binary - values, a reference to the value is returned. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on a `null` value. See example - below. - - @liveexample{The following code shows an example for `back()`.,back} - - @sa see @ref front() -- access the first element - - @since version 1.0.0 - */ - reference back() - { - auto tmp = end(); - --tmp; - return *tmp; - } - - /*! - @copydoc basic_json::back() - */ - const_reference back() const - { - auto tmp = cend(); - --tmp; - return *tmp; - } - - /*! - @brief remove element given an iterator - - Removes the element specified by iterator @a pos. The iterator @a pos must - be valid and dereferenceable. Thus the `end()` iterator (which is valid, - but is not dereferenceable) cannot be used as a value for @a pos. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] pos iterator to the element to remove - @return Iterator following the last removed element. If the iterator @a - pos refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.202 if called on an iterator which does not belong - to the current JSON value; example: `"iterator does not fit current - value"` - @throw invalid_iterator.205 if called on a primitive type with invalid - iterator (i.e., any iterator which is not `begin()`); example: `"iterator - out of range"` - - @complexity The complexity depends on the type: - - objects: amortized constant - - arrays: linear in distance between @a pos and the end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType} - - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - template < class IteratorType, typename std::enable_if < - std::is_same<IteratorType, typename basic_json_t::iterator>::value || - std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type - = 0 > - IteratorType erase(IteratorType pos) - { - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(this != pos.m_object)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - IteratorType result = end(); - - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - case value_t::binary: - { - if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin())) - { - JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this)); - } - - if (is_string()) - { - AllocatorType<string_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1); - m_value.string = nullptr; - } - else if (is_binary()) - { - AllocatorType<binary_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1); - m_value.binary = nullptr; - } - - m_type = value_t::null; - assert_invariant(); - break; - } - - case value_t::object: - { - result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator); - break; - } - - case value_t::array: - { - result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator); - break; - } - - case value_t::null: - case value_t::discarded: - default: - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - - return result; - } - - /*! - @brief remove elements given an iterator range - - Removes the element specified by the range `[first; last)`. The iterator - @a first does not need to be dereferenceable if `first == last`: erasing - an empty range is a no-op. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] first iterator to the beginning of the range to remove - @param[in] last iterator past the end of the range to remove - @return Iterator following the last removed element. If the iterator @a - second refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.203 if called on iterators which does not belong - to the current JSON value; example: `"iterators do not fit current value"` - @throw invalid_iterator.204 if called on a primitive type with invalid - iterators (i.e., if `first != begin()` and `last != end()`); example: - `"iterators out of range"` - - @complexity The complexity depends on the type: - - objects: `log(size()) + std::distance(first, last)` - - arrays: linear in the distance between @a first and @a last, plus linear - in the distance between @a last and end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType_IteratorType} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - template < class IteratorType, typename std::enable_if < - std::is_same<IteratorType, typename basic_json_t::iterator>::value || - std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type - = 0 > - IteratorType erase(IteratorType first, IteratorType last) - { - // make sure iterator fits the current value - if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object)) - { - JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this)); - } - - IteratorType result = end(); - - switch (m_type) - { - case value_t::boolean: - case value_t::number_float: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::string: - case value_t::binary: - { - if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) - { - JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this)); - } - - if (is_string()) - { - AllocatorType<string_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1); - m_value.string = nullptr; - } - else if (is_binary()) - { - AllocatorType<binary_t> alloc; - std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary); - std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1); - m_value.binary = nullptr; - } - - m_type = value_t::null; - assert_invariant(); - break; - } - - case value_t::object: - { - result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator, - last.m_it.object_iterator); - break; - } - - case value_t::array: - { - result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator, - last.m_it.array_iterator); - break; - } - - case value_t::null: - case value_t::discarded: - default: - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - - return result; - } - - /*! - @brief remove element from a JSON object given a key - - Removes elements from a JSON object with the key value @a key. - - @param[in] key value of the elements to remove - - @return Number of elements removed. If @a ObjectType is the default - `std::map` type, the return value will always be `0` (@a key was not - found) or `1` (@a key was found). - - @post References and iterators to the erased elements are invalidated. - Other references and iterators are not affected. - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - - @complexity `log(size()) + count(key)` - - @liveexample{The example shows the effect of `erase()`.,erase__key_type} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ - size_type erase(const typename object_t::key_type& key) - { - // this erase only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - return m_value.object->erase(key); - } - - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - - /*! - @brief remove element from a JSON array given an index - - Removes element from a JSON array at the index @a idx. - - @param[in] idx index of the element to remove - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - @throw out_of_range.401 when `idx >= size()`; example: `"array index 17 - is out of range"` - - @complexity Linear in distance between @a idx and the end of the container. - - @liveexample{The example shows the effect of `erase()`.,erase__size_type} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - - @since version 1.0.0 - */ - void erase(const size_type idx) - { - // this erase only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - if (JSON_HEDLEY_UNLIKELY(idx >= size())) - { - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this)); - } - - m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx)); - } - else - { - JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); - } - } - - /// @} - - - //////////// - // lookup // - //////////// - - /// @name lookup - /// @{ - - /*! - @brief find an element in a JSON object - - Finds an element in a JSON object with key equivalent to @a key. If the - element is not found or the JSON value is not an object, end() is - returned. - - @note This method always returns @ref end() when executed on a JSON type - that is not an object. - - @param[in] key key value of the element to search for. - - @return Iterator to an element with key equivalent to @a key. If no such - element is found or the JSON value is not an object, past-the-end (see - @ref end()) iterator is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `find()` is used.,find__key_type} - - @sa see @ref contains(KeyT&&) const -- checks whether a key exists - - @since version 1.0.0 - */ - template<typename KeyT> - iterator find(KeyT&& key) - { - auto result = end(); - - if (is_object()) - { - result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key)); - } - - return result; - } - - /*! - @brief find an element in a JSON object - @copydoc find(KeyT&&) - */ - template<typename KeyT> - const_iterator find(KeyT&& key) const - { - auto result = cend(); - - if (is_object()) - { - result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key)); - } - - return result; - } - - /*! - @brief returns the number of occurrences of a key in a JSON object - - Returns the number of elements with key @a key. If ObjectType is the - default `std::map` type, the return value will always be `0` (@a key was - not found) or `1` (@a key was found). - - @note This method always returns `0` when executed on a JSON type that is - not an object. - - @param[in] key key value of the element to count - - @return Number of elements with key @a key. If the JSON value is not an - object, the return value will be `0`. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `count()` is used.,count} - - @since version 1.0.0 - */ - template<typename KeyT> - size_type count(KeyT&& key) const - { - // return 0 for all nonobject types - return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0; - } - - /*! - @brief check the existence of an element in a JSON object - - Check whether an element exists in a JSON object with key equivalent to - @a key. If the element is not found or the JSON value is not an object, - false is returned. - - @note This method always returns false when executed on a JSON type - that is not an object. - - @param[in] key key value to check its existence. - - @return true if an element with specified @a key exists. If no such - element with such key is found or the JSON value is not an object, - false is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains} - - @sa see @ref find(KeyT&&) -- returns an iterator to an object element - @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer - - @since version 3.6.0 - */ - template < typename KeyT, typename std::enable_if < - !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 > - bool contains(KeyT && key) const - { - return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end(); - } - - /*! - @brief check the existence of an element in a JSON object given a JSON pointer - - Check whether the given JSON pointer @a ptr can be resolved in the current - JSON value. - - @note This method can be executed on any JSON value type. - - @param[in] ptr JSON pointer to check its existence. - - @return true if the JSON pointer can be resolved to a stored value, false - otherwise. - - @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains_json_pointer} - - @sa see @ref contains(KeyT &&) const -- checks the existence of a key - - @since version 3.7.0 - */ - bool contains(const json_pointer& ptr) const - { - return ptr.contains(this); - } - - /// @} - - - /////////////// - // iterators // - /////////////// - - /// @name iterators - /// @{ - - /*! - @brief returns an iterator to the first element - - Returns an iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `begin()`.,begin} - - @sa see @ref cbegin() -- returns a const iterator to the beginning - @sa see @ref end() -- returns an iterator to the end - @sa see @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ - iterator begin() noexcept - { - iterator result(this); - result.set_begin(); - return result; - } - - /*! - @copydoc basic_json::cbegin() - */ - const_iterator begin() const noexcept - { - return cbegin(); - } - - /*! - @brief returns a const iterator to the first element - - Returns a const iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast<const basic_json&>(*this).begin()`. - - @liveexample{The following code shows an example for `cbegin()`.,cbegin} - - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref end() -- returns an iterator to the end - @sa see @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ - const_iterator cbegin() const noexcept - { - const_iterator result(this); - result.set_begin(); - return result; - } - - /*! - @brief returns an iterator to one past the last element - - Returns an iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `end()`.,end} - - @sa see @ref cend() -- returns a const iterator to the end - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ - iterator end() noexcept - { - iterator result(this); - result.set_end(); - return result; - } - - /*! - @copydoc basic_json::cend() - */ - const_iterator end() const noexcept - { - return cend(); - } - - /*! - @brief returns a const iterator to one past the last element - - Returns a const iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast<const basic_json&>(*this).end()`. - - @liveexample{The following code shows an example for `cend()`.,cend} - - @sa see @ref end() -- returns an iterator to the end - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ - const_iterator cend() const noexcept - { - const_iterator result(this); - result.set_end(); - return result; - } - - /*! - @brief returns an iterator to the reverse-beginning - - Returns an iterator to the reverse-beginning; that is, the last element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(end())`. - - @liveexample{The following code shows an example for `rbegin()`.,rbegin} - - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - reverse_iterator rbegin() noexcept - { - return reverse_iterator(end()); - } - - /*! - @copydoc basic_json::crbegin() - */ - const_reverse_iterator rbegin() const noexcept - { - return crbegin(); - } - - /*! - @brief returns an iterator to the reverse-end - - Returns an iterator to the reverse-end; that is, one before the first - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(begin())`. - - @liveexample{The following code shows an example for `rend()`.,rend} - - @sa see @ref crend() -- returns a const reverse iterator to the end - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - reverse_iterator rend() noexcept - { - return reverse_iterator(begin()); - } - - /*! - @copydoc basic_json::crend() - */ - const_reverse_iterator rend() const noexcept - { - return crend(); - } - - /*! - @brief returns a const reverse iterator to the last element - - Returns a const iterator to the reverse-beginning; that is, the last - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`. - - @liveexample{The following code shows an example for `crbegin()`.,crbegin} - - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - const_reverse_iterator crbegin() const noexcept - { - return const_reverse_iterator(cend()); - } - - /*! - @brief returns a const reverse iterator to one before the first - - Returns a const reverse iterator to the reverse-end; that is, one before - the first element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast<const basic_json&>(*this).rend()`. - - @liveexample{The following code shows an example for `crend()`.,crend} - - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - const_reverse_iterator crend() const noexcept - { - return const_reverse_iterator(cbegin()); - } - - public: - /*! - @brief wrapper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - iterator::value() during range-based for loops. In these loops, a - reference to the JSON values is returned, so there is no access to the - underlying iterator. - - For loop without iterator_wrapper: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without iterator proxy: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with iterator proxy: - - @code{cpp} - for (auto it : json::iterator_wrapper(j_object)) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). - - @param[in] ref reference to a JSON value - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the wrapper is used,iterator_wrapper} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @note The name of this function is not yet final and may change in the - future. - - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use @ref items() instead; - that is, replace `json::iterator_wrapper(j)` with `j.items()`. - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept - { - return ref.items(); - } - - /*! - @copydoc iterator_wrapper(reference) - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept - { - return ref.items(); - } - - /*! - @brief helper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - iterator::value() during range-based for loops. In these loops, a - reference to the JSON values is returned, so there is no access to the - underlying iterator. - - For loop without `items()` function: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without `items()` function: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with `items()` function: - - @code{cpp} - for (auto& el : j_object.items()) - { - std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; - } - @endcode - - The `items()` function also allows to use - [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) - (C++17): - - @code{cpp} - for (auto& [key, val] : j_object.items()) - { - std::cout << "key: " << key << ", value:" << val << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). For primitive types (e.g., numbers), - `key()` returns an empty string. - - @warning Using `items()` on temporary objects is dangerous. Make sure the - object's lifetime exeeds the iteration. See - <https://github.com/nlohmann/json/issues/2040> for more - information. - - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the function is used.,items} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 3.1.0, structured bindings support since 3.5.0. - */ - iteration_proxy<iterator> items() noexcept - { - return iteration_proxy<iterator>(*this); - } - - /*! - @copydoc items() - */ - iteration_proxy<const_iterator> items() const noexcept - { - return iteration_proxy<const_iterator>(*this); - } - - /// @} - - - ////////////// - // capacity // - ////////////// - - /// @name capacity - /// @{ - - /*! - @brief checks whether the container is empty. - - Checks if a JSON value has no elements (i.e. whether its @ref size is `0`). - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `true` - boolean | `false` - string | `false` - number | `false` - binary | `false` - object | result of function `object_t::empty()` - array | result of function `array_t::empty()` - - @liveexample{The following code uses `empty()` to check if a JSON - object contains any elements.,empty} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `empty()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note This function does not return whether a string stored as JSON value - is empty - it returns whether the JSON container itself is empty which is - false in the case of a string. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `begin() == end()`. - - @sa see @ref size() -- returns the number of elements - - @since version 1.0.0 - */ - bool empty() const noexcept - { - switch (m_type) - { - case value_t::null: - { - // null values are empty - return true; - } - - case value_t::array: - { - // delegate call to array_t::empty() - return m_value.array->empty(); - } - - case value_t::object: - { - // delegate call to object_t::empty() - return m_value.object->empty(); - } - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // all other types are nonempty - return false; - } - } - } - - /*! - @brief returns the number of elements - - Returns the number of elements in a JSON value. - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `0` - boolean | `1` - string | `1` - number | `1` - binary | `1` - object | result of function object_t::size() - array | result of function array_t::size() - - @liveexample{The following code calls `size()` on the different value - types.,size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their size() functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note This function does not return the length of a string stored as JSON - value - it returns the number of elements in the JSON value which is 1 in - the case of a string. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `std::distance(begin(), end())`. - - @sa see @ref empty() -- checks whether the container is empty - @sa see @ref max_size() -- returns the maximal number of elements - - @since version 1.0.0 - */ - size_type size() const noexcept - { - switch (m_type) - { - case value_t::null: - { - // null values are empty - return 0; - } - - case value_t::array: - { - // delegate call to array_t::size() - return m_value.array->size(); - } - - case value_t::object: - { - // delegate call to object_t::size() - return m_value.object->size(); - } - - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // all other types have size 1 - return 1; - } - } - } - - /*! - @brief returns the maximum possible number of elements - - Returns the maximum number of elements a JSON value is able to hold due to - system or library implementation limitations, i.e. `std::distance(begin(), - end())` for the JSON value. - - @return The return value depends on the different types and is - defined as follows: - Value type | return value - ----------- | ------------- - null | `0` (same as `size()`) - boolean | `1` (same as `size()`) - string | `1` (same as `size()`) - number | `1` (same as `size()`) - binary | `1` (same as `size()`) - object | result of function `object_t::max_size()` - array | result of function `array_t::max_size()` - - @liveexample{The following code calls `max_size()` on the different value - types. Note the output is implementation specific.,max_size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `max_size()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of returning `b.size()` where `b` is the largest - possible JSON value. - - @sa see @ref size() -- returns the number of elements - - @since version 1.0.0 - */ - size_type max_size() const noexcept - { - switch (m_type) - { - case value_t::array: - { - // delegate call to array_t::max_size() - return m_value.array->max_size(); - } - - case value_t::object: - { - // delegate call to object_t::max_size() - return m_value.object->max_size(); - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // all other types have max_size() == size() - return size(); - } - } - } - - /// @} - - - /////////////// - // modifiers // - /////////////// - - /// @name modifiers - /// @{ - - /*! - @brief clears the contents - - Clears the content of a JSON value and resets it to the default value as - if @ref basic_json(value_t) would have been called with the current value - type from @ref type(): - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - binary | An empty byte vector - object | `{}` - array | `[]` - - @post Has the same effect as calling - @code {.cpp} - *this = basic_json(type()); - @endcode - - @liveexample{The example below shows the effect of `clear()` to different - JSON types.,clear} - - @complexity Linear in the size of the JSON value. - - @iterators All iterators, pointers and references related to this container - are invalidated. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @sa see @ref basic_json(value_t) -- constructor that creates an object with the - same value than calling `clear()` - - @since version 1.0.0 - */ - void clear() noexcept - { - switch (m_type) - { - case value_t::number_integer: - { - m_value.number_integer = 0; - break; - } - - case value_t::number_unsigned: - { - m_value.number_unsigned = 0; - break; - } - - case value_t::number_float: - { - m_value.number_float = 0.0; - break; - } - - case value_t::boolean: - { - m_value.boolean = false; - break; - } - - case value_t::string: - { - m_value.string->clear(); - break; - } - - case value_t::binary: - { - m_value.binary->clear(); - break; - } - - case value_t::array: - { - m_value.array->clear(); - break; - } - - case value_t::object: - { - m_value.object->clear(); - break; - } - - case value_t::null: - case value_t::discarded: - default: - break; - } - } - - /*! - @brief add an object to an array - - Appends the given element @a val to the end of the JSON value. If the - function is called on a JSON null value, an empty array is created before - appending @a val. - - @param[in] val the value to add to the JSON array - - @throw type_error.308 when called on a type other than JSON array or - null; example: `"cannot use push_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` and `+=` can be used to - add elements to a JSON array. Note how the `null` value was silently - converted to a JSON array.,push_back} - - @since version 1.0.0 - */ - void push_back(basic_json&& val) - { - // push_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array (move semantics) - const auto old_capacity = m_value.array->capacity(); - m_value.array->push_back(std::move(val)); - set_parent(m_value.array->back(), old_capacity); - // if val is moved from, basic_json move constructor marks it null so we do not call the destructor - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - reference operator+=(basic_json&& val) - { - push_back(std::move(val)); - return *this; - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - void push_back(const basic_json& val) - { - // push_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array - const auto old_capacity = m_value.array->capacity(); - m_value.array->push_back(val); - set_parent(m_value.array->back(), old_capacity); - } - - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ - reference operator+=(const basic_json& val) - { - push_back(val); - return *this; - } - - /*! - @brief add an object to an object - - Inserts the given element @a val to the JSON object. If the function is - called on a JSON null value, an empty object is created before inserting - @a val. - - @param[in] val the value to add to the JSON object - - @throw type_error.308 when called on a type other than JSON object or - null; example: `"cannot use push_back() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{The example shows how `push_back()` and `+=` can be used to - add elements to a JSON object. Note how the `null` value was silently - converted to a JSON object.,push_back__object_t__value} - - @since version 1.0.0 - */ - void push_back(const typename object_t::value_type& val) - { - // push_back only works for null objects or objects - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) - { - JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // add element to object - auto res = m_value.object->insert(val); - set_parent(res.first->second); - } - - /*! - @brief add an object to an object - @copydoc push_back(const typename object_t::value_type&) - */ - reference operator+=(const typename object_t::value_type& val) - { - push_back(val); - return *this; - } - - /*! - @brief add an object to an object - - This function allows to use `push_back` with an initializer list. In case - - 1. the current value is an object, - 2. the initializer list @a init contains only two elements, and - 3. the first element of @a init is a string, - - @a init is converted into an object element and added using - @ref push_back(const typename object_t::value_type&). Otherwise, @a init - is converted to a JSON value and added using @ref push_back(basic_json&&). - - @param[in] init an initializer list - - @complexity Linear in the size of the initializer list @a init. - - @note This function is required to resolve an ambiguous overload error, - because pairs like `{"key", "value"}` can be both interpreted as - `object_t::value_type` or `std::initializer_list<basic_json>`, see - https://github.com/nlohmann/json/issues/235 for more information. - - @liveexample{The example shows how initializer lists are treated as - objects when possible.,push_back__initializer_list} - */ - void push_back(initializer_list_t init) - { - if (is_object() && init.size() == 2 && (*init.begin())->is_string()) - { - basic_json&& key = init.begin()->moved_or_copied(); - push_back(typename object_t::value_type( - std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied())); - } - else - { - push_back(basic_json(init)); - } - } - - /*! - @brief add an object to an object - @copydoc push_back(initializer_list_t) - */ - reference operator+=(initializer_list_t init) - { - push_back(init); - return *this; - } - - /*! - @brief add an object to an array - - Creates a JSON value from the passed parameters @a args to the end of the - JSON value. If the function is called on a JSON null value, an empty array - is created before appending the value created from @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return reference to the inserted element - - @throw type_error.311 when called on a type other than JSON array or - null; example: `"cannot use emplace_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` can be used to add - elements to a JSON array. Note how the `null` value was silently converted - to a JSON array.,emplace_back} - - @since version 2.0.8, returns reference since 3.7.0 - */ - template<class... Args> - reference emplace_back(Args&& ... args) - { - // emplace_back only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array()))) - { - JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this)); - } - - // transform null object into an array - if (is_null()) - { - m_type = value_t::array; - m_value = value_t::array; - assert_invariant(); - } - - // add element to array (perfect forwarding) - const auto old_capacity = m_value.array->capacity(); - m_value.array->emplace_back(std::forward<Args>(args)...); - return set_parent(m_value.array->back(), old_capacity); - } - - /*! - @brief add an object to an object if key does not exist - - Inserts a new element into a JSON object constructed in-place with the - given @a args if there is no element with the key in the container. If the - function is called on a JSON null value, an empty object is created before - appending the value created from @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return a pair consisting of an iterator to the inserted element, or the - already-existing element if no insertion happened, and a bool - denoting whether the insertion took place. - - @throw type_error.311 when called on a type other than JSON object or - null; example: `"cannot use emplace() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{The example shows how `emplace()` can be used to add elements - to a JSON object. Note how the `null` value was silently converted to a - JSON object. Further note how no value is added if there was already one - value stored with the same key.,emplace} - - @since version 2.0.8 - */ - template<class... Args> - std::pair<iterator, bool> emplace(Args&& ... args) - { - // emplace only works for null objects or arrays - if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object()))) - { - JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this)); - } - - // transform null object into an object - if (is_null()) - { - m_type = value_t::object; - m_value = value_t::object; - assert_invariant(); - } - - // add element to array (perfect forwarding) - auto res = m_value.object->emplace(std::forward<Args>(args)...); - set_parent(res.first->second); - - // create result iterator and set iterator to the result of emplace - auto it = begin(); - it.m_it.object_iterator = res.first; - - // return pair of iterator and boolean - return {it, res.second}; - } - - /// Helper for insertion of an iterator - /// @note: This uses std::distance to support GCC 4.8, - /// see https://github.com/nlohmann/json/pull/1257 - template<typename... Args> - iterator insert_iterator(const_iterator pos, Args&& ... args) - { - iterator result(this); - JSON_ASSERT(m_value.array != nullptr); - - auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator); - m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...); - result.m_it.array_iterator = m_value.array->begin() + insert_pos; - - // This could have been written as: - // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val); - // but the return value of insert is missing in GCC 4.8, so it is written this way instead. - - set_parents(); - return result; - } - - /*! - @brief inserts element - - Inserts element @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] val element to insert - @return iterator pointing to the inserted @a val. - - @throw type_error.309 if called on JSON values other than arrays; - example: `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Constant plus linear in the distance between @a pos and end of - the container. - - @liveexample{The example shows how `insert()` is used.,insert} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, const basic_json& val) - { - // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, val); - } - - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - /*! - @brief inserts element - @copydoc insert(const_iterator, const basic_json&) - */ - iterator insert(const_iterator pos, basic_json&& val) - { - return insert(pos, val); - } - - /*! - @brief inserts elements - - Inserts @a cnt copies of @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] cnt number of copies of @a val to insert - @param[in] val element to insert - @return iterator pointing to the first element inserted, or @a pos if - `cnt==0` - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Linear in @a cnt plus linear in the distance between @a pos - and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__count} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, size_type cnt, const basic_json& val) - { - // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, cnt, val); - } - - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - /*! - @brief inserts elements - - Inserts elements from range `[first, last)` before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - @throw invalid_iterator.211 if @a first or @a last are iterators into - container for which insert is called; example: `"passed iterators may not - belong to container"` - - @return iterator pointing to the first element inserted, or @a pos if - `first==last` - - @complexity Linear in `std::distance(first, last)` plus linear in the - distance between @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__range} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, const_iterator first, const_iterator last) - { - // insert only works for arrays - if (JSON_HEDLEY_UNLIKELY(!is_array())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - if (JSON_HEDLEY_UNLIKELY(first.m_object == this)) - { - JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator); - } - - /*! - @brief inserts elements - - Inserts elements from initializer list @a ilist before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] ilist initializer list to insert the values from - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @return iterator pointing to the first element inserted, or @a pos if - `ilist` is empty - - @complexity Linear in `ilist.size()` plus linear in the distance between - @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__ilist} - - @since version 1.0.0 - */ - iterator insert(const_iterator pos, initializer_list_t ilist) - { - // insert only works for arrays - if (JSON_HEDLEY_UNLIKELY(!is_array())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this)); - } - - // insert to array and return iterator - return insert_iterator(pos, ilist.begin(), ilist.end()); - } - - /*! - @brief inserts elements - - Inserts elements from range `[first, last)`. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than objects; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number - of elements to insert. - - @liveexample{The example shows how `insert()` is used.,insert__range_object} - - @since version 3.0.0 - */ - void insert(const_iterator first, const_iterator last) - { - // insert only works for objects - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); - } - - m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from JSON object @a j and overwrites existing keys. - - @param[in] j JSON object to read values from - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_reference j) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create<object_t>(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this)); - } - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this)); - } - - for (auto it = j.cbegin(); it != j.cend(); ++it) - { - m_value.object->operator[](it.key()) = it.value(); -#if JSON_DIAGNOSTICS - m_value.object->operator[](it.key()).m_parent = this; -#endif - } - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from from range `[first, last)` and overwrites existing - keys. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used__range.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_iterator first, const_iterator last) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create<object_t>(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this)); - } - - // check if range iterators belong to the same JSON object - if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) - { - JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object() - || !last.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); - } - - for (auto it = first; it != last; ++it) - { - m_value.object->operator[](it.key()) = it.value(); -#if JSON_DIAGNOSTICS - m_value.object->operator[](it.key()).m_parent = this; -#endif - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ - void swap(reference other) noexcept ( - std::is_nothrow_move_constructible<value_t>::value&& - std::is_nothrow_move_assignable<value_t>::value&& - std::is_nothrow_move_constructible<json_value>::value&& - std::is_nothrow_move_assignable<json_value>::value - ) - { - std::swap(m_type, other.m_type); - std::swap(m_value, other.m_value); - - set_parents(); - other.set_parents(); - assert_invariant(); - } - - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value from @a left with those of @a right. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. implemented as a friend function callable via ADL. - - @param[in,out] left JSON value to exchange the contents with - @param[in,out] right JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ - friend void swap(reference left, reference right) noexcept ( - std::is_nothrow_move_constructible<value_t>::value&& - std::is_nothrow_move_assignable<value_t>::value&& - std::is_nothrow_move_constructible<json_value>::value&& - std::is_nothrow_move_assignable<json_value>::value - ) - { - left.swap(right); - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON array with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other array to exchange the contents with - - @throw type_error.310 when JSON value is not an array; example: `"cannot - use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how arrays can be swapped with - `swap()`.,swap__array_t} - - @since version 1.0.0 - */ - void swap(array_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) - { - std::swap(*(m_value.array), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON object with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other object to exchange the contents with - - @throw type_error.310 when JSON value is not an object; example: - `"cannot use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how objects can be swapped with - `swap()`.,swap__object_t} - - @since version 1.0.0 - */ - void swap(object_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for objects - if (JSON_HEDLEY_LIKELY(is_object())) - { - std::swap(*(m_value.object), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other string to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__string_t} - - @since version 1.0.0 - */ - void swap(string_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_string())) - { - std::swap(*(m_value.string), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a other. Does not - invoke any move, copy, or swap operations on individual elements. All - iterators and references remain valid. The past-the-end iterator is - invalidated. - - @param[in,out] other binary to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__binary_t} - - @since version 3.8.0 - */ - void swap(binary_t& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_binary())) - { - std::swap(*(m_value.binary), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /// @copydoc swap(binary_t&) - void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape) - { - // swap only works for strings - if (JSON_HEDLEY_LIKELY(is_binary())) - { - std::swap(*(m_value.binary), other); - } - else - { - JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this)); - } - } - - /// @} - - public: - ////////////////////////////////////////// - // lexicographical comparison operators // - ////////////////////////////////////////// - - /// @name lexicographical comparison operators - /// @{ - - /*! - @brief comparison: equal - - Compares two JSON values for equality according to the following rules: - - Two JSON values are equal if (1) they are from the same type and (2) - their stored values are the same according to their respective - `operator==`. - - Integer and floating-point numbers are automatically converted before - comparison. Note that two NaN values are always treated as unequal. - - Two JSON null values are equal. - - @note Floating-point inside JSON values numbers are compared with - `json::number_float_t::operator==` which is `double::operator==` by - default. To compare floating-point while respecting an epsilon, an alternative - [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) - could be used, for instance - @code {.cpp} - template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type> - inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept - { - return std::abs(a - b) <= epsilon; - } - @endcode - Or you can self-defined operator equal function like this: - @code {.cpp} - bool my_equal(const_reference lhs, const_reference rhs) { - const auto lhs_type lhs.type(); - const auto rhs_type rhs.type(); - if (lhs_type == rhs_type) { - switch(lhs_type) - // self_defined case - case value_t::number_float: - return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon(); - // other cases remain the same with the original - ... - } - ... - } - @endcode - - @note NaN values never compare equal to themselves or to other NaN values. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are equal - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Linear. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__equal} - - @since version 1.0.0 - */ - friend bool operator==(const_reference lhs, const_reference rhs) noexcept - { -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - const auto lhs_type = lhs.type(); - const auto rhs_type = rhs.type(); - - if (lhs_type == rhs_type) - { - switch (lhs_type) - { - case value_t::array: - return *lhs.m_value.array == *rhs.m_value.array; - - case value_t::object: - return *lhs.m_value.object == *rhs.m_value.object; - - case value_t::null: - return true; - - case value_t::string: - return *lhs.m_value.string == *rhs.m_value.string; - - case value_t::boolean: - return lhs.m_value.boolean == rhs.m_value.boolean; - - case value_t::number_integer: - return lhs.m_value.number_integer == rhs.m_value.number_integer; - - case value_t::number_unsigned: - return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned; - - case value_t::number_float: - return lhs.m_value.number_float == rhs.m_value.number_float; - - case value_t::binary: - return *lhs.m_value.binary == *rhs.m_value.binary; - - case value_t::discarded: - default: - return false; - } - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) - { - return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) - { - return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) - { - return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) - { - return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer; - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned); - } - - return false; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - } - - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator==(const_reference lhs, ScalarType rhs) noexcept - { - return lhs == basic_json(rhs); - } - - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator==(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) == rhs; - } - - /*! - @brief comparison: not equal - - Compares two JSON values for inequality by calculating `not (lhs == rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are not equal - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__notequal} - - @since version 1.0.0 - */ - friend bool operator!=(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs == rhs); - } - - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept - { - return lhs != basic_json(rhs); - } - - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) != rhs; - } - - /*! - @brief comparison: less than - - Compares whether one JSON value @a lhs is less than another JSON value @a - rhs according to the following rules: - - If @a lhs and @a rhs have the same type, the values are compared using - the default `<` operator. - - Integer and floating-point numbers are automatically converted before - comparison - - In case @a lhs and @a rhs have different types, the values are ignored - and the order of the types is considered, see - @ref operator<(const value_t, const value_t). - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__less} - - @since version 1.0.0 - */ - friend bool operator<(const_reference lhs, const_reference rhs) noexcept - { - const auto lhs_type = lhs.type(); - const auto rhs_type = rhs.type(); - - if (lhs_type == rhs_type) - { - switch (lhs_type) - { - case value_t::array: - // note parentheses are necessary, see - // https://github.com/nlohmann/json/issues/1530 - return (*lhs.m_value.array) < (*rhs.m_value.array); - - case value_t::object: - return (*lhs.m_value.object) < (*rhs.m_value.object); - - case value_t::null: - return false; - - case value_t::string: - return (*lhs.m_value.string) < (*rhs.m_value.string); - - case value_t::boolean: - return (lhs.m_value.boolean) < (rhs.m_value.boolean); - - case value_t::number_integer: - return (lhs.m_value.number_integer) < (rhs.m_value.number_integer); - - case value_t::number_unsigned: - return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned); - - case value_t::number_float: - return (lhs.m_value.number_float) < (rhs.m_value.number_float); - - case value_t::binary: - return (*lhs.m_value.binary) < (*rhs.m_value.binary); - - case value_t::discarded: - default: - return false; - } - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) - { - return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) - { - return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) - { - return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float; - } - else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) - { - return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned); - } - else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) - { - return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer; - } - - // We only reach this line if we cannot compare values. In that case, - // we compare types. Note we have to call the operator explicitly, - // because MSVC has problems otherwise. - return operator<(lhs_type, rhs_type); - } - - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator<(const_reference lhs, ScalarType rhs) noexcept - { - return lhs < basic_json(rhs); - } - - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator<(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) < rhs; - } - - /*! - @brief comparison: less than or equal - - Compares whether one JSON value @a lhs is less than or equal to another - JSON value by calculating `not (rhs < lhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greater} - - @since version 1.0.0 - */ - friend bool operator<=(const_reference lhs, const_reference rhs) noexcept - { - return !(rhs < lhs); - } - - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept - { - return lhs <= basic_json(rhs); - } - - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) <= rhs; - } - - /*! - @brief comparison: greater than - - Compares whether one JSON value @a lhs is greater than another - JSON value by calculating `not (lhs <= rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__lessequal} - - @since version 1.0.0 - */ - friend bool operator>(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs <= rhs); - } - - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator>(const_reference lhs, ScalarType rhs) noexcept - { - return lhs > basic_json(rhs); - } - - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator>(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) > rhs; - } - - /*! - @brief comparison: greater than or equal - - Compares whether one JSON value @a lhs is greater than or equal to another - JSON value by calculating `not (lhs < rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greaterequal} - - @since version 1.0.0 - */ - friend bool operator>=(const_reference lhs, const_reference rhs) noexcept - { - return !(lhs < rhs); - } - - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept - { - return lhs >= basic_json(rhs); - } - - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ - template<typename ScalarType, typename std::enable_if< - std::is_scalar<ScalarType>::value, int>::type = 0> - friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept - { - return basic_json(lhs) >= rhs; - } - - /// @} - - /////////////////// - // serialization // - /////////////////// - - /// @name serialization - /// @{ -#ifndef JSON_NO_IO - /*! - @brief serialize to stream - - Serialize the given JSON value @a j to the output stream @a o. The JSON - value will be serialized using the @ref dump member function. - - - The indentation of the output can be controlled with the member variable - `width` of the output stream @a o. For instance, using the manipulator - `std::setw(4)` on @a o sets the indentation level to `4` and the - serialization result is the same as calling `dump(4)`. - - - The indentation character can be controlled with the member variable - `fill` of the output stream @a o. For instance, the manipulator - `std::setfill('\\t')` sets indentation to use a tab character rather than - the default space character. - - @param[in,out] o stream to serialize to - @param[in] j JSON value to serialize - - @return the stream @a o - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded - - @complexity Linear. - - @liveexample{The example below shows the serialization with different - parameters to `width` to adjust the indentation level.,operator_serialize} - - @since version 1.0.0; indentation character added in version 3.0.0 - */ - friend std::ostream& operator<<(std::ostream& o, const basic_json& j) - { - // read width member and use it as indentation parameter if nonzero - const bool pretty_print = o.width() > 0; - const auto indentation = pretty_print ? o.width() : 0; - - // reset width to 0 for subsequent calls to this stream - o.width(0); - - // do the actual serialization - serializer s(detail::output_adapter<char>(o), o.fill()); - s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation)); - return o; - } - - /*! - @brief serialize to stream - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use - @ref operator<<(std::ostream&, const basic_json&) - instead; that is, replace calls like `j >> o;` with `o << j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&)) - friend std::ostream& operator>>(const basic_json& j, std::ostream& o) - { - return o << j; - } -#endif // JSON_NO_IO - /// @} - - - ///////////////////// - // deserialization // - ///////////////////// - - /// @name deserialization - /// @{ - - /*! - @brief deserialize from a compatible input - - @tparam InputType A compatible input, for instance - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. The complexity can be higher if the parser callback function - @a cb or reading from the input @a i has a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `parse()` function reading - from an array.,parse__array__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__string__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__istream__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function reading - from a contiguous container.,parse__contiguouscontainer__parser_callback_t} - - @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to - ignore comments. - */ - template<typename InputType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(InputType&& i, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - /*! - @brief deserialize from a pair of character iterators - - The value_type of the iterator must be a integral type with size of 1, 2 or - 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32. - - @param[in] first iterator to start of character range - @param[in] last iterator to end of character range - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ - template<typename IteratorType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json parse(IteratorType first, - IteratorType last, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len)) - static basic_json parse(detail::span_input_adapter&& i, - const parser_callback_t cb = nullptr, - const bool allow_exceptions = true, - const bool ignore_comments = false) - { - basic_json result; - parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result); - return result; - } - - /*! - @brief check if the input is valid JSON - - Unlike the @ref parse(InputType&&, const parser_callback_t,const bool) - function, this function neither throws an exception in case of invalid JSON - input (i.e., a parse error) nor creates diagnostic information. - - @tparam InputType A compatible input, for instance - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return Whether the input read from @a i is valid JSON. - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `accept()` function reading - from a string.,accept__string} - */ - template<typename InputType> - static bool accept(InputType&& i, - const bool ignore_comments = false) - { - return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true); - } - - template<typename IteratorType> - static bool accept(IteratorType first, IteratorType last, - const bool ignore_comments = false) - { - return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len)) - static bool accept(detail::span_input_adapter&& i, - const bool ignore_comments = false) - { - return parser(i.get(), nullptr, false, ignore_comments).accept(true); - } - - /*! - @brief generate SAX events - - The SAX event lister must follow the interface of @ref json_sax. - - This function reads from a compatible input. Examples are: - - an std::istream object - - a FILE pointer - - a C-style array of characters - - a pointer to a null-terminated string of single byte characters - - an object obj for which begin(obj) and end(obj) produces a valid pair of - iterators. - - @param[in] i input to read from - @param[in,out] sax SAX event listener - @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON) - @param[in] strict whether the input has to be consumed completely - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default); only applies to the JSON file format. - - @return return value of the last processed SAX event - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. The complexity can be higher if the SAX consumer @a sax has - a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `sax_parse()` function - reading from string and processing the events with a user-defined SAX - event consumer.,sax_parse} - - @since version 3.2.0 - */ - template <typename InputType, typename SAX> - JSON_HEDLEY_NON_NULL(2) - static bool sax_parse(InputType&& i, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = detail::input_adapter(std::forward<InputType>(i)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict); - } - - template<class IteratorType, class SAX> - JSON_HEDLEY_NON_NULL(3) - static bool sax_parse(IteratorType first, IteratorType last, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = detail::input_adapter(std::move(first), std::move(last)); - return format == input_format_t::json - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict); - } - - template <typename SAX> - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...)) - JSON_HEDLEY_NON_NULL(2) - static bool sax_parse(detail::span_input_adapter&& i, SAX* sax, - input_format_t format = input_format_t::json, - const bool strict = true, - const bool ignore_comments = false) - { - auto ia = i.get(); - return format == input_format_t::json - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict); - } -#ifndef JSON_NO_IO - /*! - @brief deserialize from stream - @deprecated This stream operator is deprecated and will be removed in - version 4.0.0 of the library. Please use - @ref operator>>(std::istream&, basic_json&) - instead; that is, replace calls like `j << i;` with `i >> j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&)) - friend std::istream& operator<<(basic_json& j, std::istream& i) - { - return operator>>(i, j); - } - - /*! - @brief deserialize from stream - - Deserializes an input stream to a JSON value. - - @param[in,out] i input stream to read a serialized JSON value from - @param[in,out] j JSON value to write the deserialized input to - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below shows how a JSON value is constructed by - reading a serialization from a stream.,operator_deserialize} - - @sa parse(std::istream&, const parser_callback_t) for a variant with a - parser callback function to filter values while parsing - - @since version 1.0.0 - */ - friend std::istream& operator>>(std::istream& i, basic_json& j) - { - parser(detail::input_adapter(i)).parse(false, j); - return i; - } -#endif // JSON_NO_IO - /// @} - - /////////////////////////// - // convenience functions // - /////////////////////////// - - /*! - @brief return the type as string - - Returns the type name as string to be used in error messages - usually to - indicate that a function was called on a wrong JSON type. - - @return a string representation of a the @a m_type member: - Value type | return value - ----------- | ------------- - null | `"null"` - boolean | `"boolean"` - string | `"string"` - number | `"number"` (for all number types) - object | `"object"` - array | `"array"` - binary | `"binary"` - discarded | `"discarded"` - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Constant. - - @liveexample{The following code exemplifies `type_name()` for all JSON - types.,type_name} - - @sa see @ref type() -- return the type of the JSON value - @sa see @ref operator value_t() -- return the type of the JSON value (implicit) - - @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept` - since 3.0.0 - */ - JSON_HEDLEY_RETURNS_NON_NULL - const char* type_name() const noexcept - { - { - switch (m_type) - { - case value_t::null: - return "null"; - case value_t::object: - return "object"; - case value_t::array: - return "array"; - case value_t::string: - return "string"; - case value_t::boolean: - return "boolean"; - case value_t::binary: - return "binary"; - case value_t::discarded: - return "discarded"; - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - default: - return "number"; - } - } - } - - - JSON_PRIVATE_UNLESS_TESTED: - ////////////////////// - // member variables // - ////////////////////// - - /// the type of the current element - value_t m_type = value_t::null; - - /// the value of the current element - json_value m_value = {}; - -#if JSON_DIAGNOSTICS - /// a pointer to a parent value (for debugging purposes) - basic_json* m_parent = nullptr; -#endif - - ////////////////////////////////////////// - // binary serialization/deserialization // - ////////////////////////////////////////// - - /// @name binary serialization/deserialization support - /// @{ - - public: - /*! - @brief create a CBOR serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the CBOR (Concise - Binary Object Representation) serialization format. CBOR is a binary - serialization format which aims to be more compact than JSON itself, yet - more efficient to parse. - - The library uses the following mapping from JSON values types to - CBOR types according to the CBOR specification (RFC 7049): - - JSON value type | value/range | CBOR type | first byte - --------------- | ------------------------------------------ | ---------------------------------- | --------------- - null | `null` | Null | 0xF6 - boolean | `true` | True | 0xF5 - boolean | `false` | False | 0xF4 - number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B - number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A - number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 - number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 - number_integer | -24..-1 | Negative integer | 0x20..0x37 - number_integer | 0..23 | Integer | 0x00..0x17 - number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 - number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 - number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A - number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B - number_unsigned | 0..23 | Integer | 0x00..0x17 - number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 - number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 - number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A - number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B - number_float | *any value representable by a float* | Single-Precision Float | 0xFA - number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB - string | *length*: 0..23 | UTF-8 string | 0x60..0x77 - string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78 - string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 - string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A - string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B - array | *size*: 0..23 | array | 0x80..0x97 - array | *size*: 23..255 | array (1 byte follow) | 0x98 - array | *size*: 256..65535 | array (2 bytes follow) | 0x99 - array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A - array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B - object | *size*: 0..23 | map | 0xA0..0xB7 - object | *size*: 23..255 | map (1 byte follow) | 0xB8 - object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 - object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA - object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB - binary | *size*: 0..23 | byte string | 0x40..0x57 - binary | *size*: 23..255 | byte string (1 byte follow) | 0x58 - binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59 - binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A - binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B - - Binary values with subtype are mapped to tagged values (0xD8..0xDB) - depending on the subtype, followed by a byte string, see "binary" cells - in the table above. - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a CBOR value. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The following CBOR types are not used in the conversion: - - UTF-8 strings terminated by "break" (0x7F) - - arrays terminated by "break" (0x9F) - - maps terminated by "break" (0xBF) - - byte strings terminated by "break" (0x5F) - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - half-precision floats (0xF9) - - break (0xFF) - - @param[in] j JSON value to serialize - @return CBOR serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in CBOR format.,to_cbor} - - @sa http://cbor.io - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - analogous deserialization - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; compact representation of floating-point numbers - since version 3.8.0 - */ - static std::vector<std::uint8_t> to_cbor(const basic_json& j) - { - std::vector<std::uint8_t> result; - to_cbor(j, result); - return result; - } - - static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o) - { - binary_writer<std::uint8_t>(o).write_cbor(j); - } - - static void to_cbor(const basic_json& j, detail::output_adapter<char> o) - { - binary_writer<char>(o).write_cbor(j); - } - - /*! - @brief create a MessagePack serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the MessagePack - serialization format. MessagePack is a binary serialization format which - aims to be more compact than JSON itself, yet more efficient to parse. - - The library uses the following mapping from JSON values types to - MessagePack types according to the MessagePack specification: - - JSON value type | value/range | MessagePack type | first byte - --------------- | --------------------------------- | ---------------- | ---------- - null | `null` | nil | 0xC0 - boolean | `true` | true | 0xC3 - boolean | `false` | false | 0xC2 - number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 - number_integer | -2147483648..-32769 | int32 | 0xD2 - number_integer | -32768..-129 | int16 | 0xD1 - number_integer | -128..-33 | int8 | 0xD0 - number_integer | -32..-1 | negative fixint | 0xE0..0xFF - number_integer | 0..127 | positive fixint | 0x00..0x7F - number_integer | 128..255 | uint 8 | 0xCC - number_integer | 256..65535 | uint 16 | 0xCD - number_integer | 65536..4294967295 | uint 32 | 0xCE - number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF - number_unsigned | 0..127 | positive fixint | 0x00..0x7F - number_unsigned | 128..255 | uint 8 | 0xCC - number_unsigned | 256..65535 | uint 16 | 0xCD - number_unsigned | 65536..4294967295 | uint 32 | 0xCE - number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF - number_float | *any value representable by a float* | float 32 | 0xCA - number_float | *any value NOT representable by a float* | float 64 | 0xCB - string | *length*: 0..31 | fixstr | 0xA0..0xBF - string | *length*: 32..255 | str 8 | 0xD9 - string | *length*: 256..65535 | str 16 | 0xDA - string | *length*: 65536..4294967295 | str 32 | 0xDB - array | *size*: 0..15 | fixarray | 0x90..0x9F - array | *size*: 16..65535 | array 16 | 0xDC - array | *size*: 65536..4294967295 | array 32 | 0xDD - object | *size*: 0..15 | fix map | 0x80..0x8F - object | *size*: 16..65535 | map 16 | 0xDE - object | *size*: 65536..4294967295 | map 32 | 0xDF - binary | *size*: 0..255 | bin 8 | 0xC4 - binary | *size*: 256..65535 | bin 16 | 0xC5 - binary | *size*: 65536..4294967295 | bin 32 | 0xC6 - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a MessagePack value. - - @note The following values can **not** be converted to a MessagePack value: - - strings with more than 4294967295 bytes - - byte strings with more than 4294967295 bytes - - arrays with more than 4294967295 elements - - objects with more than 4294967295 elements - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @param[in] j JSON value to serialize - @return MessagePack serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in MessagePack format.,to_msgpack} - - @sa http://msgpack.org - @sa see @ref from_msgpack for the analogous deserialization - @sa see @ref to_cbor(const basic_json& for the related CBOR format - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9 - */ - static std::vector<std::uint8_t> to_msgpack(const basic_json& j) - { - std::vector<std::uint8_t> result; - to_msgpack(j, result); - return result; - } - - static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o) - { - binary_writer<std::uint8_t>(o).write_msgpack(j); - } - - static void to_msgpack(const basic_json& j, detail::output_adapter<char> o) - { - binary_writer<char>(o).write_msgpack(j); - } - - /*! - @brief create a UBJSON serialization of a given JSON value - - Serializes a given JSON value @a j to a byte vector using the UBJSON - (Universal Binary JSON) serialization format. UBJSON aims to be more compact - than JSON itself, yet more efficient to parse. - - The library uses the following mapping from JSON values types to - UBJSON types according to the UBJSON specification: - - JSON value type | value/range | UBJSON type | marker - --------------- | --------------------------------- | ----------- | ------ - null | `null` | null | `Z` - boolean | `true` | true | `T` - boolean | `false` | false | `F` - number_integer | -9223372036854775808..-2147483649 | int64 | `L` - number_integer | -2147483648..-32769 | int32 | `l` - number_integer | -32768..-129 | int16 | `I` - number_integer | -128..127 | int8 | `i` - number_integer | 128..255 | uint8 | `U` - number_integer | 256..32767 | int16 | `I` - number_integer | 32768..2147483647 | int32 | `l` - number_integer | 2147483648..9223372036854775807 | int64 | `L` - number_unsigned | 0..127 | int8 | `i` - number_unsigned | 128..255 | uint8 | `U` - number_unsigned | 256..32767 | int16 | `I` - number_unsigned | 32768..2147483647 | int32 | `l` - number_unsigned | 2147483648..9223372036854775807 | int64 | `L` - number_unsigned | 2147483649..18446744073709551615 | high-precision | `H` - number_float | *any value* | float64 | `D` - string | *with shortest length indicator* | string | `S` - array | *see notes on optimized format* | array | `[` - object | *see notes on optimized format* | map | `{` - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a UBJSON value. - - @note The following values can **not** be converted to a UBJSON value: - - strings with more than 9223372036854775807 bytes (theoretical) - - @note The following markers are not used in the conversion: - - `Z`: no-op values are not created. - - `C`: single-byte strings are serialized with `S` markers. - - @note Any UBJSON output created @ref to_ubjson can be successfully parsed - by @ref from_ubjson. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The optimized formats for containers are supported: Parameter - @a use_size adds size information to the beginning of a container and - removes the closing marker. Parameter @a use_type further checks - whether all elements of a container have the same type and adds the - type marker to the beginning of the container. The @a use_type - parameter must only be used together with @a use_size = true. Note - that @a use_size = true alone may result in larger representations - - the benefit of this parameter is that the receiving side is - immediately informed on the number of elements of the container. - - @note If the JSON data contains the binary type, the value stored is a list - of integers, as suggested by the UBJSON documentation. In particular, - this means that serialization and the deserialization of a JSON - containing binary values into UBJSON and back will result in a - different JSON object. - - @param[in] j JSON value to serialize - @param[in] use_size whether to add size annotations to container types - @param[in] use_type whether to add type annotations to container types - (must be combined with @a use_size = true) - @return UBJSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in UBJSON format.,to_ubjson} - - @sa http://ubjson.org - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - analogous deserialization - @sa see @ref to_cbor(const basic_json& for the related CBOR format - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - - @since version 3.1.0 - */ - static std::vector<std::uint8_t> to_ubjson(const basic_json& j, - const bool use_size = false, - const bool use_type = false) - { - std::vector<std::uint8_t> result; - to_ubjson(j, result, use_size, use_type); - return result; - } - - static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o, - const bool use_size = false, const bool use_type = false) - { - binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type); - } - - static void to_ubjson(const basic_json& j, detail::output_adapter<char> o, - const bool use_size = false, const bool use_type = false) - { - binary_writer<char>(o).write_ubjson(j, use_size, use_type); - } - - - /*! - @brief Serializes the given JSON object `j` to BSON and returns a vector - containing the corresponding BSON-representation. - - BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are - stored as a single entity (a so-called document). - - The library uses the following mapping from JSON values types to BSON types: - - JSON value type | value/range | BSON type | marker - --------------- | --------------------------------- | ----------- | ------ - null | `null` | null | 0x0A - boolean | `true`, `false` | boolean | 0x08 - number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 - number_integer | -2147483648..2147483647 | int32 | 0x10 - number_integer | 2147483648..9223372036854775807 | int64 | 0x12 - number_unsigned | 0..2147483647 | int32 | 0x10 - number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 - number_unsigned | 9223372036854775808..18446744073709551615| -- | -- - number_float | *any value* | double | 0x01 - string | *any value* | string | 0x02 - array | *any value* | document | 0x04 - object | *any value* | document | 0x03 - binary | *any value* | binary | 0x05 - - @warning The mapping is **incomplete**, since only JSON-objects (and things - contained therein) can be serialized to BSON. - Also, integers larger than 9223372036854775807 cannot be serialized to BSON, - and the keys may not contain U+0000, since they are serialized a - zero-terminated c-strings. - - @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807` - @throw out_of_range.409 if a key in `j` contains a NULL (U+0000) - @throw type_error.317 if `!j.is_object()` - - @pre The input `j` is required to be an object: `j.is_object() == true`. - - @note Any BSON output created via @ref to_bson can be successfully parsed - by @ref from_bson. - - @param[in] j JSON value to serialize - @return BSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in BSON format.,to_bson} - - @sa http://bsonspec.org/spec.html - @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the - analogous deserialization - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - @sa see @ref to_cbor(const basic_json&) for the related CBOR format - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - */ - static std::vector<std::uint8_t> to_bson(const basic_json& j) - { - std::vector<std::uint8_t> result; - to_bson(j, result); - return result; - } - - /*! - @brief Serializes the given JSON object `j` to BSON and forwards the - corresponding BSON-representation to the given output_adapter `o`. - @param j The JSON object to convert to BSON. - @param o The output adapter that receives the binary BSON representation. - @pre The input `j` shall be an object: `j.is_object() == true` - @sa see @ref to_bson(const basic_json&) - */ - static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o) - { - binary_writer<std::uint8_t>(o).write_bson(j); - } - - /*! - @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>) - */ - static void to_bson(const basic_json& j, detail::output_adapter<char> o) - { - binary_writer<char>(o).write_bson(j); - } - - - /*! - @brief create a JSON value from an input in CBOR format - - Deserializes a given input @a i to a JSON value using the CBOR (Concise - Binary Object Representation) serialization format. - - The library maps CBOR types to JSON value types as follows: - - CBOR type | JSON value type | first byte - ---------------------- | --------------- | ---------- - Integer | number_unsigned | 0x00..0x17 - Unsigned integer | number_unsigned | 0x18 - Unsigned integer | number_unsigned | 0x19 - Unsigned integer | number_unsigned | 0x1A - Unsigned integer | number_unsigned | 0x1B - Negative integer | number_integer | 0x20..0x37 - Negative integer | number_integer | 0x38 - Negative integer | number_integer | 0x39 - Negative integer | number_integer | 0x3A - Negative integer | number_integer | 0x3B - Byte string | binary | 0x40..0x57 - Byte string | binary | 0x58 - Byte string | binary | 0x59 - Byte string | binary | 0x5A - Byte string | binary | 0x5B - UTF-8 string | string | 0x60..0x77 - UTF-8 string | string | 0x78 - UTF-8 string | string | 0x79 - UTF-8 string | string | 0x7A - UTF-8 string | string | 0x7B - UTF-8 string | string | 0x7F - array | array | 0x80..0x97 - array | array | 0x98 - array | array | 0x99 - array | array | 0x9A - array | array | 0x9B - array | array | 0x9F - map | object | 0xA0..0xB7 - map | object | 0xB8 - map | object | 0xB9 - map | object | 0xBA - map | object | 0xBB - map | object | 0xBF - False | `false` | 0xF4 - True | `true` | 0xF5 - Null | `null` | 0xF6 - Half-Precision Float | number_float | 0xF9 - Single-Precision Float | number_float | 0xFA - Double-Precision Float | number_float | 0xFB - - @warning The mapping is **incomplete** in the sense that not all CBOR - types can be converted to a JSON value. The following CBOR types - are not supported and will yield parse errors (parse_error.112): - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - @warning CBOR allows map keys of any type, whereas JSON only allows - strings as keys in object values. Therefore, CBOR maps with keys - other than UTF-8 strings are rejected (parse_error.113). - - @note Any CBOR output created @ref to_cbor can be successfully parsed by - @ref from_cbor. - - @param[in] i an input in CBOR format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] tag_handler how to treat CBOR tags (optional, error by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from CBOR were - used in the given input @a v or if the input is not valid CBOR - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in CBOR - format to a JSON value.,from_cbor} - - @sa http://cbor.io - @sa see @ref to_cbor(const basic_json&) for the analogous serialization - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the - related MessagePack format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0; added @a tag_handler parameter since 3.9.0. - */ - template<typename InputType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward<InputType>(i)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) - */ - template<typename IteratorType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_cbor(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - template<typename T> - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) - static basic_json from_cbor(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler); - } - - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len)) - static basic_json from_cbor(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true, - const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @brief create a JSON value from an input in MessagePack format - - Deserializes a given input @a i to a JSON value using the MessagePack - serialization format. - - The library maps MessagePack types to JSON value types as follows: - - MessagePack type | JSON value type | first byte - ---------------- | --------------- | ---------- - positive fixint | number_unsigned | 0x00..0x7F - fixmap | object | 0x80..0x8F - fixarray | array | 0x90..0x9F - fixstr | string | 0xA0..0xBF - nil | `null` | 0xC0 - false | `false` | 0xC2 - true | `true` | 0xC3 - float 32 | number_float | 0xCA - float 64 | number_float | 0xCB - uint 8 | number_unsigned | 0xCC - uint 16 | number_unsigned | 0xCD - uint 32 | number_unsigned | 0xCE - uint 64 | number_unsigned | 0xCF - int 8 | number_integer | 0xD0 - int 16 | number_integer | 0xD1 - int 32 | number_integer | 0xD2 - int 64 | number_integer | 0xD3 - str 8 | string | 0xD9 - str 16 | string | 0xDA - str 32 | string | 0xDB - array 16 | array | 0xDC - array 32 | array | 0xDD - map 16 | object | 0xDE - map 32 | object | 0xDF - bin 8 | binary | 0xC4 - bin 16 | binary | 0xC5 - bin 32 | binary | 0xC6 - ext 8 | binary | 0xC7 - ext 16 | binary | 0xC8 - ext 32 | binary | 0xC9 - fixext 1 | binary | 0xD4 - fixext 2 | binary | 0xD5 - fixext 4 | binary | 0xD6 - fixext 8 | binary | 0xD7 - fixext 16 | binary | 0xD8 - negative fixint | number_integer | 0xE0-0xFF - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @param[in] i an input in MessagePack format convertible to an input - adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from MessagePack were - used in the given input @a i or if the input is not valid MessagePack - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - MessagePack format to a JSON value.,from_msgpack} - - @sa http://msgpack.org - @sa see @ref to_msgpack(const basic_json&) for the analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for - the related UBJSON format - @sa see @ref from_bson(InputType&&, const bool, const bool) for - the related BSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0 - */ - template<typename InputType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward<InputType>(i)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_msgpack(InputType&&, const bool, const bool) - */ - template<typename IteratorType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_msgpack(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - template<typename T> - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) - static basic_json from_msgpack(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_msgpack(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) - static basic_json from_msgpack(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - /*! - @brief create a JSON value from an input in UBJSON format - - Deserializes a given input @a i to a JSON value using the UBJSON (Universal - Binary JSON) serialization format. - - The library maps UBJSON types to JSON value types as follows: - - UBJSON type | JSON value type | marker - ----------- | --------------------------------------- | ------ - no-op | *no value, next value is read* | `N` - null | `null` | `Z` - false | `false` | `F` - true | `true` | `T` - float32 | number_float | `d` - float64 | number_float | `D` - uint8 | number_unsigned | `U` - int8 | number_integer | `i` - int16 | number_integer | `I` - int32 | number_integer | `l` - int64 | number_integer | `L` - high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H' - string | string | `S` - char | string | `C` - array | array (optimized values are supported) | `[` - object | object (optimized values are supported) | `{` - - @note The mapping is **complete** in the sense that any UBJSON value can - be converted to a JSON value. - - @param[in] i an input in UBJSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if a parse error occurs - @throw parse_error.113 if a string could not be parsed successfully - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - UBJSON format to a JSON value.,from_ubjson} - - @sa http://ubjson.org - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for - the related MessagePack format - @sa see @ref from_bson(InputType&&, const bool, const bool) for - the related BSON format - - @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0 - */ - template<typename InputType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward<InputType>(i)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_ubjson(InputType&&, const bool, const bool) - */ - template<typename IteratorType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_ubjson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - template<typename T> - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) - static basic_json from_ubjson(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_ubjson(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len)) - static basic_json from_ubjson(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - - /*! - @brief Create a JSON value from an input in BSON format - - Deserializes a given input @a i to a JSON value using the BSON (Binary JSON) - serialization format. - - The library maps BSON record types to JSON value types as follows: - - BSON type | BSON marker byte | JSON value type - --------------- | ---------------- | --------------------------- - double | 0x01 | number_float - string | 0x02 | string - document | 0x03 | object - array | 0x04 | array - binary | 0x05 | binary - undefined | 0x06 | still unsupported - ObjectId | 0x07 | still unsupported - boolean | 0x08 | boolean - UTC Date-Time | 0x09 | still unsupported - null | 0x0A | null - Regular Expr. | 0x0B | still unsupported - DB Pointer | 0x0C | still unsupported - JavaScript Code | 0x0D | still unsupported - Symbol | 0x0E | still unsupported - JavaScript Code | 0x0F | still unsupported - int32 | 0x10 | number_integer - Timestamp | 0x11 | still unsupported - 128-bit decimal float | 0x13 | still unsupported - Max Key | 0x7F | still unsupported - Min Key | 0xFF | still unsupported - - @warning The mapping is **incomplete**. The unsupported mappings - are indicated in the table above. - - @param[in] i an input in BSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.114 if an unsupported BSON record type is encountered - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - BSON format to a JSON value.,from_bson} - - @sa http://bsonspec.org/spec.html - @sa see @ref to_bson(const basic_json&) for the analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for - the related MessagePack format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - related UBJSON format - */ - template<typename InputType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(InputType&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::forward<InputType>(i)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - /*! - @copydoc from_bson(InputType&&, const bool, const bool) - */ - template<typename IteratorType> - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json from_bson(IteratorType first, IteratorType last, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = detail::input_adapter(std::move(first), std::move(last)); - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - - template<typename T> - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) - static basic_json from_bson(const T* ptr, std::size_t len, - const bool strict = true, - const bool allow_exceptions = true) - { - return from_bson(ptr, ptr + len, strict, allow_exceptions); - } - - JSON_HEDLEY_WARN_UNUSED_RESULT - JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len)) - static basic_json from_bson(detail::span_input_adapter&& i, - const bool strict = true, - const bool allow_exceptions = true) - { - basic_json result; - detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions); - auto ia = i.get(); - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict); - return res ? result : basic_json(value_t::discarded); - } - /// @} - - ////////////////////////// - // JSON Pointer support // - ////////////////////////// - - /// @name JSON Pointer functions - /// @{ - - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. Similar to @ref operator[](const typename - object_t::key_type&), `null` values are created in arrays and objects if - necessary. - - In particular: - - If the JSON pointer points to an object key that does not exist, it - is created an filled with a `null` value before a reference to it - is returned. - - If the JSON pointer points to an array index that does not exist, it - is created an filled with a `null` value before a reference to it - is returned. All indices between the current maximum and the given - index are also filled with `null`. - - The special value `-` is treated as a synonym for the index past the - end. - - @param[in] ptr a JSON pointer - - @return reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer} - - @since version 2.0.0 - */ - reference operator[](const json_pointer& ptr) - { - return ptr.get_unchecked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. The function does not change the JSON - value; no `null` values are created. In particular, the special value - `-` yields an exception. - - @param[in] ptr JSON pointer to the desired element - - @return const reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer_const} - - @since version 2.0.0 - */ - const_reference operator[](const json_pointer& ptr) const - { - return ptr.get_unchecked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Returns a reference to the element at with specified JSON pointer @a ptr, - with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer} - */ - reference at(const json_pointer& ptr) - { - return ptr.get_checked(this); - } - - /*! - @brief access specified element via JSON Pointer - - Returns a const reference to the element at with specified JSON pointer @a - ptr, with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer_const} - */ - const_reference at(const json_pointer& ptr) const - { - return ptr.get_checked(this); - } - - /*! - @brief return flattened JSON value - - The function creates a JSON object whose keys are JSON pointers (see [RFC - 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all - primitive. The original JSON value can be restored using the @ref - unflatten() function. - - @return an object that maps JSON pointers to primitive values - - @note Empty objects and arrays are flattened to `null` and will not be - reconstructed correctly by the @ref unflatten() function. - - @complexity Linear in the size the JSON value. - - @liveexample{The following code shows how a JSON object is flattened to an - object whose keys consist of JSON pointers.,flatten} - - @sa see @ref unflatten() for the reverse function - - @since version 2.0.0 - */ - basic_json flatten() const - { - basic_json result(value_t::object); - json_pointer::flatten("", *this, result); - return result; - } - - /*! - @brief unflatten a previously flattened JSON value - - The function restores the arbitrary nesting of a JSON value that has been - flattened before using the @ref flatten() function. The JSON value must - meet certain constraints: - 1. The value must be an object. - 2. The keys must be JSON pointers (see - [RFC 6901](https://tools.ietf.org/html/rfc6901)) - 3. The mapped values must be primitive JSON types. - - @return the original JSON from a flattened version - - @note Empty objects and arrays are flattened by @ref flatten() to `null` - values and can not unflattened to their original type. Apart from - this example, for a JSON value `j`, the following is always true: - `j == j.flatten().unflatten()`. - - @complexity Linear in the size the JSON value. - - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - - @liveexample{The following code shows how a flattened JSON object is - unflattened into the original nested JSON object.,unflatten} - - @sa see @ref flatten() for the reverse function - - @since version 2.0.0 - */ - basic_json unflatten() const - { - return json_pointer::unflatten(*this); - } - - /// @} - - ////////////////////////// - // JSON Patch functions // - ////////////////////////// - - /// @name JSON Patch functions - /// @{ - - /*! - @brief applies a JSON patch - - [JSON Patch](http://jsonpatch.com) defines a JSON document structure for - expressing a sequence of operations to apply to a JSON) document. With - this function, a JSON Patch is applied to the current JSON value by - executing all operations from the patch. - - @param[in] json_patch JSON patch document - @return patched document - - @note The application of a patch is atomic: Either all operations succeed - and the patched document is returned or an exception is thrown. In - any case, the original value is not changed: the patch is applied - to a copy of the value. - - @throw parse_error.104 if the JSON patch does not consist of an array of - objects - - @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory - attributes are missing); example: `"operation add must have member path"` - - @throw out_of_range.401 if an array index is out of range. - - @throw out_of_range.403 if a JSON pointer inside the patch could not be - resolved successfully in the current JSON value; example: `"key baz not - found"` - - @throw out_of_range.405 if JSON pointer has no parent ("add", "remove", - "move") - - @throw other_error.501 if "test" operation was unsuccessful - - @complexity Linear in the size of the JSON value and the length of the - JSON patch. As usually only a fraction of the JSON value is affected by - the patch, the complexity can usually be neglected. - - @liveexample{The following code shows how a JSON patch is applied to a - value.,patch} - - @sa see @ref diff -- create a JSON patch by comparing two JSON values - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) - - @since version 2.0.0 - */ - basic_json patch(const basic_json& json_patch) const - { - // make a working copy to apply the patch to - basic_json result = *this; - - // the valid JSON Patch operations - enum class patch_operations {add, remove, replace, move, copy, test, invalid}; - - const auto get_op = [](const std::string & op) - { - if (op == "add") - { - return patch_operations::add; - } - if (op == "remove") - { - return patch_operations::remove; - } - if (op == "replace") - { - return patch_operations::replace; - } - if (op == "move") - { - return patch_operations::move; - } - if (op == "copy") - { - return patch_operations::copy; - } - if (op == "test") - { - return patch_operations::test; - } - - return patch_operations::invalid; - }; - - // wrapper for "add" operation; add value at ptr - const auto operation_add = [&result](json_pointer & ptr, basic_json val) - { - // adding to the root of the target document means replacing it - if (ptr.empty()) - { - result = val; - return; - } - - // make sure the top element of the pointer exists - json_pointer top_pointer = ptr.top(); - if (top_pointer != ptr) - { - result.at(top_pointer); - } - - // get reference to parent of JSON pointer ptr - const auto last_path = ptr.back(); - ptr.pop_back(); - basic_json& parent = result[ptr]; - - switch (parent.m_type) - { - case value_t::null: - case value_t::object: - { - // use operator[] to add value - parent[last_path] = val; - break; - } - - case value_t::array: - { - if (last_path == "-") - { - // special case: append to back - parent.push_back(val); - } - else - { - const auto idx = json_pointer::array_index(last_path); - if (JSON_HEDLEY_UNLIKELY(idx > parent.size())) - { - // avoid undefined behavior - JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent)); - } - - // default case: insert add offset - parent.insert(parent.begin() + static_cast<difference_type>(idx), val); - } - break; - } - - // if there exists a parent it cannot be primitive - case value_t::string: // LCOV_EXCL_LINE - case value_t::boolean: // LCOV_EXCL_LINE - case value_t::number_integer: // LCOV_EXCL_LINE - case value_t::number_unsigned: // LCOV_EXCL_LINE - case value_t::number_float: // LCOV_EXCL_LINE - case value_t::binary: // LCOV_EXCL_LINE - case value_t::discarded: // LCOV_EXCL_LINE - default: // LCOV_EXCL_LINE - JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE - } - }; - - // wrapper for "remove" operation; remove value at ptr - const auto operation_remove = [this, &result](json_pointer & ptr) - { - // get reference to parent of JSON pointer ptr - const auto last_path = ptr.back(); - ptr.pop_back(); - basic_json& parent = result.at(ptr); - - // remove child - if (parent.is_object()) - { - // perform range check - auto it = parent.find(last_path); - if (JSON_HEDLEY_LIKELY(it != parent.end())) - { - parent.erase(it); - } - else - { - JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this)); - } - } - else if (parent.is_array()) - { - // note erase performs range check - parent.erase(json_pointer::array_index(last_path)); - } - }; - - // type check: top level value must be an array - if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array())) - { - JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch)); - } - - // iterate and apply the operations - for (const auto& val : json_patch) - { - // wrapper to get a value for an operation - const auto get_value = [&val](const std::string & op, - const std::string & member, - bool string_type) -> basic_json & - { - // find value - auto it = val.m_value.object->find(member); - - // context-sensitive error message - const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'"; - - // check if desired value is present - if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end())) - { - // NOLINTNEXTLINE(performance-inefficient-string-concatenation) - JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val)); - } - - // check if result is of type string - if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string())) - { - // NOLINTNEXTLINE(performance-inefficient-string-concatenation) - JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val)); - } - - // no error: return value - return it->second; - }; - - // type check: every element of the array must be an object - if (JSON_HEDLEY_UNLIKELY(!val.is_object())) - { - JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val)); - } - - // collect mandatory members - const auto op = get_value("op", "op", true).template get<std::string>(); - const auto path = get_value(op, "path", true).template get<std::string>(); - json_pointer ptr(path); - - switch (get_op(op)) - { - case patch_operations::add: - { - operation_add(ptr, get_value("add", "value", false)); - break; - } - - case patch_operations::remove: - { - operation_remove(ptr); - break; - } - - case patch_operations::replace: - { - // the "path" location must exist - use at() - result.at(ptr) = get_value("replace", "value", false); - break; - } - - case patch_operations::move: - { - const auto from_path = get_value("move", "from", true).template get<std::string>(); - json_pointer from_ptr(from_path); - - // the "from" location must exist - use at() - basic_json v = result.at(from_ptr); - - // The move operation is functionally identical to a - // "remove" operation on the "from" location, followed - // immediately by an "add" operation at the target - // location with the value that was just removed. - operation_remove(from_ptr); - operation_add(ptr, v); - break; - } - - case patch_operations::copy: - { - const auto from_path = get_value("copy", "from", true).template get<std::string>(); - const json_pointer from_ptr(from_path); - - // the "from" location must exist - use at() - basic_json v = result.at(from_ptr); - - // The copy is functionally identical to an "add" - // operation at the target location using the value - // specified in the "from" member. - operation_add(ptr, v); - break; - } - - case patch_operations::test: - { - bool success = false; - JSON_TRY - { - // check if "value" matches the one at "path" - // the "path" location must exist - use at() - success = (result.at(ptr) == get_value("test", "value", false)); - } - JSON_INTERNAL_CATCH (out_of_range&) - { - // ignore out of range errors: success remains false - } - - // throw an exception if test fails - if (JSON_HEDLEY_UNLIKELY(!success)) - { - JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val)); - } - - break; - } - - case patch_operations::invalid: - default: - { - // op must be "add", "remove", "replace", "move", "copy", or - // "test" - JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val)); - } - } - } - - return result; - } - - /*! - @brief creates a diff as a JSON patch - - Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can - be changed into the value @a target by calling @ref patch function. - - @invariant For two JSON values @a source and @a target, the following code - yields always `true`: - @code {.cpp} - source.patch(diff(source, target)) == target; - @endcode - - @note Currently, only `remove`, `add`, and `replace` operations are - generated. - - @param[in] source JSON value to compare from - @param[in] target JSON value to compare against - @param[in] path helper value to create JSON pointers - - @return a JSON patch to convert the @a source to @a target - - @complexity Linear in the lengths of @a source and @a target. - - @liveexample{The following code shows how a JSON patch is created as a - diff for two JSON values.,diff} - - @sa see @ref patch -- apply a JSON patch - @sa see @ref merge_patch -- apply a JSON Merge Patch - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - - @since version 2.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json diff(const basic_json& source, const basic_json& target, - const std::string& path = "") - { - // the patch - basic_json result(value_t::array); - - // if the values are the same, return empty patch - if (source == target) - { - return result; - } - - if (source.type() != target.type()) - { - // different types: replace value - result.push_back( - { - {"op", "replace"}, {"path", path}, {"value", target} - }); - return result; - } - - switch (source.type()) - { - case value_t::array: - { - // first pass: traverse common elements - std::size_t i = 0; - while (i < source.size() && i < target.size()) - { - // recursive call to compare array values at index i - auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); - result.insert(result.end(), temp_diff.begin(), temp_diff.end()); - ++i; - } - - // i now reached the end of at least one array - // in a second pass, traverse the remaining elements - - // remove my remaining elements - const auto end_index = static_cast<difference_type>(result.size()); - while (i < source.size()) - { - // add operations in reverse order to avoid invalid - // indices - result.insert(result.begin() + end_index, object( - { - {"op", "remove"}, - {"path", path + "/" + std::to_string(i)} - })); - ++i; - } - - // add other remaining elements - while (i < target.size()) - { - result.push_back( - { - {"op", "add"}, - {"path", path + "/-"}, - {"value", target[i]} - }); - ++i; - } - - break; - } - - case value_t::object: - { - // first pass: traverse this object's elements - for (auto it = source.cbegin(); it != source.cend(); ++it) - { - // escape the key name to be used in a JSON patch - const auto path_key = path + "/" + detail::escape(it.key()); - - if (target.find(it.key()) != target.end()) - { - // recursive call to compare object values at key it - auto temp_diff = diff(it.value(), target[it.key()], path_key); - result.insert(result.end(), temp_diff.begin(), temp_diff.end()); - } - else - { - // found a key that is not in o -> remove it - result.push_back(object( - { - {"op", "remove"}, {"path", path_key} - })); - } - } - - // second pass: traverse other object's elements - for (auto it = target.cbegin(); it != target.cend(); ++it) - { - if (source.find(it.key()) == source.end()) - { - // found a key that is not in this -> add it - const auto path_key = path + "/" + detail::escape(it.key()); - result.push_back( - { - {"op", "add"}, {"path", path_key}, - {"value", it.value()} - }); - } - } - - break; - } - - case value_t::null: - case value_t::string: - case value_t::boolean: - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - case value_t::binary: - case value_t::discarded: - default: - { - // both primitive type: replace value - result.push_back( - { - {"op", "replace"}, {"path", path}, {"value", target} - }); - break; - } - } - - return result; - } - - /// @} - - //////////////////////////////// - // JSON Merge Patch functions // - //////////////////////////////// - - /// @name JSON Merge Patch functions - /// @{ - - /*! - @brief applies a JSON Merge Patch - - The merge patch format is primarily intended for use with the HTTP PATCH - method as a means of describing a set of modifications to a target - resource's content. This function applies a merge patch to the current - JSON value. - - The function implements the following algorithm from Section 2 of - [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): - - ``` - define MergePatch(Target, Patch): - if Patch is an Object: - if Target is not an Object: - Target = {} // Ignore the contents and set it to an empty Object - for each Name/Value pair in Patch: - if Value is null: - if Name exists in Target: - remove the Name/Value pair from Target - else: - Target[Name] = MergePatch(Target[Name], Value) - return Target - else: - return Patch - ``` - - Thereby, `Target` is the current object; that is, the patch is applied to - the current value. - - @param[in] apply_patch the patch to apply - - @complexity Linear in the lengths of @a patch. - - @liveexample{The following code shows how a JSON Merge Patch is applied to - a JSON document.,merge_patch} - - @sa see @ref patch -- apply a JSON patch - @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - - @since version 3.0.0 - */ - void merge_patch(const basic_json& apply_patch) - { - if (apply_patch.is_object()) - { - if (!is_object()) - { - *this = object(); - } - for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it) - { - if (it.value().is_null()) - { - erase(it.key()); - } - else - { - operator[](it.key()).merge_patch(it.value()); - } - } - } - else - { - *this = apply_patch; - } - } - - /// @} -}; - -/*! -@brief user-defined to_string function for JSON values - -This function implements a user-defined to_string for JSON objects. - -@param[in] j a JSON object -@return a std::string object -*/ - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) -{ - return j.dump(); -} -} // namespace nlohmann - -/////////////////////// -// nonmember support // -/////////////////////// - -// specialization of std::swap, and std::hash -namespace std -{ - -/// hash value for JSON objects -template<> -struct hash<nlohmann::json> -{ - /*! - @brief return a hash value for a JSON object - - @since version 1.0.0 - */ - std::size_t operator()(const nlohmann::json& j) const - { - return nlohmann::detail::hash(j); - } -}; - -/// specialization for std::less<value_t> -/// @note: do not remove the space after '<', -/// see https://github.com/nlohmann/json/pull/679 -template<> -struct less<::nlohmann::detail::value_t> -{ - /*! - @brief compare two value_t enum values - @since version 3.0.0 - */ - bool operator()(nlohmann::detail::value_t lhs, - nlohmann::detail::value_t rhs) const noexcept - { - return nlohmann::detail::operator<(lhs, rhs); - } -}; - -// C++20 prohibit function specialization in the std namespace. -#ifndef JSON_HAS_CPP_20 - -/*! -@brief exchanges the values of two JSON objects - -@since version 1.0.0 -*/ -template<> -inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) - is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression) - is_nothrow_move_assignable<nlohmann::json>::value - ) -{ - j1.swap(j2); -} - -#endif - -} // namespace std - -/*! -@brief user-defined string literal for JSON values - -This operator implements a user-defined string literal for JSON objects. It -can be used by adding `"_json"` to a string literal and returns a JSON object -if no parse error occurred. - -@param[in] s a string representation of a JSON object -@param[in] n the length of string @a s -@return a JSON object - -@since version 1.0.0 -*/ -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json operator "" _json(const char* s, std::size_t n) -{ - return nlohmann::json::parse(s, s + n); -} - -/*! -@brief user-defined string literal for JSON pointer - -This operator implements a user-defined string literal for JSON Pointers. It -can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer -object if no parse error occurred. - -@param[in] s a string representation of a JSON Pointer -@param[in] n the length of string @a s -@return a JSON pointer object - -@since version 2.0.0 -*/ -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) -{ - return nlohmann::json::json_pointer(std::string(s, n)); -} - -// #include <nlohmann/detail/macro_unscope.hpp> - - -// restore clang diagnostic settings -#if defined(__clang__) - #pragma clang diagnostic pop -#endif - -// clean up -#undef JSON_ASSERT -#undef JSON_INTERNAL_CATCH -#undef JSON_CATCH -#undef JSON_THROW -#undef JSON_TRY -#undef JSON_PRIVATE_UNLESS_TESTED -#undef JSON_HAS_CPP_11 -#undef JSON_HAS_CPP_14 -#undef JSON_HAS_CPP_17 -#undef JSON_HAS_CPP_20 -#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION -#undef NLOHMANN_BASIC_JSON_TPL -#undef JSON_EXPLICIT -#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL - -// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp> - - -#undef JSON_HEDLEY_ALWAYS_INLINE -#undef JSON_HEDLEY_ARM_VERSION -#undef JSON_HEDLEY_ARM_VERSION_CHECK -#undef JSON_HEDLEY_ARRAY_PARAM -#undef JSON_HEDLEY_ASSUME -#undef JSON_HEDLEY_BEGIN_C_DECLS -#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#undef JSON_HEDLEY_CLANG_HAS_FEATURE -#undef JSON_HEDLEY_CLANG_HAS_WARNING -#undef JSON_HEDLEY_COMPCERT_VERSION -#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#undef JSON_HEDLEY_CONCAT -#undef JSON_HEDLEY_CONCAT3 -#undef JSON_HEDLEY_CONCAT3_EX -#undef JSON_HEDLEY_CONCAT_EX -#undef JSON_HEDLEY_CONST -#undef JSON_HEDLEY_CONSTEXPR -#undef JSON_HEDLEY_CONST_CAST -#undef JSON_HEDLEY_CPP_CAST -#undef JSON_HEDLEY_CRAY_VERSION -#undef JSON_HEDLEY_CRAY_VERSION_CHECK -#undef JSON_HEDLEY_C_DECL -#undef JSON_HEDLEY_DEPRECATED -#undef JSON_HEDLEY_DEPRECATED_FOR -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#undef JSON_HEDLEY_DIAGNOSTIC_POP -#undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#undef JSON_HEDLEY_DMC_VERSION -#undef JSON_HEDLEY_DMC_VERSION_CHECK -#undef JSON_HEDLEY_EMPTY_BASES -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#undef JSON_HEDLEY_END_C_DECLS -#undef JSON_HEDLEY_FLAGS -#undef JSON_HEDLEY_FLAGS_CAST -#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_BUILTIN -#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_GCC_HAS_EXTENSION -#undef JSON_HEDLEY_GCC_HAS_FEATURE -#undef JSON_HEDLEY_GCC_HAS_WARNING -#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#undef JSON_HEDLEY_GCC_VERSION -#undef JSON_HEDLEY_GCC_VERSION_CHECK -#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#undef JSON_HEDLEY_GNUC_HAS_FEATURE -#undef JSON_HEDLEY_GNUC_HAS_WARNING -#undef JSON_HEDLEY_GNUC_VERSION -#undef JSON_HEDLEY_GNUC_VERSION_CHECK -#undef JSON_HEDLEY_HAS_ATTRIBUTE -#undef JSON_HEDLEY_HAS_BUILTIN -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#undef JSON_HEDLEY_HAS_EXTENSION -#undef JSON_HEDLEY_HAS_FEATURE -#undef JSON_HEDLEY_HAS_WARNING -#undef JSON_HEDLEY_IAR_VERSION -#undef JSON_HEDLEY_IAR_VERSION_CHECK -#undef JSON_HEDLEY_IBM_VERSION -#undef JSON_HEDLEY_IBM_VERSION_CHECK -#undef JSON_HEDLEY_IMPORT -#undef JSON_HEDLEY_INLINE -#undef JSON_HEDLEY_INTEL_CL_VERSION -#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#undef JSON_HEDLEY_INTEL_VERSION -#undef JSON_HEDLEY_INTEL_VERSION_CHECK -#undef JSON_HEDLEY_IS_CONSTANT -#undef JSON_HEDLEY_IS_CONSTEXPR_ -#undef JSON_HEDLEY_LIKELY -#undef JSON_HEDLEY_MALLOC -#undef JSON_HEDLEY_MCST_LCC_VERSION -#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#undef JSON_HEDLEY_MESSAGE -#undef JSON_HEDLEY_MSVC_VERSION -#undef JSON_HEDLEY_MSVC_VERSION_CHECK -#undef JSON_HEDLEY_NEVER_INLINE -#undef JSON_HEDLEY_NON_NULL -#undef JSON_HEDLEY_NO_ESCAPE -#undef JSON_HEDLEY_NO_RETURN -#undef JSON_HEDLEY_NO_THROW -#undef JSON_HEDLEY_NULL -#undef JSON_HEDLEY_PELLES_VERSION -#undef JSON_HEDLEY_PELLES_VERSION_CHECK -#undef JSON_HEDLEY_PGI_VERSION -#undef JSON_HEDLEY_PGI_VERSION_CHECK -#undef JSON_HEDLEY_PREDICT -#undef JSON_HEDLEY_PRINTF_FORMAT -#undef JSON_HEDLEY_PRIVATE -#undef JSON_HEDLEY_PUBLIC -#undef JSON_HEDLEY_PURE -#undef JSON_HEDLEY_REINTERPRET_CAST -#undef JSON_HEDLEY_REQUIRE -#undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#undef JSON_HEDLEY_REQUIRE_MSG -#undef JSON_HEDLEY_RESTRICT -#undef JSON_HEDLEY_RETURNS_NON_NULL -#undef JSON_HEDLEY_SENTINEL -#undef JSON_HEDLEY_STATIC_ASSERT -#undef JSON_HEDLEY_STATIC_CAST -#undef JSON_HEDLEY_STRINGIFY -#undef JSON_HEDLEY_STRINGIFY_EX -#undef JSON_HEDLEY_SUNPRO_VERSION -#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#undef JSON_HEDLEY_TINYC_VERSION -#undef JSON_HEDLEY_TINYC_VERSION_CHECK -#undef JSON_HEDLEY_TI_ARMCL_VERSION -#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL2000_VERSION -#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL430_VERSION -#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL6X_VERSION -#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#undef JSON_HEDLEY_TI_CL7X_VERSION -#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#undef JSON_HEDLEY_TI_CLPRU_VERSION -#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#undef JSON_HEDLEY_TI_VERSION -#undef JSON_HEDLEY_TI_VERSION_CHECK -#undef JSON_HEDLEY_UNAVAILABLE -#undef JSON_HEDLEY_UNLIKELY -#undef JSON_HEDLEY_UNPREDICTABLE -#undef JSON_HEDLEY_UNREACHABLE -#undef JSON_HEDLEY_UNREACHABLE_RETURN -#undef JSON_HEDLEY_VERSION -#undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#undef JSON_HEDLEY_VERSION_DECODE_MINOR -#undef JSON_HEDLEY_VERSION_DECODE_REVISION -#undef JSON_HEDLEY_VERSION_ENCODE -#undef JSON_HEDLEY_WARNING -#undef JSON_HEDLEY_WARN_UNUSED_RESULT -#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#undef JSON_HEDLEY_FALL_THROUGH - - - -#endif // INCLUDE_NLOHMANN_JSON_HPP_ diff --git a/third_party/libarchive b/third_party/libarchive new file mode 160000 +Subproject b1b501161013296d19dfe9acb84a341c8a1755b diff --git a/third_party/libconfig b/third_party/libconfig new file mode 160000 +Subproject 020a9ce12d1be7ab79ca0674fc957e732ab67f4 diff --git a/third_party/qt-aes b/third_party/qt-aes new file mode 160000 +Subproject 845e3b4d3d3873843ca26dc365232aa1aa8ea2a diff --git a/third_party/smtp-mime b/third_party/smtp-mime new file mode 160000 +Subproject 39d6f35ca78327ed2c109e30d630e2ea22363cd diff --git a/third_party/vmime b/third_party/vmime new file mode 160000 +Subproject 0c9dc59b6ff4e612d97cc2103ff948c5cbab0a7 diff --git a/ui/ExportKeyPackageDialog.ui b/ui/ExportKeyPackageDialog.ui index a40d0154..c11c34fe 100644 --- a/ui/ExportKeyPackageDialog.ui +++ b/ui/ExportKeyPackageDialog.ui @@ -1,207 +1,209 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>exportKeyPackageDialog</class> - <widget class="QDialog" name="exportKeyPackageDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>527</width> - <height>385</height> - </rect> - </property> - <property name="windowTitle"> - <string>Export As Key Package</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> + <class>exportKeyPackageDialog</class> + <widget class="QDialog" name="exportKeyPackageDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>527</width> + <height>385</height> + </rect> + </property> + <property name="windowTitle"> + <string>Export As Key Package</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QDialogButtonBox" name="button_box_"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="nameLabel"> + <property name="text"> + <string>Key Package Name</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="gnerateNameButton"> + <property name="text"> + <string>Generate Key Package Name</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="nameValueLabel"> + <property name="text"> + <string>KeyPackage_0000</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="selectOutputPathLabel"> + <property name="text"> + <string>Output Path</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="setOutputPathButton"> + <property name="text"> + <string>Select Output Path</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="outputPathLabel"> + <property name="text"> + <string/> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="passphraseLabel"> + <property name="text"> + <string>Passphrase</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="generatePassphraseButton"> + <property name="text"> + <string>Generate and Save Passphrase</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="passphraseValueLabel"> + <property name="text"> + <string/> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="includeSecretKeyCheckBox"> + <property name="text"> + <string>Include secret key (Think twice before acting)</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="noPublicKeyCheckBox"> + <property name="text"> + <string>Exclude keys that do not have a private key</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="tipsLabel"> + <property name="text"> + <string>Tips: You can use Key Package to safely and conveniently transfer your public + and private keys between devices. + </string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> </widget> - </item> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="nameLabel"> - <property name="text"> - <string>Key Package Name</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="gnerateNameButton"> - <property name="text"> - <string>Generate Key Package Name</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="nameValueLabel"> - <property name="text"> - <string>KeyPackage_0000</string> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="selectOutputPathLabel"> - <property name="text"> - <string>Output Path</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="setOutputPathButton"> - <property name="text"> - <string>Select Output Path</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="outputPathLabel"> - <property name="text"> - <string/> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="passphraseLabel"> - <property name="text"> - <string>Passphrase</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="generatePassphraseButton"> - <property name="text"> - <string>Generate and Save Passphrase</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="passphraseValueLabel"> - <property name="text"> - <string/> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="includeSecretKeyCheckBox"> - <property name="text"> - <string>Include secret key (Think twice before acting)</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="noPublicKeyCheckBox"> - <property name="text"> - <string>Exclude keys that do not have a private key</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="tipsLabel"> - <property name="text"> - <string>Tips: You can use Key Package to safely and conveniently transfer your public and private keys between devices.</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>exportKeyPackageDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>exportKeyPackageDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> + <resources/> + <connections> + <connection> + <sender>button_box_</sender> + <signal>accepted()</signal> + <receiver>exportKeyPackageDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>button_box_</sender> + <signal>rejected()</signal> + <receiver>exportKeyPackageDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> </ui> diff --git a/ui/FilePage.ui b/ui/FilePage.ui index cb4517b1..7a04c992 100644 --- a/ui/FilePage.ui +++ b/ui/FilePage.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>1041</width> - <height>619</height> + <width>798</width> + <height>476</height> </rect> </property> <property name="sizePolicy"> @@ -26,6 +26,21 @@ <string>Form</string> </property> <layout class="QGridLayout" name="gridLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> <item row="0" column="0"> <layout class="QVBoxLayout" name="verticalLayout"> <property name="sizeConstraint"> @@ -121,6 +136,9 @@ <property name="autoFillBackground"> <bool>false</bool> </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> <property name="uniformRowHeights"> <bool>true</bool> </property> @@ -143,31 +161,6 @@ </layout> </item> </layout> - <action name="actionEncrypt"> - <property name="text"> - <string>Encrypt</string> - </property> - </action> - <action name="actionEncryptSign"> - <property name="text"> - <string>EncryptSign</string> - </property> - </action> - <action name="actionDecrypt"> - <property name="text"> - <string>Decrypt</string> - </property> - </action> - <action name="actionSign"> - <property name="text"> - <string>Sign</string> - </property> - </action> - <action name="actionVerify"> - <property name="text"> - <string>Verify</string> - </property> - </action> <action name="actionOpenFile"> <property name="text"> <string>OpenFile</string> @@ -198,6 +191,11 @@ <string>CreateEmptyFile</string> </property> </action> + <action name="actionCompressFiles"> + <property name="text"> + <string>CompressFiles</string> + </property> + </action> </widget> <resources> <include location="../gpgfrontend.qrc"/> diff --git a/ui/ModifiedExpirationDateTime.ui b/ui/ModifiedExpirationDateTime.ui index c6341745..10c1d326 100644 --- a/ui/ModifiedExpirationDateTime.ui +++ b/ui/ModifiedExpirationDateTime.ui @@ -15,7 +15,7 @@ </property> <layout class="QGridLayout" name="gridLayout"> <item row="2" column="0"> - <widget class="QDialogButtonBox" name="buttonBox"> + <widget class="QDialogButtonBox" name="button_box_"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -60,7 +60,9 @@ <item> <widget class="QLabel" name="label"> <property name="text"> - <string>Tips: For the sake of security, the key is valid for up to two years. If you are an expert user, please unlock it for a longer time in the settings.</string> + <string>Tips: For the sake of security, the key is valid for up to two years. If you are + an expert user, please unlock it for a longer time in the settings. + </string> </property> <property name="wordWrap"> <bool>true</bool> @@ -87,7 +89,7 @@ <resources/> <connections> <connection> - <sender>buttonBox</sender> + <sender>button_box_</sender> <signal>accepted()</signal> <receiver>ModifiedExpirationDateTime</receiver> <slot>accept()</slot> @@ -103,7 +105,7 @@ </hints> </connection> <connection> - <sender>buttonBox</sender> + <sender>button_box_</sender> <signal>rejected()</signal> <receiver>ModifiedExpirationDateTime</receiver> <slot>reject()</slot> diff --git a/ui/PlainTextEditor.ui b/ui/PlainTextEditor.ui new file mode 100644 index 00000000..266eba56 --- /dev/null +++ b/ui/PlainTextEditor.ui @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PlainTextEditor</class> + <widget class="QWidget" name="PlainTextEditor"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1007</width> + <height>701</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QPlainTextEdit" name="textPage"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>12</number> + </property> + <item> + <widget class="QLabel" name="loadingLabel"> + <property name="text"> + <string>Loading...</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="characterLabel"> + <property name="text"> + <string>Character</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lfLabel"> + <property name="text"> + <string>LF</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="encodingLabel"> + <property name="text"> + <string>UTF-8</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/ui/ReceiveMailDialog.ui b/ui/ReceiveMailDialog.ui index 61c23738..5895599b 100644 --- a/ui/ReceiveMailDialog.ui +++ b/ui/ReceiveMailDialog.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>643</width> + <width>814</width> <height>657</height> </rect> </property> @@ -14,15 +14,48 @@ <string>Receive Mail</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> + <item row="1" column="0"> <layout class="QVBoxLayout" name="verticalLayout"> <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="refreshButton"> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QTreeWidget" name="treeWidget"> + <widget class="QTreeWidget" name="accountTreeWidget"> + <property name="indentation"> + <number>15</number> + </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <property name="animated"> + <bool>true</bool> + </property> <column> <property name="text"> - <string notr="true">1</string> + <string>Name</string> </property> </column> </widget> @@ -32,6 +65,24 @@ </item> </layout> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> + </layout> + </item> </layout> </item> </layout> diff --git a/ui/SendMailDialog.ui b/ui/SendMailDialog.ui index d29a5f63..f68d2f45 100644 --- a/ui/SendMailDialog.ui +++ b/ui/SendMailDialog.ui @@ -349,7 +349,7 @@ <item alignment="Qt::AlignLeft|Qt::AlignVCenter"> <widget class="QLabel" name="senderKeyLabel"> <property name="text"> - <string>Sender GPG Key: </string> + <string>Sender GPG Key:</string> </property> </widget> </item> @@ -373,7 +373,7 @@ <item alignment="Qt::AlignLeft|Qt::AlignVCenter"> <widget class="QLabel" name="recipientKeysLabel"> <property name="text"> - <string>Recipient(s) GPG Key: </string> + <string>Recipient(s) GPG Key:</string> </property> </widget> </item> |