Repository: ithewei/libhv Branch: master Commit: 62cd137f50d1 Files: 371 Total size: 3.0 MB Directory structure: gitextract_3mi7bcus/ ├── .bazelrc ├── .clang-format ├── .gitattributes ├── .github/ │ └── workflows/ │ ├── CI.yml │ └── benchmark.yml ├── .gitignore ├── .travis.yml ├── BUILD.bazel ├── BUILD.md ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── Makefile.in ├── Makefile.vars ├── README-CN.md ├── README.md ├── TREE.md ├── WORKSPACE.bazel ├── base/ │ ├── README.md │ ├── array.h │ ├── hatomic.h │ ├── hbase.c │ ├── hbase.h │ ├── hbuf.h │ ├── hdef.h │ ├── heap.h │ ├── hendian.h │ ├── herr.c │ ├── herr.h │ ├── hlog.c │ ├── hlog.h │ ├── hmain.c │ ├── hmain.h │ ├── hmath.h │ ├── hmutex.h │ ├── hplatform.h │ ├── hproc.h │ ├── hsocket.c │ ├── hsocket.h │ ├── hsysinfo.h │ ├── hthread.h │ ├── htime.c │ ├── htime.h │ ├── hversion.c │ ├── hversion.h │ ├── list.h │ ├── netinet.h │ ├── queue.h │ ├── rbtree.c │ └── rbtree.h ├── cert/ │ ├── cacert.pem │ ├── gen.sh │ ├── server.crt │ └── server.key ├── cmake/ │ ├── ios.toolchain.cmake │ ├── libhvConfig.cmake │ ├── utils.cmake │ └── vars.cmake ├── config.ini ├── configure ├── cpputil/ │ ├── LRUCache.h │ ├── RAII.cpp │ ├── README.md │ ├── ThreadLocalStorage.cpp │ ├── ThreadLocalStorage.h │ ├── hasync.cpp │ ├── hasync.h │ ├── hdir.cpp │ ├── hdir.h │ ├── hfile.h │ ├── hmap.h │ ├── hobjectpool.h │ ├── hpath.cpp │ ├── hpath.h │ ├── hscope.h │ ├── hstring.cpp │ ├── hstring.h │ ├── hthreadpool.h │ ├── hurl.cpp │ ├── hurl.h │ ├── ifconfig.cpp │ ├── ifconfig.h │ ├── iniparser.cpp │ ├── iniparser.h │ ├── json.hpp │ └── singleton.h ├── docs/ │ ├── API.md │ ├── PLAN.md │ └── cn/ │ ├── Channel.md │ ├── EventLoop.md │ ├── HttpClient.md │ ├── HttpContext.md │ ├── HttpMessage.md │ ├── HttpServer.md │ ├── README.md │ ├── TcpClient.md │ ├── TcpServer.md │ ├── UdpClient.md │ ├── UdpServer.md │ ├── WebSocketClient.md │ ├── WebSocketServer.md │ ├── hbase.md │ ├── hlog.md │ └── hloop.md ├── echo-servers/ │ ├── asio_echo.cpp │ ├── benchmark.sh │ ├── build.sh │ ├── libev_echo.c │ ├── libevent_echo.c │ ├── libhv_echo.c │ ├── libuv_echo.c │ ├── muduo_echo.cpp │ ├── pingpong_client.cpp │ └── poco_echo.cpp ├── etc/ │ ├── hmain_test.conf │ ├── httpd.conf │ └── nginx.conf ├── event/ │ ├── README.md │ ├── epoll.c │ ├── evport.c │ ├── hevent.c │ ├── hevent.h │ ├── hloop.c │ ├── hloop.h │ ├── io_uring.c │ ├── iocp.c │ ├── iowatcher.h │ ├── kcp/ │ │ ├── LICENSE │ │ ├── hkcp.c │ │ ├── hkcp.h │ │ ├── ikcp.c │ │ └── ikcp.h │ ├── kqueue.c │ ├── nio.c │ ├── nlog.c │ ├── nlog.h │ ├── noevent.c │ ├── overlapio.c │ ├── overlapio.h │ ├── poll.c │ ├── rudp.c │ ├── rudp.h │ ├── select.c │ ├── unpack.c │ ├── unpack.h │ └── wepoll/ │ ├── LICENSE │ ├── README.md │ ├── wepoll.c │ └── wepoll.h ├── evpp/ │ ├── Buffer.h │ ├── Channel.h │ ├── Event.h │ ├── EventLoop.h │ ├── EventLoopThread.h │ ├── EventLoopThreadPool.h │ ├── EventLoopThreadPool_test.cpp │ ├── EventLoopThread_test.cpp │ ├── EventLoop_test.cpp │ ├── README.md │ ├── Status.h │ ├── TcpClient.h │ ├── TcpClientEventLoop_test.cpp │ ├── TcpClient_test.cpp │ ├── TcpServer.h │ ├── TcpServer_test.cpp │ ├── TimerThread.h │ ├── TimerThread_test.cpp │ ├── UdpClient.h │ ├── UdpClient_test.cpp │ ├── UdpServer.h │ ├── UdpServer_test.cpp │ └── build_test.sh ├── examples/ │ ├── BUILD.bazel │ ├── CMakeLists.txt │ ├── README.md │ ├── consul/ │ │ ├── consul.cpp │ │ ├── consul.h │ │ └── main.cpp │ ├── curl.cpp │ ├── hloop_test.c │ ├── hmain_test.cpp │ ├── htimer_test.c │ ├── http_client_test.cpp │ ├── http_server_test.cpp │ ├── httpd/ │ │ ├── handler.cpp │ │ ├── handler.h │ │ ├── httpd.cpp │ │ ├── router.cpp │ │ └── router.h │ ├── jsonrpc/ │ │ ├── cJSON.c │ │ ├── cJSON.h │ │ ├── handler.h │ │ ├── jsonrpc_client.c │ │ ├── jsonrpc_server.c │ │ └── router.h │ ├── kcptun/ │ │ ├── README.md │ │ ├── client/ │ │ │ └── main.cpp │ │ ├── server/ │ │ │ └── main.cpp │ │ └── smux/ │ │ ├── smux.cpp │ │ └── smux.h │ ├── mqtt/ │ │ ├── mqtt_client_test.cpp │ │ ├── mqtt_pub.c │ │ └── mqtt_sub.c │ ├── multi-thread/ │ │ ├── multi-acceptor-processes.c │ │ ├── multi-acceptor-threads.c │ │ └── one-acceptor-multi-workers.c │ ├── nc.c │ ├── nmap/ │ │ ├── main.cpp │ │ ├── nmap.cpp │ │ └── nmap.h │ ├── pipe_test.c │ ├── protorpc/ │ │ ├── handler/ │ │ │ ├── calc.h │ │ │ ├── handler.h │ │ │ └── login.h │ │ ├── proto/ │ │ │ ├── base.proto │ │ │ ├── calc.proto │ │ │ ├── login.proto │ │ │ └── protoc.sh │ │ ├── protorpc.c │ │ ├── protorpc.h │ │ ├── protorpc_client.cpp │ │ ├── protorpc_server.cpp │ │ └── router.h │ ├── socks5_proxy_server.c │ ├── tcp_chat_server.c │ ├── tcp_client_test.c │ ├── tcp_echo_server.c │ ├── tcp_proxy_server.c │ ├── tinyhttpd.c │ ├── tinyproxyd.c │ ├── udp_echo_server.c │ ├── udp_proxy_server.c │ ├── websocket_client_test.cpp │ ├── websocket_server_test.cpp │ ├── wget.cpp │ └── wrk.cpp ├── getting_started.sh ├── hconfig.h.in ├── hexport.h ├── html/ │ ├── EventSource.html │ ├── WebSocket.html │ ├── downloads/ │ │ └── 中文.html │ ├── error.html │ ├── index.html │ └── 中文路径/ │ └── 中文名称.txt ├── http/ │ ├── Http1Parser.cpp │ ├── Http1Parser.h │ ├── Http2Parser.cpp │ ├── Http2Parser.h │ ├── HttpMessage.cpp │ ├── HttpMessage.h │ ├── HttpParser.cpp │ ├── HttpParser.h │ ├── README.md │ ├── WebSocketChannel.cpp │ ├── WebSocketChannel.h │ ├── WebSocketParser.cpp │ ├── WebSocketParser.h │ ├── client/ │ │ ├── AsyncHttpClient.cpp │ │ ├── AsyncHttpClient.h │ │ ├── HttpClient.cpp │ │ ├── HttpClient.h │ │ ├── WebSocketClient.cpp │ │ ├── WebSocketClient.h │ │ ├── axios.h │ │ └── requests.h │ ├── grpcdef.h │ ├── http2def.h │ ├── http_content.cpp │ ├── http_content.h │ ├── http_parser.c │ ├── http_parser.h │ ├── httpdef.c │ ├── httpdef.h │ ├── multipart_parser.c │ ├── multipart_parser.h │ ├── server/ │ │ ├── FileCache.cpp │ │ ├── FileCache.h │ │ ├── HttpContext.h │ │ ├── HttpHandler.cpp │ │ ├── HttpHandler.h │ │ ├── HttpMiddleware.cpp │ │ ├── HttpMiddleware.h │ │ ├── HttpResponseWriter.cpp │ │ ├── HttpResponseWriter.h │ │ ├── HttpServer.cpp │ │ ├── HttpServer.h │ │ ├── HttpService.cpp │ │ ├── HttpService.h │ │ ├── WebSocketServer.h │ │ ├── http_page.cpp │ │ └── http_page.h │ ├── websocket_parser.c │ ├── websocket_parser.h │ ├── wsdef.c │ └── wsdef.h ├── hv.h ├── hv.rc.in ├── misc/ │ ├── grpc_server.h │ └── win32_getopt.h ├── mqtt/ │ ├── mqtt_client.c │ ├── mqtt_client.h │ ├── mqtt_protocol.c │ └── mqtt_protocol.h ├── protocol/ │ ├── README.md │ ├── dns.c │ ├── dns.h │ ├── ftp.c │ ├── ftp.h │ ├── icmp.c │ ├── icmp.h │ ├── smtp.c │ └── smtp.h ├── scripts/ │ ├── check.sh │ ├── cmake_cross_compile.sh │ ├── consul.py │ ├── consul_agent.sh │ ├── coredump.sh │ ├── create_repo.sh │ ├── libhv.cmake │ ├── shini.sh │ ├── test-coverage.sh │ ├── toolchain.sh │ ├── unittest.sh │ └── websocket_server.py ├── ssl/ │ ├── appletls.c │ ├── gnutls.c │ ├── hssl.c │ ├── hssl.h │ ├── mbedtls.c │ ├── nossl.c │ ├── openssl.c │ └── wintls.c ├── unittest/ │ ├── CMakeLists.txt │ ├── base64_test.c │ ├── connect_test.c │ ├── date_test.c │ ├── defer_test.cpp │ ├── ftp_test.c │ ├── hatomic_test.c │ ├── hatomic_test.cpp │ ├── hbase_test.c │ ├── hlog_test.c │ ├── hmutex_test.c │ ├── hpath_test.cpp │ ├── hstring_test.cpp │ ├── hthread_test.cpp │ ├── hurl_test.cpp │ ├── ifconfig_test.cpp │ ├── listdir_test.cpp │ ├── md5_test.c │ ├── mkdir_test.c │ ├── nslookup_test.c │ ├── objectpool_test.cpp │ ├── ping_test.c │ ├── rbtree_test.c │ ├── rmdir_test.c │ ├── sendmail_test.c │ ├── sha1_test.c │ ├── sizeof_test.cpp │ ├── socketpair_test.c │ ├── synchronized_test.cpp │ ├── threadpool_test.cpp │ └── webbench.c └── util/ ├── README.md ├── base64.c ├── base64.h ├── md5.c ├── md5.h ├── sha1.c └── sha1.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .bazelrc ================================================ build --copt=-std=c99 build --cxxopt=-std=c++11 build --define BUILD_SHARED=ON build --define BUILD_STATIC=ON build --define BUILD_EXAMPLES=ON build --define BUILD_UNITTEST=OFF build --define WITH_PROTOCOL=OFF build --define WITH_EVPP=ON build --define WITH_HTTP=ON build --define WITH_HTTP_SERVER=ON build --define WITH_HTTP_CLIENT=ON build --define WITH_MQTT=OFF build --define ENABLE_UDS=OFF build --define USE_MULTIMAP=OFF build --define WITH_CURL=OFF build --define WITH_NGHTTP2=OFF build --define WITH_OPENSSL=OFF build --define WITH_GNUTLS=OFF build --define WITH_MBEDTLS=OFF build --define WITH_KCP=OFF build --define WITH_WEPOLL=ON build --define ENABLE_WINDUMP=OFF build --define BUILD_FOR_MT=OFF ================================================ FILE: .clang-format ================================================ --- Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlinesLeft: true AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: Inline AllowShortIfStatementsOnASingleLine: true AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: false BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false BeforeCatch: true BeforeElse: true IndentBraces: false BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 160 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: true DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] IncludeCategories: - Regex: '.*' Priority: 1 - Regex: '^".*/' Priority: 2 - Regex: '^<)' Priority: 3 IncludeIsMainRegex: '$' IndentCaseLabels: false IndentWidth: 4 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: true MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBlockIndentWidth: 4 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: true SortIncludes: false SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp11 TabWidth: 4 UseTab: Never ... ================================================ FILE: .gitattributes ================================================ cpputil/json.hpp linguist-vendored ================================================ FILE: .github/workflows/CI.yml ================================================ name: CI on: push: paths-ignore: - '**.md' pull_request: paths-ignore: - '**.md' jobs: build-linux: name: build-linux runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: build run: | sudo apt update sudo apt install libssl-dev libnghttp2-dev ./configure --with-openssl --with-nghttp2 --with-kcp --with-mqtt make libhv evpp - name: test run: | make check make run-unittest build-windows: name: build-windows runs-on: windows-latest steps: - uses: actions/checkout@v3 - name: build run: | mkdir cmake-build-win64 cd cmake-build-win64 cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release cmake --build . --config Release cd .. - name: test run: | cd cmake-build-win64 start bin/Release/http_server_test bin/Release/http_client_test bin/Release/curl -v -X HEAD http://example.com/ bin/Release/curl -v -X HEAD https://example.com/ bin/Release/wrk -c 100 -t 2 -d 10s http://127.0.0.1:8080/ping build-mac: name: build-mac runs-on: macos-latest steps: - uses: actions/checkout@v3 - name: build run: | ./configure make libhv evpp examples unittest - name: test run: | bin/curl -v -X HEAD http://example.com/ bin/curl -v -X HEAD https://example.com/ build-android: name: build-android runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: build run: | mkdir cmake-build-arm64 cd cmake-build-arm64 cmake .. -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake" -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-21 cmake --build . --target hv --config Release build-ios: name: build-ios runs-on: macos-latest steps: - uses: actions/checkout@v3 - name: build run: | mkdir cmake-build-ios cd cmake-build-ios cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.toolchain.cmake -DPLATFORM=OS64 -DARCHS="arm64" -DDEPLOYMENT_TARGET=9.0 cmake --build . --target hv_static --config Release ================================================ FILE: .github/workflows/benchmark.yml ================================================ name: benchmark on: push: paths-ignore: - '**.md' pull_request: paths-ignore: - '**.md' jobs: benchmark: name: benchmark runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: prepare run: | sudo apt update sudo apt install libssl-dev sudo apt install iperf sudo apt install nginx - name: make examples run: | ./configure make examples - name: build echo-servers run: | bash echo-servers/build.sh - name: benchmark echo-servers run: | bash echo-servers/benchmark.sh - name: benchmark tcp_proxy_server run: | iperf -s -p 5001 > /dev/null & bin/tcp_proxy_server 1212 127.0.0.1:5001 & iperf -c 127.0.0.1 -p 5001 -l 8K iperf -c 127.0.0.1 -p 1212 -l 8K - name: webbench run: | sudo nginx -c /etc/nginx/nginx.conf sudo cp html/index.html index.html sudo cp html/index.html /var/www/html/index.html bin/httpd -c etc/httpd.conf -d ps aux | grep nginx ps aux | grep httpd bin/tinyhttpd 9090 & echo -e "\n======Test nginx send file===============================" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:80/ echo -e "\n======Test libhv/httpd send file (with FileCache)========" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:8080/ echo -e "\n======Test libhv/tinyhttpd send file (no FileCache)======" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:9090/ echo -e "\n======Test nginx 404 Not Found===========================" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:80/404 echo -e "\n======Test libhv/httpd 404 Not Found=====================" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:8080/404 echo -e "\n======Test libhv/tinyhttpd 404 Not found=================" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:9090/404 echo -e "\n======Test libhv/httpd /ping=============================" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:8080/ping echo -e "\n======Test libhv/tinyhttpd /ping=========================" bin/wrk -c 100 -t 2 -d 10s http://127.0.0.1:9090/ping ================================================ FILE: .gitignore ================================================ # Bazel bazel-* MODULE.bazel MODULE.bazel.lock # Compiled Object files *.o *.lo *.slo *.obj # Compiled Depfile *.d # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Compiled Static libraries *.a *.la *.lai *.lib # Executables *.exe *.out *.app # cache *~ *.bk *.bak *.old *.new # IDE .vs .vscode .DS_Store tags cscope* .ycm* # generated examples/protorpc/generated # output *.pid *.log *.db include lib bin tmp dist test *_test build build-* config.mk hconfig.h html/uploads # msvc *.VC.* *.vcxproj.* Debug Release # cmake CMakeFiles CMakeCache.txt cmake_install.cmake _codeql_build_dir/ _codeql_detected_source_root ================================================ FILE: .travis.yml ================================================ language: cpp jobs: include: - os: linux dist: xenial compiler: gcc env: COVERALLS=no script: - ./configure - make libhv examples unittest evpp - os: osx compiler: clang env: COVERALLS=no script: - ./configure - make libhv examples unittest evpp - os: windows compiler: msvc env: COVERALLS=no script: - mkdir win64 - cd win64 - cmake .. -G "Visual Studio 15 2017 Win64" - cmake --build . before_script: - if [ "$COVERALLS" = "yes" ]; then pip install --user cpp-coveralls; export CC="$CC --coverage" CXX="$CXX --coverage"; fi after_success: - if [ "$COVERALLS" = "yes" ]; then scripts/test-coverage.sh; coveralls --gcov-options '\-lp' --include base --include event --include http; fi ================================================ FILE: BUILD.bazel ================================================ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") config_setting( name = "ios", constraint_values = ["@platforms//apple:ios"], ) config_setting( name = "msvc", values = { "compiler": "msvc-cl", }, ) config_setting( name = "debug", values = {"compilation_mode": "dbg"}, ) config_setting( name = "release", values = {"compilation_mode": "opt"}, ) config_setting( name = "build_shared", define_values = {"BUILD_SHARED": "ON"}, ) config_setting( name = "build_static", define_values = {"BUILD_STATIC": "ON"} ) config_setting( name = "build_examples", define_values = {"BUILD_EXAMPLES": "ON"}, ) config_setting( name = "build_unittest", define_values = {"BUILD_UNITTEST": "ON"} ) config_setting( name = "with_protocol", define_values = {"WITH_PROTOCOL": "ON"} ) config_setting( name = "with_evpp", define_values = { "WITH_EVPP": "ON", }, visibility = [":__subpackages__"] ) config_setting( name = "with_http", define_values = { "WITH_EVPP": "ON", "WITH_HTTP": "ON", }, visibility = [":__subpackages__"] ) config_setting( name = "with_http_server", define_values = { "WITH_EVPP": "ON", "WITH_HTTP": "ON", "WITH_HTTP_SERVER": "ON", }, visibility = [":__subpackages__"] ) config_setting( name = "with_http_client", define_values = { "WITH_EVPP": "ON", "WITH_HTTP": "ON", "WITH_HTTP_CLIENT": "ON", }, visibility = [":__subpackages__"] ) config_setting( name = "with_evpp_nghttp2", define_values = { "WITH_EVPP": "ON", "WITH_HTTP": "ON", "WITH_NGHTTP2": "ON", } ) config_setting( name = "with_mqtt", define_values = {"WITH_MQTT": "ON"}, visibility = [":__subpackages__"], ) config_setting( name = "enable_uds", define_values = {"ENABLE_UDS": "ON"} ) config_setting( name = "use_multimap", define_values = {"USE_MULTIMAP": "ON"} ) config_setting( name = "with_curl", define_values = {"WITH_CURL": "ON"} ) config_setting( name = "with_nghttp2", define_values = {"WITH_NGHTTP2": "ON"} ) config_setting( name = "with_openssl", define_values = {"WITH_OPENSSL": "ON"} ) config_setting( name = "with_gnutls", define_values = {"WITH_GNUTLS": "ON"} ) config_setting( name = "with_mbedtls", define_values = {"WITH_MBEDTLS": "ON"} ) config_setting( name = "with_kcp", define_values = {"WITH_KCP": "ON"} ) config_setting( name = "with_wepoll", constraint_values = ["@platforms//os:windows"], define_values = {"WITH_WEPOLL": "ON"} ) config_setting( name = "enable_windump", constraint_values = ["@platforms//os:windows"], define_values = {"ENABLE_WINDUMP": "ON"} ) config_setting( name = "build_for_mt_dbg", constraint_values = ["@platforms//os:windows"], define_values = { "BUILD_FOR_MT": "ON", "compilation_mode": "dbg" } ) config_setting( name = "build_for_mt_opt", constraint_values = ["@platforms//os:windows"], define_values = { "BUILD_FOR_MT": "ON", "compilation_mode": "opt" } ) genrule( name = "config", outs = ["hconfig.h"], cmd = "($(execpath configure) && cp hconfig.h $@) || exit 1", tools = ["configure"], ) HEADERS_DIRS = ["base", "ssl", "event"] + select({ "with_wepoll": ["event/wepoll"], "//conditions:default": [], }) + select({ "with_kcp": ["event/kcp"], "//conditions:default": [], }) + ["util"] + select({ "with_protocol": ["protocol"], "//conditions:default": [], }) + select({ "with_evpp": ["cpputil", "evpp"], "//conditions:default": [], }) + select({ "with_http": ["http"], "//conditions:default": [], }) + select({ "with_http_server": ["http/server"], "//conditions:default": [], }) + select({ "with_http_client": ["http/client"], "//conditions:default": [], }) + select({ "with_mqtt": ["mqtt"], "//conditions:default": [], }) COPTS = select({ "debug": ["-DDEBUG"], "release": ["-DNDEBUG"], "//conditions:default": [], }) + select({ "enable_uds": ["-DENABLE_UDS"], "//conditions:default": [], }) + select({ "use_multimap": ["-DUSE_MULTIMAP"], "//conditions:default": [], }) + select({ "with_curl": ["-DWITH_CURL"], "//conditions:default": [], }) + select({ "with_nghttp2": ["-DWITH_NGHTTP2"], "//conditions:default": [], }) + select({ "with_openssl": ["-DWITH_OPENSSL"], "//conditions:default": [], }) + select({ "with_gnutls": ["-DWITH_GNUTLS"], "//conditions:default": [], }) + select({ "with_mbedtls": ["-DWITH_MBEDTLS"], "//conditions:default": [], }) + select({ "@platforms//os:windows": ["-DWIN32_LEAN_AND_MEAN", "-D_CRT_SECURE_NO_WARNINGS", "-D_WIN32_WINNT=0x0600"], "//conditions:default": [], }) + select({ "enable_windump": ["-DENABLE_WINDUMP"], "//conditions:default": [], }) + select({ "build_for_mt_dbg": ["/MTd"], "build_for_mt_opt": ["/MT"], "//conditions:default": [], }) LINKOPTS = select({ "msvc": [], "//conditions:default": ["-pthread"], }) + select({ "@platforms//os:linux": [ "-lpthread", "-lm", "-ldl", ], "//conditions:default": [], }) + select({ "@bazel_tools//tools/cpp:gcc": ["-lrt"], "//conditions:default": [], }) BASE_HEADERS = [ "base/hplatform.h", "base/hdef.h", "base/hatomic.h", "base/herr.h", "base/htime.h", "base/hmath.h", "base/hbase.h", "base/hversion.h", "base/hsysinfo.h", "base/hproc.h", "base/hthread.h", "base/hmutex.h", "base/hsocket.h", "base/hlog.h", "base/hbuf.h", "base/hmain.h", "base/hendian.h", ] SSL_HEADERS = [ "ssl/hssl.h", ] EVENT_HEADERS = [ "event/hloop.h", "event/nlog.h", ] UTIL_HEADERS = [ "util/base64.h", "util/md5.h", "util/sha1.h", ] CPPUTIL_HEADERS = [ "cpputil/hmap.h", "cpputil/hstring.h", "cpputil/hfile.h", "cpputil/hpath.h", "cpputil/hdir.h", "cpputil/hurl.h", "cpputil/hscope.h", "cpputil/hthreadpool.h", "cpputil/hasync.h", "cpputil/hobjectpool.h", "cpputil/ifconfig.h", "cpputil/iniparser.h", "cpputil/json.hpp", "cpputil/singleton.h", "cpputil/ThreadLocalStorage.h", ] EVPP_HEADERS = [ "evpp/Buffer.h", "evpp/Channel.h", "evpp/Event.h", "evpp/EventLoop.h", "evpp/EventLoopThread.h", "evpp/EventLoopThreadPool.h", "evpp/Status.h", "evpp/TcpClient.h", "evpp/TcpServer.h", "evpp/UdpClient.h", "evpp/UdpServer.h", ] PROTOCOL_HEADERS = [ "protocol/icmp.h", "protocol/dns.h", "protocol/ftp.h", "protocol/smtp.h", ] HTTP_HEADERS = [ "http/httpdef.h", "http/wsdef.h", "http/http_content.h", "http/HttpMessage.h", "http/HttpParser.h", "http/WebSocketParser.h", "http/WebSocketChannel.h", ] HTTP2_HEADERS = [ "http/http2def.h", "http/grpcdef.h", ] HTTP_CLIENT_HEADERS = [ "http/client/HttpClient.h", "http/client/requests.h", "http/client/axios.h", "http/client/AsyncHttpClient.h", "http/client/WebSocketClient.h", ] HTTP_SERVER_HEADERS = [ "http/server/HttpServer.h", "http/server/HttpService.h", "http/server/HttpContext.h", "http/server/HttpResponseWriter.h", "http/server/WebSocketServer.h", ] MQTT_HEADERS = [ "mqtt/mqtt_protocol.h", "mqtt/mqtt_client.h", ] HEADERS = ["hv.h", ":config", "hexport.h"] + BASE_HEADERS + SSL_HEADERS + EVENT_HEADERS + UTIL_HEADERS + select({ "with_protocol": PROTOCOL_HEADERS, "//conditions:default": [], }) + select({ "with_evpp": CPPUTIL_HEADERS + EVPP_HEADERS, "//conditions:default": [], }) + select({ "with_http": HTTP_HEADERS, "//conditions:default": [], }) + select({ "with_evpp_nghttp2": HTTP2_HEADERS, "//conditions:default": [], }) + select({ "with_http_server": HTTP_SERVER_HEADERS, "//conditions:default": [], }) + select({ "with_http_client": HTTP_CLIENT_HEADERS, "//conditions:default": [], }) + select({ "with_mqtt": MQTT_HEADERS, "//conditions:default": [], }) CORE_SRCS = glob( ["*.h"], exclude = ["*_test.c"] ) + glob( ["base/*.h", "base/*.c", "base/*.cpp"], exclude = ["base/*_test.c"] ) + glob( ["ssl/*.h", "ssl/*.c", "ssl/*.cpp"], exclude = ["ssl/*_test.c"] ) + glob( ["event/*.h", "event/*.c", "event/*.cpp"], exclude = ["event/*_test.c"] ) + select({ "with_wepoll": glob(["event/wepoll/*.h", "event/wepoll/*.c", "event/wepoll/*.cpp"], exclude = ["event/wepoll/*_test.c"]), "//conditions:default": [], }) + select({ "with_kcp": glob(["event/kcp/*.h", "event/kcp/*.c", "event/kcp/*.cpp"], exclude = ["event/kcp/*_test.c"]), "//conditions:default": [], }) SRCS = CORE_SRCS + glob(["util/*.h", "util/*.c", "util/*.cpp"], exclude = ["util/*_test.c"]) + select({ "with_protocol": glob(["protocol/*.h", "protocol/*.c", "protocol/*.cpp"], exclude = ["protocol/*_test.c"]), "//conditions:default": [], }) + select({ "with_evpp": glob(["cpputil/*.h", "cpputil/*.c", "cpputil/*.cpp", "evpp/*.h", "evpp/*.c", "evpp/*.cpp"], exclude = ["cpputil/*_test.c", "evpp/*_test.c", "evpp/*_test.cpp"]), "//conditions:default": [], }) + select({ "with_http": glob(["http/*.h", "http/*.c", "http/*.cpp"], exclude = ["http/*_test.c"]), "//conditions:default": [], }) + select({ "with_http_server": glob(["http/server/*.h", "http/server/*.c", "http/server/*.cpp"], exclude = ["http/server/*_test.c"]), "//conditions:default": [], }) + select({ "with_http_client": glob(["http/client/*.h", "http/client/*.c", "http/client/*.cpp"], exclude = ["http/client/*_test.c"]), "//conditions:default": [], }) + select({ "with_mqtt": glob(["mqtt/*.h", "mqtt/*.c", "mqtt/*.cpp"], exclude = ["mqtt/*_test.c"]), "//conditions:default": [], }) cc_library( name = "hv_static", srcs = SRCS, hdrs = HEADERS, includes = HEADERS_DIRS, defines = ["HV_STATICLIB"], copts = COPTS, linkstatic = True, linkopts = LINKOPTS, ) cc_library( name = "hv", srcs = SRCS, hdrs = HEADERS, includes = HEADERS_DIRS, defines = ["HV_DYNAMICLIB"], copts = COPTS, linkopts = LINKOPTS, visibility = ["//visibility:public"] ) filegroup( name = "libhv", srcs = select({ "build_shared": [":hv"], "//conditions:default": [], }) + select({ "build_static": [":hv_static"], "//conditions:default": [], }) + select({ "build_examples": ["//examples:examples"], "//conditions:default": [], }) ) ================================================ FILE: BUILD.md ================================================ ## Prequired - c99 - c++11 gcc4.8+, msvc2015 or later ## Makefile options see [config.ini](config.ini) ``` ./configure --with-openssl make sudo make install ``` ## cmake options see [CMakeLists.txt](CMakeLists.txt) ``` mkdir build cd build cmake .. -DWITH_OPENSSL=ON cmake --build . ``` ## bazel options see [.bazelrc](.bazelrc) ``` bazel build libhv ``` ## Unix use Makefile or cmake or bazel ## Windows use cmake ``` mkdir win64 cd win64 cmake .. -G "Visual Studio 15 2017 Win64" #cmake .. -G "Visual Studio 16 2019" -A x64 #cmake .. -G "Visual Studio 17 2022" -A x64 cmake --build . ``` ## CROSS_COMPILE use Makefile ``` sudo apt install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi # ubuntu export CROSS_COMPILE=arm-linux-gnueabi- ./configure make clean make libhv ``` or use cmake ``` mkdir build cd build cmake .. -DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc -DCMAKE_CXX_COMPILER=arm-linux-gnueabi-g++ cmake --build . --target libhv libhv_static ``` ### mingw see CROSS_COMPILE ``` sudo apt install mingw-w64 # ubuntu #export CROSS_COMPILE=i686-w64-mingw32- export CROSS_COMPILE=x86_64-w64-mingw32- ./configure make clean make libhv ``` ### Android ``` #https://developer.android.com/ndk/downloads #export ANDROID_NDK_ROOT=~/Downloads/android-ndk-r21b mkdir build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake" -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-21 cmake --build . --target hv --config Release ``` ### iOS ``` mkdir build cd build cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.toolchain.cmake -DPLATFORM=OS64 -DARCHS="arm64" -DDEPLOYMENT_TARGET=9.0 cmake --build . --target hv_static --config Release ``` ## targets ### lib - make libhv ### examples - make examples ### unittest - make unittest ## options ### compile without c++ ``` ./configure --without-evpp make clean && make libhv ``` ### compile WITH_OPENSSL Enable SSL/TLS in libhv is so easy :) ``` // see ssl/hssl.h hssl_ctx_t hssl_ctx_new(hssl_ctx_opt_t* opt); // see event/hloop.h int hio_new_ssl_ctx(hio_t* io, hssl_ctx_opt_t* opt); ``` https is the best example. ``` sudo apt install openssl libssl-dev # ubuntu ./configure --with-openssl make clean && make bin/httpd -s restart -d bin/curl -v http://localhost:8080 bin/curl -v https://localhost:8443 ``` ### compile WITH_CURL ``` ./configure --with-curl make clean && make bin/httpd -s restart -d bin/curl -v http://localhost:8080 ``` ### compile WITH_NGHTTP2 ``` sudo apt install libnghttp2-dev # ubuntu ./configure --with-nghttp2 make clean && make bin/httpd -s restart -d bin/curl -v http://localhost:8080 --http2 ``` ### compile WITH_KCP ``` ./configure --with-kcp make clean && make ``` ### compile WITH_MQTT ``` ./configure --with-mqtt make clean && make ``` ### More ``` ./configure --help ``` ================================================ FILE: CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.6) cmake_policy(SET CMP0077 NEW) project(hv VERSION 1.3.4) option(BUILD_SHARED "build shared library" ON) option(BUILD_STATIC "build static library" ON) option(BUILD_EXAMPLES "build examples" ON) option(BUILD_UNITTEST "build unittest" OFF) # see config.ini option(WITH_PROTOCOL "compile protocol" OFF) option(WITH_EVPP "compile evpp" ON) option(WITH_HTTP "compile http" ON) option(WITH_HTTP_SERVER "compile http/server" ON) option(WITH_HTTP_CLIENT "compile http/client" ON) option(WITH_MQTT "compile mqtt" OFF) option(ENABLE_UDS "Unix Domain Socket" OFF) option(USE_MULTIMAP "MultiMap" OFF) option(WITH_CURL "with curl library (deprecated)" OFF) option(WITH_NGHTTP2 "with nghttp2 library" OFF) option(WITH_OPENSSL "with openssl library" OFF) option(WITH_GNUTLS "with gnutls library" OFF) option(WITH_MBEDTLS "with mbedtls library" OFF) option(WITH_KCP "compile event/kcp" OFF) if(CMAKE_SYSTEM_NAME MATCHES "Linux") option(WITH_IO_URING "with io_uring" OFF) endif() if(WIN32 OR MINGW) option(WITH_WEPOLL "compile event/wepoll -> use iocp" ON) option(ENABLE_WINDUMP "Windows MiniDumpWriteDump" OFF) option(BUILD_FOR_MT "build for /MT" OFF) if(BUILD_FOR_MT) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") endif() endif() message(STATUS "CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}") message(STATUS "CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}") if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") set(BUILD_EXAMPLES OFF) endif() if(IOS) set(BUILD_SHARED OFF) set(BUILD_EXAMPLES OFF) endif() set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") include(utils) include(vars) # see configure # Checks for header files check_header("stdbool.h") check_header("stdint.h") check_header("stdatomic.h") check_header("sys/types.h") check_header("sys/stat.h") check_header("sys/time.h") check_header("fcntl.h") check_header("pthread.h") check_header("endian.h") check_header("sys/endian.h") # Checks for functions if(NOT MSVC) set(CMAKE_REQUIRED_LIBRARIES "-pthread") endif() check_function("gettid" "unistd.h") check_function("strlcpy" "string.h") check_function("strlcat" "string.h") check_function("clock_gettime" "time.h") check_function("gettimeofday" "sys/time.h") check_function("pthread_spin_lock" "pthread.h") check_function("pthread_mutex_timedlock" "pthread.h") check_function("sem_timedwait" "semaphore.h") check_function("pipe" "unistd.h") check_function("socketpair" "sys/socket.h") check_function("eventfd" "sys/eventfd.h") check_function("setproctitle" "unistd.h") if (NOT HAVE_CLOCK_GETTIME) include(CheckLibraryExists) check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME_IN_RT) if (HAVE_CLOCK_GETTIME_IN_RT) set(HAVE_CLOCK_GETTIME ${HAVE_CLOCK_GETTIME_IN_RT}) endif() endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hconfig.h.in ${CMAKE_CURRENT_SOURCE_DIR}/hconfig.h) # see Makefile.in set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED True) if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_C_COMPILER_ID STREQUAL "GNU") set(CMAKE_C_EXTENSIONS ON) endif() set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) set(INCDIR include) set(SRCDIR src) set(LIBDIR lib) set(BINDIR bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIBDIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIBDIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINDIR}) message(STATUS "CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") set(INCDIRS . include 3rd/include) set(LIBDIRS . lib 3rd/lib) include_directories(${INCDIRS} ${SRCDIR}) link_directories(${LIBDIRS}) message(STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") add_definitions(-DDEBUG) else() add_definitions(-DNDEBUG) endif() if(ENABLE_UDS) add_definitions(-DENABLE_UDS) endif() if(USE_MULTIMAP) add_definitions(-DUSE_MULTIMAP) endif() if(WITH_CURL) add_definitions(-DWITH_CURL) set(LIBS ${LIBS} curl) if(WIN32 OR MINGW) set(LIBS ${LIBS} wldap32 advapi32 crypt32) endif() endif() if(WITH_NGHTTP2) add_definitions(-DWITH_NGHTTP2) set(LIBS ${LIBS} nghttp2) endif() if(WITH_OPENSSL) add_definitions(-DWITH_OPENSSL) find_package(OpenSSL) if(OpenSSL_FOUND) set(LIBS ${LIBS} OpenSSL::SSL OpenSSL::Crypto) else() set(LIBS ${LIBS} ssl crypto) endif() endif() if(WITH_GNUTLS) add_definitions(-DWITH_GNUTLS) set(LIBS ${LIBS} gnutls) endif() if(WITH_MBEDTLS) add_definitions(-DWITH_MBEDTLS) set(LIBS ${LIBS} mbedtls mbedx509 mbedcrypto) endif() if(WITH_IO_URING) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") message(FATAL_ERROR "WITH_IO_URING is only supported on Linux because liburing is Linux-only.") endif() set(LIBS ${LIBS} uring) endif() if(WIN32 OR MINGW) add_definitions(-DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS -D_WIN32_WINNT=0x0600) set(LIBS ${LIBS} secur32 crypt32 winmm iphlpapi ws2_32) if(ENABLE_WINDUMP) add_definitions(-DENABLE_WINDUMP) set(LIBS ${LIBS} dbghelp) endif() endif() if(ANDROID) set(LIBS ${LIBS} log) elseif(UNIX AND NOT MINGW) set(LIBS ${LIBS} pthread m dl) find_library(RT_LIBRARY rt) if(RT_LIBRARY) set(LIBS ${LIBS} rt) endif() endif() if(APPLE) set(LIBS ${LIBS} "-framework CoreFoundation" "-framework Security") endif() # see Makefile set(ALL_SRCDIRS . base ssl event event/kcp util cpputil evpp protocol http http/client http/server mqtt) set(CORE_SRCDIRS . base ssl event) if(WIN32 OR MINGW) if(WITH_WEPOLL) set(CORE_SRCDIRS ${CORE_SRCDIRS} event/wepoll) endif() endif() if(WITH_KCP) set(CORE_SRCDIRS ${CORE_SRCDIRS} event/kcp) endif() set(LIBHV_SRCDIRS ${CORE_SRCDIRS} util) set(LIBHV_HEADERS hv.h hconfig.h hexport.h) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${BASE_HEADERS} ${SSL_HEADERS} ${EVENT_HEADERS} ${UTIL_HEADERS}) if(WITH_PROTOCOL) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${PROTOCOL_HEADERS}) set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} protocol) endif() if(WITH_EVPP) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${CPPUTIL_HEADERS} ${EVPP_HEADERS}) set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} cpputil evpp) if(WITH_HTTP) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${HTTP_HEADERS}) set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} http) if(WITH_NGHTTP2) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${HTTP2_HEADERS}) endif() if(WITH_HTTP_SERVER) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${HTTP_SERVER_HEADERS}) set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} http/server) endif() if(WITH_HTTP_CLIENT) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${HTTP_CLIENT_HEADERS}) set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} http/client) endif() endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND CMAKE_COMPILER_IS_GNUCC) set(LIBS ${LIBS} stdc++) endif() endif() if(WITH_MQTT) set(LIBHV_HEADERS ${LIBHV_HEADERS} ${MQTT_HEADERS}) set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} mqtt) endif() list_source_directories(LIBHV_SRCS ${LIBHV_SRCDIRS}) if(WIN32) set(CMAKE_RC_FLAGS_DEBUG -D_DEBUG) configure_file(${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.rc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.rc) list(APPEND LIBHV_SRCS ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.rc) endif() file(INSTALL ${LIBHV_HEADERS} DESTINATION include/hv) file(INSTALL ${LIBHV_HEADERS} DESTINATION ${PROJECT_SOURCE_DIR}/include/hv) if(BUILD_SHARED) add_library(hv SHARED ${LIBHV_SRCS}) target_compile_definitions(hv PRIVATE HV_DYNAMICLIB) target_include_directories(hv PRIVATE ${LIBHV_SRCDIRS} INTERFACE $ $) target_link_libraries(hv ${LIBS}) install(TARGETS hv EXPORT libhvConfig ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin) add_custom_target(libhv DEPENDS hv) endif() if(BUILD_STATIC) add_library(hv_static STATIC ${LIBHV_SRCS}) target_compile_definitions(hv_static PUBLIC HV_STATICLIB) target_include_directories(hv_static PRIVATE ${LIBHV_SRCDIRS} INTERFACE $ $) target_link_libraries(hv_static ${LIBS}) if(NOT (WIN32 AND BUILD_SHARED)) set_target_properties(hv_static PROPERTIES OUTPUT_NAME hv) endif() install(TARGETS hv_static EXPORT libhvConfig ARCHIVE DESTINATION lib) add_custom_target(libhv_static DEPENDS hv_static) endif() if(WIN32 AND NOT MINGW) if(BUILD_SHARED) install(FILES $ DESTINATION bin OPTIONAL) endif() endif() install(FILES ${LIBHV_HEADERS} DESTINATION include/hv) install(EXPORT libhvConfig DESTINATION lib/cmake/libhv) if(BUILD_SHARED) set(HV_LIBRARIES hv CACHE INTERNAL "link hv libraries") else() add_definitions(-DHV_STATICLIB) set(HV_LIBRARIES hv_static ${LIBS} CACHE INTERNAL "link hv libraries") endif() if(BUILD_EXAMPLES) add_subdirectory(examples) # for httpd -c etc/httpd.conf file(INSTALL etc DESTINATION ${CMAKE_BINARY_DIR}) file(INSTALL etc DESTINATION ${CMAKE_BINARY_DIR}/bin) file(INSTALL etc DESTINATION ${CMAKE_BINARY_DIR}/examples) endif() if(BUILD_UNITTEST) add_subdirectory(unittest) endif() # CPack settings set(CPACK_PACKAGE_NAME "libhv") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") set(CPACK_PACKAGE_RELEASE 1) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A high-performance C/C++ network library") set(CPACK_PACKAGE_VENDOR "libhv") set(CPACK_PACKAGE_CONTACT "ithewei ") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") # Specify the package generators set(CPACK_GENERATOR "TGZ;DEB;RPM") # Enable CPack debug output set(CPACK_PACKAGE_DEBUG True) # https://cmake.org/cmake/help/latest/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.html set(CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION "ON") include(CPack) ================================================ FILE: LICENSE ================================================ BSD 3-Clause License Copyright (c) 2020, ithewei All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: Makefile ================================================ include config.mk include Makefile.vars MAKEF=$(MAKE) -f Makefile.in ALL_SRCDIRS=. base ssl event event/kcp util cpputil evpp protocol http http/client http/server mqtt CORE_SRCDIRS=. base ssl event ifeq ($(WITH_KCP), yes) CORE_SRCDIRS += event/kcp endif BUILD_SHARED ?= yes BUILD_STATIC ?= yes LIBHV_SRCDIRS = $(CORE_SRCDIRS) util LIBHV_HEADERS = hv.h hconfig.h hexport.h LIBHV_HEADERS += $(BASE_HEADERS) $(SSL_HEADERS) $(EVENT_HEADERS) $(UTIL_HEADERS) ifeq ($(WITH_PROTOCOL), yes) LIBHV_HEADERS += $(PROTOCOL_HEADERS) LIBHV_SRCDIRS += protocol endif ifeq ($(WITH_EVPP), yes) LIBHV_HEADERS += $(CPPUTIL_HEADERS) $(EVPP_HEADERS) LIBHV_SRCDIRS += cpputil evpp ifeq ($(WITH_HTTP), yes) LIBHV_HEADERS += $(HTTP_HEADERS) LIBHV_SRCDIRS += http ifeq ($(WITH_NGHTTP2), yes) LIBHV_HEADERS += $(HTTP2_HEADERS) endif ifeq ($(WITH_HTTP_SERVER), yes) LIBHV_HEADERS += $(HTTP_SERVER_HEADERS) LIBHV_SRCDIRS += http/server endif ifeq ($(WITH_HTTP_CLIENT), yes) LIBHV_HEADERS += $(HTTP_CLIENT_HEADERS) LIBHV_SRCDIRS += http/client endif endif endif ifeq ($(WITH_MQTT), yes) LIBHV_HEADERS += $(MQTT_HEADERS) LIBHV_SRCDIRS += mqtt endif default: all all: libhv examples @echo "make all done, please enjoy libhv." EXAMPLES = hmain_test htimer_test hloop_test pipe_test \ nc tinyhttpd tinyproxyd \ tcp_client_test \ tcp_echo_server \ tcp_chat_server \ tcp_proxy_server \ udp_echo_server \ udp_proxy_server \ socks5_proxy_server \ multi-acceptor-processes \ multi-acceptor-threads \ one-acceptor-multi-workers \ jsonrpc ifeq ($(WITH_EVPP), yes) EXAMPLES += nmap ifeq ($(WITH_HTTP), yes) EXAMPLES += wrk ifeq ($(WITH_HTTP_SERVER), yes) EXAMPLES += http_server_test websocket_server_test endif ifeq ($(WITH_HTTP_CLIENT), yes) EXAMPLES += curl wget consul http_client_test websocket_client_test ifeq ($(WITH_HTTP_SERVER), yes) EXAMPLES += httpd endif endif endif endif ifeq ($(WITH_MQTT), yes) EXAMPLES += mqtt_sub mqtt_pub mqtt_client_test endif examples: $(EXAMPLES) @echo "make examples done." clean: $(MAKEF) clean SRCDIRS="$(ALL_SRCDIRS)" $(RM) examples/*.o examples/*/*.o $(RM) include/hv @echo "make clean done." prepare: $(MKDIR) bin libhv: $(MKDIR) lib ifeq ($(BUILD_SHARED), yes) ifeq ($(BUILD_STATIC), yes) $(MAKEF) TARGET=$@ TARGET_TYPE="SHARED|STATIC" SRCDIRS="$(LIBHV_SRCDIRS)" else $(MAKEF) TARGET=$@ TARGET_TYPE="SHARED" SRCDIRS="$(LIBHV_SRCDIRS)" endif else ifeq ($(BUILD_STATIC), yes) $(MAKEF) TARGET=$@ TARGET_TYPE="STATIC" SRCDIRS="$(LIBHV_SRCDIRS)" endif endif $(MKDIR) include/hv $(CP) $(LIBHV_HEADERS) include/hv @echo "make libhv done." install: $(MKDIR) $(INSTALL_INCDIR) $(MKDIR) $(INSTALL_LIBDIR) $(CP) include/hv/* $(INSTALL_INCDIR) $(CP) lib/libhv.* $(INSTALL_LIBDIR) $(LDCONFIG) @echo "make install done." uninstall: clean $(RM) $(PREFIX)/include/hv $(RM) $(PREFIX)/lib/libhv.* @echo "make uninstall done." hmain_test: prepare $(MAKEF) TARGET=$@ SRCDIRS=". base cpputil" SRCS="examples/hmain_test.cpp" htimer_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/htimer_test.c" hloop_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/hloop_test.c" pipe_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/pipe_test.c" tcp_client_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/tcp_client_test.c" tcp_echo_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/tcp_echo_server.c" tcp_chat_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/tcp_chat_server.c" tcp_proxy_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/tcp_proxy_server.c" udp_echo_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/udp_echo_server.c" udp_proxy_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/udp_proxy_server.c" socks5_proxy_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/socks5_proxy_server.c" multi-acceptor-processes: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/multi-thread/multi-acceptor-processes.c" multi-acceptor-threads: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/multi-thread/multi-acceptor-threads.c" one-acceptor-multi-workers: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/multi-thread/one-acceptor-multi-workers.c" nc: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/nc.c" tinyhttpd: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/tinyhttpd.c" tinyproxyd: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/tinyproxyd.c" nmap: prepare libhv $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) cpputil examples/nmap" DEFINES="PRINT_DEBUG" wrk: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http" SRCS="examples/wrk.cpp" httpd: prepare $(RM) examples/httpd/*.o $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client http/server examples/httpd" consul: prepare libhv $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client examples/consul" DEFINES="PRINT_DEBUG" curl: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client" SRCS="examples/curl.cpp" # $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client" SRCS="examples/curl.cpp" WITH_CURL=yes wget: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client" SRCS="examples/wget.cpp" http_server_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/server" SRCS="examples/http_server_test.cpp" http_client_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client" SRCS="examples/http_client_test.cpp" websocket_server_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/server" SRCS="examples/websocket_server_test.cpp" websocket_client_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) util cpputil evpp http http/client" SRCS="examples/websocket_client_test.cpp" mqtt_sub: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) mqtt" SRCS="examples/mqtt/mqtt_sub.c" mqtt_pub: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) mqtt" SRCS="examples/mqtt/mqtt_pub.c" mqtt_client_test: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) mqtt" SRCS="examples/mqtt/mqtt_client_test.cpp" kcptun: kcptun_client kcptun_server kcptun_client: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) examples/kcptun/smux examples/kcptun/client" kcptun_server: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) examples/kcptun/smux examples/kcptun/server" jsonrpc: jsonrpc_client jsonrpc_server jsonrpc_client: prepare $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/jsonrpc/jsonrpc_client.c examples/jsonrpc/cJSON.c" jsonrpc_server: prepare $(RM) examples/jsonrpc/*.o $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS)" SRCS="examples/jsonrpc/jsonrpc_server.c examples/jsonrpc/cJSON.c" protorpc: protorpc_client protorpc_server protorpc_protoc: bash examples/protorpc/proto/protoc.sh protorpc_client: prepare protorpc_protoc $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) cpputil evpp examples/protorpc/generated" \ SRCS="examples/protorpc/protorpc_client.cpp examples/protorpc/protorpc.c" \ LIBS="protobuf" protorpc_server: prepare protorpc_protoc $(RM) examples/protorpc/*.o $(MAKEF) TARGET=$@ SRCDIRS="$(CORE_SRCDIRS) cpputil evpp examples/protorpc/generated" \ SRCS="examples/protorpc/protorpc_server.cpp examples/protorpc/protorpc.c" \ LIBS="protobuf" unittest: prepare $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/rbtree_test unittest/rbtree_test.c base/rbtree.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hbase_test unittest/hbase_test.c base/hbase.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/mkdir_p unittest/mkdir_test.c base/hbase.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/rmdir_p unittest/rmdir_test.c base/hbase.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/date unittest/date_test.c base/htime.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hlog_test unittest/hlog_test.c base/hlog.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hatomic_test unittest/hatomic_test.c -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -o bin/hatomic_cpp_test unittest/hatomic_test.cpp -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -o bin/hthread_test unittest/hthread_test.cpp -pthread $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hmutex_test unittest/hmutex_test.c base/htime.c -pthread $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/connect_test unittest/connect_test.c base/hsocket.c base/htime.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/socketpair_test unittest/socketpair_test.c base/hsocket.c base/htime.c $(CC) -g -Wall -O0 -std=c99 -I. -Iutil -o bin/base64 unittest/base64_test.c util/base64.c $(CC) -g -Wall -O0 -std=c99 -I. -Iutil -o bin/md5 unittest/md5_test.c util/md5.c $(CC) -g -Wall -O0 -std=c99 -I. -Iutil -o bin/sha1 unittest/sha1_test.c util/sha1.c $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/hstring_test unittest/hstring_test.cpp cpputil/hstring.cpp $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/hpath_test unittest/hpath_test.cpp cpputil/hpath.cpp $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/hurl_test unittest/hurl_test.cpp cpputil/hurl.cpp base/hbase.c $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/ls unittest/listdir_test.cpp cpputil/hdir.cpp $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/ifconfig unittest/ifconfig_test.cpp cpputil/ifconfig.cpp $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/defer_test unittest/defer_test.cpp $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/synchronized_test unittest/synchronized_test.cpp -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/threadpool_test unittest/threadpool_test.cpp -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Icpputil -o bin/objectpool_test unittest/objectpool_test.cpp -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Ievpp -Icpputil -Ihttp -Ihttp/client -Ihttp/server -o bin/sizeof_test unittest/sizeof_test.cpp $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -Iprotocol -o bin/nslookup unittest/nslookup_test.c protocol/dns.c base/hsocket.c base/htime.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -Iprotocol -o bin/ping unittest/ping_test.c protocol/icmp.c base/hsocket.c base/htime.c -DPRINT_DEBUG $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -Iprotocol -o bin/ftp unittest/ftp_test.c protocol/ftp.c base/hsocket.c base/htime.c $(CC) -g -Wall -O0 -std=c99 -I. -Ibase -Iprotocol -Iutil -o bin/sendmail unittest/sendmail_test.c protocol/smtp.c base/hsocket.c base/htime.c util/base64.c run-unittest: unittest bash scripts/unittest.sh check: examples bash scripts/check.sh evpp: prepare libhv $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/EventLoop_test evpp/EventLoop_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/EventLoopThread_test evpp/EventLoopThread_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/EventLoopThreadPool_test evpp/EventLoopThreadPool_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/TimerThread_test evpp/TimerThread_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/TcpServer_test evpp/TcpServer_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/TcpClient_test evpp/TcpClient_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/TcpClientEventLoop_test evpp/TcpClientEventLoop_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/UdpServer_test evpp/UdpServer_test.cpp -Llib -lhv -pthread $(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -o bin/UdpClient_test evpp/UdpClient_test.cpp -Llib -lhv -pthread # UNIX only webbench: prepare $(CC) -o bin/webbench unittest/webbench.c echo-servers: $(CXX) -g -Wall -std=c++11 -O3 -o bin/pingpong_client echo-servers/pingpong_client.cpp -lhv -pthread $(CC) -g -Wall -std=c99 -O3 -o bin/libevent_echo echo-servers/libevent_echo.c -levent $(CC) -g -Wall -std=c99 -O3 -o bin/libev_echo echo-servers/libev_echo.c -lev $(CC) -g -Wall -std=c99 -O3 -o bin/libuv_echo echo-servers/libuv_echo.c -luv $(CC) -g -Wall -std=c99 -O3 -o bin/libhv_echo echo-servers/libhv_echo.c -lhv $(CXX) -g -Wall -std=c++11 -O3 -o bin/asio_echo echo-servers/asio_echo.cpp -lboost_system -pthread $(CXX) -g -Wall -std=c++11 -O3 -o bin/poco_echo echo-servers/poco_echo.cpp -lPocoNet -lPocoUtil -lPocoFoundation # $(CXX) -g -Wall -std=c++11 -O3 -o bin/muduo_echo echo-servers/muduo_echo.cpp -lmuduo_net -lmuduo_base -pthread echo-benchmark: echo-servers bash echo-servers/benchmark.sh .PHONY: clean prepare install uninstall libhv examples unittest evpp echo-servers ================================================ FILE: Makefile.in ================================================ #+++++++++++++++++++++++++++++++++configure++++++++++++++++++++++++++++++++++++++++ # OS=Windows,Linux,Android # ARCH=x86,x86_64,arm,aarch64 # CC = $(CROSS_COMPILE)gcc # CXX = $(CROSS_COMPILE)g++ # CPPFLAGS += $(addprefix -D, $(DEFINES)) # CPPFLAGS += $(addprefix -I, $(SRCDIRS)) # CPPFLAGS += $(addprefix -I, $(INCDIRS)) # LDFLAGS += $(addprefix -L, $(LIBDIRS)) # LDFLAGS += $(addprefix -l, $(LIBS)) # # Usage: # make all \ # TARGET=libxx \ # TARGET_TYPE=SHARED \ # BUILD_TYPE=DEBUG \ # CROSS_COMPILE=arm-linux-androideabi- \ # SRCDIRS="src/base src/event" \ # INCDIRS="src/util" \ # SRCS="src/util/hmain.cpp src/util/iniparser.cpp" \ # DEFINES=USE_OPENCV \ # LIBS="opencv_core opencv_highgui" #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -include config.mk # VARIABLES TARGET ?= test # BUILD_TYPE=DEBUG,RELEASE BUILD_TYPE ?= RELEASE # TARGET_TYPE=EXECUTABLE,SHARED,STATIC,SHARED|STATIC TARGET_TYPE ?= EXECUTABLE # COMMANDS ifdef CROSS_COMPILE CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ CPP = $(CC) -E AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip endif MKDIR = -mkdir -p 2>/dev/null CP = -cp -r 2>/dev/null RM = -rm -r 2>/dev/null # PLATFORM: OS, ARCH CC_VERSION=$(shell $(CC) --version 2>&1 | head -n 1) TARGET_PLATFORM=$(shell $(CC) -v 2>&1 | grep Target | sed 's/Target: //') ifneq ($(findstring mingw, $(TARGET_PLATFORM)), ) OS=Windows endif ifneq ($(findstring android, $(TARGET_PLATFORM)), ) OS=Android endif ifneq ($(findstring darwin, $(TARGET_PLATFORM)), ) OS=Darwin endif ifndef OS OS=Linux endif ifndef ARCH ARCH=$(shell echo $(TARGET_PLATFORM) | awk -F'-' '{print $$1}') endif # CFLAGS, CXXFLAGS, ARFLAGS BUILD_TYPE_UPPER := $(shell echo $(BUILD_TYPE) | tr 'a-z' 'A-Z') ifeq ($(BUILD_TYPE_UPPER), DEBUG) DEFAULT_CFLAGS = -g -Wall -O0 else DEFAULT_CFLAGS += -O2 endif CFLAGS ?= $(DEFAULT_CFLAGS) CXXFLAGS ?= $(DEFAULT_CFLAGS) ifneq ($(OS), Windows) ifeq ($(findstring -fPIC, $(CFLAGS)), ) override CFLAGS += -fPIC endif ifeq ($(findstring -fPIC, $(CXXFLAGS)), ) override CXXFLAGS += -fPIC endif endif ifeq ($(findstring -std, $(CFLAGS)), ) ifeq ($(OS), Linux) override CFLAGS += -std=gnu99 else override CFLAGS += -std=c99 endif endif ifeq ($(findstring -std, $(CXXFLAGS)), ) override CXXFLAGS += -std=c++11 endif override CFLAGS += -MMD override CXXFLAGS += -MMD ARFLAGS ?= cr # DIRS ifeq ($(OS), Linux) PREFIX ?= /usr/local else PREFIX ?= install endif INCDIR = include LIBDIR = lib SRCDIR = src BINDIR = bin DEPDIR = 3rd CONFDIR = etc DISTDIR = dist DOCDIR = docs SRCDIRS += $(shell find $(SRCDIR) -type d) override INCDIRS += $(INCDIR) $(DEPDIR) $(DEPDIR)/include override LIBDIRS += $(LIBDIR) $(DEPDIR)/lib $(DEPDIR)/lib/$(TARGET_PLATFORM) ALL_SRCS += $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c $(dir)/*.cc $(dir)/*.cpp)) ifeq ($(ALL_SRCS), ) ALL_SRCS = $(wildcard *.c *.cc *.cpp) endif override SRCS += $(filter-out %_test.c %_test.cc %_test.cpp, $(ALL_SRCS)) # OBJS += $(patsubst %.c, %.o, $(SRCS)) # OBJS += $(patsubst %.cc, %.o, $(SRCS)) # OBJS += $(patsubst %.cpp, %.o, $(SRCS)) OBJS := $(addsuffix .o, $(basename $(SRCS))) DEPS := $(OBJS:.o=.d) INSTALLED_INCS=$(addprefix $(PREFIX)/$(INCDIR)/, $(shell ls $(INCDIR))) INSTALLED_LIBS=$(addprefix $(PREFIX)/$(LIBDIR)/, $(shell ls $(LIBDIR))) INSTALLED_BINS=$(addprefix $(PREFIX)/$(BINDIR)/, $(shell ls $(BINDIR))) # CPPFLAGS ifeq ($(OS), Windows) CPPFLAGS += -D_WIN32_WINNT=0x600 ifeq ($(TARGET_TYPE), SHARED) CPPFLAGS += -DDLL_EXPORTS endif endif ifeq ($(BUILD_TYPE_UPPER), DEBUG) CPPFLAGS += -DDEBUG else CPPFLAGS += -DNDEBUG endif ifeq ($(ENABLE_UDS), yes) CPPFLAGS += -DENABLE_UDS endif ifeq ($(USE_MULTIMAP), yes) CPPFLAGS += -DUSE_MULTIMAP endif CPPFLAGS += $(addprefix -D, $(DEFINES)) CPPFLAGS += $(addprefix -I, $(INCDIRS)) CPPFLAGS += $(addprefix -I, $(SRCDIRS)) # LDFLAGS ifeq ($(OS), Windows) LDFLAGS += -static-libgcc -static-libstdc++ endif ifeq ($(WITH_CURL), yes) CPPFLAGS += -DWITH_CURL LDFLAGS += -lcurl ifeq ($(OS), Windows) LDFLAGS += -lwldap32 -ladvapi32 -lcrypt32 endif endif ifeq ($(WITH_NGHTTP2), yes) CPPFLAGS += -DWITH_NGHTTP2 LDFLAGS += -lnghttp2 endif ifeq ($(WITH_OPENSSL), yes) CPPFLAGS += -DWITH_OPENSSL LDFLAGS += -lssl -lcrypto else ifeq ($(WITH_GNUTLS), yes) CPPFLAGS += -DWITH_GNUTLS LDFLAGS += -lgnutls else ifeq ($(WITH_MBEDTLS), yes) CPPFLAGS += -DWITH_MBEDTLS LDFLAGS += -lmbedtls -lmbedx509 -lmbedcrypto endif endif endif ifeq ($(OS), Linux) ifeq ($(WITH_IO_URING), yes) LDFLAGS += -luring endif endif LDFLAGS += $(addprefix -L, $(LIBDIRS)) LDFLAGS += $(addprefix -l, $(LIBS)) ifeq ($(OS), Windows) LDFLAGS += -lsecur32 -lcrypt32 -lwinmm -liphlpapi -lws2_32 ifeq ($(ENABLE_WINDUMP), yes) CPPFLAGS += -DENABLE_WINDUMP LDFLAGS += -ldbghelp endif LDFLAGS += -Wl,-Bstatic -lstdc++ -lpthread -lm else ifeq ($(filter %.cc %.cpp, $(SRCS)), ) LINK = $(CC) else LINK = $(CXX) LDFLAGS += -lstdc++ endif ifeq ($(OS), Android) LDFLAGS += -lm -llog -ldl else LDFLAGS += -lpthread -lm -ldl LINK_RT=$(shell echo "int main(){return 0;}" | $(CC) -x c - -lrt 2>&1) ifeq ($(LINK_RT), ) LDFLAGS += -lrt endif endif endif ifeq ($(OS), Darwin) LDFLAGS += -framework CoreFoundation -framework Security endif LINK ?= $(CC) # info $(info $(CC_VERSION)) $(info OS = $(OS)) $(info ARCH = $(ARCH)) $(info MAKE = $(MAKE)) $(info CC = $(CC)) $(info CXX = $(CXX)) $(info CFLAGS = $(CFLAGS)) $(info CXXFLAGS = $(CXXFLAGS)) $(info CPPFLAGS = $(CPPFLAGS)) $(info LDFLAGS = $(LDFLAGS)) $(info TARGET = $(TARGET)) $(info TARGET_TYPE = $(TARGET_TYPE)) $(info TARGET_PLATFORM = $(TARGET_PLATFORM)) $(info BUILD_TYPE = $(BUILD_TYPE)) $(info SRCS=$(SRCS)) $(info OBJS=$(OBJS)) # $(info INSTALLED_INCS=$(INSTALLED_INCS)) # $(info INSTALLED_LIBS=$(INSTALLED_LIBS)) # $(info INSTALLED_BINS=$(INSTALLED_BINS)) default: all all: prepare $(TARGET) prepare: $(MKDIR) $(BINDIR) $(LIBDIR) $(TARGET): $(OBJS) ifneq ($(findstring SHARED, $(TARGET_TYPE)), ) ifeq ($(OS), Windows) $(LINK) -shared $^ -o $(LIBDIR)/$@.dll $(LDFLAGS) -Wl,--output-def,$(LIBDIR)/$(@).def else ifeq ($(OS), Darwin) $(LINK) -dynamiclib -install_name @rpath/$@.dylib $^ -o $(LIBDIR)/$@.dylib $(LDFLAGS) else $(LINK) -shared $^ -o $(LIBDIR)/$@.so $(LDFLAGS) endif endif endif ifneq ($(findstring STATIC, $(TARGET_TYPE)), ) $(AR) $(ARFLAGS) $(LIBDIR)/$@.a $^ endif ifneq ($(findstring EXECUTABLE, $(TARGET_TYPE)), ) ifeq ($(OS), Windows) $(LINK) $^ -o $(BINDIR)/$@.exe $(LDFLAGS) else $(LINK) $^ -o $(BINDIR)/$@ $(LDFLAGS) endif endif clean: $(RM) $(OBJS) $(DEPS) #$(RM) $(LIBDIR) #$(RM) $(BINDIR) install: $(CP) $(INCDIR)/* $(PREFIX)/$(INCDIR)/ $(CP) $(LIBDIR)/* $(PREFIX)/$(LIBDIR)/ $(CP) $(BINDIR)/* $(PREFIX)/$(BINDIR)/ $(LDCONFIG) uninstall: $(RM) $(INSTALLED_INCS) $(RM) $(INSTALLED_LIBS) $(RM) $(INSTALLED_BINS) dist: $(MKDIR) $(DISTDIR) $(CP) $(INCDIR) $(LIBDIR) $(BINDIR) $(CONFDIR) $(DOCDIR) $(DISTDIR) undist: $(RM) $(DISTDIR) -include $(DEPS) .PHONY: default all prepare clean install uninstall dist undist ================================================ FILE: Makefile.vars ================================================ MKDIR = -mkdir -p 2>/dev/null CP = -cp -r 2>/dev/null RM = -rm -r 2>/dev/null LDCONFIG = -ldconfig 2>/dev/null PREFIX ?= /usr/local INSTALL_INCDIR ?= $(PREFIX)/include/hv INSTALL_LIBDIR ?= $(PREFIX)/lib BASE_HEADERS = base/hplatform.h\ \ base/hdef.h\ base/hatomic.h\ base/herr.h\ base/htime.h\ base/hmath.h\ base/hbase.h\ base/hversion.h\ base/hsysinfo.h\ base/hproc.h\ base/hthread.h\ base/hmutex.h\ base/hsocket.h\ base/hlog.h\ base/hbuf.h\ base/hmain.h\ base/hendian.h\ SSL_HEADERS = ssl/hssl.h EVENT_HEADERS = event/hloop.h\ event/nlog.h\ UTIL_HEADERS = util/base64.h\ util/md5.h\ util/sha1.h\ CPPUTIL_HEADERS = cpputil/hmap.h\ cpputil/hstring.h\ cpputil/hfile.h\ cpputil/hpath.h\ cpputil/hdir.h\ cpputil/hurl.h\ cpputil/hscope.h\ cpputil/hthreadpool.h\ cpputil/hasync.h\ cpputil/hobjectpool.h\ cpputil/ifconfig.h\ cpputil/iniparser.h\ cpputil/json.hpp\ cpputil/singleton.h\ cpputil/LRUCache.h\ cpputil/ThreadLocalStorage.h\ EVPP_HEADERS = evpp/Buffer.h\ evpp/Channel.h\ evpp/Event.h\ evpp/EventLoop.h\ evpp/EventLoopThread.h\ evpp/EventLoopThreadPool.h\ evpp/Status.h\ evpp/TcpClient.h\ evpp/TcpServer.h\ evpp/UdpClient.h\ evpp/UdpServer.h\ PROTOCOL_HEADERS = protocol/icmp.h\ protocol/dns.h\ protocol/ftp.h\ protocol/smtp.h HTTP_HEADERS = http/httpdef.h\ http/wsdef.h\ http/http_content.h\ http/HttpMessage.h\ http/HttpParser.h\ http/WebSocketParser.h\ http/WebSocketChannel.h\ HTTP2_HEADERS = http/http2def.h\ http/grpcdef.h\ HTTP_CLIENT_HEADERS = http/client/HttpClient.h\ http/client/requests.h\ http/client/axios.h\ http/client/AsyncHttpClient.h\ http/client/WebSocketClient.h\ HTTP_SERVER_HEADERS = http/server/HttpServer.h\ http/server/HttpService.h\ http/server/HttpContext.h\ http/server/HttpResponseWriter.h\ http/server/WebSocketServer.h\ MQTT_HEADERS = mqtt/mqtt_protocol.h\ mqtt/mqtt_client.h\ ================================================ FILE: README-CN.md ================================================ [English](README.md) | 中文 # libhv [![Linux](https://badgen.net/badge/Linux/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![Windows](https://badgen.net/badge/Windows/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![macOS](https://badgen.net/badge/macOS/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![Android](https://badgen.net/badge/Android/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![iOS](https://badgen.net/badge/iOS/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![benchmark](https://github.com/ithewei/libhv/workflows/benchmark/badge.svg?branch=master)](https://github.com/ithewei/libhv/actions/workflows/benchmark.yml?query=branch%3Amaster)
[![release](https://badgen.net/github/release/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/releases) [![stars](https://badgen.net/github/stars/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/stargazers) [![forks](https://badgen.net/github/forks/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/forks) [![issues](https://badgen.net/github/issues/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/issues) [![PRs](https://badgen.net/github/prs/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/pulls) [![contributors](https://badgen.net/github/contributors/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/contributors) [![license](https://badgen.net/github/license/ithewei/libhv?icon=github)](LICENSE)
[![gitee](https://badgen.net/badge/mirror/gitee/red)](https://gitee.com/libhv/libhv) [![awesome-c](https://badgen.net/badge/icon/awesome-c/pink?icon=awesome&label&color)](https://github.com/oz123/awesome-c) [![awesome-cpp](https://badgen.net/badge/icon/awesome-cpp/pink?icon=awesome&label&color)](https://github.com/fffaraz/awesome-cpp) `libhv`是一个类似于`libevent、libev、libuv`的跨平台网络库,提供了更易用的接口和更丰富的协议。 ## 📚 中文资料 - **libhv QQ群**: `739352073`,欢迎加群交流 - **libhv 源码剖析**: - **libhv 接口手册**: - **libhv 教程目录**: - [libhv教程01--介绍与体验](https://hewei.blog.csdn.net/article/details/113702536) - [libhv教程02--编译与安装](https://hewei.blog.csdn.net/article/details/113704737) - [libhv教程03--链库与使用](https://hewei.blog.csdn.net/article/details/113706378) - [libhv教程04--编写一个完整的命令行程序](https://hewei.blog.csdn.net/article/details/113719503) - [libhv教程05--事件循环以及定时器的简单使用](https://hewei.blog.csdn.net/article/details/113724474) - [libhv教程06--创建一个简单的TCP服务端](https://hewei.blog.csdn.net/article/details/113737580) - [libhv教程07--创建一个简单的TCP客户端](https://hewei.blog.csdn.net/article/details/113738900) - [libhv教程08--创建一个简单的UDP服务端](https://hewei.blog.csdn.net/article/details/113871498) - [libhv教程09--创建一个简单的UDP客户端](https://hewei.blog.csdn.net/article/details/113871724) - [libhv教程10--创建一个简单的HTTP服务端](https://hewei.blog.csdn.net/article/details/113982999) - [libhv教程11--创建一个简单的HTTP客户端](https://hewei.blog.csdn.net/article/details/113984302) - [libhv教程12--创建一个简单的WebSocket服务端](https://hewei.blog.csdn.net/article/details/113985321) - [libhv教程13--创建一个简单的WebSocket客户端](https://hewei.blog.csdn.net/article/details/113985895) - [libhv教程14--200行实现一个纯C版jsonrpc框架](https://hewei.blog.csdn.net/article/details/119920540) - [libhv教程15--200行实现一个C++版protorpc框架](https://hewei.blog.csdn.net/article/details/119966701) - [libhv教程16--多线程/多进程服务端编程](https://hewei.blog.csdn.net/article/details/120366024) - [libhv教程17--Qt中使用libhv](https://hewei.blog.csdn.net/article/details/120699890) - [libhv教程18--动手写一个tinyhttpd](https://hewei.blog.csdn.net/article/details/121706604) - [libhv教程19--MQTT的实现与使用](https://hewei.blog.csdn.net/article/details/122753665) ## ✨ 特性 - 跨平台(Linux, Windows, macOS, Android, iOS, BSD, Solaris) - 高性能事件循环(网络IO事件、定时器事件、空闲事件、自定义事件、信号) - TCP/UDP服务端/客户端/代理 - TCP支持心跳、重连、转发、多线程安全write和close等特性 - 内置常见的拆包模式(固定包长、分界符、头部长度字段) - 可靠UDP支持: WITH_KCP - SSL/TLS加密通信(可选WITH_OPENSSL、WITH_GNUTLS、WITH_MBEDTLS) - HTTP服务端/客户端(支持https http1/x http2 grpc) - HTTP支持静态文件服务、目录服务、正向/反向代理服务、同步/异步API处理器 - HTTP支持RESTful风格、路由、中间件、keep-alive长连接、chunked分块、SSE等特性 - WebSocket服务端/客户端 - MQTT客户端 ## ⌛️ 构建 见[BUILD.md](BUILD.md) libhv提供了以下构建方式: 1、通过Makefile: ```shell ./configure make sudo make install ``` 2、通过cmake: ```shell mkdir build cd build cmake .. cmake --build . ``` 3、通过bazel: ```shell bazel build libhv ``` 4、通过vcpkg: ```shell vcpkg install libhv ``` 5、通过xmake: ```shell xrepo install libhv ``` ## ⚡️ 快速入门 ### 体验 运行脚本`./getting_started.sh`: ```shell # 下载编译 git clone https://github.com/ithewei/libhv.git cd libhv ./configure make # 运行httpd服务 bin/httpd -h bin/httpd -d #bin/httpd -c etc/httpd.conf -s restart -d ps aux | grep httpd # 文件服务 bin/curl -v localhost:8080 # 目录服务 bin/curl -v localhost:8080/downloads/ # API服务 bin/curl -v localhost:8080/ping bin/curl -v localhost:8080/echo -d "hello,world!" bin/curl -v localhost:8080/query?page_no=1\&page_size=10 bin/curl -v localhost:8080/kv -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456' bin/curl -v localhost:8080/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}' bin/curl -v localhost:8080/form -F 'user=admin' -F 'pswd=123456' bin/curl -v localhost:8080/upload -d "@LICENSE" bin/curl -v localhost:8080/upload -F "file=@LICENSE" bin/curl -v localhost:8080/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello' bin/curl -v localhost:8080/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}' bin/curl -v localhost:8080/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello' # RESTful API: /group/:group_name/user/:user_id bin/curl -v -X DELETE localhost:8080/group/test/user/123 # 压力测试 bin/wrk -c 1000 -d 10 -t 4 http://127.0.0.1:8080/ ``` ### TCP #### TCP服务端 **c版本**: [examples/tcp_echo_server.c](examples/tcp_echo_server.c) **c++版本**: [evpp/TcpServer_test.cpp](evpp/TcpServer_test.cpp) ```c++ #include "TcpServer.h" using namespace hv; int main() { int port = 1234; TcpServer srv; int listenfd = srv.createsocket(port); if (listenfd < 0) { return -1; } printf("server listen on port %d, listenfd=%d ...\n", port, listenfd); srv.onConnection = [](const SocketChannelPtr& channel) { std::string peeraddr = channel->peeraddr(); if (channel->isConnected()) { printf("%s connected! connfd=%d\n", peeraddr.c_str(), channel->fd()); } else { printf("%s disconnected! connfd=%d\n", peeraddr.c_str(), channel->fd()); } }; srv.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) { // echo channel->write(buf); }; srv.setThreadNum(4); srv.start(); // press Enter to stop while (getchar() != '\n'); return 0; } ``` **注意**: 以上示例只是简单的`echo`服务,TCP是流式协议,实际应用中请务必添加边界进行拆包。
文本协议建议加上`\0`或者`\r\n`分隔符,可参考 [examples/jsonrpc](examples/jsonrpc);
二进制协议建议加上自定义协议头,通过头部长度字段表明负载长度,可参考 [examples/protorpc](examples/protorpc);
通过`setUnpack`(c接口即`hio_set_unpack`)设置拆包规则,支持固定包长、分隔符、头部长度字段三种常见的拆包方式,
内部根据拆包规则处理粘包与分包,保证`onMessage`回调上来的是完整的一包数据,大大节省了上层处理粘包与分包的成本。
不想自定义协议和拆包组包的可直接使用现成的`HTTP/WebSocket`协议。

`channel->write`(c接口即`hio_write`)是非阻塞的(事件循环异步编程里所有的一切都要求是非阻塞的),且多线程安全的。
发送大数据时应该做流控,通过`onWriteComplete`监听写完成事件,在可写时再发送下一帧数据。
具体示例代码可参考 [examples/tinyhttpd.c](examples/tinyhttpd.c) 中的 `http_serve_file`。

`channel->close`(c接口即`hio_close`) 也是多线程安全的,这可以让网络IO事件循环线程里接收数据、拆包组包、反序列化后放入队列,
消费者线程/线程池从队列里取出数据、处理后发送响应和关闭连接,变得更加简单。
#### TCP客户端 **c版本**: [examples/tcp_client_test.c](examples/tcp_client_test.c) **c++版本**: [evpp/TcpClient_test.cpp](evpp/TcpClient_test.cpp) ```c++ #include #include "TcpClient.h" using namespace hv; int main() { int port = 1234; TcpClient cli; int connfd = cli.createsocket(port); if (connfd < 0) { return -1; } cli.onConnection = [](const SocketChannelPtr& channel) { std::string peeraddr = channel->peeraddr(); if (channel->isConnected()) { printf("connected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd()); } else { printf("disconnected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd()); } }; cli.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) { printf("< %.*s\n", (int)buf->size(), (char*)buf->data()); }; cli.start(); std::string str; while (std::getline(std::cin, str)) { if (str == "close") { cli.closesocket(); } else if (str == "start") { cli.start(); } else if (str == "stop") { cli.stop(); break; } else { if (!cli.isConnected()) break; cli.send(str); } } return 0; } ``` ### HTTP #### HTTP服务端 见[examples/http_server_test.cpp](examples/http_server_test.cpp) **golang gin 风格** ```c++ #include "HttpServer.h" using namespace hv; int main() { HttpService router; router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) { return resp->String("pong"); }); router.GET("/data", [](HttpRequest* req, HttpResponse* resp) { static char data[] = "0123456789"; return resp->Data(data, 10); }); router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) { return resp->Json(router.Paths()); }); router.GET("/get", [](HttpRequest* req, HttpResponse* resp) { resp->json["origin"] = req->client_addr.ip; resp->json["url"] = req->url; resp->json["args"] = req->query_params; resp->json["headers"] = req->headers; return 200; }); router.POST("/echo", [](const HttpContextPtr& ctx) { return ctx->send(ctx->body(), ctx->type()); }); HttpServer server(&router); server.setPort(8080); server.setThreadNum(4); server.run(); return 0; } ``` **注意**: 上面示例直接运行在`main`主线程,`server.run()`会阻塞当前线程运行,所以`router`和`server`对象不会被析构,
如使用`server.start()`内部会另起线程运行,不会阻塞当前线程,但需要注意`router`和`server`的生命周期,
不要定义为局部变量被析构了,可定义为类成员变量或者全局变量,下面的`WebSocket`服务同理。
#### HTTP客户端 见[examples/http_client_test.cpp](examples/http_client_test.cpp) **python requests 风格** ```c++ #include "requests.h" int main() { auto resp = requests::get("http://www.example.com"); if (resp == NULL) { printf("request failed!\n"); } else { printf("%s\n", resp->body.c_str()); } resp = requests::post("127.0.0.1:8080/echo", "hello,world!"); if (resp == NULL) { printf("request failed!\n"); } else { printf("%s\n", resp->body.c_str()); } return 0; } ``` 附HTTP相关接口文档: - [class HttpMessage](docs/cn/HttpMessage.md) - [class HttpClient](docs/cn/HttpClient.md) - [class HttpServer](docs/cn/HttpServer.md) - [class HttpContext](docs/cn/HttpContext.md) ### WebSocket #### WebSocket服务端 见[examples/websocket_server_test.cpp](examples/websocket_server_test.cpp) ```c++ #include "WebSocketServer.h" using namespace hv; int main(int argc, char** argv) { WebSocketService ws; ws.onopen = [](const WebSocketChannelPtr& channel, const HttpRequestPtr& req) { printf("onopen: GET %s\n", req->Path().c_str()); }; ws.onmessage = [](const WebSocketChannelPtr& channel, const std::string& msg) { printf("onmessage: %.*s\n", (int)msg.size(), msg.data()); }; ws.onclose = [](const WebSocketChannelPtr& channel) { printf("onclose\n"); }; WebSocketServer server(&ws); server.setPort(9999); server.setThreadNum(4); server.run(); return 0; } ``` #### WebSocket客户端 见[examples/websocket_client_test.cpp](examples/websocket_client_test.cpp) ```c++ #include "WebSocketClient.h" using namespace hv; int main(int argc, char** argv) { WebSocketClient ws; ws.onopen = []() { printf("onopen\n"); }; ws.onmessage = [](const std::string& msg) { printf("onmessage: %.*s\n", (int)msg.size(), msg.data()); }; ws.onclose = []() { printf("onclose\n"); }; // reconnect: 1,2,4,8,10,10,10... reconn_setting_t reconn; reconn_setting_init(&reconn); reconn.min_delay = 1000; reconn.max_delay = 10000; reconn.delay_policy = 2; ws.setReconnect(&reconn); ws.open("ws://127.0.0.1:9999/test"); std::string str; while (std::getline(std::cin, str)) { if (!ws.isConnected()) break; if (str == "quit") { ws.close(); break; } ws.send(str); } return 0; } ``` ## 🍭 更多示例 ### c版本 - 事件循环: [examples/hloop_test.c](examples/hloop_test.c) - 定时器: [examples/htimer_test.c](examples/htimer_test.c) - pipe示例: [examples/pipe_test.c](examples/pipe_test.c) - TCP回显服务: [examples/tcp_echo_server.c](examples/tcp_echo_server.c) - TCP聊天服务: [examples/tcp_chat_server.c](examples/tcp_chat_server.c) - TCP代理服务: [examples/tcp_proxy_server.c](examples/tcp_proxy_server.c) - UDP回显服务: [examples/udp_echo_server.c](examples/udp_echo_server.c) - UDP代理服务: [examples/udp_proxy_server.c](examples/udp_proxy_server.c) - SOCKS5代理服务: [examples/socks5_proxy_server.c](examples/socks5_proxy_server.c) - HTTP服务: [examples/tinyhttpd.c](examples/tinyhttpd.c) - HTTP代理服务: [examples/tinyproxyd.c](examples/tinyproxyd.c) - jsonRPC示例: [examples/jsonrpc](examples/jsonrpc) - MQTT示例: [examples/mqtt](examples/mqtt) - 多accept进程模式: [examples/multi-thread/multi-acceptor-processes.c](examples/multi-thread/multi-acceptor-processes.c) - 多accept线程模式: [examples/multi-thread/multi-acceptor-threads.c](examples/multi-thread/multi-acceptor-threads.c) - 一个accept线程+多worker线程: [examples/multi-thread/one-acceptor-multi-workers.c](examples/multi-thread/one-acceptor-multi-workers.c) ### c++版本 - 事件循环: [evpp/EventLoop_test.cpp](evpp/EventLoop_test.cpp) - 事件循环线程: [evpp/EventLoopThread_test.cpp](evpp/EventLoopThread_test.cpp) - 事件循环线程池: [evpp/EventLoopThreadPool_test.cpp](evpp/EventLoopThreadPool_test.cpp) - 定时器: [evpp/TimerThread_test.cpp](evpp/TimerThread_test.cpp) - TCP服务端: [evpp/TcpServer_test.cpp](evpp/TcpServer_test.cpp) - TCP客户端: [evpp/TcpClient_test.cpp](evpp/TcpClient_test.cpp) - UDP服务端: [evpp/UdpServer_test.cpp](evpp/UdpServer_test.cpp) - UDP客户端: [evpp/UdpClient_test.cpp](evpp/UdpClient_test.cpp) - HTTP服务端: [examples/http_server_test.cpp](examples/http_server_test.cpp) - HTTP客户端: [examples/http_client_test.cpp](examples/http_client_test.cpp) - WebSocket服务端: [examples/websocket_server_test.cpp](examples/websocket_server_test.cpp) - WebSocket客户端: [examples/websocket_client_test.cpp](examples/websocket_client_test.cpp) - protobufRPC示例: [examples/protorpc](examples/protorpc) - Qt中使用libhv示例: [hv-projects/QtDemo](https://github.com/hv-projects/QtDemo) ### 模拟实现著名的命令行工具 - 网络连接工具: [examples/nc](examples/nc.c) - 网络扫描工具: [examples/nmap](examples/nmap) - HTTP服务程序: [examples/httpd](examples/httpd) - HTTP压测工具: [examples/wrk](examples/wrk.cpp) - URL请求工具: [examples/curl](examples/curl.cpp) - 文件下载工具: [examples/wget](examples/wget.cpp) - 服务注册与发现: [examples/consul](examples/consul) - kcptun隧道: [examples/kcptun](examples/kcptun) ## 🥇 性能测试 ### TCP回显服务pingpong测试 ```shell cd echo-servers ./build.sh ./benchmark.sh ``` **吞吐量**: ```shell libevent running on port 2001 libev running on port 2002 libuv running on port 2003 libhv running on port 2004 asio running on port 2005 poco running on port 2006 ==============2001===================================== [127.0.0.1:2001] 4 threads 1000 connections run 10s total readcount=1616761 readbytes=1655563264 throughput = 157 MB/s ==============2002===================================== [127.0.0.1:2002] 4 threads 1000 connections run 10s total readcount=2153171 readbytes=2204847104 throughput = 210 MB/s ==============2003===================================== [127.0.0.1:2003] 4 threads 1000 connections run 10s total readcount=1599727 readbytes=1638120448 throughput = 156 MB/s ==============2004===================================== [127.0.0.1:2004] 4 threads 1000 connections run 10s total readcount=2202271 readbytes=2255125504 throughput = 215 MB/s ==============2005===================================== [127.0.0.1:2005] 4 threads 1000 connections run 10s total readcount=1354230 readbytes=1386731520 throughput = 132 MB/s ==============2006===================================== [127.0.0.1:2006] 4 threads 1000 connections run 10s total readcount=1699652 readbytes=1740443648 throughput = 165 MB/s ``` ### TCP代理服务压测 ```shell # sudo apt install iperf iperf -s -p 5001 > /dev/null & bin/tcp_proxy_server 1212 127.0.0.1:5001 & iperf -c 127.0.0.1 -p 5001 -l 8K iperf -c 127.0.0.1 -p 1212 -l 8K ``` **带宽**: ```shell ------------------------------------------------------------ [ 3] local 127.0.0.1 port 52560 connected with 127.0.0.1 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 20.8 GBytes 17.9 Gbits/sec ------------------------------------------------------------ [ 3] local 127.0.0.1 port 48142 connected with 127.0.0.1 port 1212 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 11.9 GBytes 10.2 Gbits/sec ``` ### HTTP压测 ```shell # sudo apt install wrk wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/ # sudo apt install apache2-utils ab -c 100 -n 100000 http://127.0.0.1:8080/ ``` **libhv(port:8080) vs nginx(port:80)** ![libhv-vs-nginx.png](html/downloads/libhv-vs-nginx.png) 以上测试结果可以在 [Github Actions](https://github.com/ithewei/libhv/actions/workflows/benchmark.yml) 中查看。 ## 💎 用户案例 如果您在使用`libhv`,欢迎通过PR将信息提交至此列表,让更多的用户了解`libhv`的实际使用场景,以建立更好的网络生态。 | 用户 (公司名/项目名/个人联系方式) | 案例 (项目简介/业务场景) | | :--- | :--- | | [阅面科技](https://www.readsense.cn) | [猎户AIoT平台](https://orionweb.readsense.cn)设备管理、人脸检测HTTP服务、人脸搜索HTTP服务 | | [socks5-libhv](https://gitee.com/billykang/socks5-libhv) | socks5代理 | | [hvloop](https://github.com/xiispace/hvloop) | 类似[uvloop](https://github.com/MagicStack/uvloop)的python异步IO事件循环 | | [tsproxyd-android](https://github.com/Haiwen-GitHub/tsproxyd-android) | 一个基于libhv实现的android端web代理服务 | | [玄舟智维](https://zjzwxw.com) | C100K设备连接网关服务 | ================================================ FILE: README.md ================================================ English | [中文](README-CN.md) # libhv [![Linux](https://badgen.net/badge/Linux/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![Windows](https://badgen.net/badge/Windows/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![macOS](https://badgen.net/badge/macOS/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![Android](https://badgen.net/badge/Android/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![iOS](https://badgen.net/badge/iOS/success/green?icon=github)](https://github.com/ithewei/libhv/actions/workflows/CI.yml?query=branch%3Amaster) [![benchmark](https://github.com/ithewei/libhv/workflows/benchmark/badge.svg?branch=master)](https://github.com/ithewei/libhv/actions/workflows/benchmark.yml?query=branch%3Amaster)
[![release](https://badgen.net/github/release/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/releases) [![stars](https://badgen.net/github/stars/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/stargazers) [![forks](https://badgen.net/github/forks/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/forks) [![issues](https://badgen.net/github/issues/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/issues) [![PRs](https://badgen.net/github/prs/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/pulls) [![contributors](https://badgen.net/github/contributors/ithewei/libhv?icon=github)](https://github.com/ithewei/libhv/contributors) [![license](https://badgen.net/github/license/ithewei/libhv?icon=github)](LICENSE)
[![gitee](https://badgen.net/badge/mirror/gitee/red)](https://gitee.com/libhv/libhv) [![awesome-c](https://badgen.net/badge/icon/awesome-c/pink?icon=awesome&label&color)](https://github.com/oz123/awesome-c) [![awesome-cpp](https://badgen.net/badge/icon/awesome-cpp/pink?icon=awesome&label&color)](https://github.com/fffaraz/awesome-cpp) Like `libevent, libev, and libuv`, `libhv` provides event-loop with non-blocking IO and timer, but simpler api and richer protocols. ## ✨ Features - Cross-platform (Linux, Windows, macOS, Android, iOS, BSD, Solaris) - High-performance EventLoop (IO, timer, idle, custom, signal) - TCP/UDP client/server/proxy - TCP supports heartbeat, reconnect, upstream, MultiThread-safe write and close, etc. - Built-in common unpacking modes (FixedLength, Delimiter, LengthField) - RUDP support: WITH_KCP - SSL/TLS support: (via WITH_OPENSSL or WITH_GNUTLS or WITH_MBEDTLS) - HTTP client/server (support https http1/x http2 grpc) - HTTP supports static service, indexof service, forward/reverse proxy service, sync/async API handler - HTTP supports RESTful, router, middleware, keep-alive, chunked, SSE, etc. - WebSocket client/server - MQTT client ## ⌛️ Build see [BUILD.md](BUILD.md) Makefile: ```shell ./configure make sudo make install ``` or cmake: ```shell mkdir build cd build cmake .. cmake --build . ``` or bazel: ```shell bazel build libhv ``` or vcpkg: ```shell vcpkg install libhv ``` or xmake: ```shell xrepo install libhv ``` ## ⚡️ Getting Started run `./getting_started.sh`: ```shell git clone https://github.com/ithewei/libhv.git cd libhv ./configure make bin/httpd -h bin/httpd -d #bin/httpd -c etc/httpd.conf -s restart -d ps aux | grep httpd # http file service bin/curl -v localhost:8080 # http indexof service bin/curl -v localhost:8080/downloads/ # http api service bin/curl -v localhost:8080/ping bin/curl -v localhost:8080/echo -d "hello,world!" bin/curl -v localhost:8080/query?page_no=1\&page_size=10 bin/curl -v localhost:8080/kv -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456' bin/curl -v localhost:8080/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}' bin/curl -v localhost:8080/form -F 'user=admin' -F 'pswd=123456' bin/curl -v localhost:8080/upload -d "@LICENSE" bin/curl -v localhost:8080/upload -F "file=@LICENSE" bin/curl -v localhost:8080/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello' bin/curl -v localhost:8080/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}' bin/curl -v localhost:8080/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello' # RESTful API: /group/:group_name/user/:user_id bin/curl -v -X DELETE localhost:8080/group/test/user/123 # benchmark bin/wrk -c 1000 -d 10 -t 4 http://127.0.0.1:8080/ ``` ### TCP #### tcp server **c version**: [examples/tcp_echo_server.c](examples/tcp_echo_server.c) **c++ version**: [evpp/TcpServer_test.cpp](evpp/TcpServer_test.cpp) ```c++ #include "TcpServer.h" using namespace hv; int main() { int port = 1234; TcpServer srv; int listenfd = srv.createsocket(port); if (listenfd < 0) { return -1; } printf("server listen on port %d, listenfd=%d ...\n", port, listenfd); srv.onConnection = [](const SocketChannelPtr& channel) { std::string peeraddr = channel->peeraddr(); if (channel->isConnected()) { printf("%s connected! connfd=%d\n", peeraddr.c_str(), channel->fd()); } else { printf("%s disconnected! connfd=%d\n", peeraddr.c_str(), channel->fd()); } }; srv.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) { // echo channel->write(buf); }; srv.setThreadNum(4); srv.start(); // press Enter to stop while (getchar() != '\n'); return 0; } ``` #### tcp client **c version**: [examples/tcp_client_test.c](examples/tcp_client_test.c) **c++ version**: [evpp/TcpClient_test.cpp](evpp/TcpClient_test.cpp) ```c++ #include #include "TcpClient.h" using namespace hv; int main() { int port = 1234; TcpClient cli; int connfd = cli.createsocket(port); if (connfd < 0) { return -1; } cli.onConnection = [](const SocketChannelPtr& channel) { std::string peeraddr = channel->peeraddr(); if (channel->isConnected()) { printf("connected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd()); } else { printf("disconnected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd()); } }; cli.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) { printf("< %.*s\n", (int)buf->size(), (char*)buf->data()); }; cli.start(); std::string str; while (std::getline(std::cin, str)) { if (str == "close") { cli.closesocket(); } else if (str == "start") { cli.start(); } else if (str == "stop") { cli.stop(); break; } else { if (!cli.isConnected()) break; cli.send(str); } } return 0; } ``` ### HTTP #### http server see [examples/http_server_test.cpp](examples/http_server_test.cpp) **golang gin style** ```c++ #include "HttpServer.h" using namespace hv; int main() { HttpService router; router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) { return resp->String("pong"); }); router.GET("/data", [](HttpRequest* req, HttpResponse* resp) { static char data[] = "0123456789"; return resp->Data(data, 10); }); router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) { return resp->Json(router.Paths()); }); router.GET("/get", [](HttpRequest* req, HttpResponse* resp) { resp->json["origin"] = req->client_addr.ip; resp->json["url"] = req->url; resp->json["args"] = req->query_params; resp->json["headers"] = req->headers; return 200; }); router.POST("/echo", [](const HttpContextPtr& ctx) { return ctx->send(ctx->body(), ctx->type()); }); HttpServer server(&router); server.setPort(8080); server.setThreadNum(4); server.run(); return 0; } ``` #### http client see [examples/http_client_test.cpp](examples/http_client_test.cpp) **python requests style** ```c++ #include "requests.h" int main() { auto resp = requests::get("http://www.example.com"); if (resp == NULL) { printf("request failed!\n"); } else { printf("%s\n", resp->body.c_str()); } resp = requests::post("127.0.0.1:8080/echo", "hello,world!"); if (resp == NULL) { printf("request failed!\n"); } else { printf("%s\n", resp->body.c_str()); } return 0; } ``` ### WebSocket #### WebSocket server see [examples/websocket_server_test.cpp](examples/websocket_server_test.cpp) ```c++ #include "WebSocketServer.h" using namespace hv; int main(int argc, char** argv) { WebSocketService ws; ws.onopen = [](const WebSocketChannelPtr& channel, const HttpRequestPtr& req) { printf("onopen: GET %s\n", req->Path().c_str()); }; ws.onmessage = [](const WebSocketChannelPtr& channel, const std::string& msg) { printf("onmessage: %.*s\n", (int)msg.size(), msg.data()); }; ws.onclose = [](const WebSocketChannelPtr& channel) { printf("onclose\n"); }; WebSocketServer server(&ws); server.setPort(9999); server.setThreadNum(4); server.run(); return 0; } ``` #### WebSocket client see [examples/websocket_client_test.cpp](examples/websocket_client_test.cpp) ```c++ #include "WebSocketClient.h" using namespace hv; int main(int argc, char** argv) { WebSocketClient ws; ws.onopen = []() { printf("onopen\n"); }; ws.onmessage = [](const std::string& msg) { printf("onmessage: %.*s\n", (int)msg.size(), msg.data()); }; ws.onclose = []() { printf("onclose\n"); }; // reconnect: 1,2,4,8,10,10,10... reconn_setting_t reconn; reconn_setting_init(&reconn); reconn.min_delay = 1000; reconn.max_delay = 10000; reconn.delay_policy = 2; ws.setReconnect(&reconn); ws.open("ws://127.0.0.1:9999/test"); std::string str; while (std::getline(std::cin, str)) { if (!ws.isConnected()) break; if (str == "quit") { ws.close(); break; } ws.send(str); } return 0; } ``` ## 🍭 More examples ### c version - [examples/hloop_test.c](examples/hloop_test.c) - [examples/htimer_test.c](examples/htimer_test.c) - [examples/pipe_test.c](examples/pipe_test.c) - [examples/tcp_echo_server.c](examples/tcp_echo_server.c) - [examples/tcp_chat_server.c](examples/tcp_chat_server.c) - [examples/tcp_proxy_server.c](examples/tcp_proxy_server.c) - [examples/udp_echo_server.c](examples/udp_echo_server.c) - [examples/udp_proxy_server.c](examples/udp_proxy_server.c) - [examples/socks5_proxy_server.c](examples/socks5_proxy_server.c) - [examples/tinyhttpd.c](examples/tinyhttpd.c) - [examples/tinyproxyd.c](examples/tinyproxyd.c) - [examples/jsonrpc](examples/jsonrpc) - [examples/mqtt](examples/mqtt) - [examples/multi-thread/multi-acceptor-processes.c](examples/multi-thread/multi-acceptor-processes.c) - [examples/multi-thread/multi-acceptor-threads.c](examples/multi-thread/multi-acceptor-threads.c) - [examples/multi-thread/one-acceptor-multi-workers.c](examples/multi-thread/one-acceptor-multi-workers.c) ### c++ version - [evpp/EventLoop_test.cpp](evpp/EventLoop_test.cpp) - [evpp/EventLoopThread_test.cpp](evpp/EventLoopThread_test.cpp) - [evpp/EventLoopThreadPool_test.cpp](evpp/EventLoopThreadPool_test.cpp) - [evpp/TimerThread_test.cpp](evpp/TimerThread_test.cpp) - [evpp/TcpServer_test.cpp](evpp/TcpServer_test.cpp) - [evpp/TcpClient_test.cpp](evpp/TcpClient_test.cpp) - [evpp/UdpServer_test.cpp](evpp/UdpServer_test.cpp) - [evpp/UdpClient_test.cpp](evpp/UdpClient_test.cpp) - [examples/http_server_test.cpp](examples/http_server_test.cpp) - [examples/http_client_test.cpp](examples/http_client_test.cpp) - [examples/websocket_server_test.cpp](examples/websocket_server_test.cpp) - [examples/websocket_client_test.cpp](examples/websocket_client_test.cpp) - [examples/protorpc](examples/protorpc) - [hv-projects/QtDemo](https://github.com/hv-projects/QtDemo) ### simulate well-known command line tools - [examples/nc](examples/nc.c) - [examples/nmap](examples/nmap) - [examples/httpd](examples/httpd) - [examples/wrk](examples/wrk.cpp) - [examples/curl](examples/curl.cpp) - [examples/wget](examples/wget.cpp) - [examples/consul](examples/consul) - [examples/kcptun](examples/kcptun) ## 🥇 Benchmark ### `pingpong echo-servers` ```shell cd echo-servers ./build.sh ./benchmark.sh ``` **throughput**: ```shell libevent running on port 2001 libev running on port 2002 libuv running on port 2003 libhv running on port 2004 asio running on port 2005 poco running on port 2006 ==============2001===================================== [127.0.0.1:2001] 4 threads 1000 connections run 10s total readcount=1616761 readbytes=1655563264 throughput = 157 MB/s ==============2002===================================== [127.0.0.1:2002] 4 threads 1000 connections run 10s total readcount=2153171 readbytes=2204847104 throughput = 210 MB/s ==============2003===================================== [127.0.0.1:2003] 4 threads 1000 connections run 10s total readcount=1599727 readbytes=1638120448 throughput = 156 MB/s ==============2004===================================== [127.0.0.1:2004] 4 threads 1000 connections run 10s total readcount=2202271 readbytes=2255125504 throughput = 215 MB/s ==============2005===================================== [127.0.0.1:2005] 4 threads 1000 connections run 10s total readcount=1354230 readbytes=1386731520 throughput = 132 MB/s ==============2006===================================== [127.0.0.1:2006] 4 threads 1000 connections run 10s total readcount=1699652 readbytes=1740443648 throughput = 165 MB/s ``` ### `iperf tcp_proxy_server` ```shell # sudo apt install iperf iperf -s -p 5001 > /dev/null & bin/tcp_proxy_server 1212 127.0.0.1:5001 & iperf -c 127.0.0.1 -p 5001 -l 8K iperf -c 127.0.0.1 -p 1212 -l 8K ``` **Bandwidth**: ```shell ------------------------------------------------------------ [ 3] local 127.0.0.1 port 52560 connected with 127.0.0.1 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 20.8 GBytes 17.9 Gbits/sec ------------------------------------------------------------ [ 3] local 127.0.0.1 port 48142 connected with 127.0.0.1 port 1212 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 11.9 GBytes 10.2 Gbits/sec ``` ### `webbench` ```shell # sudo apt install wrk wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/ # sudo apt install apache2-utils ab -c 100 -n 100000 http://127.0.0.1:8080/ ``` **libhv(port:8080) vs nginx(port:80)** ![libhv-vs-nginx.png](html/downloads/libhv-vs-nginx.png) Above test results can be found on [Github Actions](https://github.com/ithewei/libhv/actions/workflows/benchmark.yml). ================================================ FILE: TREE.md ================================================ ## 目录结构 ``` . ├── base libhv基础设施,如常用宏定义、数据结构、日期时间、线程、进程、日志、套接字 ├── bin 可执行文件安装目录 ├── build cmake默认构建目录 ├── cert SSL证书存放目录 ├── cmake cmake脚本存放目录 ├── cpputil libhv工具类,如字符串、文件、路径、线程池、json解析、ini解析 ├── docs 文档存放目录 ├── echo-servers 包含libevent、libev、libuv、libhv、asio、poco、muduo等多个网络库的tcp echo server写法,并做压力测试 ├── etc 应用程序配置目录 ├── event libhv事件循环模块 ├── evpp 事件循环c++封装类 ├── examples 示例代码 │   └── httpd ├── html 网页document_root目录 │   ├── downloads 下载目录 │   └── uploads 上传目录 ├── http libhv http模块 │   ├── client │   └── server ├── include 头文件安装目录 │   └── hv ├── lib 库文件安装目录 ├── logs 日志生成目录 ├── misc 杂项 ├── mqtt MQTT协议 ├── protocol 包含icmp、dns、ftp、smtp等协议的实现 ├── scripts shell脚本存放目录 ├── ssl SSL/TLS加密通信 ├── unittest 单元测试代码 └── util libhv工具函数,如base64、md5、sha1 ``` ================================================ FILE: WORKSPACE.bazel ================================================ workspace(name = "hv") ================================================ FILE: base/README.md ================================================ ## 目录结构 ``` . ├── array.h 动态数组 ├── hatomic.h 原子操作 ├── hbase.h 基础函数 ├── hbuf.h 缓存 ├── hdef.h 常见宏定义 ├── heap.h 堆 ├── hendian.h 大小端 ├── herr.h 错误码表 ├── hlog.h 日志 ├── hmain.h 命令行解析 ├── hmath.h 数学函数 ├── hmutex.h 线程同步锁 ├── hplatform.h 平台相关宏 ├── hproc.h 进程 ├── hsocket.h 套接字 ├── hsysinfo.h 系统信息 ├── hthread.h 线程 ├── htime.h 时间 ├── hversion.h 版本 ├── list.h 链表 ├── queue.h 队列 └── rbtree.h 红黑树 ``` ================================================ FILE: base/array.h ================================================ #ifndef HV_ARRAY_H_ #define HV_ARRAY_H_ /* * array * at: random access by pos * @effective * push_back,pop_back,del_nomove,swap * @ineffective * add,del */ #include // for assert #include // for NULL #include // for malloc,realloc,free #include // for memset,memmove #include "hbase.h" // for HV_ALLOC, HV_FREE #define ARRAY_INIT_SIZE 16 // #include // typedef std::vector atype; #define ARRAY_DECL(type, atype) \ struct atype { \ type* ptr; \ size_t size; \ size_t maxsize;\ }; \ typedef struct atype atype;\ \ static inline type* atype##_data(atype* p) {\ return p->ptr;\ }\ \ static inline int atype##_size(atype* p) {\ return p->size;\ }\ \ static inline int atype##_maxsize(atype* p) {\ return p->maxsize;\ }\ \ static inline int atype##_empty(atype* p) {\ return p->size == 0;\ }\ \ static inline type* atype##_at(atype* p, int pos) {\ if (pos < 0) {\ pos += p->size;\ }\ assert(pos >= 0 && pos < p->size);\ return p->ptr + pos;\ }\ \ static inline type* atype##_front(atype* p) {\ return p->size == 0 ? NULL : p->ptr;\ }\ \ static inline type* atype##_back(atype* p) {\ return p->size == 0 ? NULL : p->ptr + p->size - 1;\ }\ \ static inline void atype##_init(atype* p, int maxsize) {\ p->size = 0;\ p->maxsize = maxsize;\ HV_ALLOC(p->ptr, sizeof(type) * maxsize);\ }\ \ static inline void atype##_clear(atype* p) {\ p->size = 0;\ memset(p->ptr, 0, sizeof(type) * p->maxsize);\ }\ \ static inline void atype##_cleanup(atype* p) {\ HV_FREE(p->ptr);\ p->size = p->maxsize = 0;\ }\ \ static inline void atype##_resize(atype* p, int maxsize) {\ if (maxsize == 0) maxsize = ARRAY_INIT_SIZE;\ p->ptr = (type*)hv_realloc(p->ptr, sizeof(type) * maxsize, sizeof(type) * p->maxsize);\ p->maxsize = maxsize;\ }\ \ static inline void atype##_double_resize(atype* p) {\ atype##_resize(p, p->maxsize * 2);\ }\ \ static inline void atype##_push_back(atype* p, type* elem) {\ if (p->size == p->maxsize) {\ atype##_double_resize(p);\ }\ p->ptr[p->size] = *elem;\ p->size++;\ }\ \ static inline void atype##_pop_back(atype* p) {\ assert(p->size > 0);\ p->size--;\ }\ \ static inline void atype##_add(atype* p, type* elem, int pos) {\ if (pos < 0) {\ pos += p->size;\ }\ assert(pos >= 0 && pos <= p->size);\ if (p->size == p->maxsize) {\ atype##_double_resize(p);\ }\ if (pos < p->size) {\ memmove(p->ptr + pos+1, p->ptr + pos, sizeof(type) * (p->size - pos));\ }\ p->ptr[pos] = *elem;\ p->size++;\ }\ \ static inline void atype##_del(atype* p, int pos) {\ if (pos < 0) {\ pos += p->size;\ }\ assert(pos >= 0 && pos < p->size);\ p->size--;\ if (pos < p->size) {\ memmove(p->ptr + pos, p->ptr + pos+1, sizeof(type) * (p->size - pos));\ }\ }\ \ static inline void atype##_del_nomove(atype* p, int pos) {\ if (pos < 0) {\ pos += p->size;\ }\ assert(pos >= 0 && pos < p->size);\ p->size--;\ if (pos < p->size) {\ p->ptr[pos] = p->ptr[p->size];\ }\ }\ \ static inline void atype##_swap(atype* p, int pos1, int pos2) {\ if (pos1 < 0) {\ pos1 += p->size;\ }\ if (pos2 < 0) {\ pos2 += p->size;\ }\ type tmp = p->ptr[pos1];\ p->ptr[pos1] = p->ptr[pos2];\ p->ptr[pos2] = tmp;\ }\ #endif // HV_ARRAY_H_ ================================================ FILE: base/hatomic.h ================================================ #ifndef HV_ATOMIC_H_ #define HV_ATOMIC_H_ #ifdef __cplusplus // c++11 #include using std::atomic_flag; using std::atomic_long; #define ATOMIC_FLAG_TEST_AND_SET(p) ((p)->test_and_set()) #define ATOMIC_FLAG_CLEAR(p) ((p)->clear()) #else #include "hplatform.h" // for HAVE_STDATOMIC_H #if HAVE_STDATOMIC_H // c11 #include #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set #define ATOMIC_FLAG_CLEAR atomic_flag_clear #define ATOMIC_ADD atomic_fetch_add #define ATOMIC_SUB atomic_fetch_sub #define ATOMIC_INC(p) ATOMIC_ADD(p, 1) #define ATOMIC_DEC(p) ATOMIC_SUB(p, 1) #else typedef volatile bool atomic_bool; typedef volatile char atomic_char; typedef volatile unsigned char atomic_uchar; typedef volatile short atomic_short; typedef volatile unsigned short atomic_ushort; typedef volatile int atomic_int; typedef volatile unsigned int atomic_uint; typedef volatile long atomic_long; typedef volatile unsigned long atomic_ulong; typedef volatile long long atomic_llong; typedef volatile unsigned long long atomic_ullong; typedef volatile size_t atomic_size_t; typedef struct atomic_flag { atomic_long _Value; } atomic_flag; #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set static inline bool atomic_flag_test_and_set(atomic_flag* p) { return !__sync_bool_compare_and_swap(&p->_Value, 0, 1); } #define ATOMIC_ADD __sync_fetch_and_add #define ATOMIC_SUB __sync_fetch_and_sub #define ATOMIC_INC(p) ATOMIC_ADD(p, 1) #define ATOMIC_DEC(p) ATOMIC_SUB(p, 1) #elif defined(_WIN32) #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set static inline bool atomic_flag_test_and_set(atomic_flag* p) { // return InterlockedIncrement((LONG*)&p->_Value, 1); return InterlockedCompareExchange(&p->_Value, 1, 0); } #define ATOMIC_ADD InterlockedExchangeAdd #define ATOMIC_SUB(p, n) InterlockedExchangeAdd(p, -(n)) #define ATOMIC_INC(p) InterlockedExchangeAdd(p, 1) #define ATOMIC_DEC(p) InterlockedExchangeAdd(p, -1) #endif #endif // HAVE_STDATOMIC_H #endif // __cplusplus #ifndef ATOMIC_FLAG_INIT #define ATOMIC_FLAG_INIT { 0 } #endif #ifndef ATOMIC_VAR_INIT #define ATOMIC_VAR_INIT(value) (value) #endif #ifndef ATOMIC_FLAG_TEST_AND_SET #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set static inline bool atomic_flag_test_and_set(atomic_flag* p) { bool ret = p->_Value; p->_Value = 1; return ret; } #endif #ifndef ATOMIC_FLAG_CLEAR #define ATOMIC_FLAG_CLEAR atomic_flag_clear static inline void atomic_flag_clear(atomic_flag* p) { p->_Value = 0; } #endif #ifndef ATOMIC_ADD #define ATOMIC_ADD(p, n) (*(p) += (n)) #endif #ifndef ATOMIC_SUB #define ATOMIC_SUB(p, n) (*(p) -= (n)) #endif #ifndef ATOMIC_INC #define ATOMIC_INC(p) ((*(p))++) #endif #ifndef ATOMIC_DEC #define ATOMIC_DEC(p) ((*(p))--) #endif typedef atomic_flag hatomic_flag_t; #define HATOMIC_FLAG_INIT ATOMIC_FLAG_INIT #define hatomic_flag_test_and_set ATOMIC_FLAG_TEST_AND_SET #define hatomic_flag_clear ATOMIC_FLAG_CLEAR typedef atomic_long hatomic_t; #define HATOMIC_VAR_INIT ATOMIC_VAR_INIT #define hatomic_add ATOMIC_ADD #define hatomic_sub ATOMIC_SUB #define hatomic_inc ATOMIC_INC #define hatomic_dec ATOMIC_DEC #endif // HV_ATOMIC_H_ ================================================ FILE: base/hbase.c ================================================ #include "hbase.h" #ifdef OS_DARWIN #include // for _NSGetExecutablePath #endif #include "hatomic.h" #ifndef RAND_MAX #define RAND_MAX 2147483647 #endif static hatomic_t s_alloc_cnt = HATOMIC_VAR_INIT(0); static hatomic_t s_free_cnt = HATOMIC_VAR_INIT(0); long hv_alloc_cnt() { return s_alloc_cnt; } long hv_free_cnt() { return s_free_cnt; } void* hv_malloc(size_t size) { hatomic_inc(&s_alloc_cnt); void* ptr = malloc(size); if (!ptr) { fprintf(stderr, "malloc failed!\n"); exit(-1); } return ptr; } void* hv_realloc(void* oldptr, size_t newsize, size_t oldsize) { hatomic_inc(&s_alloc_cnt); if (oldptr) hatomic_inc(&s_free_cnt); void* ptr = realloc(oldptr, newsize); if (!ptr) { fprintf(stderr, "realloc failed!\n"); exit(-1); } if (newsize > oldsize) { memset((char*)ptr + oldsize, 0, newsize - oldsize); } return ptr; } void* hv_calloc(size_t nmemb, size_t size) { hatomic_inc(&s_alloc_cnt); void* ptr = calloc(nmemb, size); if (!ptr) { fprintf(stderr, "calloc failed!\n"); exit(-1); } return ptr; } void* hv_zalloc(size_t size) { hatomic_inc(&s_alloc_cnt); void* ptr = malloc(size); if (!ptr) { fprintf(stderr, "malloc failed!\n"); exit(-1); } memset(ptr, 0, size); return ptr; } void hv_free(void* ptr) { if (ptr) { free(ptr); ptr = NULL; hatomic_inc(&s_free_cnt); } } char* hv_strupper(char* str) { char* p = str; while (*p != '\0') { if (*p >= 'a' && *p <= 'z') { *p &= ~0x20; } ++p; } return str; } char* hv_strlower(char* str) { char* p = str; while (*p != '\0') { if (*p >= 'A' && *p <= 'Z') { *p |= 0x20; } ++p; } return str; } char* hv_strreverse(char* str) { if (str == NULL) return NULL; char* b = str; char* e = str; while(*e) {++e;} --e; char tmp; while (e > b) { tmp = *e; *e = *b; *b = tmp; --e; ++b; } return str; } // n = sizeof(dest_buf) char* hv_strncpy(char* dest, const char* src, size_t n) { assert(dest != NULL && src != NULL); char* ret = dest; while (*src != '\0' && --n > 0) { *dest++ = *src++; } *dest = '\0'; return ret; } // n = sizeof(dest_buf) char* hv_strncat(char* dest, const char* src, size_t n) { assert(dest != NULL && src != NULL); char* ret = dest; while (*dest) {++dest;--n;} while (*src != '\0' && --n > 0) { *dest++ = *src++; } *dest = '\0'; return ret; } bool hv_strstartswith(const char* str, const char* start) { assert(str != NULL && start != NULL); while (*str && *start && *str == *start) { ++str; ++start; } return *start == '\0'; } bool hv_strendswith(const char* str, const char* end) { assert(str != NULL && end != NULL); int len1 = 0; int len2 = 0; while (*str) {++str; ++len1;} while (*end) {++end; ++len2;} if (len1 < len2) return false; while (len2-- > 0) { --str; --end; if (*str != *end) { return false; } } return true; } bool hv_strcontains(const char* str, const char* sub) { assert(str != NULL && sub != NULL); return strstr(str, sub) != NULL; } bool hv_wildcard_match(const char* str, const char* pattern) { assert(str != NULL && pattern != NULL); bool match = false; while (*str && *pattern) { if (*pattern == '*') { match = hv_strendswith(str, pattern + 1); break; } else if (*str != *pattern) { match = false; break; } else { ++str; ++pattern; } } return match ? match : (*str == '\0' && *pattern == '\0'); } char* hv_strnchr(const char* s, char c, size_t n) { assert(s != NULL); const char* p = s; while (*p != '\0' && n-- > 0) { if (*p == c) return (char*)p; ++p; } return NULL; } char* hv_strnrchr(const char* s, char c, size_t n) { assert(s != NULL); const char* p = s; const char* last = NULL; while (*p != '\0' && n-- > 0) { if (*p == c) last = p; ++p; } return (char*)last; } char* hv_strrchr_dir(const char* filepath) { char* p = (char*)filepath; while (*p) ++p; while (--p >= filepath) { #ifdef OS_WIN if (*p == '/' || *p == '\\') #else if (*p == '/') #endif return p; } return NULL; } const char* hv_basename(const char* filepath) { const char* pos = hv_strrchr_dir(filepath); return pos ? pos+1 : filepath; } const char* hv_suffixname(const char* filename) { const char* pos = hv_strrchr_dot(filename); return pos ? pos+1 : ""; } int hv_mkdir_p(const char* dir) { if (access(dir, 0) == 0) { return EEXIST; } char tmp[MAX_PATH] = {0}; hv_strncpy(tmp, dir, sizeof(tmp)); char* p = tmp; char delim = '/'; while (*p) { #ifdef OS_WIN if (*p == '/' || *p == '\\') { delim = *p; #else if (*p == '/') { #endif *p = '\0'; hv_mkdir(tmp); *p = delim; } ++p; } if (hv_mkdir(tmp) != 0) { return EPERM; } return 0; } int hv_rmdir_p(const char* dir) { if (access(dir, 0) != 0) { return ENOENT; } if (rmdir(dir) != 0) { return EPERM; } char tmp[MAX_PATH] = {0}; hv_strncpy(tmp, dir, sizeof(tmp)); char* p = tmp; while (*p) ++p; while (--p >= tmp) { #ifdef OS_WIN if (*p == '/' || *p == '\\') { #else if (*p == '/') { #endif *p = '\0'; if (rmdir(tmp) != 0) { return 0; } } } return 0; } bool hv_exists(const char* path) { return access(path, 0) == 0; } bool hv_isdir(const char* path) { if (access(path, 0) != 0) return false; struct stat st; memset(&st, 0, sizeof(st)); stat(path, &st); return S_ISDIR(st.st_mode); } bool hv_isfile(const char* path) { if (access(path, 0) != 0) return false; struct stat st; memset(&st, 0, sizeof(st)); stat(path, &st); return S_ISREG(st.st_mode); } bool hv_islink(const char* path) { #ifdef OS_WIN return hv_isdir(path) && (GetFileAttributes(path) & FILE_ATTRIBUTE_REPARSE_POINT); #else if (access(path, 0) != 0) return false; struct stat st; memset(&st, 0, sizeof(st)); lstat(path, &st); return S_ISLNK(st.st_mode); #endif } size_t hv_filesize(const char* filepath) { struct stat st; memset(&st, 0, sizeof(st)); stat(filepath, &st); return st.st_size; } char* get_executable_path(char* buf, int size) { #ifdef OS_WIN GetModuleFileName(NULL, buf, size); #elif defined(OS_LINUX) if (readlink("/proc/self/exe", buf, size) == -1) { return NULL; } #elif defined(OS_DARWIN) _NSGetExecutablePath(buf, (uint32_t*)&size); #endif return buf; } char* get_executable_dir(char* buf, int size) { char filepath[MAX_PATH] = {0}; get_executable_path(filepath, sizeof(filepath)); char* pos = hv_strrchr_dir(filepath); if (pos) { *pos = '\0'; strncpy(buf, filepath, size); } return buf; } char* get_executable_file(char* buf, int size) { char filepath[MAX_PATH] = {0}; get_executable_path(filepath, sizeof(filepath)); char* pos = hv_strrchr_dir(filepath); if (pos) { strncpy(buf, pos+1, size); } return buf; } char* get_run_dir(char* buf, int size) { return getcwd(buf, size); } int hv_rand(int min, int max) { static int s_seed = 0; assert(max > min); if (s_seed == 0) { s_seed = time(NULL); srand(s_seed); } int _rand = rand(); _rand = min + (int) ((double) ((double) (max) - (min) + 1.0) * ((_rand) / ((RAND_MAX) + 1.0))); return _rand; } char* hv_random_string(char *buf, int len) { static char s_characters[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', }; int i = 0; for (; i < len; i++) { buf[i] = s_characters[hv_rand(0, sizeof(s_characters) - 1)]; } buf[i] = '\0'; return buf; } bool hv_getboolean(const char* str) { if (str == NULL) return false; int len = strlen(str); if (len == 0) return false; switch (len) { case 1: return *str == '1' || *str == 'y' || *str == 'Y'; case 2: return stricmp(str, "on") == 0; case 3: return stricmp(str, "yes") == 0; case 4: return stricmp(str, "true") == 0; case 6: return stricmp(str, "enable") == 0; default: return false; } } size_t hv_parse_size(const char* str) { size_t size = 0, n = 0; const char* p = str; char c; while ((c = *p) != '\0') { if (c >= '0' && c <= '9') { n = n * 10 + c - '0'; } else { switch (c) { case 'K': case 'k': n <<= 10; break; case 'M': case 'm': n <<= 20; break; case 'G': case 'g': n <<= 30; break; case 'T': case 't': if(sizeof(size_t) > 5) n <<= 40; break; default: break; } size += n; n = 0; } ++p; } return size + n; } time_t hv_parse_time(const char* str) { time_t time = 0, n = 0; const char* p = str; char c; while ((c = *p) != '\0') { if (c >= '0' && c <= '9') { n = n * 10 + c - '0'; } else { switch (c) { case 's': break; case 'm': n *= 60; break; case 'h': n *= 60 * 60; break; case 'd': n *= 24 * 60 * 60; break; case 'w': n *= 7 * 24 * 60 * 60; break; default: break; } time += n; n = 0; } ++p; } return time + n; } int hv_parse_url(hurl_t* stURL, const char* strURL) { if (stURL == NULL || strURL == NULL) return -1; memset(stURL, 0, sizeof(hurl_t)); const char* begin = strURL; const char* end = strURL; while (*end != '\0') ++end; if (end - begin > 65535) return -2; // scheme:// const char* sp = strURL; const char* ep = strstr(sp, "://"); if (ep) { // stURL->fields[HV_URL_SCHEME].off = sp - begin; stURL->fields[HV_URL_SCHEME].len = ep - sp; sp = ep + 3; } // user:pswd@host:port ep = strchr(sp, '/'); if (ep == NULL) ep = end; const char* user = sp; const char* host = sp; const char* pos = hv_strnchr(sp, '@', ep - sp); if (pos) { // user:pswd const char* pswd = hv_strnchr(user, ':', pos - user); if (pswd) { stURL->fields[HV_URL_PASSWORD].off = pswd + 1 - begin; stURL->fields[HV_URL_PASSWORD].len = pos - pswd - 1; } else { pswd = pos; } stURL->fields[HV_URL_USERNAME].off = user - begin; stURL->fields[HV_URL_USERNAME].len = pswd - user; // @ host = pos + 1; } // host:port or ipv4:port or [ipv6]:port const char* hostend = host; if (*host == '[') { pos = hv_strnchr(host, ']', ep - host); if (pos) { // ipv6 host++; hostend = pos; stURL->fields[HV_URL_HOST].off = host - begin; stURL->fields[HV_URL_HOST].len = hostend - host; } } const char* port = hv_strnchr(hostend, ':', ep - hostend); if (port) { stURL->fields[HV_URL_PORT].off = port + 1 - begin; stURL->fields[HV_URL_PORT].len = ep - port - 1; // atoi for (unsigned short i = 1; i <= stURL->fields[HV_URL_PORT].len; ++i) { stURL->port = stURL->port * 10 + (port[i] - '0'); } } else { port = ep; // set default port stURL->port = 80; if (stURL->fields[HV_URL_SCHEME].len > 0) { if (strncmp(strURL, "https://", 8) == 0) { stURL->port = 443; } } } if (stURL->fields[HV_URL_HOST].len == 0) { stURL->fields[HV_URL_HOST].off = host - begin; stURL->fields[HV_URL_HOST].len = port - host; } if (ep == end) return 0; // /path sp = ep; ep = strchr(sp, '?'); if (ep == NULL) ep = end; stURL->fields[HV_URL_PATH].off = sp - begin; stURL->fields[HV_URL_PATH].len = ep - sp; if (ep == end) return 0; // ?query sp = ep + 1; ep = strchr(sp, '#'); if (ep == NULL) ep = end; stURL->fields[HV_URL_QUERY].off = sp - begin; stURL->fields[HV_URL_QUERY].len = ep - sp; if (ep == end) return 0; // #fragment sp = ep + 1; ep = end; stURL->fields[HV_URL_FRAGMENT].off = sp - begin; stURL->fields[HV_URL_FRAGMENT].len = ep - sp; return 0; } ================================================ FILE: base/hbase.h ================================================ #ifndef HV_BASE_H_ #define HV_BASE_H_ #include "hexport.h" #include "hplatform.h" // for bool #include "hdef.h" // for printd BEGIN_EXTERN_C //--------------------alloc/free--------------------------- HV_EXPORT void* hv_malloc(size_t size); HV_EXPORT void* hv_realloc(void* oldptr, size_t newsize, size_t oldsize); HV_EXPORT void* hv_calloc(size_t nmemb, size_t size); HV_EXPORT void* hv_zalloc(size_t size); HV_EXPORT void hv_free(void* ptr); #define HV_ALLOC(ptr, size)\ do {\ *(void**)&(ptr) = hv_zalloc(size);\ printd("alloc(%p, size=%llu)\tat [%s:%d:%s]\n", ptr, (unsigned long long)size, __FILE__, __LINE__, __FUNCTION__);\ } while(0) #define HV_ALLOC_SIZEOF(ptr) HV_ALLOC(ptr, sizeof(*(ptr))) #define HV_FREE(ptr)\ do {\ if (ptr) {\ hv_free(ptr);\ printd("free( %p )\tat [%s:%d:%s]\n", ptr, __FILE__, __LINE__, __FUNCTION__);\ ptr = NULL;\ }\ } while(0) #define STACK_OR_HEAP_ALLOC(ptr, size, stack_size)\ unsigned char _stackbuf_[stack_size] = { 0 };\ if ((size) > (stack_size)) {\ HV_ALLOC(ptr, size);\ } else {\ *(unsigned char**)&(ptr) = _stackbuf_;\ } #define STACK_OR_HEAP_FREE(ptr)\ if ((unsigned char*)(ptr) != _stackbuf_) {\ HV_FREE(ptr);\ } #define HV_DEFAULT_STACKBUF_SIZE 1024 #define HV_STACK_ALLOC(ptr, size) STACK_OR_HEAP_ALLOC(ptr, size, HV_DEFAULT_STACKBUF_SIZE) #define HV_STACK_FREE(ptr) STACK_OR_HEAP_FREE(ptr) HV_EXPORT long hv_alloc_cnt(); HV_EXPORT long hv_free_cnt(); HV_INLINE void hv_memcheck(void) { printf("Memcheck => alloc:%ld free:%ld\n", hv_alloc_cnt(), hv_free_cnt()); } #define HV_MEMCHECK atexit(hv_memcheck); //--------------------string------------------------------- HV_EXPORT char* hv_strupper(char* str); HV_EXPORT char* hv_strlower(char* str); HV_EXPORT char* hv_strreverse(char* str); HV_EXPORT bool hv_strstartswith(const char* str, const char* start); HV_EXPORT bool hv_strendswith(const char* str, const char* end); HV_EXPORT bool hv_strcontains(const char* str, const char* sub); HV_EXPORT bool hv_wildcard_match(const char* str, const char* pattern); // strncpy n = sizeof(dest_buf)-1 // hv_strncpy n = sizeof(dest_buf) HV_EXPORT char* hv_strncpy(char* dest, const char* src, size_t n); // strncat n = sizeof(dest_buf)-1-strlen(dest) // hv_strncpy n = sizeof(dest_buf) HV_EXPORT char* hv_strncat(char* dest, const char* src, size_t n); #if !HAVE_STRLCPY #define strlcpy hv_strncpy #endif #if !HAVE_STRLCAT #define strlcat hv_strncat #endif HV_EXPORT char* hv_strnchr(const char* s, char c, size_t n); HV_EXPORT char* hv_strnrchr(const char* s, char c, size_t n); #define hv_strrchr_dot(str) strrchr(str, '.') HV_EXPORT char* hv_strrchr_dir(const char* filepath); // basename HV_EXPORT const char* hv_basename(const char* filepath); HV_EXPORT const char* hv_suffixname(const char* filename); // mkdir -p HV_EXPORT int hv_mkdir_p(const char* dir); // rmdir -p HV_EXPORT int hv_rmdir_p(const char* dir); // path HV_EXPORT bool hv_exists(const char* path); HV_EXPORT bool hv_isdir(const char* path); HV_EXPORT bool hv_isfile(const char* path); HV_EXPORT bool hv_islink(const char* path); HV_EXPORT size_t hv_filesize(const char* filepath); HV_EXPORT char* get_executable_path(char* buf, int size); HV_EXPORT char* get_executable_dir(char* buf, int size); HV_EXPORT char* get_executable_file(char* buf, int size); HV_EXPORT char* get_run_dir(char* buf, int size); // random HV_EXPORT int hv_rand(int min, int max); HV_EXPORT char* hv_random_string(char *buf, int len); // 1 y on yes true enable => true HV_EXPORT bool hv_getboolean(const char* str); // 1T2G3M4K5B => ?B HV_EXPORT size_t hv_parse_size(const char* str); // 1w2d3h4m5s => ?s HV_EXPORT time_t hv_parse_time(const char* str); // scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment] typedef enum { HV_URL_SCHEME, HV_URL_USERNAME, HV_URL_PASSWORD, HV_URL_HOST, HV_URL_PORT, HV_URL_PATH, HV_URL_QUERY, HV_URL_FRAGMENT, HV_URL_FIELD_NUM, } hurl_field_e; typedef struct hurl_s { struct { unsigned short off; unsigned short len; } fields[HV_URL_FIELD_NUM]; unsigned short port; } hurl_t; HV_EXPORT int hv_parse_url(hurl_t* stURL, const char* strURL); END_EXTERN_C #endif // HV_BASE_H_ ================================================ FILE: base/hbuf.h ================================================ #ifndef HV_BUF_H_ #define HV_BUF_H_ #include "hdef.h" // for MAX #include "hbase.h" // for HV_ALLOC, HV_FREE typedef struct hbuf_s { char* base; size_t len; #ifdef __cplusplus hbuf_s() { base = NULL; len = 0; } hbuf_s(void* data, size_t len) { this->base = (char*)data; this->len = len; } #endif } hbuf_t; typedef struct offset_buf_s { char* base; size_t len; size_t offset; #ifdef __cplusplus offset_buf_s() { base = NULL; len = 0; offset = 0; } offset_buf_s(void* data, size_t len) { this->base = (char*)data; this->len = len; offset = 0; } #endif } offset_buf_t; typedef struct fifo_buf_s { char* base; size_t len; size_t head; size_t tail; #ifdef __cplusplus fifo_buf_s() { base = NULL; len = 0; head = tail = 0; } fifo_buf_s(void* data, size_t len) { this->base = (char*)data; this->len = len; head = tail = 0; } #endif } fifo_buf_t; #ifdef __cplusplus class HBuf : public hbuf_t { public: HBuf() : hbuf_t() { cleanup_ = false; } HBuf(void* data, size_t len) : hbuf_t(data, len) { cleanup_ = false; } HBuf(size_t cap) { resize(cap); } virtual ~HBuf() { cleanup(); } void* data() { return base; } size_t size() { return len; } bool isNull() { return base == NULL || len == 0; } void cleanup() { if (cleanup_) { HV_FREE(base); len = 0; cleanup_ = false; } } void resize(size_t cap) { if (cap == len) return; if (base == NULL) { HV_ALLOC(base, cap); } else { base = (char*)hv_realloc(base, cap, len); } len = cap; cleanup_ = true; } void copy(void* data, size_t len) { resize(len); memcpy(base, data, len); } void copy(hbuf_t* buf) { copy(buf->base, buf->len); } private: bool cleanup_; }; // VL: Variable-Length class HVLBuf : public HBuf { public: HVLBuf() : HBuf() {_offset = _size = 0;} HVLBuf(void* data, size_t len) : HBuf(data, len) {_offset = 0; _size = len;} HVLBuf(size_t cap) : HBuf(cap) {_offset = _size = 0;} virtual ~HVLBuf() {} char* data() { return base + _offset; } size_t size() { return _size; } void push_front(void* ptr, size_t len) { if (len > this->len - _size) { size_t newsize = MAX(this->len, len)*2; resize(newsize); } if (_offset < len) { // move => end memmove(base+this->len-_size, data(), _size); _offset = this->len-_size; } memcpy(data()-len, ptr, len); _offset -= len; _size += len; } void push_back(void* ptr, size_t len) { if (len > this->len - _size) { size_t newsize = MAX(this->len, len)*2; resize(newsize); } else if (len > this->len - _offset - _size) { // move => start memmove(base, data(), _size); _offset = 0; } memcpy(data()+_size, ptr, len); _size += len; } void pop_front(void* ptr, size_t len) { if (len <= _size) { if (ptr) { memcpy(ptr, data(), len); } _offset += len; if (_offset >= this->len) _offset = 0; _size -= len; } } void pop_back(void* ptr, size_t len) { if (len <= _size) { if (ptr) { memcpy(ptr, data()+_size-len, len); } _size -= len; } } void clear() { _offset = _size = 0; } void prepend(void* ptr, size_t len) { push_front(ptr, len); } void append(void* ptr, size_t len) { push_back(ptr, len); } void insert(void* ptr, size_t len) { push_back(ptr, len); } void remove(size_t len) { pop_front(NULL, len); } private: size_t _offset; size_t _size; }; class HRingBuf : public HBuf { public: HRingBuf() : HBuf() {_head = _tail = _size = 0;} HRingBuf(size_t cap) : HBuf(cap) {_head = _tail = _size = 0;} virtual ~HRingBuf() {} char* alloc(size_t len) { char* ret = NULL; if (_head < _tail || _size == 0) { // [_tail, this->len) && [0, _head) if (this->len - _tail >= len) { ret = base + _tail; _tail += len; if (_tail == this->len) _tail = 0; } else if (_head >= len) { ret = base; _tail = len; } } else { // [_tail, _head) if (_head - _tail >= len) { ret = base + _tail; _tail += len; } } _size += ret ? len : 0; return ret; } void free(size_t len) { _size -= len; if (len <= this->len - _head) { _head += len; if (_head == this->len) _head = 0; } else { _head = len; } } void clear() {_head = _tail = _size = 0;} size_t size() {return _size;} private: size_t _head; size_t _tail; size_t _size; }; #endif #endif // HV_BUF_H_ ================================================ FILE: base/hdef.h ================================================ #ifndef HV_DEF_H_ #define HV_DEF_H_ #include "hplatform.h" #ifndef ABS #define ABS(n) ((n) > 0 ? (n) : -(n)) #endif #ifndef NABS #define NABS(n) ((n) < 0 ? (n) : -(n)) #endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) #endif #ifndef BITSET #define BITSET(p, n) (*(p) |= (1u << (n))) #endif #ifndef BITCLR #define BITCLR(p, n) (*(p) &= ~(1u << (n))) #endif #ifndef BITGET #define BITGET(i, n) ((i) & (1u << (n))) #endif /* #ifndef CR #define CR '\r' #endif #ifndef LF #define LF '\n' #endif #ifndef CRLF #define CRLF "\r\n" #endif */ #define FLOAT_PRECISION 1e-6 #define FLOAT_EQUAL_ZERO(f) (ABS(f) < FLOAT_PRECISION) #ifndef INFINITE #define INFINITE (uint32_t)-1 #endif /* ASCII: [0, 0x20) control-charaters [0x20, 0x7F) printable-charaters 0x0A => LF 0x0D => CR 0x20 => SPACE 0x7F => DEL [0x09, 0x0D] => \t\n\v\f\r [0x30, 0x39] => 0~9 [0x41, 0x5A] => A~Z [0x61, 0x7A] => a~z */ #ifndef IS_ALPHA #define IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) #endif // NOTE: IS_NUM conflicts with mysql.h #ifndef IS_DIGIT #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') #endif #ifndef IS_ALPHANUM #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_DIGIT(c)) #endif #ifndef IS_CNTRL #define IS_CNTRL(c) ((c) >= 0 && (c) < 0x20) #endif #ifndef IS_GRAPH #define IS_GRAPH(c) ((c) >= 0x20 && (c) < 0x7F) #endif #ifndef IS_HEX #define IS_HEX(c) (IS_DIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) #endif #ifndef IS_LOWER #define IS_LOWER(c) (((c) >= 'a' && (c) <= 'z')) #endif #ifndef IS_UPPER #define IS_UPPER(c) (((c) >= 'A' && (c) <= 'Z')) #endif #ifndef LOWER #define LOWER(c) ((c) | 0x20) #endif #ifndef UPPER #define UPPER(c) ((c) & ~0x20) #endif // LD, LU, LLD, LLU for explicit conversion of integer // #ifndef LD // #define LD(v) ((long)(v)) // #endif // #ifndef LU // #define LU(v) ((unsigned long)(v)) // #endif #ifndef LLD #define LLD(v) ((long long)(v)) #endif #ifndef LLU #define LLU(v) ((unsigned long long)(v)) #endif #ifndef _WIN32 // MAKEWORD, HIBYTE, LOBYTE #ifndef MAKEWORD #define MAKEWORD(h, l) ( (((WORD)h) << 8) | (l & 0xff) ) #endif #ifndef HIBYTE #define HIBYTE(w) ( (BYTE)(((WORD)w) >> 8) ) #endif #ifndef LOBYTE #define LOBYTE(w) ( (BYTE)(w & 0xff) ) #endif // MAKELONG, HIWORD, LOWORD #ifndef MAKELONG #define MAKELONG(h, l) ( ((int32_t)h) << 16 | (l & 0xffff) ) #endif #ifndef HIWORD #define HIWORD(n) ( (WORD)(((int32_t)n) >> 16) ) #endif #ifndef LOWORD #define LOWORD(n) ( (WORD)(n & 0xffff) ) #endif #endif // _WIN32 // MAKEINT64, HIINT, LOINT #ifndef MAKEINT64 #define MAKEINT64(h, l) ( ((int64_t)h) << 32 | (l & 0xffffffff) ) #endif #ifndef HIINT #define HIINT(n) ( (int32_t)(((int64_t)n) >> 32) ) #endif #ifndef LOINT #define LOINT(n) ( (int32_t)(n & 0xffffffff) ) #endif #ifndef MAKE_FOURCC #define MAKE_FOURCC(a, b, c, d) \ ( ((uint32)d) | ( ((uint32)c) << 8 ) | ( ((uint32)b) << 16 ) | ( ((uint32)a) << 24 ) ) #endif #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef LIMIT #define LIMIT(lower, v, upper) ((v) < (lower) ? (lower) : (v) > (upper) ? (upper) : (v)) #endif #ifndef MAX_PATH #define MAX_PATH 260 #endif #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void*)0) #endif #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef SAFE_ALLOC #define SAFE_ALLOC(p, size)\ do {\ void* ptr = malloc(size);\ if (!ptr) {\ fprintf(stderr, "malloc failed!\n");\ exit(-1);\ }\ memset(ptr, 0, size);\ *(void**)&(p) = ptr;\ } while(0) #endif #ifndef SAFE_FREE #define SAFE_FREE(p) do {if (p) {free(p); (p) = NULL;}} while(0) #endif #ifndef SAFE_DELETE #define SAFE_DELETE(p) do {if (p) {delete (p); (p) = NULL;}} while(0) #endif #ifndef SAFE_DELETE_ARRAY #define SAFE_DELETE_ARRAY(p) do {if (p) {delete[] (p); (p) = NULL;}} while(0) #endif #ifndef SAFE_RELEASE #define SAFE_RELEASE(p) do {if (p) {(p)->release(); (p) = NULL;}} while(0) #endif #ifndef SAFE_CLOSE #define SAFE_CLOSE(fd) do {if ((fd) >= 0) {close(fd); (fd) = -1;}} while(0) #endif #define STRINGIFY(x) STRINGIFY_HELPER(x) #define STRINGIFY_HELPER(x) #x #define STRINGCAT(x, y) STRINGCAT_HELPER(x, y) #define STRINGCAT_HELPER(x, y) x##y #ifndef offsetof #define offsetof(type, member) \ ((size_t)(&((type*)0)->member)) #endif #ifndef offsetofend #define offsetofend(type, member) \ (offsetof(type, member) + sizeof(((type*)0)->member)) #endif #ifndef container_of #define container_of(ptr, type, member) \ ((type*)((char*)(ptr) - offsetof(type, member))) #endif #ifdef PRINT_DEBUG #define printd(...) printf(__VA_ARGS__) #else #define printd(...) #endif #ifdef PRINT_ERROR #define printe(...) fprintf(stderr, __VA_ARGS__) #else #define printe(...) #endif #endif // HV_DEF_H_ ================================================ FILE: base/heap.h ================================================ #ifndef HV_HEAP_H_ #define HV_HEAP_H_ #include // for assert #include // for NULL struct heap_node { struct heap_node* parent; struct heap_node* left; struct heap_node* right; }; typedef int (*heap_compare_fn)(const struct heap_node* lhs, const struct heap_node* rhs); struct heap { struct heap_node* root; int nelts; // if compare is less_than, root is min of heap // if compare is larger_than, root is max of heap heap_compare_fn compare; }; static inline void heap_init(struct heap* heap, heap_compare_fn fn) { heap->root = NULL; heap->nelts = 0; heap->compare = fn; } // replace s with r static inline void heap_replace(struct heap* heap, struct heap_node* s, struct heap_node* r) { // s->parent->child, s->left->parent, s->right->parent if (s->parent == NULL) heap->root = r; else if (s->parent->left == s) s->parent->left = r; else if (s->parent->right == s) s->parent->right = r; if (s->left) s->left->parent = r; if (s->right) s->right->parent = r; if (r) { //*r = *s; r->parent = s->parent; r->left = s->left; r->right = s->right; } } static inline void heap_swap(struct heap* heap, struct heap_node* parent, struct heap_node* child) { assert(child->parent == parent && (parent->left == child || parent->right == child)); struct heap_node* pparent = parent->parent; struct heap_node* lchild = child->left; struct heap_node* rchild = child->right; struct heap_node* sibling = NULL; if (pparent == NULL) heap->root = child; else if (pparent->left == parent) pparent->left = child; else if (pparent->right == parent) pparent->right = child; if (lchild) lchild->parent = parent; if (rchild) rchild->parent = parent; child->parent = pparent; if (parent->left == child) { sibling = parent->right; child->left = parent; child->right = sibling; } else { sibling = parent->left; child->left = sibling; child->right = parent; } if (sibling) sibling->parent = child; parent->parent = child; parent->left = lchild; parent->right = rchild; } static inline void heap_insert(struct heap* heap, struct heap_node* node) { // get last => insert node => sift up // 0: left, 1: right int path = 0; int n,d; ++heap->nelts; // traverse from bottom to up, get path of last node for (d = 0, n = heap->nelts; n >= 2; ++d, n>>=1) { path = (path << 1) | (n & 1); } // get last->parent by path struct heap_node* parent = heap->root; while(d > 1) { parent = (path & 1) ? parent->right : parent->left; --d; path >>= 1; } // insert node node->parent = parent; if (parent == NULL) heap->root = node; else if (path & 1) parent->right = node; else parent->left = node; // sift up if (heap->compare) { while (node->parent && heap->compare(node, node->parent)) { heap_swap(heap, node->parent, node); } } } static inline void heap_remove(struct heap* heap, struct heap_node* node) { if (heap->nelts == 0) return; // get last => replace node with last => sift down and sift up // 0: left, 1: right int path = 0; int n,d; // traverse from bottom to up, get path of last node for (d = 0, n = heap->nelts; n >= 2; ++d, n>>=1) { path = (path << 1) | (n & 1); } --heap->nelts; // get last->parent by path struct heap_node* parent = heap->root; while(d > 1) { parent = (path & 1) ? parent->right : parent->left; --d; path >>= 1; } // replace node with last struct heap_node* last = NULL; if (parent == NULL) { return; } else if (path & 1) { last = parent->right; parent->right = NULL; } else { last = parent->left; parent->left = NULL; } if (last == NULL) { if (heap->root == node) { heap->root = NULL; } return; } heap_replace(heap, node, last); node->parent = node->left = node->right = NULL; if (!heap->compare) return; struct heap_node* v = last; struct heap_node* est = NULL; // sift down while (1) { est = v; if (v->left) est = heap->compare(est, v->left) ? est : v->left; if (v->right) est = heap->compare(est, v->right) ? est : v->right; if (est == v) break; heap_swap(heap, v, est); } // sift up while (v->parent && heap->compare(v, v->parent)) { heap_swap(heap, v->parent, v); } } static inline void heap_dequeue(struct heap* heap) { heap_remove(heap, heap->root); } #endif // HV_HEAP_H_ ================================================ FILE: base/hendian.h ================================================ #ifndef HV_ENDIAN_H_ #define HV_ENDIAN_H_ #include "hplatform.h" #if defined(OS_MAC) #include #define htobe16(v) OSSwapHostToBigInt16(v) #define htobe32(v) OSSwapHostToBigInt32(v) #define htobe64(v) OSSwapHostToBigInt64(v) #define be16toh(v) OSSwapBigToHostInt16(v) #define be32toh(v) OSSwapBigToHostInt32(v) #define be64toh(v) OSSwapBigToHostInt64(v) #define htole16(v) OSSwapHostToLittleInt16(v) #define htole32(v) OSSwapHostToLittleInt32(v) #define htole64(v) OSSwapHostToLittleInt64(v) #define le16toh(v) OSSwapLittleToHostInt16(v) #define le32toh(v) OSSwapLittleToHostInt32(v) #define le64toh(v) OSSwapLittleToHostInt64(v) #elif defined(OS_WIN) #if _WIN32_WINNT < _WIN32_WINNT_WIN8 /* * Byte order conversion functions for 64-bit integers and 32 + 64 bit * floating-point numbers. IEEE big-endian format is used for the * network floating point format. */ #define _WS2_32_WINSOCK_SWAP_LONG(l) \ ( ( ((l) >> 24) & 0x000000FFL ) | \ ( ((l) >> 8) & 0x0000FF00L ) | \ ( ((l) << 8) & 0x00FF0000L ) | \ ( ((l) << 24) & 0xFF000000L ) ) #define _WS2_32_WINSOCK_SWAP_LONGLONG(l) \ ( ( ((l) >> 56) & 0x00000000000000FFLL ) | \ ( ((l) >> 40) & 0x000000000000FF00LL ) | \ ( ((l) >> 24) & 0x0000000000FF0000LL ) | \ ( ((l) >> 8) & 0x00000000FF000000LL ) | \ ( ((l) << 8) & 0x000000FF00000000LL ) | \ ( ((l) << 24) & 0x0000FF0000000000LL ) | \ ( ((l) << 40) & 0x00FF000000000000LL ) | \ ( ((l) << 56) & 0xFF00000000000000LL ) ) #ifndef htonll __inline unsigned __int64 htonll ( unsigned __int64 Value ) { const unsigned __int64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value); return Retval; } #endif /* htonll */ #ifndef ntohll __inline unsigned __int64 ntohll ( unsigned __int64 Value ) { const unsigned __int64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value); return Retval; } #endif /* ntohll */ #ifndef htonf __inline unsigned __int32 htonf ( float Value ) { unsigned __int32 Tempval; unsigned __int32 Retval; Tempval = *(unsigned __int32*)(&Value); Retval = _WS2_32_WINSOCK_SWAP_LONG (Tempval); return Retval; } #endif /* htonf */ #ifndef ntohf __inline float ntohf ( unsigned __int32 Value ) { const unsigned __int32 Tempval = _WS2_32_WINSOCK_SWAP_LONG (Value); float Retval; *((unsigned __int32*)&Retval) = Tempval; return Retval; } #endif /* ntohf */ #ifndef htond __inline unsigned __int64 htond ( double Value ) { unsigned __int64 Tempval; unsigned __int64 Retval; Tempval = *(unsigned __int64*)(&Value); Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Tempval); return Retval; } #endif /* htond */ #ifndef ntohd __inline double ntohd ( unsigned __int64 Value ) { const unsigned __int64 Tempval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value); double Retval; *((unsigned __int64*)&Retval) = Tempval; return Retval; } #endif /* ntohd */ #endif #define htobe16(v) htons(v) #define htobe32(v) htonl(v) #define htobe64(v) htonll(v) #define be16toh(v) ntohs(v) #define be32toh(v) ntohl(v) #define be64toh(v) ntohll(v) #if (BYTE_ORDER == LITTLE_ENDIAN) #define htole16(v) (v) #define htole32(v) (v) #define htole64(v) (v) #define le16toh(v) (v) #define le32toh(v) (v) #define le64toh(v) (v) #elif (BYTE_ORDER == BIG_ENDIAN) #define htole16(v) __builtin_bswap16(v) #define htole32(v) __builtin_bswap32(v) #define htole64(v) __builtin_bswap64(v) #define le16toh(v) __builtin_bswap16(v) #define le32toh(v) __builtin_bswap32(v) #define le64toh(v) __builtin_bswap64(v) #endif #elif HAVE_ENDIAN_H #include #elif HAVE_SYS_ENDIAN_H #include #else #warning "Not found endian.h!" #endif #define PI8(p) *(int8_t*)(p) #define PI16(p) *(int16_t*)(p) #define PI32(p) *(int32_t*)(p) #define PI64(p) *(int64_t*)(p) #define PU8(p) *(uint8_t*)(p) #define PU16(p) *(uint16_t*)(p) #define PU32(p) *(uint32_t*)(p) #define PU64(p) *(uint64_t*)(p) #define PF32(p) *(float*)(p) #define PF64(p) *(double*)(p) #define GET_BE16(p) be16toh(PU16(p)) #define GET_BE32(p) be32toh(PU32(p)) #define GET_BE64(p) be64toh(PU64(p)) #define GET_LE16(p) le16toh(PU16(p)) #define GET_LE32(p) le32toh(PU32(p)) #define GET_LE64(p) le64toh(PU64(p)) #define PUT_BE16(p, v) PU16(p) = htobe16(v) #define PUT_BE32(p, v) PU32(p) = htobe32(v) #define PUT_BE64(p, v) PU64(p) = htobe64(v) #define PUT_LE16(p, v) PU16(p) = htole16(v) #define PUT_LE32(p, v) PU32(p) = htole32(v) #define PUT_LE64(p, v) PU64(p) = htole64(v) // NOTE: uint8_t* p = (uint8_t*)buf; #define POP_BE8(p, v) v = *p; ++p #define POP_BE16(p, v) v = be16toh(PU16(p)); p += 2 #define POP_BE32(p, v) v = be32toh(PU32(p)); p += 4 #define POP_BE64(p, v) v = be64toh(PU64(p)); p += 8 #define POP_LE8(p, v) v= *p; ++p #define POP_LE16(p, v) v = le16toh(PU16(p)); p += 2 #define POP_LE32(p, v) v = le32toh(PU32(p)); p += 4 #define POP_LE64(p, v) v = le64toh(PU64(p)); p += 8 #define PUSH_BE8(p, v) *p = v; ++p #define PUSH_BE16(p, v) PU16(p) = htobe16(v); p += 2 #define PUSH_BE32(p, v) PU32(p) = htobe32(v); p += 4 #define PUSH_BE64(p, v) PU64(p) = htobe64(v); p += 8 #define PUSH_LE8(p, v) *p = v; ++p #define PUSH_LE16(p, v) PU16(p) = htole16(v); p += 2 #define PUSH_LE32(p, v) PU32(p) = htole32(v); p += 4 #define PUSH_LE64(p, v) PU64(p) = htole64(v); p += 8 // NOTE: NET_ENDIAN = BIG_ENDIAN #define POP8(p, v) POP_BE8(p, v) #define POP16(p, v) POP_BE16(p, v) #define POP32(p, v) POP_BE32(p, v) #define POP64(p, v) POP_BE64(p, v) #define POP_N(p, v, n) memcpy(v, p, n); p += n #define PUSH8(p, v) PUSH_BE8(p, v) #define PUSH16(p, v) PUSH_BE16(p, v) #define PUSH32(p, v) PUSH_BE32(p, v) #define PUSH64(p, v) PUSH_BE64(p, v) #define PUSH_N(p, v, n) memcpy(p, v, n); p += n static inline int detect_endian() { union { char c; short s; } u; u.s = 0x1122; return u.c ==0x11 ? BIG_ENDIAN : LITTLE_ENDIAN; } #ifdef __cplusplus template uint8_t* serialize(uint8_t* buf, T value, int host_endian = LITTLE_ENDIAN, int buf_endian = BIG_ENDIAN) { size_t size = sizeof(T); uint8_t* pDst = buf; uint8_t* pSrc = (uint8_t*)&value; if (host_endian == buf_endian) { memcpy(pDst, pSrc, size); } else { for (int i = 0; i < size; ++i) { pDst[i] = pSrc[size-i-1]; } } return buf+size; } template uint8_t* deserialize(uint8_t* buf, T* value, int host_endian = LITTLE_ENDIAN, int buf_endian = BIG_ENDIAN) { size_t size = sizeof(T); uint8_t* pSrc = buf; uint8_t* pDst = (uint8_t*)value; if (host_endian == buf_endian) { memcpy(pDst, pSrc, size); } else { for (int i = 0; i < size; ++i) { pDst[i] = pSrc[size-i-1]; } } return buf+size; } #endif // __cplusplus #endif // HV_ENDIAN_H_ ================================================ FILE: base/herr.c ================================================ #include "herr.h" #include // for strerror // errcode => errmsg const char* hv_strerror(int err) { if (err > 0 && err <= SYS_NERR) { return strerror(err); } switch (err) { #define F(errcode, name, errmsg) \ case errcode: return errmsg; FOREACH_ERR(F) #undef F default: return "Undefined error"; } } ================================================ FILE: base/herr.h ================================================ #ifndef HV_ERR_H_ #define HV_ERR_H_ #include #include "hexport.h" #ifndef SYS_NERR #define SYS_NERR 133 #endif // F(errcode, name, errmsg) // [1, 133] #define FOREACH_ERR_SYS(F) // [1xx~5xx] #define FOREACH_ERR_STATUS(F) // [1xxx] #define FOREACH_ERR_COMMON(F) \ F(0, OK, "OK") \ F(1000, UNKNOWN, "Unknown error") \ \ F(1001, NULL_PARAM, "Null parameter") \ F(1002, NULL_POINTER, "Null pointer") \ F(1003, NULL_DATA, "Null data") \ F(1004, NULL_HANDLE, "Null handle") \ \ F(1011, INVALID_PARAM, "Invalid parameter")\ F(1012, INVALID_POINTER, "Invalid pointer") \ F(1013, INVALID_DATA, "Invalid data") \ F(1014, INVALID_HANDLE, "Invalid handle") \ F(1015, INVALID_JSON, "Invalid json") \ F(1016, INVALID_XML, "Invalid xml") \ F(1017, INVALID_FMT, "Invalid format") \ F(1018, INVALID_PROTOCOL, "Invalid protocol") \ F(1019, INVALID_PACKAGE, "Invalid package") \ \ F(1021, OUT_OF_RANGE, "Out of range") \ F(1022, OVER_LIMIT, "Over the limit") \ F(1023, MISMATCH, "Mismatch") \ F(1024, PARSE, "Parse failed") \ \ F(1030, OPEN_FILE, "Open file failed") \ F(1031, SAVE_FILE, "Save file failed") \ F(1032, READ_FILE, "Read file failed") \ F(1033, WRITE_FILE, "Write file failed")\ \ F(1040, SSL, "SSL/TLS error") \ F(1041, NEW_SSL_CTX, "New SSL_CTX failed") \ F(1042, NEW_SSL, "New SSL failed") \ F(1043, SSL_HANDSHAKE, "SSL handshake failed") \ \ F(1100, TASK_TIMEOUT, "Task timeout") \ F(1101, TASK_QUEUE_FULL, "Task queue full") \ F(1102, TASK_QUEUE_EMPTY, "Task queue empty") \ \ F(1400, REQUEST, "Bad request") \ F(1401, RESPONSE, "Bad response") \ // [-1xxx] #define FOREACH_ERR_FUNC(F) \ F(-1001, MALLOC, "malloc() error") \ F(-1002, REALLOC, "realloc() error") \ F(-1003, CALLOC, "calloc() error") \ F(-1004, FREE, "free() error") \ \ F(-1011, SOCKET, "socket() error") \ F(-1012, BIND, "bind() error") \ F(-1013, LISTEN, "listen() error") \ F(-1014, ACCEPT, "accept() error") \ F(-1015, CONNECT, "connect() error") \ F(-1016, RECV, "recv() error") \ F(-1017, SEND, "send() error") \ F(-1018, RECVFROM, "recvfrom() error") \ F(-1019, SENDTO, "sendto() error") \ F(-1020, SETSOCKOPT, "setsockopt() error") \ F(-1021, GETSOCKOPT, "getsockopt() error") \ // grpc [4xxx] #define FOREACH_ERR_GRPC(F) \ F(4000, GRPC_FIRST, "grpc no error") \ F(4001, GRPC_STATUS_CANCELLED, "grpc status: cancelled") \ F(4002, GRPC_STATUS_UNKNOWN, "grpc unknown error") \ F(4003, GRPC_STATUS_INVALID_ARGUMENT, "grpc status: invalid argument")\ F(4004, GRPC_STATUS_DEADLINE, "grpc status: deadline") \ F(4005, GRPC_STATUS_NOT_FOUND, "grpc status: not found") \ F(4006, GRPC_STATUS_ALREADY_EXISTS, "grpc status: already exists") \ F(4007, GRPC_STATUS_PERMISSION_DENIED, "grpc status: permission denied") \ F(4008, GRPC_STATUS_RESOURCE_EXHAUSTED, "grpc status: resource exhausted") \ F(4009, GRPC_STATUS_FAILED_PRECONDITION,"grpc status: failed precondition") \ F(4010, GRPC_STATUS_ABORTED, "grpc status: aborted") \ F(4011, GRPC_STATUS_OUT_OF_RANGE, "grpc status: out of range") \ F(4012, GRPC_STATUS_UNIMPLEMENTED, "grpc status: unimplemented") \ F(4013, GRPC_STATUS_INTERNAL, "grpc internal error") \ F(4014, GRPC_STATUS_UNAVAILABLE, "grpc service unavailable") \ F(4015, GRPC_STATUS_DATA_LOSS, "grpc status: data loss") \ #define FOREACH_ERR(F) \ FOREACH_ERR_COMMON(F) \ FOREACH_ERR_FUNC(F) \ FOREACH_ERR_GRPC(F) \ #undef ERR_OK // prevent conflict enum { #define F(errcode, name, errmsg) ERR_##name = errcode, FOREACH_ERR(F) #undef F }; #ifdef __cplusplus extern "C" { #endif // errcode => errmsg HV_EXPORT const char* hv_strerror(int err); #ifdef __cplusplus } // extern "C" #endif #endif // HV_ERR_H_ ================================================ FILE: base/hlog.c ================================================ #include "hlog.h" #include #include #include #include #include #include //#include "hmutex.h" #ifdef _WIN32 #pragma warning (disable: 4244) // conversion loss of data #include #define hmutex_t CRITICAL_SECTION #define hmutex_init InitializeCriticalSection #define hmutex_destroy DeleteCriticalSection #define hmutex_lock EnterCriticalSection #define hmutex_unlock LeaveCriticalSection #else #include // for gettimeofday #include #define hmutex_t pthread_mutex_t #define hmutex_init(mutex) pthread_mutex_init(mutex, NULL) #define hmutex_destroy pthread_mutex_destroy #define hmutex_lock pthread_mutex_lock #define hmutex_unlock pthread_mutex_unlock #endif //#include "htime.h" #define SECONDS_PER_HOUR 3600 #define SECONDS_PER_DAY 86400 // 24*3600 #define SECONDS_PER_WEEK 604800 // 7*24*3600; static int s_gmtoff = 28800; // 8*3600 struct logger_s { logger_handler handler; unsigned int bufsize; char* buf; int level; int enable_color; char format[64]; // for file logger char filepath[256]; unsigned long long max_filesize; float truncate_percent; int remain_days; int enable_fsync; FILE* fp_; char cur_logfile[256]; time_t last_logfile_ts; int can_write_cnt; hmutex_t mutex_; // thread-safe }; static void logger_init(logger_t* logger) { logger->handler = NULL; logger->bufsize = DEFAULT_LOG_MAX_BUFSIZE; logger->buf = (char*)malloc(logger->bufsize); logger->level = DEFAULT_LOG_LEVEL; logger->enable_color = 0; // NOTE: format is faster 6% than snprintf // logger->format[0] = '\0'; strncpy(logger->format, DEFAULT_LOG_FORMAT, sizeof(logger->format) - 1); logger->fp_ = NULL; logger->max_filesize = DEFAULT_LOG_MAX_FILESIZE; logger->truncate_percent = DEFAULT_LOG_TRUNCATE_PERCENT; logger->remain_days = DEFAULT_LOG_REMAIN_DAYS; logger->enable_fsync = 1; logger_set_file(logger, DEFAULT_LOG_FILE); logger->last_logfile_ts = 0; logger->can_write_cnt = -1; hmutex_init(&logger->mutex_); } logger_t* logger_create() { // init gmtoff here time_t ts = time(NULL); struct tm* local_tm = localtime(&ts); int local_hour = local_tm->tm_hour; struct tm* gmt_tm = gmtime(&ts); int gmt_hour = gmt_tm->tm_hour; s_gmtoff = (local_hour - gmt_hour) * SECONDS_PER_HOUR; logger_t* logger = (logger_t*)malloc(sizeof(logger_t)); logger_init(logger); return logger; } void logger_destroy(logger_t* logger) { if (logger) { if (logger->buf) { free(logger->buf); logger->buf = NULL; } if (logger->fp_) { fclose(logger->fp_); logger->fp_ = NULL; } hmutex_destroy(&logger->mutex_); free(logger); } } void logger_set_handler(logger_t* logger, logger_handler fn) { logger->handler = fn; } void logger_set_level(logger_t* logger, int level) { logger->level = level; } void logger_set_level_by_str(logger_t* logger, const char* szLoglevel) { int loglevel = DEFAULT_LOG_LEVEL; if (strcmp(szLoglevel, "VERBOSE") == 0) { loglevel = LOG_LEVEL_VERBOSE; } else if (strcmp(szLoglevel, "DEBUG") == 0) { loglevel = LOG_LEVEL_DEBUG; } else if (strcmp(szLoglevel, "INFO") == 0) { loglevel = LOG_LEVEL_INFO; } else if (strcmp(szLoglevel, "WARN") == 0) { loglevel = LOG_LEVEL_WARN; } else if (strcmp(szLoglevel, "ERROR") == 0) { loglevel = LOG_LEVEL_ERROR; } else if (strcmp(szLoglevel, "FATAL") == 0) { loglevel = LOG_LEVEL_FATAL; } else if (strcmp(szLoglevel, "SILENT") == 0) { loglevel = LOG_LEVEL_SILENT; } else { loglevel = DEFAULT_LOG_LEVEL; } logger->level = loglevel; } void logger_set_format(logger_t* logger, const char* format) { if (format) { strncpy(logger->format, format, sizeof(logger->format) - 1); } else { logger->format[0] = '\0'; } } void logger_set_remain_days(logger_t* logger, int days) { logger->remain_days = days; } void logger_set_truncate_percent(logger_t* logger, float percent) { assert(percent <= 1.0f); logger->truncate_percent = percent; } void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize) { logger->bufsize = bufsize; logger->buf = (char*)realloc(logger->buf, bufsize); } void logger_enable_color(logger_t* logger, int on) { logger->enable_color = on; } void logger_set_file(logger_t* logger, const char* filepath) { strncpy(logger->filepath, filepath, sizeof(logger->filepath) - 1); // remove suffix .log char* suffix = strrchr(logger->filepath, '.'); if (suffix && strcmp(suffix, ".log") == 0) { *suffix = '\0'; } } void logger_set_max_filesize(logger_t* logger, unsigned long long filesize) { logger->max_filesize = filesize; } void logger_set_max_filesize_by_str(logger_t* logger, const char* str) { int num = atoi(str); if (num <= 0) return; // 16 16M 16MB const char* e = str; while (*e != '\0') ++e; --e; char unit; if (*e >= '0' && *e <= '9') unit = 'M'; else if (*e == 'B') unit = *(e-1); else unit = *e; unsigned long long filesize = num; switch (unit) { case 'K': filesize <<= 10; break; case 'M': filesize <<= 20; break; case 'G': filesize <<= 30; break; default: filesize <<= 20; break; } logger->max_filesize = filesize; } void logger_enable_fsync(logger_t* logger, int on) { logger->enable_fsync = on; } void logger_fsync(logger_t* logger) { hmutex_lock(&logger->mutex_); if (logger->fp_) { fflush(logger->fp_); } hmutex_unlock(&logger->mutex_); } const char* logger_get_cur_file(logger_t* logger) { return logger->cur_logfile; } static void logfile_name(const char* filepath, time_t ts, char* buf, int len) { struct tm* tm = localtime(&ts); snprintf(buf, len, "%s.%04d%02d%02d.log", filepath, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday); } static void logfile_truncate(logger_t* logger) { // close if (logger->fp_) { fclose(logger->fp_); logger->fp_ = NULL; } char tmp_logfile[sizeof(logger->cur_logfile) + 4] = {0}; FILE* tmpfile = NULL; if (logger->truncate_percent < 1.0f) { snprintf(tmp_logfile, sizeof(tmp_logfile), "%s.tmp", logger->cur_logfile); tmpfile = fopen(tmp_logfile, "w"); } if (tmpfile) { // truncate percent logger->fp_ = fopen(logger->cur_logfile, "r"); if (logger->fp_) { fseek(logger->fp_, 0, SEEK_END); long filesize = ftell(logger->fp_); long truncate_size = (long)((double)filesize * logger->truncate_percent); fseek(logger->fp_, -(filesize - truncate_size), SEEK_CUR); char buf[4096] = {0}; const char* pbuf = buf; size_t nread = 0; char find_newline = 0; while ((nread = fread(buf, 1, sizeof(buf), logger->fp_)) > 0) { pbuf = buf; if (find_newline == 0) { while (nread > 0) { if (*pbuf == '\n') { find_newline = 1; ++pbuf; --nread; break; } ++pbuf; --nread; } } if (nread > 0) { fwrite(pbuf, 1, nread, tmpfile); } } fclose(tmpfile); fclose(logger->fp_); logger->fp_ = NULL; remove(logger->cur_logfile); rename(tmp_logfile, logger->cur_logfile); } } else { // truncate all // remove(logger->cur_logfile); logger->fp_ = fopen(logger->cur_logfile, "w"); if (logger->fp_) { fclose(logger->fp_); logger->fp_ = NULL; } } // reopen logger->fp_ = fopen(logger->cur_logfile, "a"); } static FILE* logfile_shift(logger_t* logger) { time_t ts_now = time(NULL); int interval_days = logger->last_logfile_ts == 0 ? 0 : (ts_now+s_gmtoff) / SECONDS_PER_DAY - (logger->last_logfile_ts+s_gmtoff) / SECONDS_PER_DAY; if (logger->fp_ == NULL || interval_days > 0) { // close old logfile if (logger->fp_) { fclose(logger->fp_); logger->fp_ = NULL; } else { interval_days = 30; } if (logger->remain_days >= 0) { char rm_logfile[256] = {0}; if (interval_days >= logger->remain_days) { // remove [today-interval_days, today-remain_days] logfile for (int i = interval_days; i >= logger->remain_days; --i) { time_t ts_rm = ts_now - i * SECONDS_PER_DAY; logfile_name(logger->filepath, ts_rm, rm_logfile, sizeof(rm_logfile)); remove(rm_logfile); } } else { // remove today-remain_days logfile time_t ts_rm = ts_now - logger->remain_days * SECONDS_PER_DAY; logfile_name(logger->filepath, ts_rm, rm_logfile, sizeof(rm_logfile)); remove(rm_logfile); } } } // open today logfile if (logger->fp_ == NULL) { logfile_name(logger->filepath, ts_now, logger->cur_logfile, sizeof(logger->cur_logfile)); logger->fp_ = fopen(logger->cur_logfile, "a"); logger->last_logfile_ts = ts_now; } // NOTE: estimate can_write_cnt to avoid frequent fseek/ftell if (logger->fp_ && --logger->can_write_cnt < 0) { fseek(logger->fp_, 0, SEEK_END); long filesize = ftell(logger->fp_); if (filesize > logger->max_filesize) { logfile_truncate(logger); } else { logger->can_write_cnt = (logger->max_filesize - filesize) / logger->bufsize; } } return logger->fp_; } static void logfile_write(logger_t* logger, const char* buf, int len) { FILE* fp = logfile_shift(logger); if (fp) { fwrite(buf, 1, len, fp); if (logger->enable_fsync) { fflush(fp); } } } static int i2a(int i, char* buf, int len) { for (int l = len - 1; l >= 0; --l) { if (i == 0) { buf[l] = '0'; } else { buf[l] = i % 10 + '0'; i /= 10; } } return len; } int logger_print(logger_t* logger, int level, const char* fmt, ...) { if (level < logger->level) return -10; int year,month,day,hour,min,sec,us; #ifdef _WIN32 SYSTEMTIME tm; GetLocalTime(&tm); year = tm.wYear; month = tm.wMonth; day = tm.wDay; hour = tm.wHour; min = tm.wMinute; sec = tm.wSecond; us = tm.wMilliseconds * 1000; #else struct timeval tv; struct tm* tm = NULL; gettimeofday(&tv, NULL); time_t tt = tv.tv_sec; tm = localtime(&tt); year = tm->tm_year + 1900; month = tm->tm_mon + 1; day = tm->tm_mday; hour = tm->tm_hour; min = tm->tm_min; sec = tm->tm_sec; us = tv.tv_usec; #endif const char* pcolor = ""; const char* plevel = ""; #define XXX(id, str, clr) \ case id: plevel = str; pcolor = clr; break; switch (level) { LOG_LEVEL_MAP(XXX) } #undef XXX // lock logger->buf hmutex_lock(&logger->mutex_); char* buf = logger->buf; int bufsize = logger->bufsize; int len = 0; if (logger->enable_color) { len = snprintf(buf, bufsize, "%s", pcolor); } const char* p = logger->format; if (*p) { while (*p) { if (*p == '%') { switch(*++p) { case 'y': len += i2a(year, buf + len, 4); break; case 'm': len += i2a(month, buf + len, 2); break; case 'd': len += i2a(day, buf + len, 2); break; case 'H': len += i2a(hour, buf + len, 2); break; case 'M': len += i2a(min, buf + len, 2); break; case 'S': len += i2a(sec, buf + len, 2); break; case 'z': len += i2a(us/1000, buf + len, 3); break; case 'Z': len += i2a(us, buf + len, 6); break; case 'l': buf[len++] = *plevel; break; case 'L': for (int i = 0; i < 5; ++i) { buf[len++] = plevel[i]; } break; case 's': { va_list ap; va_start(ap, fmt); len += vsnprintf(buf + len, bufsize - len, fmt, ap); va_end(ap); } break; case '%': buf[len++] = '%'; break; default: break; } } else { buf[len++] = *p; } ++p; if (len >= bufsize) break; } } else { len += snprintf(buf + len, bufsize - len, "%04d-%02d-%02d %02d:%02d:%02d.%03d %s ", year, month, day, hour, min, sec, us/1000, plevel); va_list ap; va_start(ap, fmt); len += vsnprintf(buf + len, bufsize - len, fmt, ap); va_end(ap); } if (logger->enable_color && len < bufsize) { len += snprintf(buf + len, bufsize - len, "%s", CLR_CLR); } if (len < bufsize) { buf[len++] = '\n'; } else { buf[bufsize - 1] = '\n'; len = bufsize; } if (logger->handler) { logger->handler(level, buf, len); } else { logfile_write(logger, buf, len); } hmutex_unlock(&logger->mutex_); return len; } static logger_t* s_logger = NULL; logger_t* hv_default_logger() { if (s_logger == NULL) { s_logger = logger_create(); atexit(hv_destroy_default_logger); } return s_logger; } void hv_destroy_default_logger(void) { if (s_logger) { logger_fsync(s_logger); logger_destroy(s_logger); s_logger = NULL; } } void stdout_logger(int loglevel, const char* buf, int len) { fprintf(stdout, "%.*s", len, buf); } void stderr_logger(int loglevel, const char* buf, int len) { fprintf(stderr, "%.*s", len, buf); } void file_logger(int loglevel, const char* buf, int len) { logfile_write(hv_default_logger(), buf, len); } ================================================ FILE: base/hlog.h ================================================ #ifndef HV_LOG_H_ #define HV_LOG_H_ /* * hlog is thread-safe */ #include #ifdef _WIN32 #define DIR_SEPARATOR '\\' #define DIR_SEPARATOR_STR "\\" #else #define DIR_SEPARATOR '/' #define DIR_SEPARATOR_STR "/" #endif #ifndef __FILENAME__ // #define __FILENAME__ (strrchr(__FILE__, DIR_SEPARATOR) ? strrchr(__FILE__, DIR_SEPARATOR) + 1 : __FILE__) #define __FILENAME__ (strrchr(DIR_SEPARATOR_STR __FILE__, DIR_SEPARATOR) + 1) #endif #include "hexport.h" #ifdef __cplusplus extern "C" { #endif #define CLR_CLR "\033[0m" /* 恢复颜色 */ #define CLR_BLACK "\033[30m" /* 黑色字 */ #define CLR_RED "\033[31m" /* 红色字 */ #define CLR_GREEN "\033[32m" /* 绿色字 */ #define CLR_YELLOW "\033[33m" /* 黄色字 */ #define CLR_BLUE "\033[34m" /* 蓝色字 */ #define CLR_PURPLE "\033[35m" /* 紫色字 */ #define CLR_SKYBLUE "\033[36m" /* 天蓝字 */ #define CLR_WHITE "\033[37m" /* 白色字 */ #define CLR_BLK_WHT "\033[40;37m" /* 黑底白字 */ #define CLR_RED_WHT "\033[41;37m" /* 红底白字 */ #define CLR_GREEN_WHT "\033[42;37m" /* 绿底白字 */ #define CLR_YELLOW_WHT "\033[43;37m" /* 黄底白字 */ #define CLR_BLUE_WHT "\033[44;37m" /* 蓝底白字 */ #define CLR_PURPLE_WHT "\033[45;37m" /* 紫底白字 */ #define CLR_SKYBLUE_WHT "\033[46;37m" /* 天蓝底白字 */ #define CLR_WHT_BLK "\033[47;30m" /* 白底黑字 */ // XXX(id, str, clr) #define LOG_LEVEL_MAP(XXX) \ XXX(LOG_LEVEL_DEBUG, "DEBUG", CLR_WHITE) \ XXX(LOG_LEVEL_INFO, "INFO ", CLR_GREEN) \ XXX(LOG_LEVEL_WARN, "WARN ", CLR_YELLOW) \ XXX(LOG_LEVEL_ERROR, "ERROR", CLR_RED) \ XXX(LOG_LEVEL_FATAL, "FATAL", CLR_RED_WHT) typedef enum { LOG_LEVEL_VERBOSE = 0, #define XXX(id, str, clr) id, LOG_LEVEL_MAP(XXX) #undef XXX LOG_LEVEL_SILENT } log_level_e; #define DEFAULT_LOG_FILE "libhv" #define DEFAULT_LOG_LEVEL LOG_LEVEL_INFO #define DEFAULT_LOG_FORMAT "%y-%m-%d %H:%M:%S.%z %L %s" #define DEFAULT_LOG_REMAIN_DAYS 1 #define DEFAULT_LOG_MAX_BUFSIZE (1<<14) // 16k #define DEFAULT_LOG_MAX_FILESIZE (1<<24) // 16M #define DEFAULT_LOG_TRUNCATE_PERCENT 0.99f // truncate when exceeded max filesize // logger: default file_logger // network_logger() see event/nlog.h typedef void (*logger_handler)(int loglevel, const char* buf, int len); HV_EXPORT void stdout_logger(int loglevel, const char* buf, int len); HV_EXPORT void stderr_logger(int loglevel, const char* buf, int len); HV_EXPORT void file_logger(int loglevel, const char* buf, int len); // network_logger implement see event/nlog.h // HV_EXPORT void network_logger(int loglevel, const char* buf, int len); typedef struct logger_s logger_t; HV_EXPORT logger_t* logger_create(); HV_EXPORT void logger_destroy(logger_t* logger); HV_EXPORT void logger_set_handler(logger_t* logger, logger_handler fn); HV_EXPORT void logger_set_level(logger_t* logger, int level); // level = [VERBOSE,DEBUG,INFO,WARN,ERROR,FATAL,SILENT] HV_EXPORT void logger_set_level_by_str(logger_t* logger, const char* level); /* * format = "%y-%m-%d %H:%M:%S.%z %L %s" * message = "2020-01-02 03:04:05.067 DEBUG message" * %y year * %m month * %d day * %H hour * %M min * %S sec * %z ms * %Z us * %l First character of level * %L All characters of level * %s message * %% % */ HV_EXPORT void logger_set_format(logger_t* logger, const char* format); HV_EXPORT void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize); HV_EXPORT void logger_enable_color(logger_t* logger, int on); HV_EXPORT int logger_print(logger_t* logger, int level, const char* fmt, ...); // below for file logger HV_EXPORT void logger_set_file(logger_t* logger, const char* filepath); HV_EXPORT void logger_set_max_filesize(logger_t* logger, unsigned long long filesize); // 16, 16M, 16MB HV_EXPORT void logger_set_max_filesize_by_str(logger_t* logger, const char* filesize); HV_EXPORT void logger_set_remain_days(logger_t* logger, int days); HV_EXPORT void logger_set_truncate_percent(logger_t* logger, float percent); HV_EXPORT void logger_enable_fsync(logger_t* logger, int on); HV_EXPORT void logger_fsync(logger_t* logger); HV_EXPORT const char* logger_get_cur_file(logger_t* logger); // hlog: default logger instance HV_EXPORT logger_t* hv_default_logger(); HV_EXPORT void hv_destroy_default_logger(void); // macro hlog* #define hlog hv_default_logger() #define hlog_destory() hv_destroy_default_logger() #define hlog_disable() logger_set_level(hlog, LOG_LEVEL_SILENT) #define hlog_set_file(filepath) logger_set_file(hlog, filepath) #define hlog_set_level(level) logger_set_level(hlog, level) #define hlog_set_level_by_str(level) logger_set_level_by_str(hlog, level) #define hlog_set_handler(fn) logger_set_handler(hlog, fn) #define hlog_set_format(format) logger_set_format(hlog, format) #define hlog_set_max_filesize(filesize) logger_set_max_filesize(hlog, filesize) #define hlog_set_max_filesize_by_str(filesize) logger_set_max_filesize_by_str(hlog, filesize) #define hlog_set_remain_days(days) logger_set_remain_days(hlog, days) #define hlog_set_truncate_percent(val) logger_set_truncate_percent(hlog, val) #define hlog_enable_fsync() logger_enable_fsync(hlog, 1) #define hlog_disable_fsync() logger_enable_fsync(hlog, 0) #define hlog_fsync() logger_fsync(hlog) #define hlog_get_cur_file() logger_get_cur_file(hlog) #define hlogd(fmt, ...) logger_print(hlog, LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogi(fmt, ...) logger_print(hlog, LOG_LEVEL_INFO, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogw(fmt, ...) logger_print(hlog, LOG_LEVEL_WARN, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hloge(fmt, ...) logger_print(hlog, LOG_LEVEL_ERROR, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogf(fmt, ...) logger_print(hlog, LOG_LEVEL_FATAL, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) // below for android #if defined(ANDROID) || defined(__ANDROID__) #include #define LOG_TAG "JNI" #undef hlogd #undef hlogi #undef hlogw #undef hloge #undef hlogf #define hlogd(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define hlogi(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define hlogw(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define hloge(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #define hlogf(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__) #endif // macro alias #if !defined(LOGD) && !defined(LOGI) && !defined(LOGW) && !defined(LOGE) && !defined(LOGF) #define LOGD hlogd #define LOGI hlogi #define LOGW hlogw #define LOGE hloge #define LOGF hlogf #endif #ifdef __cplusplus } // extern "C" #endif #endif // HV_LOG_H_ ================================================ FILE: base/hmain.c ================================================ #include "hmain.h" #include "hbase.h" #include "hlog.h" #include "herr.h" #include "htime.h" #include "hthread.h" #ifdef OS_DARWIN #include #define environ (*_NSGetEnviron()) #endif main_ctx_t g_main_ctx; printf_t printf_fn = printf; static void init_arg_kv(int maxsize) { g_main_ctx.arg_kv_size = 0; SAFE_ALLOC(g_main_ctx.arg_kv, sizeof(char*) * maxsize); } static void save_arg_kv(const char* key, int key_len, const char* val, int val_len) { if (key_len <= 0) key_len = strlen(key); if (val_len <= 0) val_len = strlen(val); char* arg = NULL; SAFE_ALLOC(arg, key_len + val_len + 2); memcpy(arg, key, key_len); arg[key_len] = '='; memcpy(arg + key_len + 1, val, val_len); // printf("save_arg_kv: %s\n", arg); g_main_ctx.arg_kv[g_main_ctx.arg_kv_size++] = arg; } static void init_arg_list(int maxsize) { g_main_ctx.arg_list_size = 0; SAFE_ALLOC(g_main_ctx.arg_list, sizeof(char*) * maxsize); } static void save_arg_list(const char* arg) { // printf("save_arg_list: %s\n", arg); g_main_ctx.arg_list[g_main_ctx.arg_list_size++] = strdup(arg); } static const char* get_val(char** kvs, const char* key) { if (kvs == NULL) return NULL; int key_len = strlen(key); char* kv = NULL; int kv_len = 0; for (int i = 0; kvs[i]; ++i) { kv = kvs[i]; kv_len = strlen(kv); if (kv_len <= key_len) continue; // key=val if (memcmp(kv, key, key_len) == 0 && kv[key_len] == '=') { return kv + key_len + 1; } } return NULL; } const char* get_arg(const char* key) { return get_val(g_main_ctx.arg_kv, key); } const char* get_env(const char* key) { return get_val(g_main_ctx.save_envp, key); } int main_ctx_init(int argc, char** argv) { if (argc == 0 || argv == NULL) { argc = 1; SAFE_ALLOC(argv, 2 * sizeof(char*)); SAFE_ALLOC(argv[0], MAX_PATH); get_executable_path(argv[0], MAX_PATH); } get_run_dir(g_main_ctx.run_dir, sizeof(g_main_ctx.run_dir)); //printf("run_dir=%s\n", g_main_ctx.run_dir); strncpy(g_main_ctx.program_name, hv_basename(argv[0]), sizeof(g_main_ctx.program_name)); #ifdef OS_WIN if (strcmp(g_main_ctx.program_name+strlen(g_main_ctx.program_name)-4, ".exe") == 0) { *(g_main_ctx.program_name+strlen(g_main_ctx.program_name)-4) = '\0'; } #endif //printf("program_name=%s\n", g_main_ctx.program_name); char logdir[MAX_PATH] = {0}; snprintf(logdir, sizeof(logdir), "%s/logs", g_main_ctx.run_dir); hv_mkdir(logdir); snprintf(g_main_ctx.confile, sizeof(g_main_ctx.confile), "%s/etc/%s.conf", g_main_ctx.run_dir, g_main_ctx.program_name); snprintf(g_main_ctx.pidfile, sizeof(g_main_ctx.pidfile), "%s/logs/%s.pid", g_main_ctx.run_dir, g_main_ctx.program_name); snprintf(g_main_ctx.logfile, sizeof(g_main_ctx.logfile), "%s/logs/%s.log", g_main_ctx.run_dir, g_main_ctx.program_name); hlog_set_file(g_main_ctx.logfile); g_main_ctx.pid = getpid(); g_main_ctx.oldpid = getpid_from_pidfile(); #ifdef OS_UNIX if (kill(g_main_ctx.oldpid, 0) == -1 && errno == ESRCH) { g_main_ctx.oldpid = -1; } #else HANDLE hproc = OpenProcess(PROCESS_TERMINATE, FALSE, g_main_ctx.oldpid); if (hproc == NULL) { g_main_ctx.oldpid = -1; } else { CloseHandle(hproc); } #endif // save arg int i = 0; g_main_ctx.os_argv = argv; g_main_ctx.argc = 0; g_main_ctx.arg_len = 0; for (i = 0; argv[i]; ++i) { g_main_ctx.arg_len += strlen(argv[i]) + 1; } g_main_ctx.argc = i; char* argp = NULL; SAFE_ALLOC(argp, g_main_ctx.arg_len); SAFE_ALLOC(g_main_ctx.save_argv, (g_main_ctx.argc + 1) * sizeof(char*)); char* cmdline = NULL; SAFE_ALLOC(cmdline, g_main_ctx.arg_len); g_main_ctx.cmdline = cmdline; for (i = 0; argv[i]; ++i) { strcpy(argp, argv[i]); g_main_ctx.save_argv[i] = argp; argp += strlen(argv[i]) + 1; strcpy(cmdline, argv[i]); cmdline += strlen(argv[i]); *cmdline = ' '; ++cmdline; } g_main_ctx.save_argv[g_main_ctx.argc] = NULL; g_main_ctx.cmdline[g_main_ctx.arg_len-1] = '\0'; #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_DARWIN) // save env g_main_ctx.os_envp = environ; g_main_ctx.envc = 0; g_main_ctx.env_len = 0; for (i = 0; environ[i]; ++i) { g_main_ctx.env_len += strlen(environ[i]) + 1; } g_main_ctx.envc = i; char* envp = NULL; SAFE_ALLOC(envp, g_main_ctx.env_len); SAFE_ALLOC(g_main_ctx.save_envp, (g_main_ctx.envc + 1) * sizeof(char*)); for (i = 0; environ[i]; ++i) { g_main_ctx.save_envp[i] = envp; strcpy(g_main_ctx.save_envp[i], environ[i]); envp += strlen(environ[i]) + 1; } g_main_ctx.save_envp[g_main_ctx.envc] = NULL; #endif // signals g_main_ctx.reload_fn = NULL; g_main_ctx.reload_userdata = NULL; // master workers g_main_ctx.worker_processes = 0; g_main_ctx.worker_threads = 0; g_main_ctx.worker_fn = 0; g_main_ctx.worker_userdata = 0; g_main_ctx.proc_ctxs = NULL; atexit(main_ctx_free); return 0; } void main_ctx_free(void) { if (g_main_ctx.save_argv) { SAFE_FREE(g_main_ctx.save_argv[0]); SAFE_FREE(g_main_ctx.save_argv); } SAFE_FREE(g_main_ctx.cmdline); if (g_main_ctx.save_envp) { SAFE_FREE(g_main_ctx.save_envp[0]); SAFE_FREE(g_main_ctx.save_envp); } if (g_main_ctx.arg_kv) { for (int i = 0; i < g_main_ctx.arg_kv_size; ++i) { SAFE_FREE(g_main_ctx.arg_kv[i]); } SAFE_FREE(g_main_ctx.arg_kv); } if (g_main_ctx.arg_list) { for (int i = 0; i < g_main_ctx.arg_list_size; ++i) { SAFE_FREE(g_main_ctx.arg_list[i]); } SAFE_FREE(g_main_ctx.arg_list); } } #define UNDEFINED_OPTION -1 static int get_arg_type(int short_opt, const char* options) { if (options == NULL) return UNDEFINED_OPTION; const char* p = options; while (*p && *p != short_opt) ++p; if (*p == '\0') return UNDEFINED_OPTION; if (*(p+1) == ':') return REQUIRED_ARGUMENT; return NO_ARGUMENT; } int parse_opt(int argc, char** argv, const char* options) { if (argc < 1) return 0; init_arg_kv(strlen(options) + 1); init_arg_list(argc); for (int i = 1; argv[i]; ++i) { char* p = argv[i]; if (*p != '-') { save_arg_list(argv[i]); continue; } while (*++p) { int arg_type = get_arg_type(*p, options); if (arg_type == UNDEFINED_OPTION) { printf_fn("Invalid option '%c'\n", *p); return -20; } else if (arg_type == NO_ARGUMENT) { save_arg_kv(p, 1, OPTION_ENABLE, 0); continue; } else if (arg_type == REQUIRED_ARGUMENT) { if (*(p+1) != '\0') { save_arg_kv(p, 1, p+1, 0); break; } else if (argv[i+1] != NULL) { save_arg_kv(p, 1, argv[++i], 0); break; } else { printf_fn("Option '%c' requires param\n", *p); return -30; } } } } return 0; } static const option_t* get_option(const char* opt, const option_t* long_options, int size) { if (opt == NULL || long_options == NULL) return NULL; int len = strlen(opt); if (len == 0) return NULL; if (len == 1) { for (int i = 0; i < size; ++i) { if (long_options[i].short_opt == *opt) { return &long_options[i]; } } } else { for (int i = 0; i < size; ++i) { if (strcmp(long_options[i].long_opt, opt) == 0) { return &long_options[i]; } } } return NULL; } #define MAX_OPTION 32 // opt type #define NOPREFIX_OPTION 0 #define SHORT_OPTION -1 #define LONG_OPTION -2 int parse_opt_long(int argc, char** argv, const option_t* long_options, int size) { if (argc < 1) return 0; init_arg_kv(size + 1); init_arg_list(argc); char opt[MAX_OPTION+1] = {0}; for (int i = 1; argv[i]; ++i) { char* arg = argv[i]; int opt_type = NOPREFIX_OPTION; // prefix if (*arg == OPTION_PREFIX) { ++arg; opt_type = SHORT_OPTION; if (*arg == OPTION_PREFIX) { ++arg; opt_type = LONG_OPTION; } } int arg_len = strlen(arg); // delim char* delim = strchr(arg, OPTION_DELIM); if (delim) { if (delim == arg || delim == arg+arg_len-1 || delim-arg > MAX_OPTION) { printf_fn("Invalid option '%s'\n", argv[i]); return -10; } memcpy(opt, arg, delim-arg); opt[delim-arg] = '\0'; } else { if (opt_type == SHORT_OPTION) { *opt = *arg; opt[1] = '\0'; } else { strncpy(opt, arg, MAX_OPTION); } } // get_option const option_t* pOption = get_option(opt, long_options, size); if (pOption == NULL) { if (delim == NULL && opt_type == NOPREFIX_OPTION) { save_arg_list(arg); continue; } else { printf_fn("Invalid option: '%s'\n", argv[i]); return -10; } } const char* value = NULL; if (pOption->arg_type == NO_ARGUMENT) { // -h value = OPTION_ENABLE; } else { if (delim) { // --port=80 value = delim+1; } else { if (opt_type == SHORT_OPTION && *(arg+1) != '\0') { // p80 value = arg+1; } else if (argv[i+1] != NULL) { // --port 80 value = argv[++i]; } else if (pOption->arg_type == REQUIRED_ARGUMENT) { printf_fn("Option '%s' requires parament\n", opt); return -20; } else { // arg_type == OPTIONAL_ARGUMENT value = OPTION_ENABLE; } } } // preferred to use short_opt as key if (pOption->short_opt > 0) { save_arg_kv(&pOption->short_opt, 1, value, 0); } else if (pOption->long_opt) { save_arg_kv(pOption->long_opt, 0, value, 0); } } return 0; } int dump_opt_long(const option_t* long_options, int opt_size, char* out_str, int out_size) { /* * Usage: program_name [short_options] * Options: * -%c|--%s description * -%c|--%s description * -%c|--%s [value] description */ int align = 0, max_align = 0; char short_options[256] = {0}; char* p = short_options; for (int i = 0; i < opt_size; ++i) { if (long_options[i].short_opt > 0) { *p++ = long_options[i].short_opt; } if (long_options[i].arg_type == NO_ARGUMENT) { // " -%c|--%s " align = 9 + strlen(long_options[i].long_opt); } else { // " -%c|--%s " align = 17 + strlen(long_options[i].long_opt); if (long_options[i].short_opt > 0) { *p++ = ':'; } } if (align > max_align) max_align = align; } int offset = 0; if (*g_main_ctx.program_name) { offset = snprintf(out_str, out_size, "Usage: %s [%s]\n", g_main_ctx.program_name, short_options); } offset += snprintf(out_str + offset, out_size - offset, "Options:\n"); char short_opt_chars[4] = {0}; for (int i = 0; i < opt_size; ++i) { if (long_options[i].short_opt > 0) { // -%c| short_opt_chars[0] = '-'; short_opt_chars[1] = long_options[i].short_opt; short_opt_chars[2] = '|'; } else { short_opt_chars[0] = ' '; short_opt_chars[1] = ' '; short_opt_chars[2] = ' '; } if (long_options[i].arg_type == NO_ARGUMENT) { // " -%c|--%s " align = 9 + strlen(long_options[i].long_opt); } else { // " -%c|--%s " align = 17 + strlen(long_options[i].long_opt); } offset += snprintf(out_str + offset, out_size - offset, " %s--%s%s %*s%s\n", short_opt_chars, long_options[i].long_opt, long_options[i].arg_type == REQUIRED_ARGUMENT ? " " : long_options[i].arg_type == OPTIONAL_ARGUMENT ? " [value]" : "", max_align - align, "", long_options[i].description ? long_options[i].description : ""); } return offset; } #if defined(OS_UNIX) && !HAVE_SETPROCTITLE /* * memory layout * argv[0]\0argv[1]\0argv[n]\0env[0]\0env[1]\0env[n]\0 */ void setproctitle(const char* fmt, ...) { char buf[256] = {0}; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); int len = g_main_ctx.arg_len + g_main_ctx.env_len; if (g_main_ctx.os_argv && len) { strncpy(g_main_ctx.os_argv[0], buf, len-1); } } #endif int create_pidfile() { FILE* fp = fopen(g_main_ctx.pidfile, "w"); if (fp == NULL) { hloge("fopen('%s') error: %d", g_main_ctx.pidfile, errno); return -1; } g_main_ctx.pid = hv_getpid(); fprintf(fp, "%d\n", (int)g_main_ctx.pid); fclose(fp); hlogi("create_pidfile('%s') pid=%d", g_main_ctx.pidfile, g_main_ctx.pid); atexit(delete_pidfile); return 0; } void delete_pidfile(void) { hlogi("delete_pidfile('%s') pid=%d", g_main_ctx.pidfile, g_main_ctx.pid); remove(g_main_ctx.pidfile); } pid_t getpid_from_pidfile() { FILE* fp = fopen(g_main_ctx.pidfile, "r"); if (fp == NULL) { // hloge("fopen('%s') error: %d", g_main_ctx.pidfile, errno); return -1; } int pid = -1; fscanf(fp, "%d", &pid); fclose(fp); return pid; } #ifdef OS_UNIX // unix use signal #include void signal_handler(int signo) { hlogi("pid=%d recv signo=%d", getpid(), signo); switch (signo) { case SIGINT: case SIGNAL_TERMINATE: hlogi("killall processes"); signal(SIGCHLD, SIG_IGN); // master send SIGKILL => workers for (int i = 0; i < g_main_ctx.worker_processes; ++i) { if (g_main_ctx.proc_ctxs[i].pid <= 0) break; kill(g_main_ctx.proc_ctxs[i].pid, SIGKILL); g_main_ctx.proc_ctxs[i].pid = -1; } exit(0); break; case SIGCHLD: { pid_t pid = 0; int status = 0; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { hlogw("proc stop/waiting, pid=%d status=%d", pid, status); for (int i = 0; i < g_main_ctx.worker_processes; ++i) { proc_ctx_t* ctx = g_main_ctx.proc_ctxs + i; if (ctx->pid == pid) { ctx->pid = -1; // NOTE: avoid frequent crash and restart time_t run_time = time(NULL) - ctx->start_time; if (ctx->spawn_cnt < 3 || run_time > 3600) { hproc_spawn(ctx); } else { hloge("proc crash, pid=%d spawn_cnt=%d run_time=%us", pid, ctx->spawn_cnt, (unsigned int)run_time); bool have_worker = false; for (int i = 0; i < g_main_ctx.worker_processes; ++i) { if (g_main_ctx.proc_ctxs[i].pid > 0) { have_worker = true; break; } } if (!have_worker) { hlogw("No alive worker process, exit master process!"); exit(0); } } break; } } } } break; case SIGNAL_RELOAD: if (g_main_ctx.reload_fn) { g_main_ctx.reload_fn(g_main_ctx.reload_userdata); if (getpid_from_pidfile() == getpid()) { // master send SIGNAL_RELOAD => workers for (int i = 0; i < g_main_ctx.worker_processes; ++i) { if (g_main_ctx.proc_ctxs[i].pid <= 0) break; kill(g_main_ctx.proc_ctxs[i].pid, SIGNAL_RELOAD); } } } break; default: break; } } int signal_init(procedure_t reload_fn, void* reload_userdata) { g_main_ctx.reload_fn = reload_fn; g_main_ctx.reload_userdata = reload_userdata; signal(SIGINT, signal_handler); signal(SIGCHLD, signal_handler); signal(SIGNAL_TERMINATE, signal_handler); signal(SIGNAL_RELOAD, signal_handler); return 0; } #elif defined(OS_WIN) #include // for timeSetEvent // win32 use Event static HANDLE s_hEventTerm = NULL; static HANDLE s_hEventTermWait = NULL; static HANDLE s_hEventReload = NULL; static void WINAPI on_timer(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { DWORD ret; ret = WaitForSingleObject(s_hEventTerm, 0); if (ret == WAIT_OBJECT_0) { hlogi("pid=%d recv event [TERM]", getpid()); if (getpid_from_pidfile() == getpid()) { SetEvent(s_hEventTermWait); timeKillEvent(uTimerID); exit(0); } } ret = WaitForSingleObject(s_hEventReload, 0); if (ret == WAIT_OBJECT_0) { hlogi("pid=%d recv event [RELOAD]", getpid()); if (g_main_ctx.reload_fn) { g_main_ctx.reload_fn(g_main_ctx.reload_userdata); } } } static void signal_cleanup(void) { CloseHandle(s_hEventTerm); s_hEventTerm = NULL; CloseHandle(s_hEventTermWait); s_hEventTermWait = NULL; CloseHandle(s_hEventReload); s_hEventReload = NULL; } int signal_init(procedure_t reload_fn, void* reload_userdata) { g_main_ctx.reload_fn = reload_fn; g_main_ctx.reload_userdata = reload_userdata; char eventname[MAX_PATH] = {0}; snprintf(eventname, sizeof(eventname), "%s_term_event", g_main_ctx.program_name); s_hEventTerm = CreateEvent(NULL, FALSE, FALSE, eventname); if(s_hEventTerm == NULL) return -1; snprintf(eventname, sizeof(eventname), "%s_term_wait_event", g_main_ctx.program_name); s_hEventTermWait = CreateEvent(NULL, FALSE, FALSE, eventname); if(s_hEventTermWait == NULL) return -2; snprintf(eventname, sizeof(eventname), "%s_reload_event", g_main_ctx.program_name); s_hEventReload = CreateEvent(NULL, FALSE, FALSE, eventname); if(s_hEventReload == NULL) return -3; timeSetEvent(1000, 1000, on_timer, 0, TIME_PERIODIC); atexit(signal_cleanup); return 0; } #endif static void kill_proc(int pid) { #ifdef OS_UNIX kill(pid, SIGNAL_TERMINATE); #else SetEvent(s_hEventTerm); if (WaitForSingleObject(s_hEventTermWait, 2000) == WAIT_OBJECT_0) return; HANDLE hproc = OpenProcess(PROCESS_TERMINATE, FALSE, pid); if (hproc) { TerminateProcess(hproc, 0); CloseHandle(hproc); } #endif } void signal_handle(const char* signal) { if (signal_handle_noexit(signal)) exit(0); } bool signal_handle_noexit(const char* signal) { if (strcmp(signal, "start") == 0) { if (g_main_ctx.oldpid > 0) { printf_fn("%s is already running, pid=%d\n", g_main_ctx.program_name, g_main_ctx.oldpid); return true; } } else if (strcmp(signal, "stop") == 0) { if (g_main_ctx.oldpid > 0) { kill_proc(g_main_ctx.oldpid); printf_fn("%s stop/waiting\n", g_main_ctx.program_name); } else { printf_fn("%s is already stopped\n", g_main_ctx.program_name); } return true; } else if (strcmp(signal, "restart") == 0) { if (g_main_ctx.oldpid > 0) { kill_proc(g_main_ctx.oldpid); printf_fn("%s stop/waiting\n", g_main_ctx.program_name); hv_sleep(1); } } else if (strcmp(signal, "status") == 0) { if (g_main_ctx.oldpid > 0) { printf_fn("%s start/running, pid=%d\n", g_main_ctx.program_name, g_main_ctx.oldpid); } else { printf_fn("%s is already stopped\n", g_main_ctx.program_name); } return true; } else if (strcmp(signal, "reload") == 0) { if (g_main_ctx.oldpid > 0) { printf_fn("reload confile [%s]\n", g_main_ctx.confile); #ifdef OS_UNIX kill(g_main_ctx.oldpid, SIGNAL_RELOAD); #else SetEvent(s_hEventReload); #endif hv_sleep(1); } else { printf_fn("%s is already stopped\n", g_main_ctx.program_name); } return true; } else { printf_fn("Invalid signal: '%s'\n", signal); return true; } printf_fn("%s start/running\n", g_main_ctx.program_name); return false; } // master-workers processes static HTHREAD_ROUTINE(worker_thread) { hlogi("worker_thread pid=%ld tid=%ld", hv_getpid(), hv_gettid()); if (g_main_ctx.worker_fn) { g_main_ctx.worker_fn(g_main_ctx.worker_userdata); } return 0; } static void worker_init(void* userdata) { #ifdef OS_UNIX setproctitle("%s: worker process", g_main_ctx.program_name); signal(SIGNAL_RELOAD, signal_handler); #endif } static void worker_proc(void* userdata) { for (int i = 1; i < g_main_ctx.worker_threads; ++i) { hthread_create(worker_thread, NULL); } worker_thread(NULL); } int master_workers_run(procedure_t worker_fn, void* worker_userdata, int worker_processes, int worker_threads, bool wait) { #ifdef OS_WIN // NOTE: Windows not provide MultiProcesses if (worker_threads == 0) { // MultiProcesses => MultiThreads worker_threads = worker_processes; } worker_processes = 0; #endif if (worker_threads == 0) worker_threads = 1; g_main_ctx.worker_threads = worker_threads; g_main_ctx.worker_fn = worker_fn; g_main_ctx.worker_userdata = worker_userdata; if (worker_processes == 0) { // single process if (wait) { for (int i = 1; i < worker_threads; ++i) { hthread_create(worker_thread, NULL); } worker_thread(NULL); } else { for (int i = 0; i < worker_threads; ++i) { hthread_create(worker_thread, NULL); } } } else { if (g_main_ctx.worker_processes != 0) { return ERR_OVER_LIMIT; } // master-workers processes #ifdef OS_UNIX setproctitle("%s: master process", g_main_ctx.program_name); signal(SIGNAL_RELOAD, signal_handler); #endif g_main_ctx.worker_processes = worker_processes; int bytes = g_main_ctx.worker_processes * sizeof(proc_ctx_t); SAFE_ALLOC(g_main_ctx.proc_ctxs, bytes); proc_ctx_t* ctx = g_main_ctx.proc_ctxs; for (int i = 0; i < g_main_ctx.worker_processes; ++i, ++ctx) { ctx->init = worker_init; ctx->proc = worker_proc; hproc_spawn(ctx); hlogi("workers[%d] start/running, pid=%d", i, ctx->pid); } g_main_ctx.pid = getpid(); hlogi("master start/running, pid=%d", g_main_ctx.pid); if (wait) { while (1) hv_sleep (1); } } return 0; } ================================================ FILE: base/hmain.h ================================================ #ifndef HV_MAIN_H_ #define HV_MAIN_H_ #include "hexport.h" #include "hplatform.h" #include "hdef.h" #include "hproc.h" #ifdef _MSC_VER #pragma comment(lib, "winmm.lib") // for timeSetEvent #endif BEGIN_EXTERN_C typedef int (*printf_t)(const char *const fmt, ...); typedef struct main_ctx_s { char run_dir[MAX_PATH]; char program_name[MAX_PATH]; char confile[MAX_PATH]; // default etc/${program}.conf char pidfile[MAX_PATH]; // default logs/${program}.pid char logfile[MAX_PATH]; // default logs/${program}.log pid_t pid; // getpid pid_t oldpid; // getpid_from_pidfile // arg int argc; int arg_len; char** os_argv; char** save_argv; char* cmdline; // parsed arg int arg_kv_size; char** arg_kv; int arg_list_size; char** arg_list; // env int envc; int env_len; char** os_envp; char** save_envp; // signals procedure_t reload_fn; void* reload_userdata; // master workers model int worker_processes; int worker_threads; procedure_t worker_fn; void* worker_userdata; proc_ctx_t* proc_ctxs; } main_ctx_t; // arg_type #define NO_ARGUMENT 0 #define REQUIRED_ARGUMENT 1 #define OPTIONAL_ARGUMENT 2 // option define #define OPTION_PREFIX '-' #define OPTION_DELIM '=' #define OPTION_ENABLE "1" #define OPTION_DISABLE "0" typedef struct option_s { char short_opt; const char* long_opt; int arg_type; const char* description; } option_t; HV_EXPORT int main_ctx_init(int argc, char** argv); HV_EXPORT void main_ctx_free(void); // ls -a -l // ls -al // watch -n 10 ls // watch -n10 ls HV_EXPORT int parse_opt(int argc, char** argv, const char* opt); // gcc -g -Wall -O3 -std=cpp main.c HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int opt_size); HV_EXPORT int dump_opt_long(const option_t* long_options, int opt_size, char* out_str, int out_size); HV_EXPORT const char* get_arg(const char* key); HV_EXPORT const char* get_env(const char* key); #if defined(OS_UNIX) && !HAVE_SETPROCTITLE HV_EXPORT void setproctitle(const char* fmt, ...); #endif // pidfile HV_EXPORT int create_pidfile(); HV_EXPORT void delete_pidfile(void); HV_EXPORT pid_t getpid_from_pidfile(); // signal=[start,stop,restart,status,reload] HV_EXPORT int signal_init(procedure_t reload_fn DEFAULT(NULL), void* reload_userdata DEFAULT(NULL)); HV_EXPORT void signal_handle(const char* signal); HV_EXPORT bool signal_handle_noexit(const char* signal); #ifdef OS_UNIX // we use SIGTERM to quit process, SIGUSR1 to reload confile #define SIGNAL_TERMINATE SIGTERM #define SIGNAL_RELOAD SIGUSR1 void signal_handler(int signo); #endif // global var #define DEFAULT_WORKER_PROCESSES 4 #define MAXNUM_WORKER_PROCESSES 256 HV_EXPORT extern main_ctx_t g_main_ctx; HV_EXPORT extern printf_t printf_fn; // master-workers processes HV_EXPORT int master_workers_run( procedure_t worker_fn, void* worker_userdata DEFAULT(NULL), int worker_processes DEFAULT(DEFAULT_WORKER_PROCESSES), int worker_threads DEFAULT(0), bool wait DEFAULT(true)); END_EXTERN_C #endif // HV_MAIN_H_ ================================================ FILE: base/hmath.h ================================================ #ifndef HV_MATH_H_ #define HV_MATH_H_ #include static inline unsigned long floor2e(unsigned long num) { unsigned long n = num; int e = 0; while (n>>=1) ++e; unsigned long ret = 1; while (e--) ret<<=1; return ret; } static inline unsigned long ceil2e(unsigned long num) { // 2**0 = 1 if (num == 0 || num == 1) return 1; unsigned long n = num - 1; int e = 1; while (n>>=1) ++e; unsigned long ret = 1; while (e--) ret<<=1; return ret; } // varint little-endian // MSB static inline int varint_encode(long long value, unsigned char* buf) { unsigned char ch; unsigned char *p = buf; int bytes = 0; do { ch = value & 0x7F; value >>= 7; *p++ = value == 0 ? ch : (ch | 0x80); ++bytes; } while (value); return bytes; } // @param[IN|OUT] len: in=>buflen, out=>varint bytesize static inline long long varint_decode(const unsigned char* buf, int* len) { long long ret = 0; int bytes = 0, bits = 0; const unsigned char *p = buf; do { if (len && *len && bytes == *len) { // Not enough length *len = 0; return 0; } ret |= ((long long)(*p & 0x7F)) << bits; ++bytes; if ((*p & 0x80) == 0) { // Found end if (len) *len = bytes; return ret; } ++p; bits += 7; } while(bytes < 10); // Not found end if (len) *len = -1; return ret; } static inline int asn1_encode(long long value, unsigned char* buf) { /* * unrolled for efficiency * check each possibitlity of the 4 byte integer */ unsigned char* p = buf; if (value < 128) { *p = (unsigned char)value; return 1; } else if (value < 256) { *p = 0x81; p++; *p = (unsigned char)value; return 2; } else if (value < 65536) { *p = 0x82; p++; *p = (unsigned char)(value>>8); p++; *p = (unsigned char)value; return 3; } else if (value < 16777126) { *p = 0x83; p++; *p = (unsigned char)(value>>16); p++; *p = (unsigned char)(value >> 8); p++; *p = (unsigned char)value; return 4; } else { *p = 0x84; p++; *p = (unsigned char)(value >> 24); p++; *p = (unsigned char)(value >> 16); p++; *p = (unsigned char)(value >> 8); p++; *p = (unsigned char)value; return 5; } } static inline long long asn1_decode(const unsigned char* buf, int* len) { long long ret = 0; int bytes = 0; unsigned int tag = 0, lenBytes = 0; const unsigned char* p = buf; tag = *p; p++; if (tag < 128) { // Single-byte data if (len) *len = 1; return tag; } else if (tag == 0x80) { // invalid data if (len) *len = -1; return 0; } // Multi-byte data bytes++; lenBytes = tag & 0x7F; for (ret = 0; lenBytes > 0; lenBytes--) { if (len && *len && bytes == *len) { // Not enough length *len = 0; return 0; } ret = (ret << 8) | *p; p++; bytes++; } if (len) *len = bytes; return ret; } #endif // HV_MATH_H_ ================================================ FILE: base/hmutex.h ================================================ #ifndef HV_MUTEX_H_ #define HV_MUTEX_H_ #include "hexport.h" #include "hplatform.h" #include "htime.h" BEGIN_EXTERN_C #ifdef OS_WIN #define hmutex_t CRITICAL_SECTION #define hmutex_init InitializeCriticalSection #define hmutex_destroy DeleteCriticalSection #define hmutex_lock EnterCriticalSection #define hmutex_trylock TryEnterCriticalSection #define hmutex_unlock LeaveCriticalSection #define hrecursive_mutex_t CRITICAL_SECTION #define hrecursive_mutex_init InitializeCriticalSection #define hrecursive_mutex_destroy DeleteCriticalSection #define hrecursive_mutex_lock EnterCriticalSection #define hrecursive_mutex_unlock LeaveCriticalSection #define HSPINLOCK_COUNT -1 #define hspinlock_t CRITICAL_SECTION #define hspinlock_init(pspin) InitializeCriticalSectionAndSpinCount(pspin, HSPINLOCK_COUNT) #define hspinlock_destroy DeleteCriticalSection #define hspinlock_lock EnterCriticalSection #define hspinlock_unlock LeaveCriticalSection #define hrwlock_t SRWLOCK #define hrwlock_init InitializeSRWLock #define hrwlock_destroy(plock) #define hrwlock_rdlock AcquireSRWLockShared #define hrwlock_rdunlock ReleaseSRWLockShared #define hrwlock_wrlock AcquireSRWLockExclusive #define hrwlock_wrunlock ReleaseSRWLockExclusive #define htimed_mutex_t HANDLE #define htimed_mutex_init(pmutex) *(pmutex) = CreateMutex(NULL, FALSE, NULL) #define htimed_mutex_destroy(pmutex) CloseHandle(*(pmutex)) #define htimed_mutex_lock(pmutex) WaitForSingleObject(*(pmutex), INFINITE) #define htimed_mutex_unlock(pmutex) ReleaseMutex(*(pmutex)) // true: WAIT_OBJECT_0 // false: WAIT_OBJECT_TIMEOUT #define htimed_mutex_lock_for(pmutex, ms) ( WaitForSingleObject(*(pmutex), ms) == WAIT_OBJECT_0 ) #define hcondvar_t CONDITION_VARIABLE #define hcondvar_init InitializeConditionVariable #define hcondvar_destroy(pcond) #define hcondvar_wait(pcond, pmutex) SleepConditionVariableCS(pcond, pmutex, INFINITE) #define hcondvar_wait_for(pcond, pmutex, ms) SleepConditionVariableCS(pcond, pmutex, ms) #define hcondvar_signal WakeConditionVariable #define hcondvar_broadcast WakeAllConditionVariable #define honce_t INIT_ONCE #define HONCE_INIT INIT_ONCE_STATIC_INIT typedef void (*honce_fn)(); static inline BOOL WINAPI s_once_func(INIT_ONCE* once, PVOID arg, PVOID* _) { honce_fn fn = (honce_fn)arg; fn(); return TRUE; } static inline void honce(honce_t* once, honce_fn fn) { PVOID dummy = NULL; InitOnceExecuteOnce(once, s_once_func, (PVOID)fn, &dummy); } #define hsem_t HANDLE #define hsem_init(psem, value) *(psem) = CreateSemaphore(NULL, value, value+100000, NULL) #define hsem_destroy(psem) CloseHandle(*(psem)) #define hsem_wait(psem) WaitForSingleObject(*(psem), INFINITE) #define hsem_post(psem) ReleaseSemaphore(*(psem), 1, NULL) // true: WAIT_OBJECT_0 // false: WAIT_OBJECT_TIMEOUT #define hsem_wait_for(psem, ms) ( WaitForSingleObject(*(psem), ms) == WAIT_OBJECT_0 ) #else #define hmutex_t pthread_mutex_t #define hmutex_init(pmutex) pthread_mutex_init(pmutex, NULL) #define hmutex_destroy pthread_mutex_destroy #define hmutex_lock pthread_mutex_lock #define hmutex_trylock(pmutex) (pthread_mutex_trylock(pmutex) == 0) #define hmutex_unlock pthread_mutex_unlock #define hrecursive_mutex_t pthread_mutex_t #define hrecursive_mutex_init(pmutex) \ do {\ pthread_mutexattr_t attr;\ pthread_mutexattr_init(&attr);\ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);\ pthread_mutex_init(pmutex, &attr);\ } while(0) #define hrecursive_mutex_destroy pthread_mutex_destroy #define hrecursive_mutex_lock pthread_mutex_lock #define hrecursive_mutex_unlock pthread_mutex_unlock #if HAVE_PTHREAD_SPIN_LOCK #define hspinlock_t pthread_spinlock_t #define hspinlock_init(pspin) pthread_spin_init(pspin, PTHREAD_PROCESS_PRIVATE) #define hspinlock_destroy pthread_spin_destroy #define hspinlock_lock pthread_spin_lock #define hspinlock_unlock pthread_spin_unlock #else #define hspinlock_t pthread_mutex_t #define hspinlock_init(pmutex) pthread_mutex_init(pmutex, NULL) #define hspinlock_destroy pthread_mutex_destroy #define hspinlock_lock pthread_mutex_lock #define hspinlock_unlock pthread_mutex_unlock #endif #define hrwlock_t pthread_rwlock_t #define hrwlock_init(prwlock) pthread_rwlock_init(prwlock, NULL) #define hrwlock_destroy pthread_rwlock_destroy #define hrwlock_rdlock pthread_rwlock_rdlock #define hrwlock_rdunlock pthread_rwlock_unlock #define hrwlock_wrlock pthread_rwlock_wrlock #define hrwlock_wrunlock pthread_rwlock_unlock #define htimed_mutex_t pthread_mutex_t #define htimed_mutex_init(pmutex) pthread_mutex_init(pmutex, NULL) #define htimed_mutex_destroy pthread_mutex_destroy #define htimed_mutex_lock pthread_mutex_lock #define htimed_mutex_unlock pthread_mutex_unlock static inline void timespec_after(struct timespec* ts, unsigned int ms) { struct timeval tv; gettimeofday(&tv, NULL); ts->tv_sec = tv.tv_sec + ms / 1000; ts->tv_nsec = tv.tv_usec * 1000 + ms % 1000 * 1000000; if (ts->tv_nsec >= 1000000000) { ts->tv_nsec -= 1000000000; ts->tv_sec += 1; } } // true: OK // false: ETIMEDOUT static inline int htimed_mutex_lock_for(htimed_mutex_t* mutex, unsigned int ms) { #if HAVE_PTHREAD_MUTEX_TIMEDLOCK struct timespec ts; timespec_after(&ts, ms); return pthread_mutex_timedlock(mutex, &ts) != ETIMEDOUT; #else int ret = 0; unsigned int end = gettick_ms() + ms; while ((ret = pthread_mutex_trylock(mutex)) != 0) { if (gettick_ms() >= end) { break; } hv_msleep(1); } return ret == 0; #endif } #define hcondvar_t pthread_cond_t #define hcondvar_init(pcond) pthread_cond_init(pcond, NULL) #define hcondvar_destroy pthread_cond_destroy #define hcondvar_wait pthread_cond_wait #define hcondvar_signal pthread_cond_signal #define hcondvar_broadcast pthread_cond_broadcast // true: OK // false: ETIMEDOUT static inline int hcondvar_wait_for(hcondvar_t* cond, hmutex_t* mutex, unsigned int ms) { struct timespec ts; timespec_after(&ts, ms); return pthread_cond_timedwait(cond, mutex, &ts) != ETIMEDOUT; } #define honce_t pthread_once_t #define HONCE_INIT PTHREAD_ONCE_INIT #define honce pthread_once #include #define hsem_t sem_t #define hsem_init(psem, value) sem_init(psem, 0, value) #define hsem_destroy sem_destroy #define hsem_wait sem_wait #define hsem_post sem_post // true: OK // false: ETIMEDOUT static inline int hsem_wait_for(hsem_t* sem, unsigned int ms) { #if HAVE_SEM_TIMEDWAIT struct timespec ts; timespec_after(&ts, ms); return sem_timedwait(sem, &ts) != ETIMEDOUT; #else int ret = 0; unsigned int end = gettick_ms() + ms; while ((ret = sem_trywait(sem)) != 0) { if (gettick_ms() >= end) { break; } hv_msleep(1); } return ret == 0; #endif } #endif END_EXTERN_C #ifdef __cplusplus #include #include // using std::mutex; // NOTE: test std::timed_mutex incorrect in some platforms, use htimed_mutex_t // using std::timed_mutex; using std::condition_variable; using std::lock_guard; using std::unique_lock; BEGIN_NAMESPACE_HV class MutexLock { public: MutexLock() { hmutex_init(&_mutex); } ~MutexLock() { hmutex_destroy(&_mutex); } void lock() { hmutex_lock(&_mutex); } void unlock() { hmutex_unlock(&_mutex); } protected: hmutex_t _mutex; }; class SpinLock { public: SpinLock() { hspinlock_init(&_spin); } ~SpinLock() { hspinlock_destroy(&_spin); } void lock() { hspinlock_lock(&_spin); } void unlock() { hspinlock_unlock(&_spin); } protected: hspinlock_t _spin; }; class RWLock { public: RWLock() { hrwlock_init(&_rwlock); } ~RWLock() { hrwlock_destroy(&_rwlock); } void rdlock() { hrwlock_rdlock(&_rwlock); } void rdunlock() { hrwlock_rdunlock(&_rwlock); } void wrlock() { hrwlock_wrlock(&_rwlock); } void wrunlock() { hrwlock_wrunlock(&_rwlock); } void lock() { rdlock(); } void unlock() { rdunlock(); } protected: hrwlock_t _rwlock; }; template class LockGuard { public: LockGuard(T& t) : _lock(t) { _lock.lock(); } ~LockGuard() { _lock.unlock(); } protected: T& _lock; }; END_NAMESPACE_HV // same as java synchronized(lock) { ... } #define synchronized(lock) for (std::lock_guard _lock_(lock), *p = &_lock_; p != NULL; p = NULL) #endif // __cplusplus #endif // HV_MUTEX_H_ ================================================ FILE: base/hplatform.h ================================================ #ifndef HV_PLATFORM_H_ #define HV_PLATFORM_H_ #include "hconfig.h" // OS #if defined(WIN64) || defined(_WIN64) #define OS_WIN64 #define OS_WIN32 #elif defined(WIN32)|| defined(_WIN32) #define OS_WIN32 #elif defined(ANDROID) || defined(__ANDROID__) #define OS_ANDROID #define OS_LINUX #elif defined(linux) || defined(__linux) || defined(__linux__) #define OS_LINUX #elif defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__)) #include #if defined(TARGET_OS_MAC) && TARGET_OS_MAC #include #define OS_MAC #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE #define OS_IOS #endif #define OS_DARWIN #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #define OS_FREEBSD #define OS_BSD #elif defined(__NetBSD__) #define OS_NETBSD #define OS_BSD #elif defined(__OpenBSD__) #define OS_OPENBSD #define OS_BSD #elif defined(sun) || defined(__sun) || defined(__sun__) #define OS_SOLARIS #else #warning "Untested operating system platform!" #endif #if defined(OS_WIN32) || defined(OS_WIN64) #undef OS_UNIX #define OS_WIN #else #undef OS_WIN #define OS_UNIX #endif // ARCH #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) #define ARCH_X64 #define ARCH_X86_64 #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) #define ARCH_X86 #define ARCH_X86_32 #elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) #define ARCH_ARM64 #elif defined(__arm__) || defined(_M_ARM) #define ARCH_ARM #elif defined(__mips64__) #define ARCH_MIPS64 #elif defined(__mips__) #define ARCH_MIPS #elif defined(__riscv) #define ARCH_RISCV #elif defined(__ppc64__) || defined(__powerpc64__) #define ARCH_PPC64 #elif defined(__ppc__) || defined(__powerpc__) #define ARCH_PPC #else #warning "Untested hardware architecture!" #endif // COMPILER #if defined (_MSC_VER) #define COMPILER_MSVC #if (_MSC_VER < 1200) // Visual C++ 6.0 #define MSVS_VERSION 1998 #define MSVC_VERSION 60 #elif (_MSC_VER >= 1200) && (_MSC_VER < 1300) // Visual Studio 2002, MSVC++ 7.0 #define MSVS_VERSION 2002 #define MSVC_VERSION 70 #elif (_MSC_VER >= 1300) && (_MSC_VER < 1400) // Visual Studio 2003, MSVC++ 7.1 #define MSVS_VERSION 2003 #define MSVC_VERSION 71 #elif (_MSC_VER >= 1400) && (_MSC_VER < 1500) // Visual Studio 2005, MSVC++ 8.0 #define MSVS_VERSION 2005 #define MSVC_VERSION 80 #elif (_MSC_VER >= 1500) && (_MSC_VER < 1600) // Visual Studio 2008, MSVC++ 9.0 #define MSVS_VERSION 2008 #define MSVC_VERSION 90 #elif (_MSC_VER >= 1600) && (_MSC_VER < 1700) // Visual Studio 2010, MSVC++ 10.0 #define MSVS_VERSION 2010 #define MSVC_VERSION 100 #elif (_MSC_VER >= 1700) && (_MSC_VER < 1800) // Visual Studio 2012, MSVC++ 11.0 #define MSVS_VERSION 2012 #define MSVC_VERSION 110 #elif (_MSC_VER >= 1800) && (_MSC_VER < 1900) // Visual Studio 2013, MSVC++ 12.0 #define MSVS_VERSION 2013 #define MSVC_VERSION 120 #elif (_MSC_VER >= 1900) && (_MSC_VER < 1910) // Visual Studio 2015, MSVC++ 14.0 #define MSVS_VERSION 2015 #define MSVC_VERSION 140 #elif (_MSC_VER >= 1910) && (_MSC_VER < 1920) // Visual Studio 2017, MSVC++ 15.0 #define MSVS_VERSION 2017 #define MSVC_VERSION 150 #elif (_MSC_VER >= 1920) && (_MSC_VER < 2000) // Visual Studio 2019, MSVC++ 16.0 #define MSVS_VERSION 2019 #define MSVC_VERSION 160 #endif #undef HAVE_STDATOMIC_H #define HAVE_STDATOMIC_H 0 #undef HAVE_SYS_TIME_H #define HAVE_SYS_TIME_H 0 #undef HAVE_PTHREAD_H #define HAVE_PTHREAD_H 0 #pragma warning (disable: 4018) // signed/unsigned comparison #pragma warning (disable: 4100) // unused param #pragma warning (disable: 4102) // unreferenced label #pragma warning (disable: 4244) // conversion loss of data #pragma warning (disable: 4267) // size_t => int #pragma warning (disable: 4819) // Unicode #pragma warning (disable: 4996) // _CRT_SECURE_NO_WARNINGS #elif defined(__GNUC__) #define COMPILER_GCC #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #elif defined(__clang__) #define COMPILER_CLANG #elif defined(__MINGW32__) || defined(__MINGW64__) #define COMPILER_MINGW #elif defined(__MSYS__) #define COMPILER_MSYS #elif defined(__CYGWIN__) #define COMPILER_CYGWIN #else #warning "Untested compiler!" #endif #ifndef __GNUC_PREREQ #define __GNUC_PREREQ(a, b) 0 #endif // headers #ifdef OS_WIN #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0600 #elif _WIN32_WINNT < 0x0600 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0600 #endif #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef _CRT_NONSTDC_NO_DEPRECATE #define _CRT_NONSTDC_NO_DEPRECATE #endif #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #endif #include #include // for inet_pton,inet_ntop #include #include // for getpid,exec #include // for mkdir,rmdir,chdir,getcwd #include // for open,close,read,write,lseek,tell #define hv_sleep(s) Sleep((s) * 1000) #define hv_msleep(ms) Sleep(ms) #define hv_usleep(us) Sleep((us) / 1000) #define hv_delay(ms) hv_msleep(ms) #define hv_mkdir(dir) mkdir(dir) // access #ifndef F_OK #define F_OK 0 /* test for existence of file */ #endif #ifndef X_OK #define X_OK (1<<0) /* test for execute or search permission */ #endif #ifndef W_OK #define W_OK (1<<1) /* test for write permission */ #endif #ifndef R_OK #define R_OK (1<<2) /* test for read permission */ #endif // stat #ifndef S_ISREG #define S_ISREG(st_mode) (((st_mode) & S_IFMT) == S_IFREG) #endif #ifndef S_ISDIR #define S_ISDIR(st_mode) (((st_mode) & S_IFMT) == S_IFDIR) #endif #else #include #include // for mkdir,rmdir,chdir,getcwd // socket #include #include #include #include #include #include #include // for gethostbyname #define hv_sleep(s) sleep(s) #define hv_msleep(ms) usleep((ms) * 1000) #define hv_usleep(us) usleep(us) #define hv_delay(ms) hv_msleep(ms) #define hv_mkdir(dir) mkdir(dir, 0777) #endif #ifdef _MSC_VER typedef int pid_t; typedef int gid_t; typedef int uid_t; #define strcasecmp stricmp #define strncasecmp strnicmp #else typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef void* HANDLE; #include #define stricmp strcasecmp #define strnicmp strncasecmp #endif // ENDIAN #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #ifndef NET_ENDIAN #define NET_ENDIAN BIG_ENDIAN #endif // BYTE_ORDER #ifndef BYTE_ORDER #if defined(__BYTE_ORDER) #define BYTE_ORDER __BYTE_ORDER #elif defined(__BYTE_ORDER__) #define BYTE_ORDER __BYTE_ORDER__ #elif defined(ARCH_X86) || defined(ARCH_X86_64) || \ defined(__ARMEL__) || defined(__AARCH64EL__) || \ defined(__MIPSEL) || defined(__MIPS64EL) #define BYTE_ORDER LITTLE_ENDIAN #elif defined(__ARMEB__) || defined(__AARCH64EB__) || \ defined(__MIPSEB) || defined(__MIPS64EB) || \ defined(__ppc__) || defined(__ppc64__) #define BYTE_ORDER BIG_ENDIAN #elif defined(OS_WIN) #define BYTE_ORDER LITTLE_ENDIAN #else #warning "Unknown byte order!" #endif #endif // ANSI C #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __cplusplus #if HAVE_STDBOOL_H #include #else #ifndef bool #define bool char #endif #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif #endif #endif #if HAVE_STDINT_H #include #elif defined(_MSC_VER) && _MSC_VER < 1700 typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #endif typedef float float32_t; typedef double float64_t; typedef int (*method_t)(void* userdata); typedef void (*procedure_t)(void* userdata); #if HAVE_SYS_TYPES_H #include #endif #if HAVE_SYS_STAT_H #include #endif #if HAVE_SYS_TIME_H #include // for gettimeofday #endif #if HAVE_FCNTL_H #include #endif #if HAVE_PTHREAD_H #include #endif #endif // HV_PLATFORM_H_ ================================================ FILE: base/hproc.h ================================================ #ifndef HV_PROC_H_ #define HV_PROC_H_ #include "hplatform.h" typedef struct proc_ctx_s { pid_t pid; // tid in Windows time_t start_time; int spawn_cnt; procedure_t init; void* init_userdata; procedure_t proc; void* proc_userdata; procedure_t exit; void* exit_userdata; } proc_ctx_t; static inline void hproc_run(proc_ctx_t* ctx) { if (ctx->init) { ctx->init(ctx->init_userdata); } if (ctx->proc) { ctx->proc(ctx->proc_userdata); } if (ctx->exit) { ctx->exit(ctx->exit_userdata); } } #ifdef OS_UNIX // unix use multi-processes static inline int hproc_spawn(proc_ctx_t* ctx) { ++ctx->spawn_cnt; ctx->start_time = time(NULL); pid_t pid = fork(); if (pid < 0) { perror("fork"); return -1; } else if (pid == 0) { // child process ctx->pid = getpid(); hproc_run(ctx); exit(0); } else if (pid > 0) { // parent process ctx->pid = pid; } return pid; } #elif defined(OS_WIN) // win32 use multi-threads static void win_thread(void* userdata) { proc_ctx_t* ctx = (proc_ctx_t*)userdata; ctx->pid = GetCurrentThreadId(); // tid in Windows hproc_run(ctx); } static inline int hproc_spawn(proc_ctx_t* ctx) { ++ctx->spawn_cnt; ctx->start_time = time(NULL); HANDLE h = (HANDLE)_beginthread(win_thread, 0, ctx); if (h == NULL) { return -1; } ctx->pid = GetThreadId(h); // tid in Windows return ctx->pid; } #endif #endif // HV_PROC_H_ ================================================ FILE: base/hsocket.c ================================================ #include "hsocket.h" #include "hdef.h" #include "htime.h" #ifdef OS_UNIX #include #endif #ifdef OS_WIN #include "hatomic.h" static hatomic_flag_t s_wsa_initialized = HATOMIC_FLAG_INIT; void WSAInit() { if (!hatomic_flag_test_and_set(&s_wsa_initialized)) { WSADATA wsadata; WSAStartup(MAKEWORD(2, 2), &wsadata); } } void WSADeinit() { if (hatomic_flag_test_and_set(&s_wsa_initialized)) { hatomic_flag_clear(&s_wsa_initialized); WSACleanup(); } } #endif static inline int socket_errno_negative(int sockfd) { int err = socket_errno(); if (sockfd >= 0) closesocket(sockfd); return err > 0 ? -err : -1; } const char* socket_strerror(int err) { #ifdef OS_WIN static char buffer[128]; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0, ABS(err), 0, buffer, sizeof(buffer), NULL); return buffer; #else return strerror(ABS(err)); #endif } bool is_ipv4(const char* host) { struct sockaddr_in sin; return inet_pton(AF_INET, host, &sin) == 1; } bool is_ipv6(const char* host) { struct sockaddr_in6 sin6; return inet_pton(AF_INET6, host, &sin6) == 1; } int ResolveAddr(const char* host, sockaddr_u* addr) { #ifdef OS_WIN WSAInit(); #endif if (inet_pton(AF_INET, host, &addr->sin.sin_addr) == 1) { addr->sa.sa_family = AF_INET; // host is ipv4, so easy ;) return 0; } if (inet_pton(AF_INET6, host, &addr->sin6.sin6_addr) == 1) { addr->sa.sa_family = AF_INET6; // host is ipv6 } struct addrinfo* ais = NULL; int ret = getaddrinfo(host, NULL, NULL, &ais); if (ret != 0 || ais == NULL || ais->ai_addr == NULL || ais->ai_addrlen == 0) { printd("unknown host: %s err:%d:%s\n", host, ret, gai_strerror(ret)); return ret; } struct addrinfo* pai = ais; while (pai != NULL) { if (pai->ai_family == AF_INET) break; pai = pai->ai_next; } if (pai == NULL) pai = ais; memcpy(addr, pai->ai_addr, pai->ai_addrlen); freeaddrinfo(ais); return 0; } const char* sockaddr_ip(sockaddr_u* addr, char *ip, int len) { if (addr->sa.sa_family == AF_INET) { return inet_ntop(AF_INET, &addr->sin.sin_addr, ip, len); } else if (addr->sa.sa_family == AF_INET6) { return inet_ntop(AF_INET6, &addr->sin6.sin6_addr, ip, len); } return ip; } uint16_t sockaddr_port(sockaddr_u* addr) { uint16_t port = 0; if (addr->sa.sa_family == AF_INET) { port = ntohs(addr->sin.sin_port); } else if (addr->sa.sa_family == AF_INET6) { port = ntohs(addr->sin6.sin6_port); } return port; } int sockaddr_set_ip(sockaddr_u* addr, const char* host) { if (!host || *host == '\0') { addr->sin.sin_family = AF_INET; addr->sin.sin_addr.s_addr = htonl(INADDR_ANY); return 0; } return ResolveAddr(host, addr); } void sockaddr_set_port(sockaddr_u* addr, int port) { if (addr->sa.sa_family == AF_INET) { addr->sin.sin_port = htons(port); } else if (addr->sa.sa_family == AF_INET6) { addr->sin6.sin6_port = htons(port); } } int sockaddr_set_ipport(sockaddr_u* addr, const char* host, int port) { #ifdef ENABLE_UDS if (port < 0) { sockaddr_set_path(addr, host); return 0; } #endif int ret = sockaddr_set_ip(addr, host); if (ret != 0) return ret; sockaddr_set_port(addr, port); // SOCKADDR_PRINT(addr); return 0; } socklen_t sockaddr_len(sockaddr_u* addr) { if (addr->sa.sa_family == AF_INET) { return sizeof(struct sockaddr_in); } else if (addr->sa.sa_family == AF_INET6) { return sizeof(struct sockaddr_in6); } #ifdef ENABLE_UDS else if (addr->sa.sa_family == AF_UNIX) { return sizeof(struct sockaddr_un); } #endif return sizeof(sockaddr_u); } const char* sockaddr_str(sockaddr_u* addr, char* buf, int len) { char ip[SOCKADDR_STRLEN] = {0}; uint16_t port = 0; if (addr->sa.sa_family == AF_INET) { inet_ntop(AF_INET, &addr->sin.sin_addr, ip, len); port = ntohs(addr->sin.sin_port); snprintf(buf, len, "%s:%d", ip, port); } else if (addr->sa.sa_family == AF_INET6) { inet_ntop(AF_INET6, &addr->sin6.sin6_addr, ip, len); port = ntohs(addr->sin6.sin6_port); snprintf(buf, len, "[%s]:%d", ip, port); } #ifdef ENABLE_UDS else if (addr->sa.sa_family == AF_UNIX) { snprintf(buf, len, "%s", addr->sun.sun_path); } #endif return buf; } int sockaddr_compare(const sockaddr_u* addr1, const sockaddr_u* addr2) { if (addr1->sa.sa_family != addr2->sa.sa_family) return addr1->sa.sa_family - addr2->sa.sa_family; if (addr1->sa.sa_family == AF_INET) { if (addr1->sin.sin_family != addr2->sin.sin_family) return addr1->sin.sin_family - addr2->sin.sin_family; if (addr1->sin.sin_port != addr2->sin.sin_port) return addr1->sin.sin_port - addr2->sin.sin_port; return memcmp(&addr1->sin.sin_addr, &addr2->sin.sin_addr, sizeof(struct in_addr)); } else if (addr1->sa.sa_family == AF_INET6) { if (addr1->sin6.sin6_family != addr2->sin6.sin6_family) return addr1->sin6.sin6_family - addr2->sin6.sin6_family; if (addr1->sin6.sin6_port != addr2->sin6.sin6_port) return addr1->sin6.sin6_port - addr2->sin6.sin6_port; return memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in_addr)); } return memcmp(addr1, addr2, sizeof(sockaddr_u)); } static int sockaddr_bind(sockaddr_u* localaddr, int type) { // socket -> setsockopt -> bind #ifdef SOCK_CLOEXEC type |= SOCK_CLOEXEC; #endif int sockfd = socket(localaddr->sa.sa_family, type, 0); if (sockfd < 0) { perror("socket"); goto error; } #ifdef OS_UNIX so_reuseaddr(sockfd, 1); // so_reuseport(sockfd, 1); #endif if (localaddr->sa.sa_family == AF_INET6) { ip_v6only(sockfd, 0); } if (bind(sockfd, &localaddr->sa, sockaddr_len(localaddr)) < 0) { perror("bind"); goto error; } return sockfd; error: return socket_errno_negative(sockfd); } static int sockaddr_connect(sockaddr_u* peeraddr, int nonblock) { // socket -> nonblocking -> connect int ret = 0; int connfd = socket(peeraddr->sa.sa_family, SOCK_STREAM, 0); if (connfd < 0) { perror("socket"); goto error; } if (nonblock) { nonblocking(connfd); } ret = connect(connfd, &peeraddr->sa, sockaddr_len(peeraddr)); #ifdef OS_WIN if (ret < 0 && socket_errno() != WSAEWOULDBLOCK) { #else if (ret < 0 && socket_errno() != EINPROGRESS) { #endif // perror("connect"); goto error; } return connfd; error: return socket_errno_negative(connfd); } static int ListenFD(int sockfd) { if (sockfd < 0) return sockfd; if (listen(sockfd, SOMAXCONN) < 0) { perror("listen"); return socket_errno_negative(sockfd); } return sockfd; } static int ConnectFDTimeout(int connfd, int ms) { int err = 0; socklen_t optlen = sizeof(err); #ifdef OS_UNIX // Use poll() to avoid FD_SETSIZE limit (fd >= 1024 crashes with select) struct pollfd pfd; pfd.fd = connfd; pfd.events = POLLOUT; pfd.revents = 0; int ret = poll(&pfd, 1, ms); if (ret < 0) { perror("poll"); goto error; } #else // Windows: select() is safe (fd_set uses different implementation) struct timeval tv = { ms / 1000, (ms % 1000) * 1000 }; fd_set writefds; FD_ZERO(&writefds); FD_SET(connfd, &writefds); int ret = select(connfd+1, 0, &writefds, 0, &tv); if (ret < 0) { perror("select"); goto error; } #endif if (ret == 0) { errno = ETIMEDOUT; goto error; } if (getsockopt(connfd, SOL_SOCKET, SO_ERROR, (char*)&err, &optlen) < 0 || err != 0) { if (err != 0) errno = err; goto error; } blocking(connfd); return connfd; error: return socket_errno_negative(connfd); } int Bind(int port, const char* host, int type) { #ifdef OS_WIN WSAInit(); #endif sockaddr_u localaddr; memset(&localaddr, 0, sizeof(localaddr)); int ret = sockaddr_set_ipport(&localaddr, host, port); if (ret != 0) { return NABS(ret); } return sockaddr_bind(&localaddr, type); } int Listen(int port, const char* host) { int sockfd = Bind(port, host, SOCK_STREAM); if (sockfd < 0) return sockfd; return ListenFD(sockfd); } int Connect(const char* host, int port, int nonblock) { #ifdef OS_WIN WSAInit(); #endif sockaddr_u peeraddr; memset(&peeraddr, 0, sizeof(peeraddr)); int ret = sockaddr_set_ipport(&peeraddr, host, port); if (ret != 0) { return NABS(ret); } return sockaddr_connect(&peeraddr, nonblock); } int ConnectNonblock(const char* host, int port) { return Connect(host, port, 1); } int ConnectTimeout(const char* host, int port, int ms) { unsigned int start_time = gettick_ms(); int connfd = Connect(host, port, 1); if (connfd < 0) return connfd; unsigned int elapsed = gettick_ms() - start_time; int remaining = ms - (int)elapsed; if (remaining <= 0) { closesocket(connfd); return -ETIMEDOUT; } return ConnectFDTimeout(connfd, remaining); } #ifdef ENABLE_UDS int BindUnix(const char* path, int type) { sockaddr_u localaddr; memset(&localaddr, 0, sizeof(localaddr)); sockaddr_set_path(&localaddr, path); return sockaddr_bind(&localaddr, type); } int ListenUnix(const char* path) { int sockfd = BindUnix(path, SOCK_STREAM); if (sockfd < 0) return sockfd; return ListenFD(sockfd); } int ConnectUnix(const char* path, int nonblock) { sockaddr_u peeraddr; memset(&peeraddr, 0, sizeof(peeraddr)); sockaddr_set_path(&peeraddr, path); return sockaddr_connect(&peeraddr, nonblock); } int ConnectUnixNonblock(const char* path) { return ConnectUnix(path, 1); } int ConnectUnixTimeout(const char* path, int ms) { int connfd = ConnectUnix(path, 1); if (connfd < 0) return connfd; return ConnectFDTimeout(connfd, ms); } #endif int Socketpair(int family, int type, int protocol, int sv[2]) { #if defined(OS_UNIX) && HAVE_SOCKETPAIR return socketpair(AF_LOCAL, type, protocol, sv); #endif if (family != AF_INET || type != SOCK_STREAM) { return -1; } #ifdef OS_WIN WSAInit(); #endif int listenfd, connfd, acceptfd; listenfd = connfd = acceptfd = -1; struct sockaddr_in localaddr; socklen_t addrlen = sizeof(localaddr); memset(&localaddr, 0, addrlen); localaddr.sin_family = AF_INET; localaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); localaddr.sin_port = 0; // listener listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) { perror("socket"); goto error; } if (bind(listenfd, (struct sockaddr*)&localaddr, addrlen) < 0) { perror("bind"); goto error; } if (listen(listenfd, 1) < 0) { perror("listen"); goto error; } if (getsockname(listenfd, (struct sockaddr*)&localaddr, &addrlen) < 0) { perror("getsockname"); goto error; } // connector connfd = socket(AF_INET, SOCK_STREAM, 0); if (connfd < 0) { perror("socket"); goto error; } if (connect(connfd, (struct sockaddr*)&localaddr, addrlen) < 0) { perror("connect"); goto error; } // acceptor acceptfd = accept(listenfd, (struct sockaddr*)&localaddr, &addrlen); if (acceptfd < 0) { perror("accept"); goto error; } closesocket(listenfd); sv[0] = connfd; sv[1] = acceptfd; return 0; error: if (listenfd != -1) { closesocket(listenfd); } if (connfd != -1) { closesocket(connfd); } if (acceptfd != -1) { closesocket(acceptfd); } return -1; } ================================================ FILE: base/hsocket.h ================================================ #ifndef HV_SOCKET_H_ #define HV_SOCKET_H_ #include "hexport.h" #include "hplatform.h" #ifdef ENABLE_UDS #ifdef OS_WIN #include // import struct sockaddr_un #else #include // import struct sockaddr_un #endif #endif #ifdef _MSC_VER #pragma comment(lib, "ws2_32.lib") #endif #define LOCALHOST "127.0.0.1" #define ANYADDR "0.0.0.0" BEGIN_EXTERN_C HV_INLINE int socket_errno() { #ifdef OS_WIN return WSAGetLastError(); #else return errno; #endif } HV_EXPORT const char* socket_strerror(int err); #ifdef OS_WIN typedef SOCKET hsocket_t; typedef int socklen_t; void WSAInit(); void WSADeinit(); HV_INLINE int blocking(int sockfd) { unsigned long nb = 0; return ioctlsocket(sockfd, FIONBIO, &nb); } HV_INLINE int nonblocking(int sockfd) { unsigned long nb = 1; return ioctlsocket(sockfd, FIONBIO, &nb); } #undef EAGAIN #define EAGAIN WSAEWOULDBLOCK #undef EINPROGRESS #define EINPROGRESS WSAEINPROGRESS #undef EINTR #define EINTR WSAEINTR #undef ENOTSOCK #define ENOTSOCK WSAENOTSOCK #undef EMSGSIZE #define EMSGSIZE WSAEMSGSIZE #else typedef int hsocket_t; #ifndef SOCKET #define SOCKET int #endif #ifndef INVALID_SOCKET #define INVALID_SOCKET -1 #endif HV_INLINE int blocking(int s) { return fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK); } HV_INLINE int nonblocking(int s) { return fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); } #ifndef closesocket HV_INLINE int closesocket(int sockfd) { return close(sockfd); } #endif #endif #ifndef SAFE_CLOSESOCKET #define SAFE_CLOSESOCKET(fd) do {if ((fd) >= 0) {closesocket(fd); (fd) = -1;}} while(0) #endif //-----------------------------sockaddr_u---------------------------------------------- typedef union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; #ifdef ENABLE_UDS struct sockaddr_un sun; #endif } sockaddr_u; HV_EXPORT bool is_ipv4(const char* host); HV_EXPORT bool is_ipv6(const char* host); HV_INLINE bool is_ipaddr(const char* host) { return is_ipv4(host) || is_ipv6(host); } // @param host: domain or ip // @retval 0:succeed HV_EXPORT int ResolveAddr(const char* host, sockaddr_u* addr); HV_EXPORT const char* sockaddr_ip(sockaddr_u* addr, char *ip, int len); HV_EXPORT uint16_t sockaddr_port(sockaddr_u* addr); HV_EXPORT int sockaddr_set_ip(sockaddr_u* addr, const char* host); HV_EXPORT void sockaddr_set_port(sockaddr_u* addr, int port); HV_EXPORT int sockaddr_set_ipport(sockaddr_u* addr, const char* host, int port); HV_EXPORT socklen_t sockaddr_len(sockaddr_u* addr); HV_EXPORT const char* sockaddr_str(sockaddr_u* addr, char* buf, int len); HV_EXPORT int sockaddr_compare(const sockaddr_u* addr1, const sockaddr_u* addr2); //#define INET_ADDRSTRLEN 16 //#define INET6_ADDRSTRLEN 46 #ifdef ENABLE_UDS #define SOCKADDR_STRLEN sizeof(((struct sockaddr_un*)(NULL))->sun_path) HV_INLINE void sockaddr_set_path(sockaddr_u* addr, const char* path) { addr->sa.sa_family = AF_UNIX; strncpy(addr->sun.sun_path, path, sizeof(addr->sun.sun_path)); } #else #define SOCKADDR_STRLEN 64 // ipv4:port | [ipv6]:port #endif HV_INLINE void sockaddr_print(sockaddr_u* addr) { char buf[SOCKADDR_STRLEN] = {0}; sockaddr_str(addr, buf, sizeof(buf)); puts(buf); } #define SOCKADDR_LEN(addr) sockaddr_len((sockaddr_u*)addr) #define SOCKADDR_STR(addr, buf) sockaddr_str((sockaddr_u*)addr, buf, sizeof(buf)) #define SOCKADDR_PRINT(addr) sockaddr_print((sockaddr_u*)addr) //===================================================================================== // socket -> setsockopt -> bind // @param type: SOCK_STREAM(tcp) SOCK_DGRAM(udp) // @return sockfd HV_EXPORT int Bind(int port, const char* host DEFAULT(ANYADDR), int type DEFAULT(SOCK_STREAM)); // Bind -> listen // @return listenfd HV_EXPORT int Listen(int port, const char* host DEFAULT(ANYADDR)); // @return connfd // ResolveAddr -> socket -> nonblocking -> connect HV_EXPORT int Connect(const char* host, int port, int nonblock DEFAULT(0)); // Connect(host, port, 1) HV_EXPORT int ConnectNonblock(const char* host, int port); // Connect(host, port, 1) -> select -> blocking #define DEFAULT_CONNECT_TIMEOUT 10000 // ms HV_EXPORT int ConnectTimeout(const char* host, int port, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT)); #ifdef ENABLE_UDS HV_EXPORT int BindUnix(const char* path, int type DEFAULT(SOCK_STREAM)); HV_EXPORT int ListenUnix(const char* path); HV_EXPORT int ConnectUnix(const char* path, int nonblock DEFAULT(0)); HV_EXPORT int ConnectUnixNonblock(const char* path); HV_EXPORT int ConnectUnixTimeout(const char* path, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT)); #endif // Just implement Socketpair(AF_INET, SOCK_STREAM, 0, sv); HV_EXPORT int Socketpair(int family, int type, int protocol, int sv[2]); HV_INLINE int tcp_nodelay(int sockfd, int on DEFAULT(1)) { return setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(int)); } HV_INLINE int tcp_nopush(int sockfd, int on DEFAULT(1)) { #ifdef TCP_NOPUSH return setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, (const char*)&on, sizeof(int)); #elif defined(TCP_CORK) return setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, (const char*)&on, sizeof(int)); #else return 0; #endif } HV_INLINE int tcp_keepalive(int sockfd, int on DEFAULT(1), int delay DEFAULT(60)) { if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(int)) != 0) { return socket_errno(); } #ifdef TCP_KEEPALIVE return setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, (const char*)&delay, sizeof(int)); #elif defined(TCP_KEEPIDLE) // TCP_KEEPIDLE => tcp_keepalive_time // TCP_KEEPCNT => tcp_keepalive_probes // TCP_KEEPINTVL => tcp_keepalive_intvl return setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (const char*)&delay, sizeof(int)); #else return 0; #endif } HV_INLINE int udp_broadcast(int sockfd, int on DEFAULT(1)) { return setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof(int)); } HV_INLINE int ip_v6only(int sockfd, int on DEFAULT(1)) { #ifdef IPV6_V6ONLY return setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(int)); #else return 0; #endif } // send timeout HV_INLINE int so_sndtimeo(int sockfd, int timeout) { #ifdef OS_WIN return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(int)); #else struct timeval tv = {timeout/1000, (timeout%1000)*1000}; return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); #endif } // recv timeout HV_INLINE int so_rcvtimeo(int sockfd, int timeout) { #ifdef OS_WIN return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(int)); #else struct timeval tv = {timeout/1000, (timeout%1000)*1000}; return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); #endif } // send buffer size HV_INLINE int so_sndbuf(int sockfd, int len) { return setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&len, sizeof(int)); } // recv buffer size HV_INLINE int so_rcvbuf(int sockfd, int len) { return setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&len, sizeof(int)); } HV_INLINE int so_reuseaddr(int sockfd, int on DEFAULT(1)) { #ifdef SO_REUSEADDR // NOTE: SO_REUSEADDR allow to reuse sockaddr of TIME_WAIT status return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(int)); #else return 0; #endif } HV_INLINE int so_reuseport(int sockfd, int on DEFAULT(1)) { #ifdef SO_REUSEPORT // NOTE: SO_REUSEPORT allow multiple sockets to bind same port return setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char*)&on, sizeof(int)); #else return 0; #endif } HV_INLINE int so_linger(int sockfd, int timeout DEFAULT(1)) { #ifdef SO_LINGER struct linger linger; if (timeout >= 0) { linger.l_onoff = 1; linger.l_linger = timeout; } else { linger.l_onoff = 0; linger.l_linger = 0; } // NOTE: SO_LINGER change the default behavior of close, send RST, avoid TIME_WAIT return setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&linger, sizeof(linger)); #else return 0; #endif } END_EXTERN_C #endif // HV_SOCKET_H_ ================================================ FILE: base/hsysinfo.h ================================================ #ifndef HV_SYS_INFO_H_ #define HV_SYS_INFO_H_ #include "hplatform.h" #ifdef OS_LINUX #include #endif #ifdef OS_DARWIN #include #include #endif static inline int get_ncpu() { #ifdef OS_WIN SYSTEM_INFO si; GetSystemInfo(&si); return si.dwNumberOfProcessors; #else //return get_nprocs(); //return get_nprocs_conf(); //return sysconf(_SC_NPROCESSORS_ONLN); // processors available return sysconf(_SC_NPROCESSORS_CONF); // processors configured #endif } typedef struct meminfo_s { unsigned long total; // KB unsigned long free; // KB } meminfo_t; static inline int get_meminfo(meminfo_t* mem) { #ifdef OS_WIN MEMORYSTATUSEX memstat; memset(&memstat, 0, sizeof(memstat)); memstat.dwLength = sizeof(memstat); GlobalMemoryStatusEx(&memstat); mem->total = (unsigned long)(memstat.ullTotalPhys >> 10); mem->free = (unsigned long)(memstat.ullAvailPhys >> 10); return 0; #elif defined(OS_LINUX) struct sysinfo info; if (sysinfo(&info) < 0) { return errno; } mem->total = info.totalram * info.mem_unit >> 10; mem->free = info.freeram * info.mem_unit >> 10; return 0; #elif defined(OS_DARWIN) uint64_t memsize = 0; size_t size = sizeof(memsize); int which[2] = {CTL_HW, HW_MEMSIZE}; sysctl(which, 2, &memsize, &size, NULL, 0); mem->total = memsize >> 10; vm_statistics_data_t info; mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t); host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&info, &count); mem->free = ((uint64_t)info.free_count * sysconf(_SC_PAGESIZE)) >> 10; return 0; #else (void)(mem); return -10; #endif } #endif // HV_SYS_INFO_H_ ================================================ FILE: base/hthread.h ================================================ #ifndef HV_THREAD_H_ #define HV_THREAD_H_ #include "hplatform.h" #ifdef OS_WIN #define hv_getpid (long)GetCurrentProcessId #else #define hv_getpid (long)getpid #endif #ifdef OS_WIN #define hv_gettid (long)GetCurrentThreadId #elif HAVE_GETTID || defined(OS_ANDROID) #define hv_gettid (long)gettid #elif defined(OS_LINUX) #include #define hv_gettid() (long)syscall(SYS_gettid) #elif defined(OS_DARWIN) static inline long hv_gettid() { uint64_t tid = 0; /* pthread_threadid_np is not available before 10.6 and in 10.6 for ppc */ #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 || defined(__POWERPC__) tid = pthread_mach_thread_np(pthread_self()); #else pthread_threadid_np(NULL, &tid); #endif return tid; } #elif HAVE_PTHREAD_H #define hv_gettid (long)pthread_self #else #define hv_gettid hv_getpid #endif /* #include "hthread.h" HTHREAD_ROUTINE(thread_demo) { printf("thread[%ld] start\n", hv_gettid()); hv_delay(3000); printf("thread[%ld] end\n", hv_gettid()); return 0; } int main() { hthread_t th = hthread_create(thread_demo, NULL); hthread_join(th); return 0; } */ #ifdef OS_WIN typedef HANDLE hthread_t; typedef DWORD (WINAPI *hthread_routine)(void*); #define HTHREAD_RETTYPE DWORD #define HTHREAD_ROUTINE(fname) DWORD WINAPI fname(void* userdata) static inline hthread_t hthread_create(hthread_routine fn, void* userdata) { return CreateThread(NULL, 0, fn, userdata, 0, NULL); } static inline int hthread_join(hthread_t th) { WaitForSingleObject(th, INFINITE); CloseHandle(th); return 0; } #else typedef pthread_t hthread_t; typedef void* (*hthread_routine)(void*); #define HTHREAD_RETTYPE void* #define HTHREAD_ROUTINE(fname) void* fname(void* userdata) static inline hthread_t hthread_create(hthread_routine fn, void* userdata) { pthread_t th; pthread_create(&th, NULL, fn, userdata); return th; } static inline int hthread_join(hthread_t th) { return pthread_join(th, NULL); } #endif #ifdef __cplusplus /************************************************ * HThread * Status: STOP,RUNNING,PAUSE * Control: start,stop,pause,resume * first-level virtual: doTask * second-level virtual: run ************************************************/ #include #include #include class HThread { public: enum Status { STOP, RUNNING, PAUSE, }; enum SleepPolicy { YIELD, SLEEP_FOR, SLEEP_UNTIL, NO_SLEEP, }; HThread() { status = STOP; status_changed = false; dotask_cnt = 0; sleep_policy = YIELD; sleep_ms = 0; } virtual ~HThread() {} void setStatus(Status stat) { status_changed = true; status = stat; } void setSleepPolicy(SleepPolicy policy, uint32_t ms = 0) { sleep_policy = policy; sleep_ms = ms; setStatus(status); } virtual int start() { if (status == STOP) { thread = std::thread([this] { if (!doPrepare()) return; setStatus(RUNNING); run(); setStatus(STOP); if (!doFinish()) return; }); } return 0; } virtual int stop() { if (status != STOP) { setStatus(STOP); } if (thread.joinable()) { thread.join(); // wait thread exit } return 0; } virtual int pause() { if (status == RUNNING) { setStatus(PAUSE); } return 0; } virtual int resume() { if (status == PAUSE) { setStatus(RUNNING); } return 0; } virtual void run() { while (status != STOP) { while (status == PAUSE) { std::this_thread::yield(); } doTask(); ++dotask_cnt; HThread::sleep(); } } virtual bool doPrepare() {return true;} virtual void doTask() {} virtual bool doFinish() {return true;} std::thread thread; std::atomic status; uint32_t dotask_cnt; protected: void sleep() { switch (sleep_policy) { case YIELD: std::this_thread::yield(); break; case SLEEP_FOR: std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms)); break; case SLEEP_UNTIL: { if (status_changed) { status_changed = false; base_tp = std::chrono::steady_clock::now(); } base_tp += std::chrono::milliseconds(sleep_ms); std::this_thread::sleep_until(base_tp); } break; default: // donothing, go all out. break; } } SleepPolicy sleep_policy; uint32_t sleep_ms; // for SLEEP_UNTIL std::atomic status_changed; std::chrono::steady_clock::time_point base_tp; }; #endif #endif // HV_THREAD_H_ ================================================ FILE: base/htime.c ================================================ #include "htime.h" static const char* s_weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; static const char* s_months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; static const uint8_t s_days[] = \ // 1 3 5 7 8 10 12 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; unsigned int gettick_ms() { #ifdef OS_WIN return GetTickCount(); #elif HAVE_CLOCK_GETTIME struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (unsigned int)ts.tv_sec * 1000 + (unsigned int)ts.tv_nsec / 1000000; #else struct timeval tv; gettimeofday(&tv, NULL); return (unsigned int)tv.tv_sec * 1000 + (unsigned int)tv.tv_usec / 1000; #endif } unsigned long long gethrtime_us() { #ifdef OS_WIN static LONGLONG s_freq = 0; if (s_freq == 0) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); s_freq = freq.QuadPart; } if (s_freq != 0) { LARGE_INTEGER count; QueryPerformanceCounter(&count); return (unsigned long long)(count.QuadPart / (double)s_freq * 1000000); } return 0; #elif defined(OS_SOLARIS) return gethrtime() / 1000; #elif HAVE_CLOCK_GETTIME struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec*(unsigned long long)1000000 + ts.tv_nsec / 1000; #else struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec*(unsigned long long)1000000 + tv.tv_usec; #endif } datetime_t datetime_now() { #ifdef OS_WIN SYSTEMTIME tm; GetLocalTime(&tm); datetime_t dt; dt.year = tm.wYear; dt.month = tm.wMonth; dt.day = tm.wDay; dt.hour = tm.wHour; dt.min = tm.wMinute; dt.sec = tm.wSecond; dt.ms = tm.wMilliseconds; return dt; #else struct timeval tv; gettimeofday(&tv, NULL); datetime_t dt = datetime_localtime(tv.tv_sec); dt.ms = tv.tv_usec / 1000; return dt; #endif } datetime_t datetime_localtime(time_t seconds) { struct tm* tm = localtime(&seconds); datetime_t dt; dt.year = tm->tm_year + 1900; dt.month = tm->tm_mon + 1; dt.day = tm->tm_mday; dt.hour = tm->tm_hour; dt.min = tm->tm_min; dt.sec = tm->tm_sec; return dt; } time_t datetime_mktime(datetime_t* dt) { struct tm tm; time_t ts; time(&ts); struct tm* ptm = localtime(&ts); memcpy(&tm, ptm, sizeof(struct tm)); tm.tm_year = dt->year - 1900; tm.tm_mon = dt->month - 1; tm.tm_mday = dt->day; tm.tm_hour = dt->hour; tm.tm_min = dt->min; tm.tm_sec = dt->sec; return mktime(&tm); } int days_of_month(int month, int year) { if (month < 1 || month > 12) { return 0; } int days = s_days[month-1]; return (month == 2 && IS_LEAP_YEAR(year)) ? ++days : days; } datetime_t* datetime_past(datetime_t* dt, int days) { assert(days >= 0); int sub = days; while (sub) { if (dt->day > sub) { dt->day -= sub; break; } sub -= dt->day; if (--dt->month == 0) { dt->month = 12; --dt->year; } dt->day = days_of_month(dt->month, dt->year); } return dt; } datetime_t* datetime_future(datetime_t* dt, int days) { assert(days >= 0); int sub = days; int mdays; while (sub) { mdays = days_of_month(dt->month, dt->year); if (dt->day + sub <= mdays) { dt->day += sub; break; } sub -= (mdays - dt->day + 1); if (++dt->month > 12) { dt->month = 1; ++dt->year; } dt->day = 1; } return dt; } char* duration_fmt(int sec, char* buf) { int h, m, s; m = sec / 60; s = sec % 60; h = m / 60; m = m % 60; sprintf(buf, TIME_FMT, h, m, s); return buf; } char* datetime_fmt(datetime_t* dt, char* buf) { sprintf(buf, DATETIME_FMT, dt->year, dt->month, dt->day, dt->hour, dt->min, dt->sec); return buf; } char* datetime_fmt_iso(datetime_t* dt, char* buf) { sprintf(buf, DATETIME_FMT_ISO, dt->year, dt->month, dt->day, dt->hour, dt->min, dt->sec, dt->ms); return buf; } char* gmtime_fmt(time_t time, char* buf) { struct tm* tm = gmtime(&time); //strftime(buf, GMTIME_FMT_BUFLEN, "%a, %d %b %Y %H:%M:%S GMT", tm); sprintf(buf, GMTIME_FMT, s_weekdays[tm->tm_wday], tm->tm_mday, s_months[tm->tm_mon], tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); return buf; } int month_atoi(const char* month) { for (size_t i = 0; i < 12; ++i) { if (strnicmp(month, s_months[i], strlen(month)) == 0) return i+1; } return 0; } const char* month_itoa(int month) { assert(month >= 1 && month <= 12); return s_months[month-1]; } int weekday_atoi(const char* weekday) { for (size_t i = 0; i < 7; ++i) { if (strnicmp(weekday, s_weekdays[i], strlen(weekday)) == 0) return i; } return 0; } const char* weekday_itoa(int weekday) { assert(weekday >= 0 && weekday <= 7); if (weekday == 7) weekday = 0; return s_weekdays[weekday]; } datetime_t hv_compile_datetime() { datetime_t dt; char month[32]; sscanf(__DATE__, "%s %d %d", month, &dt.day, &dt.year); sscanf(__TIME__, "%d:%d:%d", &dt.hour, &dt.min, &dt.sec); dt.month = month_atoi(month); return dt; } time_t cron_next_timeout(int minute, int hour, int day, int week, int month) { enum { MINUTELY, HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY, } period_type = MINUTELY; struct tm tm; time_t tt; time(&tt); tm = *localtime(&tt); time_t tt_round = 0; tm.tm_sec = 0; if (minute >= 0) { period_type = HOURLY; tm.tm_min = minute; } if (hour >= 0) { period_type = DAILY; tm.tm_hour = hour; } if (week >= 0) { period_type = WEEKLY; } else if (day > 0) { period_type = MONTHLY; tm.tm_mday = day; if (month > 0) { period_type = YEARLY; tm.tm_mon = month - 1; } } tt_round = mktime(&tm); if (week >= 0) { tt_round += (week-tm.tm_wday)*SECONDS_PER_DAY; } if (tt_round > tt) { return tt_round; } switch(period_type) { case MINUTELY: tt_round += SECONDS_PER_MINUTE; return tt_round; case HOURLY: tt_round += SECONDS_PER_HOUR; return tt_round; case DAILY: tt_round += SECONDS_PER_DAY; return tt_round; case WEEKLY: tt_round += SECONDS_PER_WEEK; return tt_round; case MONTHLY: if (++tm.tm_mon == 12) { tm.tm_mon = 0; ++tm.tm_year; } break; case YEARLY: ++tm.tm_year; break; default: return -1; } return mktime(&tm); } ================================================ FILE: base/htime.h ================================================ #ifndef HV_TIME_H_ #define HV_TIME_H_ #include "hexport.h" #include "hplatform.h" BEGIN_EXTERN_C #define SECONDS_PER_MINUTE 60 #define SECONDS_PER_HOUR 3600 #define SECONDS_PER_DAY 86400 // 24*3600 #define SECONDS_PER_WEEK 604800 // 7*24*3600 #define IS_LEAP_YEAR(year) (((year)%4 == 0 && (year)%100 != 0) || (year)%400 == 0) typedef struct datetime_s { int year; int month; int day; int hour; int min; int sec; int ms; } datetime_t; #ifdef _MSC_VER /* @see winsock2.h // Structure used in select() call, taken from the BSD file sys/time.h struct timeval { long tv_sec; long tv_usec; }; */ struct timezone { int tz_minuteswest; /* of Greenwich */ int tz_dsttime; /* type of dst correction to apply */ }; #include HV_INLINE int gettimeofday(struct timeval *tv, struct timezone *tz) { struct _timeb tb; _ftime(&tb); if (tv) { tv->tv_sec = (long)tb.time; tv->tv_usec = tb.millitm * 1000; } if (tz) { tz->tz_minuteswest = tb.timezone; tz->tz_dsttime = tb.dstflag; } return 0; } #endif HV_EXPORT unsigned int gettick_ms(); HV_INLINE unsigned long long gettimeofday_ms() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * (unsigned long long)1000 + tv.tv_usec/1000; } HV_INLINE unsigned long long gettimeofday_us() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * (unsigned long long)1000000 + tv.tv_usec; } HV_EXPORT unsigned long long gethrtime_us(); HV_EXPORT datetime_t datetime_now(); HV_EXPORT datetime_t datetime_localtime(time_t seconds); HV_EXPORT time_t datetime_mktime(datetime_t* dt); HV_EXPORT datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1)); HV_EXPORT datetime_t* datetime_future(datetime_t* dt, int days DEFAULT(1)); #define TIME_FMT "%02d:%02d:%02d" #define TIME_FMT_BUFLEN 12 HV_EXPORT char* duration_fmt(int sec, char* buf); #define DATETIME_FMT "%04d-%02d-%02d %02d:%02d:%02d" #define DATETIME_FMT_ISO "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ" #define DATETIME_FMT_BUFLEN 30 HV_EXPORT char* datetime_fmt(datetime_t* dt, char* buf); HV_EXPORT char* datetime_fmt_iso(datetime_t* dt, char* buf); #define GMTIME_FMT "%.3s, %02d %.3s %04d %02d:%02d:%02d GMT" #define GMTIME_FMT_BUFLEN 30 HV_EXPORT char* gmtime_fmt(time_t time, char* buf); HV_EXPORT int days_of_month(int month, int year); HV_EXPORT int month_atoi(const char* month); HV_EXPORT const char* month_itoa(int month); HV_EXPORT int weekday_atoi(const char* weekday); HV_EXPORT const char* weekday_itoa(int weekday); HV_EXPORT datetime_t hv_compile_datetime(); /* * minute hour day week month action * 0~59 0~23 1~31 0~6 1~12 * -1 -1 -1 -1 -1 cron.minutely * 30 -1 -1 -1 -1 cron.hourly * 30 1 -1 -1 -1 cron.daily * 30 1 15 -1 -1 cron.monthly * 30 1 -1 0 -1 cron.weekly * 30 1 1 -1 10 cron.yearly */ HV_EXPORT time_t cron_next_timeout(int minute, int hour, int day, int week, int month); END_EXTERN_C #endif // HV_TIME_H_ ================================================ FILE: base/hversion.c ================================================ #include "hversion.h" #include "htime.h" const char* hv_compile_version() { static char s_version[16] = {0}; datetime_t dt = hv_compile_datetime(); snprintf(s_version, sizeof(s_version), "%d.%d.%d.%d", HV_VERSION_MAJOR, dt.year%100, dt.month, dt.day); return s_version; } int version_atoi(const char* str) { int hex = 0; // trim v1.2.3.4 const char* pv = strchr(str, 'v'); const char* pdot = pv ? pv+1 : str; while (1) { hex = (hex << 8) | atoi(pdot); pdot = strchr(pdot, '.'); if (pdot == NULL) break; ++pdot; } return hex; } void version_itoa(int num, char* str) { char* ch = (char*)# sprintf(str, "%d.%d.%d.%d", ch[3], ch[2], ch[1], ch[0]); // trim 0.1.2.3 const char* p = str; while (1) { if (p[0] == '0' && p[1] == '.') { p += 2; } else { break; } } if (p != str) { strcpy(str, p); } } ================================================ FILE: base/hversion.h ================================================ #ifndef HV_VERSION_H_ #define HV_VERSION_H_ #include "hexport.h" #include "hdef.h" BEGIN_EXTERN_C #define HV_VERSION_MAJOR 1 #define HV_VERSION_MINOR 3 #define HV_VERSION_PATCH 4 #define HV_VERSION_STRING STRINGIFY(HV_VERSION_MAJOR) "." \ STRINGIFY(HV_VERSION_MINOR) "." \ STRINGIFY(HV_VERSION_PATCH) #define HV_VERSION_NUMBER ((HV_VERSION_MAJOR << 16) | (HV_VERSION_MINOR << 8) | HV_VERSION_PATCH) HV_INLINE const char* hv_version() { return HV_VERSION_STRING; } HV_EXPORT const char* hv_compile_version(); // 1.2.3.4 => 0x01020304 HV_EXPORT int version_atoi(const char* str); // 0x01020304 => 1.2.3.4 HV_EXPORT void version_itoa(int hex, char* str); END_EXTERN_C #endif // HV_VERSION_H_ ================================================ FILE: base/list.h ================================================ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H /* * Simple doubly linked list implementation. * * Some of the internal functions ("__xxx") are useful when * manipulating whole lists rather than single entries, as * sometimes we already know the next/prev entries and we can * generate better code by using them directly rather than * using the generic single-entry routines. */ #include #ifndef prefetch #ifdef __GNUC__ #define prefetch(x) __builtin_prefetch(x) #else #define prefetch(x) (void)0 #endif #endif struct list_head { struct list_head *next, *prev; }; #define list_node list_head struct hlist_head { struct hlist_node *first; }; struct hlist_node { struct hlist_node *next, **pprev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } // TODO: defined LIST_HEAD #ifndef LIST_HEAD #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) #endif #define INIT_LIST_HEAD list_init static inline void list_init(struct list_head *list) { list->next = list; list->prev = list; } /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add(struct list_head *n, struct list_head *prev, struct list_head *next) { next->prev = n; n->next = next; n->prev = prev; prev->next = n; } /** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ static inline void list_add(struct list_head *n, struct list_head *head) { __list_add(n, head, head->next); } /** * list_add_tail - add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ static inline void list_add_tail(struct list_head *n, struct list_head *head) { __list_add(n, head->prev, head); } /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; } /** * list_del - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty() on entry does not return true after this, the entry is * in an undefined state. */ static inline void __list_del_entry(struct list_head *entry) { __list_del(entry->prev, entry->next); } static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); //entry->next = NULL; //entry->prev = NULL; } /** * list_replace - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert * * If @old was empty, it will be overwritten. */ static inline void list_replace(struct list_head *old, struct list_head *n) { n->next = old->next; n->next->prev = n; n->prev = old->prev; n->prev->next = n; } static inline void list_replace_init(struct list_head *old, struct list_head *n) { list_replace(old, n); INIT_LIST_HEAD(old); } /** * list_del_init - deletes entry from list and reinitialize it. * @entry: the element to delete from the list. */ static inline void list_del_init(struct list_head *entry) { __list_del_entry(entry); INIT_LIST_HEAD(entry); } /** * list_move - delete from one list and add as another's head * @list: the entry to move * @head: the head that will precede our entry */ static inline void list_move(struct list_head *list, struct list_head *head) { __list_del_entry(list); list_add(list, head); } /** * list_move_tail - delete from one list and add as another's tail * @list: the entry to move * @head: the head that will follow our entry */ static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del_entry(list); list_add_tail(list, head); } /** * list_is_last - tests whether @list is the last entry in list @head * @list: the entry to test * @head: the head of the list */ static inline int list_is_last(const struct list_head *list, const struct list_head *head) { return list->next == head; } /** * list_empty - tests whether a list is empty * @head: the list to test. */ static inline int list_empty(const struct list_head *head) { return head->next == head; } /** * list_empty_careful - tests whether a list is empty and not being modified * @head: the list to test * * Description: * tests whether a list is empty _and_ checks that no other CPU might be * in the process of modifying either member (next or prev) * * NOTE: using list_empty_careful() without synchronization * can only be safe if the only activity that can happen * to the list entry is list_del_init(). Eg. it cannot be used * if another CPU could re-list_add() it. */ static inline int list_empty_careful(const struct list_head *head) { struct list_head *next = head->next; return (next == head) && (next == head->prev); } /** * list_rotate_left - rotate the list to the left * @head: the head of the list */ static inline void list_rotate_left(struct list_head *head) { struct list_head *first; if (!list_empty(head)) { first = head->next; list_move_tail(first, head); } } /** * list_is_singular - tests whether a list has just one entry. * @head: the list to test. */ static inline int list_is_singular(const struct list_head *head) { return !list_empty(head) && (head->next == head->prev); } static inline void __list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry) { struct list_head *new_first = entry->next; list->next = head->next; list->next->prev = list; list->prev = entry; entry->next = list; head->next = new_first; new_first->prev = head; } /** * list_cut_position - cut a list into two * @list: a new list to add all removed entries * @head: a list with entries * @entry: an entry within head, could be the head itself * and if so we won't cut the list * * This helper moves the initial part of @head, up to and * including @entry, from @head to @list. You should * pass on @entry an element you know is on @head. @list * should be an empty list or a list you do not care about * losing its data. * */ static inline void list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry) { if (list_empty(head)) return; if (list_is_singular(head) && (head->next != entry && head != entry)) return; if (entry == head) INIT_LIST_HEAD(list); else __list_cut_position(list, head, entry); } static inline void __list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next) { struct list_head *first = list->next; struct list_head *last = list->prev; first->prev = prev; prev->next = first; last->next = next; next->prev = last; } /** * list_splice - join two lists, this is designed for stacks * @list: the new list to add. * @head: the place to add it in the first list. */ static inline void list_splice(const struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head, head->next); } /** * list_splice_tail - join two lists, each list being a queue * @list: the new list to add. * @head: the place to add it in the first list. */ static inline void list_splice_tail(struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head->prev, head); } /** * list_splice_init - join two lists and reinitialise the emptied list. * @list: the new list to add. * @head: the place to add it in the first list. * * The list at @list is reinitialised */ static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head, head->next); INIT_LIST_HEAD(list); } } /** * list_splice_tail_init - join two lists and reinitialise the emptied list * @list: the new list to add. * @head: the place to add it in the first list. * * Each of the lists is a queue. * The list at @list is reinitialised */ static inline void list_splice_tail_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head->prev, head); INIT_LIST_HEAD(list); } } /** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) /** * list_first_entry - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. * * Note, that list is expected to be not empty. */ #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each(pos, head) \ for (pos = (head)->next; prefetch(pos->next), pos != (head); \ pos = pos->next) /** * __list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. * * This variant differs from list_for_each() in that it's the * simplest possible list iteration code, no prefetching is done. * Use this for code that knows the list to be very short (empty * or 1 entry) most of the time. */ #define __list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) /** * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; \ prefetch(pos->prev), pos != (head); \ pos = n, n = pos->prev) /** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_reverse - iterate backwards over list of given type. * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member); \ prefetch(pos->member.prev), &pos->member != (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) /** * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() * @pos: the type * to use as a start point * @head: the head of the list * @member: the name of the list_struct within the struct. * * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). */ #define list_prepare_entry(pos, head, member) \ ((pos) ? : list_entry(head, typeof(*pos), member)) /** * list_for_each_entry_continue - continue iteration over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Continue to iterate over list of given type, continuing after * the current position. */ #define list_for_each_entry_continue(pos, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_continue_reverse - iterate backwards from the given point * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Start to iterate over list of given type backwards, continuing after * the current position. */ #define list_for_each_entry_continue_reverse(pos, head, member) \ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ prefetch(pos->member.prev), &pos->member != (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) /** * list_for_each_entry_from - iterate over list of given type from the current point * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate over list of given type, continuing from current position. */ #define list_for_each_entry_from(pos, head, member) \ for (; prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_continue - continue list iteration safe against removal * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate over list of given type, continuing after current point, * safe against removal of list entry. */ #define list_for_each_entry_safe_continue(pos, n, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_from - iterate over list from current point safe against removal * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate over list of given type from current point, safe against * removal of list entry. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) /** * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate backwards over list of given type, safe against removal * of list entry. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member), \ n = list_entry(pos->member.prev, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) /** * list_safe_reset_next - reset a stale list_for_each_entry_safe loop * @pos: the loop cursor used in the list_for_each_entry_safe loop * @n: temporary storage used in list_for_each_entry_safe * @member: the name of the list_struct within the struct. * * list_safe_reset_next is not safe to use in general if the list may be * modified concurrently (eg. the lock is dropped in the loop body). An * exception to this is if the cursor element (pos) is pinned in the list, * and list_safe_reset_next is called after re-taking the lock and before * completing the current iteration of the loop body. */ #define list_safe_reset_next(pos, n, member) \ n = list_entry(pos->member.next, typeof(*pos), member) /* * Double linked lists with a single pointer list head. * Mostly useful for hash tables where the two pointer list head is * too wasteful. * You lose the ability to access the tail in O(1). */ #define HLIST_HEAD_INIT { .first = NULL } #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) #define INIT_HLIST_NODE hlist_init static inline void hlist_init(struct hlist_node *h) { h->next = NULL; h->pprev = NULL; } static inline int hlist_unhashed(const struct hlist_node *h) { return !h->pprev; } static inline int hlist_empty(const struct hlist_head *h) { return !h->first; } static inline void __hlist_del(struct hlist_node *n) { struct hlist_node *next = n->next; struct hlist_node **pprev = n->pprev; *pprev = next; if (next) next->pprev = pprev; } static inline void hlist_del(struct hlist_node *n) { __hlist_del(n); //n->next = NULL; //n->pprev = NULL; } static inline void hlist_del_init(struct hlist_node *n) { if (!hlist_unhashed(n)) { __hlist_del(n); INIT_HLIST_NODE(n); } } static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; n->next = first; if (first) first->pprev = &n->next; h->first = n; n->pprev = &h->first; } /* next must be != NULL */ static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) { n->pprev = next->pprev; n->next = next; next->pprev = &n->next; *(n->pprev) = n; } static inline void hlist_add_after(struct hlist_node *n, struct hlist_node *next) { next->next = n->next; n->next = next; next->pprev = &n->next; if(next->next) next->next->pprev = &next->next; } /* after that we'll appear to be on some hlist and hlist_del will work */ static inline void hlist_add_fake(struct hlist_node *n) { n->pprev = &n->next; } /* * Move a list from one list head to another. Fixup the pprev * reference of the first entry if it exists. */ static inline void hlist_move_list(struct hlist_head *old, struct hlist_head *n) { n->first = old->first; if (n->first) n->first->pprev = &n->first; old->first = NULL; } #define hlist_entry(ptr, type, member) container_of(ptr,type,member) #define hlist_for_each(pos, head) \ for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ pos = pos->next) #define hlist_for_each_safe(pos, n, head) \ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ pos = n) /** * hlist_for_each_entry - iterate over list of given type * @tpos: the type * to use as a loop cursor. * @pos: the &struct hlist_node to use as a loop cursor. * @head: the head for your list. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry(tpos, pos, head, member) \ for (pos = (head)->first; \ pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) /** * hlist_for_each_entry_continue - iterate over a hlist continuing after current point * @tpos: the type * to use as a loop cursor. * @pos: the &struct hlist_node to use as a loop cursor. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_continue(tpos, pos, member) \ for (pos = (pos)->next; \ pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) /** * hlist_for_each_entry_from - iterate over a hlist continuing from current point * @tpos: the type * to use as a loop cursor. * @pos: the &struct hlist_node to use as a loop cursor. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_from(tpos, pos, member) \ for (; pos && ({ prefetch(pos->next); 1;}) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) /** * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @tpos: the type * to use as a loop cursor. * @pos: the &struct hlist_node to use as a loop cursor. * @n: another &struct hlist_node to use as temporary storage * @head: the head for your list. * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ for (pos = (head)->first; \ pos && ({ n = pos->next; 1; }) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = n) #endif ================================================ FILE: base/netinet.h ================================================ #ifndef HV_NETINET_H_ #define HV_NETINET_H_ #include "hplatform.h" /* #ifdef OS_UNIX #include #include #include #include #include typedef struct iphdr iphdr_t; typedef struct udphdr udphdr_t; typedef struct tcphdr tcphdr_t; typedef struct icmphdr icmphdr_t; typedef struct icmp icmp_t; #else */ // sizeof(iphdr_t) = 20 typedef struct iphdr_s { #if BYTE_ORDER == LITTLE_ENDIAN uint8_t ihl:4; // ip header length uint8_t version:4; #elif BYTE_ORDER == BIG_ENDIAN uint8_t version:4; uint8_t ihl:4; #else #error "BYTE_ORDER undefined!" #endif uint8_t tos; // type of service uint16_t tot_len; // total length uint16_t id; uint16_t frag_off; // fragment offset uint8_t ttl; // Time To Live uint8_t protocol; uint16_t check; // checksum uint32_t saddr; // srcaddr uint32_t daddr; // dstaddr /*The options start here.*/ } iphdr_t; // sizeof(udphdr_t) = 8 typedef struct udphdr_s { uint16_t source; // source port uint16_t dest; // dest port uint16_t len; // udp length uint16_t check; // checksum } udphdr_t; // sizeof(tcphdr_t) = 20 typedef struct tcphdr_s { uint16_t source; // source port uint16_t dest; // dest port uint32_t seq; // sequence uint32_t ack_seq; #if BYTE_ORDER == LITTLE_ENDIAN uint16_t res1:4; uint16_t doff:4; uint16_t fin:1; uint16_t syn:1; uint16_t rst:1; uint16_t psh:1; uint16_t ack:1; uint16_t urg:1; uint16_t res2:2; #elif BYTE_ORDER == BIG_ENDIAN uint16_t doff:4; uint16_t res1:4; uint16_t res2:2; uint16_t urg:1; uint16_t ack:1; uint16_t psh:1; uint16_t rst:1; uint16_t syn:1; uint16_t fin:1; #else #error "BYTE_ORDER undefined!" #endif uint16_t window; uint16_t check; // checksum uint16_t urg_ptr; // urgent pointer } tcphdr_t; //----------------------icmp---------------------------------- #define ICMP_ECHOREPLY 0 /* Echo Reply */ #define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ #define ICMP_SOURCE_QUENCH 4 /* Source Quench */ #define ICMP_REDIRECT 5 /* Redirect (change route) */ #define ICMP_ECHO 8 /* Echo Request */ #define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ #define ICMP_PARAMETERPROB 12 /* Parameter Problem */ #define ICMP_TIMESTAMP 13 /* Timestamp Request */ #define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ #define ICMP_INFO_REQUEST 15 /* Information Request */ #define ICMP_INFO_REPLY 16 /* Information Reply */ #define ICMP_ADDRESS 17 /* Address Mask Request */ #define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ //----------------------icmpv6-------------------------------- #define ICMP6_ECHO_REQUEST 128 /* ICMPv6 Echo Request */ #define ICMP6_ECHO_REPLY 129 /* ICMPv6 Echo Reply */ // sizeof(icmphdr_t) = 8 typedef struct icmphdr_s { uint8_t type; // message type uint8_t code; // type sub-code uint16_t checksum; union { struct { uint16_t id; uint16_t sequence; } echo; uint32_t gateway; struct { uint16_t reserved; uint16_t mtu; } frag; } un; } icmphdr_t; typedef struct icmp_s { uint8_t icmp_type; uint8_t icmp_code; uint16_t icmp_cksum; union { uint8_t ih_pptr; struct in_addr ih_gwaddr; struct ih_idseq { uint16_t icd_id; uint16_t icd_seq; } ih_idseq; uint32_t ih_void; struct ih_pmtu { uint16_t ipm_void; uint16_t ipm_nextmtu; } ih_pmtu; struct ih_rtradv { uint8_t irt_num_addrs; uint8_t irt_wpa; uint16_t irt_lifetime; } ih_rtradv; } icmp_hun; #define icmp_pptr icmp_hun.ih_pptr #define icmp_gwaddr icmp_hun.ih_gwaddr #define icmp_id icmp_hun.ih_idseq.icd_id #define icmp_seq icmp_hun.ih_idseq.icd_seq #define icmp_void icmp_hun.ih_void #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void #define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu #define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs #define icmp_wpa icmp_hun.ih_rtradv.irt_wpa #define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime union { struct { uint32_t its_otime; uint32_t its_rtime; uint32_t its_ttime; } id_ts; /* struct { struct ip idi_ip; } id_ip; struct icmp_ra_addr id_radv; */ uint32_t id_mask; uint8_t id_data[1]; } icmp_dun; #define icmp_otime icmp_dun.id_ts.its_otime #define icmp_rtime icmp_dun.id_ts.its_rtime #define icmp_ttime icmp_dun.id_ts.its_ttime #define icmp_ip icmp_dun.id_ip.idi_ip #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data } icmp_t; //#endif static inline uint16_t checksum(uint8_t* buf, int len) { unsigned int sum = 0; uint16_t* ptr = (uint16_t*)buf; while(len > 1) { sum += *ptr++; len -= 2; } if(len) { sum += *(uint8_t*)ptr; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (uint16_t)(~sum); }; #endif // HV_NETINET_H_ ================================================ FILE: base/queue.h ================================================ #ifndef HV_QUEUE_H_ #define HV_QUEUE_H_ /* * queue * FIFO: push_back,pop_front * stack * LIFO: push_back,pop_back */ #include // for assert #include // for NULL #include // for malloc,realloc,free #include // for memset,memmove #include "hbase.h" // for HV_ALLOC, HV_FREE #define QUEUE_INIT_SIZE 16 // #include // typedef std::deque qtype; #define QUEUE_DECL(type, qtype) \ struct qtype { \ type* ptr; \ size_t size; \ size_t maxsize;\ size_t _offset;\ }; \ typedef struct qtype qtype;\ \ static inline type* qtype##_data(qtype* p) {\ return p->ptr + p->_offset;\ }\ \ static inline int qtype##_size(qtype* p) {\ return p->size;\ }\ \ static inline int qtype##_maxsize(qtype* p) {\ return p->maxsize;\ }\ \ static inline int qtype##_empty(qtype* p) {\ return p->size == 0;\ }\ \ static inline type* qtype##_front(qtype* p) {\ return p->size == 0 ? NULL : p->ptr + p->_offset;\ }\ \ static inline type* qtype##_back(qtype* p) {\ return p->size == 0 ? NULL : p->ptr + p->_offset + p->size - 1;\ }\ \ static inline void qtype##_init(qtype* p, int maxsize) {\ p->_offset = 0;\ p->size = 0;\ p->maxsize = maxsize;\ HV_ALLOC(p->ptr, sizeof(type) * maxsize);\ }\ \ static inline void qtype##_clear(qtype* p) {\ p->_offset = 0;\ p->size = 0;\ memset(p->ptr, 0, sizeof(type) * p->maxsize);\ }\ \ static inline void qtype##_cleanup(qtype* p) {\ HV_FREE(p->ptr);\ p->_offset = p->size = p->maxsize = 0;\ }\ \ static inline void qtype##_resize(qtype* p, int maxsize) {\ if (maxsize == 0) maxsize = QUEUE_INIT_SIZE;\ p->ptr = (type*)hv_realloc(p->ptr, sizeof(type) * maxsize, sizeof(type) * p->maxsize);\ p->maxsize = maxsize;\ }\ \ static inline void qtype##_double_resize(qtype* p) {\ qtype##_resize(p, p->maxsize * 2);\ }\ \ static inline void qtype##_push_back(qtype* p, type* elem) {\ if (p->size == p->maxsize) {\ qtype##_double_resize(p);\ }\ else if (p->_offset + p->size == p->maxsize) {\ memmove(p->ptr, p->ptr + p->_offset, sizeof(type) * p->size);\ p->_offset = 0;\ }\ p->ptr[p->_offset + p->size] = *elem;\ p->size++;\ }\ static inline void qtype##_pop_front(qtype* p) {\ assert(p->size > 0);\ p->size--;\ if (++p->_offset == p->maxsize) p->_offset = 0;\ }\ \ static inline void qtype##_pop_back(qtype* p) {\ assert(p->size > 0);\ p->size--;\ }\ #endif // HV_QUEUE_H_ ================================================ FILE: base/rbtree.c ================================================ /* Red Black Trees (C) 1999 Andrea Arcangeli (C) 2002 David Woodhouse This program 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA linux/lib/rbtree.c */ #include "rbtree.h" static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) { struct rb_node *right = node->rb_right; if ((node->rb_right = right->rb_left)) right->rb_left->rb_parent = node; right->rb_left = node; if ((right->rb_parent = node->rb_parent)) { if (node == node->rb_parent->rb_left) node->rb_parent->rb_left = right; else node->rb_parent->rb_right = right; } else root->rb_node = right; node->rb_parent = right; } static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) { struct rb_node *left = node->rb_left; if ((node->rb_left = left->rb_right)) left->rb_right->rb_parent = node; left->rb_right = node; if ((left->rb_parent = node->rb_parent)) { if (node == node->rb_parent->rb_right) node->rb_parent->rb_right = left; else node->rb_parent->rb_left = left; } else root->rb_node = left; node->rb_parent = left; } void rb_insert_color(struct rb_node *node, struct rb_root *root) { struct rb_node *parent, *gparent; while ((parent = node->rb_parent) && parent->rb_color == RB_RED) { gparent = parent->rb_parent; if (parent == gparent->rb_left) { { register struct rb_node *uncle = gparent->rb_right; if (uncle && uncle->rb_color == RB_RED) { uncle->rb_color = RB_BLACK; parent->rb_color = RB_BLACK; gparent->rb_color = RB_RED; node = gparent; continue; } } if (parent->rb_right == node) { register struct rb_node *tmp; __rb_rotate_left(parent, root); tmp = parent; parent = node; node = tmp; } parent->rb_color = RB_BLACK; gparent->rb_color = RB_RED; __rb_rotate_right(gparent, root); } else { { register struct rb_node *uncle = gparent->rb_left; if (uncle && uncle->rb_color == RB_RED) { uncle->rb_color = RB_BLACK; parent->rb_color = RB_BLACK; gparent->rb_color = RB_RED; node = gparent; continue; } } if (parent->rb_left == node) { register struct rb_node *tmp; __rb_rotate_right(parent, root); tmp = parent; parent = node; node = tmp; } parent->rb_color = RB_BLACK; gparent->rb_color = RB_RED; __rb_rotate_left(gparent, root); } } root->rb_node->rb_color = RB_BLACK; } static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, struct rb_root *root) { struct rb_node *other; while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node) { if (parent->rb_left == node) { other = parent->rb_right; if (other->rb_color == RB_RED) { other->rb_color = RB_BLACK; parent->rb_color = RB_RED; __rb_rotate_left(parent, root); other = parent->rb_right; } if ((!other->rb_left || other->rb_left->rb_color == RB_BLACK) && (!other->rb_right || other->rb_right->rb_color == RB_BLACK)) { other->rb_color = RB_RED; node = parent; parent = node->rb_parent; } else { if (!other->rb_right || other->rb_right->rb_color == RB_BLACK) { register struct rb_node *o_left; if ((o_left = other->rb_left)) o_left->rb_color = RB_BLACK; other->rb_color = RB_RED; __rb_rotate_right(other, root); other = parent->rb_right; } other->rb_color = parent->rb_color; parent->rb_color = RB_BLACK; if (other->rb_right) other->rb_right->rb_color = RB_BLACK; __rb_rotate_left(parent, root); node = root->rb_node; break; } } else { other = parent->rb_left; if (other->rb_color == RB_RED) { other->rb_color = RB_BLACK; parent->rb_color = RB_RED; __rb_rotate_right(parent, root); other = parent->rb_left; } if ((!other->rb_left || other->rb_left->rb_color == RB_BLACK) && (!other->rb_right || other->rb_right->rb_color == RB_BLACK)) { other->rb_color = RB_RED; node = parent; parent = node->rb_parent; } else { if (!other->rb_left || other->rb_left->rb_color == RB_BLACK) { register struct rb_node *o_right; if ((o_right = other->rb_right)) o_right->rb_color = RB_BLACK; other->rb_color = RB_RED; __rb_rotate_left(other, root); other = parent->rb_left; } other->rb_color = parent->rb_color; parent->rb_color = RB_BLACK; if (other->rb_left) other->rb_left->rb_color = RB_BLACK; __rb_rotate_right(parent, root); node = root->rb_node; break; } } } if (node) node->rb_color = RB_BLACK; } void rb_erase(struct rb_node *node, struct rb_root *root) { struct rb_node *child, *parent; int color; if (!node->rb_left) child = node->rb_right; else if (!node->rb_right) child = node->rb_left; else { struct rb_node *old = node, *left; node = node->rb_right; while ((left = node->rb_left)) node = left; child = node->rb_right; parent = node->rb_parent; color = node->rb_color; if (child) child->rb_parent = parent; if (parent) { if (parent->rb_left == node) parent->rb_left = child; else parent->rb_right = child; } else root->rb_node = child; if (node->rb_parent == old) parent = node; node->rb_parent = old->rb_parent; node->rb_color = old->rb_color; node->rb_right = old->rb_right; node->rb_left = old->rb_left; if (old->rb_parent) { if (old->rb_parent->rb_left == old) old->rb_parent->rb_left = node; else old->rb_parent->rb_right = node; } else root->rb_node = node; old->rb_left->rb_parent = node; if (old->rb_right) old->rb_right->rb_parent = node; goto color; } parent = node->rb_parent; color = node->rb_color; if (child) child->rb_parent = parent; if (parent) { if (parent->rb_left == node) parent->rb_left = child; else parent->rb_right = child; } else root->rb_node = child; color: if (color == RB_BLACK) __rb_erase_color(child, parent, root); } /* * This function returns the first node (in sort order) of the tree. */ struct rb_node *rb_first(struct rb_root *root) { struct rb_node *n; n = root->rb_node; if (!n) return (struct rb_node *)0; while (n->rb_left) n = n->rb_left; return n; } struct rb_node *rb_last(struct rb_root *root) { struct rb_node *n; n = root->rb_node; if (!n) return (struct rb_node *)0; while (n->rb_right) n = n->rb_right; return n; } struct rb_node *rb_next(struct rb_node *node) { /* If we have a right-hand child, go down and then left as far as we can. */ if (node->rb_right) { node = node->rb_right; while (node->rb_left) node = node->rb_left; return node; } /* No right-hand children. Everything down and left is smaller than us, so any 'next' node must be in the general direction of our parent. Go up the tree; any time the ancestor is a right-hand child of its parent, keep going up. First time it's a left-hand child of its parent, said parent is our 'next' node. */ while (node->rb_parent && node == node->rb_parent->rb_right) node = node->rb_parent; return node->rb_parent; } struct rb_node *rb_prev(struct rb_node *node) { /* If we have a left-hand child, go down and then right as far as we can. */ if (node->rb_left) { node = node->rb_left; while (node->rb_right) node = node->rb_right; return node; } /* No left-hand children. Go up till we find an ancestor which is a right-hand child of its parent */ while (node->rb_parent && node == node->rb_parent->rb_left) node = node->rb_parent; return node->rb_parent; } void rb_replace_node(struct rb_node *victim, struct rb_node *newnode, struct rb_root *root) { struct rb_node *parent = victim->rb_parent; /* Set the surrounding nodes to point to the replacement */ if (parent) { if (victim == parent->rb_left) parent->rb_left = newnode; else parent->rb_right = newnode; } else { root->rb_node = newnode; } if (victim->rb_left) victim->rb_left->rb_parent = newnode; if (victim->rb_right) victim->rb_right->rb_parent = newnode; /* Copy the pointers/colour from the victim to the replacement */ *newnode = *victim; } ================================================ FILE: base/rbtree.h ================================================ /* Red Black Trees (C) 1999 Andrea Arcangeli This program 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA linux/include/linux/rbtree.h To use rbtrees you'll have to implement your own insert and search cores. This will avoid us to use callbacks and to drop drammatically performances. I know it's not the cleaner way, but in C (not in C++) to get performances and genericity... Some example of insert and search follows here. The search is a plain normal search over an ordered tree. The insert instead must be implemented in two steps: First, the code must insert the element in order as a red leaf in the tree, and then the support library function rb_insert_color() must be called. Such function will do the not trivial work to rebalance the rbtree, if necessary. ----------------------------------------------------------------------- static inline struct page * rb_search_page_cache(struct inode * inode, unsigned long offset) { struct rb_node * n = inode->i_rb_page_cache.rb_node; struct page * page; while (n) { page = rb_entry(n, struct page, rb_page_cache); if (offset < page->offset) n = n->rb_left; else if (offset > page->offset) n = n->rb_right; else return page; } return NULL; } static inline struct page * __rb_insert_page_cache(struct inode * inode, unsigned long offset, struct rb_node * node) { struct rb_node ** p = &inode->i_rb_page_cache.rb_node; struct rb_node * parent = NULL; struct page * page; while (*p) { parent = *p; page = rb_entry(parent, struct page, rb_page_cache); if (offset < page->offset) p = &(*p)->rb_left; else if (offset > page->offset) p = &(*p)->rb_right; else return page; } rb_link_node(node, parent, p); return NULL; } static inline struct page * rb_insert_page_cache(struct inode * inode, unsigned long offset, struct rb_node * node) { struct page * ret; if ((ret = __rb_insert_page_cache(inode, offset, node))) goto out; rb_insert_color(node, &inode->i_rb_page_cache); out: return ret; } ----------------------------------------------------------------------- */ #ifndef _LINUX_RBTREE_H #define _LINUX_RBTREE_H #include // for uintptr_t struct rb_node { struct rb_node *rb_parent; struct rb_node *rb_right; struct rb_node *rb_left; char rb_color; #define RB_RED 0 #define RB_BLACK 1 }; struct rb_root { struct rb_node *rb_node; }; #define RB_ROOT (struct rb_root){ (struct rb_node *)0, } #define rb_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(uintptr_t)(&((type *)0)->member))) #ifdef __cplusplus extern "C" { #endif void rb_insert_color(struct rb_node *node, struct rb_root *root); void rb_erase(struct rb_node *node, struct rb_root *root); /* Find logical next and previous nodes in a tree */ struct rb_node *rb_next(struct rb_node *); struct rb_node *rb_prev(struct rb_node *); struct rb_node *rb_first(struct rb_root *); struct rb_node *rb_last(struct rb_root *); /* Fast replacement of a single node without remove/rebalance/add/rebalance */ void rb_replace_node(struct rb_node *victim, struct rb_node *newnode, struct rb_root *root); #ifdef __cplusplus } #endif static inline void rb_link_node(struct rb_node *node, struct rb_node *parent, struct rb_node **link) { node->rb_parent = parent; node->rb_color = RB_RED; node->rb_left = node->rb_right = (struct rb_node *)0; *link = node; } #endif /* _LINUX_RBTREE_H */ ================================================ FILE: cert/cacert.pem ================================================ ## ## Bundle of CA Root Certificates ## ## Certificate data from Mozilla as of: Wed Aug 28 03:12:10 2019 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates ## file (certdata.txt). This file can be found in the mozilla source tree: ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt ## ## It contains the certificates in PEM format and therefore ## can be directly used with curl / libcurl / php_curl, or with ## an Apache+mod_ssl webserver for SSL client authentication. ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.27. ## SHA256: fffa309937c3be940649293f749b8207fabc6eb224e50e4bb3f2c5e44e0d6a6b ## GlobalSign Root CA ================== -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- GlobalSign Root CA - R2 ======================= -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- Verisign Class 3 Public Primary Certification Authority - G3 ============================================================ -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- Entrust.net Premium 2048 Secure Server CA ========================================= -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= -----END CERTIFICATE----- Baltimore CyberTrust Root ========================= -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- AddTrust External Root ====================== -----BEGIN CERTIFICATE----- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 +iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy 2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- Entrust Root Certification Authority ==================================== -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- GeoTrust Global CA ================== -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet 8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm Mw== -----END CERTIFICATE----- GeoTrust Universal CA ===================== -----BEGIN CERTIFICATE----- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs 7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d 8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI P/rmMuGNG2+k5o7Y+SlIis5z/iw= -----END CERTIFICATE----- GeoTrust Universal CA 2 ======================= -----BEGIN CERTIFICATE----- MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP 20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG 8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 +/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ 4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- Comodo AAA Services root ======================== -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- QuoVadis Root CA ================ -----BEGIN CERTIFICATE----- MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi 5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi 5nrQNiOKSnQ2+Q== -----END CERTIFICATE----- QuoVadis Root CA 2 ================== -----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt 66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK +JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II 4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- QuoVadis Root CA 3 ================== -----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- Security Communication Root CA ============================== -----BEGIN CERTIFICATE----- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi FL39vmwLAw== -----END CERTIFICATE----- Sonera Class 2 Root CA ====================== -----BEGIN CERTIFICATE----- MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 /Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt 0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH llpwrN9M -----END CERTIFICATE----- XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- Go Daddy Class 2 CA =================== -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b vZ8= -----END CERTIFICATE----- Starfield Class 2 CA ==================== -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- Taiwan GRCA =========== -----BEGIN CERTIFICATE----- MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O 1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk 7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy +fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS -----END CERTIFICATE----- DigiCert Assured ID Root CA =========================== -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- DigiCert Global Root CA ======================= -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- DigiCert High Assurance EV Root CA ================================== -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K -----END CERTIFICATE----- Certplus Class 2 Primary CA =========================== -----BEGIN CERTIFICATE----- MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR 5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ 7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW //1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 l7+ijrRU -----END CERTIFICATE----- DST Root CA X3 ============== -----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ -----END CERTIFICATE----- SwissSign Gold CA - G2 ====================== -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR 7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm 5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr 44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- SwissSign Silver CA - G2 ======================== -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG 9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm +/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH 6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P 4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- GeoTrust Primary Certification Authority ======================================== -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG 1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= -----END CERTIFICATE----- thawte Primary Root CA ====================== -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ 1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== -----END CERTIFICATE----- VeriSign Class 3 Public Primary Certification Authority - G5 ============================================================ -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq -----END CERTIFICATE----- SecureTrust CA ============== -----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- Secure Global CA ================ -----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW -----END CERTIFICATE----- COMODO Certification Authority ============================== -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== -----END CERTIFICATE----- Network Solutions Certificate Authority ======================================= -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- COMODO ECC Certification Authority ================================== -----BEGIN CERTIFICATE----- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- OISTE WISeKey Global Root GA CA =============================== -----BEGIN CERTIFICATE----- MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ /yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 +vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= -----END CERTIFICATE----- Certigna ======== -----BEGIN CERTIFICATE----- MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- Deutsche Telekom Root CA 2 ========================== -----BEGIN CERTIFICATE----- MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU Cm26OWMohpLzGITY+9HPBVZkVw== -----END CERTIFICATE----- Cybertrust Global Root ====================== -----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW WL1WMRJOEcgh4LMRkWXbtKaIOM5V -----END CERTIFICATE----- ePKI Root Certification Authority ================================= -----BEGIN CERTIFICATE----- MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= -----END CERTIFICATE----- certSIGN ROOT CA ================ -----BEGIN CERTIFICATE----- MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD -----END CERTIFICATE----- GeoTrust Primary Certification Authority - G3 ============================================= -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr 2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt -----END CERTIFICATE----- thawte Primary Root CA - G2 =========================== -----BEGIN CERTIFICATE----- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== -----END CERTIFICATE----- thawte Primary Root CA - G3 =========================== -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC +BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY 7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC 8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= -----END CERTIFICATE----- GeoTrust Primary Certification Authority - G2 ============================================= -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 npaqBA+K -----END CERTIFICATE----- VeriSign Universal Root Certification Authority =============================================== -----BEGIN CERTIFICATE----- MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 mJO37M2CYfE45k+XmCpajQ== -----END CERTIFICATE----- VeriSign Class 3 Public Primary Certification Authority - G4 ============================================================ -----BEGIN CERTIFICATE----- MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== -----END CERTIFICATE----- NetLock Arany (Class Gold) Főtanúsítvány ======================================== -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- Staat der Nederlanden Root CA - G2 ================================== -----BEGIN CERTIFICATE----- MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ 5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz +51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm 66+KAQ== -----END CERTIFICATE----- Hongkong Post Root CA 1 ======================= -----BEGIN CERTIFICATE----- MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== -----END CERTIFICATE----- SecureSign RootCA11 =================== -----BEGIN CERTIFICATE----- MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= -----END CERTIFICATE----- Microsec e-Szigno Root CA 2009 ============================== -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi LXpUq3DDfSJlgnCW -----END CERTIFICATE----- GlobalSign Root CA - R3 ======================= -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r kpeDMdmztcpHWD9f -----END CERTIFICATE----- Autoridad de Certificacion Firmaprofesional CIF A62634068 ========================================================= -----BEGIN CERTIFICATE----- MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V -----END CERTIFICATE----- Izenpe.com ========== -----BEGIN CERTIFICATE----- MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU +zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK 0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ 0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- Chambers of Commerce Root - 2008 ================================ -----BEGIN CERTIFICATE----- MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ 0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH 3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF 9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ -----END CERTIFICATE----- Global Chambersign Root - 2008 ============================== -----BEGIN CERTIFICATE----- MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB /gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp 1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG /5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg 9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B -----END CERTIFICATE----- Go Daddy Root Certificate Authority - G2 ======================================== -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 -----END CERTIFICATE----- Starfield Root Certificate Authority - G2 ========================================= -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 -----END CERTIFICATE----- Starfield Services Root Certificate Authority - G2 ================================================== -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 -----END CERTIFICATE----- AffirmTrust Commercial ====================== -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= -----END CERTIFICATE----- AffirmTrust Networking ====================== -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- AffirmTrust Premium =================== -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== -----END CERTIFICATE----- AffirmTrust Premium ECC ======================= -----BEGIN CERTIFICATE----- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM eQ== -----END CERTIFICATE----- Certum Trusted Network CA ========================= -----BEGIN CERTIFICATE----- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= -----END CERTIFICATE----- TWCA Root Certification Authority ================================= -----BEGIN CERTIFICATE----- MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== -----END CERTIFICATE----- Security Communication RootCA2 ============================== -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- EC-ACC ====== -----BEGIN CERTIFICATE----- MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D 5EI= -----END CERTIFICATE----- Hellenic Academic and Research Institutions RootCA 2011 ======================================================= -----BEGIN CERTIFICATE----- MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI 1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa 71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u 8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH 3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD /md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N 7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 -----END CERTIFICATE----- Actalis Authentication Root CA ============================== -----BEGIN CERTIFICATE----- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC 4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo 2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== -----END CERTIFICATE----- Trustis FPS Root CA =================== -----BEGIN CERTIFICATE----- MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P 8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl iB6XzCGcKQENZetX2fNXlrtIzYE= -----END CERTIFICATE----- Buypass Class 2 Root CA ======================= -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn 9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b /+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN rJgWVqA= -----END CERTIFICATE----- Buypass Class 3 Root CA ======================= -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR 5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh 7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH 2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV /afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz 6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi Cp/HuZc= -----END CERTIFICATE----- T-TeleSec GlobalRoot Class 3 ============================ -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK 9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W 0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== -----END CERTIFICATE----- EE Certification Centre Root CA =============================== -----BEGIN CERTIFICATE----- MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw 93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU 3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM dcGWxZ0= -----END CERTIFICATE----- D-TRUST Root Class 3 CA 2 2009 ============================== -----BEGIN CERTIFICATE----- MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ 4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm 2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= -----END CERTIFICATE----- D-TRUST Root Class 3 CA 2 EV 2009 ================================= -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T 7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv w9y4AyHqnxbxLFS1 -----END CERTIFICATE----- CA Disig Root R2 ================ -----BEGIN CERTIFICATE----- MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa 5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV 7+ZtsH8tZ/3zbBt1RqPlShfppNcL -----END CERTIFICATE----- ACCVRAIZ1 ========= -----BEGIN CERTIFICATE----- MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ 0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR 5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J 9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd 3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p EfbRD0tVNEYqi4Y7 -----END CERTIFICATE----- TWCA Global Root CA =================== -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M 8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg /eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= -----END CERTIFICATE----- TeliaSonera Root CA v1 ====================== -----BEGIN CERTIFICATE----- MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ 6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA 3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx 0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- E-Tugra Certification Authority =============================== -----BEGIN CERTIFICATE----- MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB /wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G C7TbO6Orb1wdtn7os4I07QZcJA== -----END CERTIFICATE----- T-TeleSec GlobalRoot Class 2 ============================ -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR 3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== -----END CERTIFICATE----- Atos TrustedRoot 2011 ===================== -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr 54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G 3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed -----END CERTIFICATE----- QuoVadis Root CA 1 G3 ===================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV 7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX 9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP +V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh 3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV hMJKzRwuJIczYOXD -----END CERTIFICATE----- QuoVadis Root CA 2 G3 ===================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD 6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr O3jtZsSOeWmD3n+M -----END CERTIFICATE----- QuoVadis Root CA 3 G3 ===================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe 6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX 0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 PpxxVJkES/1Y+Zj0 -----END CERTIFICATE----- DigiCert Assured ID Root G2 =========================== -----BEGIN CERTIFICATE----- MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH 35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv 0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo IhNzbM8m9Yop5w== -----END CERTIFICATE----- DigiCert Assured ID Root G3 =========================== -----BEGIN CERTIFICATE----- MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy 1vUhZscv6pZjamVFkpUBtA== -----END CERTIFICATE----- DigiCert Global Root G2 ======================= -----BEGIN CERTIFICATE----- MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO 3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu 5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl MrY= -----END CERTIFICATE----- DigiCert Global Root G3 ======================= -----BEGIN CERTIFICATE----- MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y 3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 VOKa5Vt8sycX -----END CERTIFICATE----- DigiCert Trusted Root G4 ======================== -----BEGIN CERTIFICATE----- MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy 7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN 5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb /UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa 5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP 82Z+ -----END CERTIFICATE----- COMODO RSA Certification Authority ================================== -----BEGIN CERTIFICATE----- MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ 5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX 2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I LaZRfyHBNVOFBkpdn627G190 -----END CERTIFICATE----- USERTrust RSA Certification Authority ===================================== -----BEGIN CERTIFICATE----- MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz 0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O +T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq /nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ 7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM 8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 -----END CERTIFICATE----- USERTrust ECC Certification Authority ===================================== -----BEGIN CERTIFICATE----- MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu 9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= -----END CERTIFICATE----- GlobalSign ECC Root CA - R4 =========================== -----BEGIN CERTIFICATE----- MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= -----END CERTIFICATE----- GlobalSign ECC Root CA - R5 =========================== -----BEGIN CERTIFICATE----- MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- Staat der Nederlanden Root CA - G3 ================================== -----BEGIN CERTIFICATE----- MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp 07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE 41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA 8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b 8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq 1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= -----END CERTIFICATE----- Staat der Nederlanden EV Root CA ================================ -----BEGIN CERTIFICATE----- MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r 0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr 08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV 0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd 74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq 5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi 5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== -----END CERTIFICATE----- IdenTrust Commercial Root CA 1 ============================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi 1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl 3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH 6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe 2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R cGzM7vRX+Bi6hG6H -----END CERTIFICATE----- IdenTrust Public Sector Root CA 1 ================================= -----BEGIN CERTIFICATE----- MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL 4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ 3Wl9af0AVqW3rLatt8o+Ae+c -----END CERTIFICATE----- Entrust Root Certification Authority - G2 ========================================= -----BEGIN CERTIFICATE----- MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP /vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO e4pIb4tF9g== -----END CERTIFICATE----- Entrust Root Certification Authority - EC1 ========================================== -----BEGIN CERTIFICATE----- MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef 9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G -----END CERTIFICATE----- CFCA EV ROOT ============ -----BEGIN CERTIFICATE----- MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD 7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB /wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua 4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- OISTE WISeKey Global Root GB CA =============================== -----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk 9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= -----END CERTIFICATE----- SZAFIR ROOT CA2 =============== -----BEGIN CERTIFICATE----- MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE 2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul 4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 +/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== -----END CERTIFICATE----- Certum Trusted Network CA 2 =========================== -----BEGIN CERTIFICATE----- MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ 9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 zAYspsbiDrW5viSP -----END CERTIFICATE----- Hellenic Academic and Research Institutions RootCA 2015 ======================================================= -----BEGIN CERTIFICATE----- MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ 6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn 82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q p/UsQu0yrbYhnr68 -----END CERTIFICATE----- Hellenic Academic and Research Institutions ECC RootCA 2015 =========================================================== -----BEGIN CERTIFICATE----- MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR -----END CERTIFICATE----- ISRG Root X1 ============ -----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ 4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf 1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY 9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV 0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ m+kXQ99b21/+jh5Xos1AnX5iItreGCc= -----END CERTIFICATE----- AC RAIZ FNMT-RCM ================ -----BEGIN CERTIFICATE----- MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou 08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ 47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW +YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d 8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm 5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= -----END CERTIFICATE----- Amazon Root CA 1 ================ -----BEGIN CERTIFICATE----- MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy 8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa 2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 -----END CERTIFICATE----- Amazon Root CA 2 ================ -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ 3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY +gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= -----END CERTIFICATE----- Amazon Root CA 3 ================ -----BEGIN CERTIFICATE----- MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== -----END CERTIFICATE----- Amazon Root CA 4 ================ -----BEGIN CERTIFICATE----- MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN /sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri 83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- LuxTrust Global Root 2 ====================== -----BEGIN CERTIFICATE----- MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2 xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm 1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/ a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB /zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5 Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT +Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW 7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt /f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc 7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr -----END CERTIFICATE----- TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 ============================================= -----BEGIN CERTIFICATE----- MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= -----END CERTIFICATE----- GDCA TrustAUTH R5 ROOT ====================== -----BEGIN CERTIFICATE----- MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ 9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4 oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx 9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9 H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35 6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd +PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ 8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv /EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== -----END CERTIFICATE----- TrustCor RootCert CA-1 ====================== -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4 pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0 JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw /Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5 mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P 3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk= -----END CERTIFICATE----- TrustCor RootCert CA-2 ====================== -----BEGIN CERTIFICATE----- MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0 eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0 IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1 oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1 /p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh 8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU 2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv 2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3 S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ -----END CERTIFICATE----- TrustCor ECA-1 ============== -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5 MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23 xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+ fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u /ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g== -----END CERTIFICATE----- SSL.com Root Certification Authority RSA ======================================== -----BEGIN CERTIFICATE----- MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8 P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2 UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8 1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k= -----END CERTIFICATE----- SSL.com Root Certification Authority ECC ======================================== -----BEGIN CERTIFICATE----- MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+ 8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z 5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl -----END CERTIFICATE----- SSL.com EV Root Certification Authority RSA R2 ============================================== -----BEGIN CERTIFICATE----- MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+ B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim 9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48 +qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1 ++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7 CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1 hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX 9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== -----END CERTIFICATE----- SSL.com EV Root Certification Authority ECC =========================================== -----BEGIN CERTIFICATE----- MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy 3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe 5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== -----END CERTIFICATE----- GlobalSign Root CA - R6 ======================= -----BEGIN CERTIFICATE----- MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE 3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+ azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP 0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0 lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr 3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1 0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= -----END CERTIFICATE----- OISTE WISeKey Global Root GC CA =============================== -----BEGIN CERTIFICATE----- MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- GTS Root R1 =========== -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv b3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIi MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx 9vaMf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7r aKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnW r4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqM LnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly 4cpk9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr 06zqkUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om 3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNu JLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEM BQADggIBADiWCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6ZXPYfcX3v73sv fuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZRgyFmxhE+885H7pwoHyXa/6xm ld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9b gsiG1eGZbYwE8na6SfZu6W0eX6DvJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq 4BjFbkerQUIpm/ZgDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWEr tXvM+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyyF62ARPBo pY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9SQ98POyDGCBDTtWTurQ0 sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdwsE3PYJ/HQcu51OyLemGhmW/HGY0dVHLql CFF1pkgl -----END CERTIFICATE----- GTS Root R2 =========== -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv b3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIi MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTuk k3LvCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo 7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWI m8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5Gm dFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbu ak7MkogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscsz cTJGr61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73Vululycsl aVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy 5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEM BQADggIBALZp8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiTz9D2PGcDFWEJ +YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiApJiS4wGWAqoC7o87xdFtCjMw c3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvbpxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3Da WsYDQvTtN6LwG1BUSw7YhN4ZKJmBR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5r n/WkhLx3+WuXrD5RRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56Gtmwfu Nmsk0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC5AwiWVIQ 7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiFizoHCBy69Y9Vmhh1fuXs gWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLnyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ld o/DUhgkC -----END CERTIFICATE----- GTS Root R3 =========== -----BEGIN CERTIFICATE----- MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg UjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcq hkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUU Rout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24Cej QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP 0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFukfCPAlaUs3L6JbyO5o91lAFJekazInXJ0 glMLfalAvWhgxeG4VDvBNhcl2MG9AjEAnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOa KaqW04MjyaR7YbPMAuhd -----END CERTIFICATE----- GTS Root R4 =========== -----BEGIN CERTIFICATE----- MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg UjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcq hkjOPQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa 6zzuhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqj QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV 2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0CMRw3J5QdCHojXohw0+WbhXRIjVhLfoI N+4Zba3bssx9BzT1YBkstTTZbyACMANxsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11x zPKwTdb+mciUqXWi4w== -----END CERTIFICATE----- UCA Global G2 Root ================== -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV 8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/ R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa 4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97 8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo 5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9 yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A== -----END CERTIFICATE----- UCA Extended Validation Root ============================ -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR 59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH 0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS 3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4 dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb +7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr dhh2n1ax -----END CERTIFICATE----- Certigna Root CA ================ -----BEGIN CERTIFICATE----- MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8 JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16 XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq 4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/ /TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of 1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq 7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3 4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd 8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS 6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= -----END CERTIFICATE----- emSign Root CA - G1 =================== -----BEGIN CERTIFICATE----- MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ 6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q +Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx iN66zB+Afko= -----END CERTIFICATE----- emSign ECC Root CA - G3 ======================= -----BEGIN CERTIFICATE----- MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc 58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj -----END CERTIFICATE----- emSign Root CA - C1 =================== -----BEGIN CERTIFICATE----- MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp /6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= -----END CERTIFICATE----- emSign ECC Root CA - C3 ======================= -----BEGIN CERTIFICATE----- MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd 6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== -----END CERTIFICATE----- Hongkong Post Root CA 3 ======================= -----BEGIN CERTIFICATE----- MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2 MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim 5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj 0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/ JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h +bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov +BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw 9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7 nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB 60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq dBb9HxEGmpv0 -----END CERTIFICATE----- ================================================ FILE: cert/gen.sh ================================================ openssl genrsa -out server.key 2048 openssl req -new -x509 -key server.key -out server.crt -days 3650 ================================================ FILE: cert/server.crt ================================================ -----BEGIN CERTIFICATE----- MIIDgjCCAmqgAwIBAgIJAL/XKTs4cCwRMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV BAYTAkNOMREwDwYDVQQIDAhTaGFuZ2hhaTERMA8GA1UEBwwIU2hhbmdoYWkxITAf BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA4MjkwNDA1NDda Fw0yOTA4MjYwNDA1NDdaMFYxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ2hh aTERMA8GA1UEBwwIU2hhbmdoYWkxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg UHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANJJ5DaZroEg N34H6A3uq5qDRlJe/ELhWcmtkj57cYb5U/T39C7dEjqGfhURb/NEuYbYoEb+4/lD xJOvn0qqXiJGPt0avecGhQUpggykEj4NZe6W1/WIX81Z1tF6QJZrpUDq4MD1S3KA ETvnTDv0bc6lvT/YDDb8qYMKGNZUTIQKpucdrIet9kDVIrXON4icJL9PDi/zFu3S e6feGsG7SAWv1ZInzF6wkEr8pCQc2Aab9R2BsbDsnVc8qZahfLniif7yDxiRbcEf P4P4cJ7YCD6T1Vyv7bDCnxSEJ+b+j4Ih5XVwHUeK2wG9rrNQ6Z4sSMrv1oSoxVfG mGdHHEhBN0ECAwEAAaNTMFEwHQYDVR0OBBYEFGPOMSeA6p3Vkf4uHdt5eRbrkoXU MB8GA1UdIwQYMBaAFGPOMSeA6p3Vkf4uHdt5eRbrkoXUMA8GA1UdEwEB/wQFMAMB Af8wDQYJKoZIhvcNAQELBQADggEBAEa3x7MzIBQvr43l6zuoK9SBoW6DET42yCRb YA6as/8fFYc4A1GqJStjvOgS0nIhBeCdyLJCy40U5ERhhVKqjPLLHHB4i7sv98Ac aXgVr91eUZcKeuiEkDHWRPCitkPj3p2v9J2VDAHpxfKvIB+r/q+7O4W6tjJT5fPq iUgdpr/R6uBFndBtGc+k65byxSQgvAvdM4kpGA8nnypT9i8SGVp0gB7lMG8avUTU zH16msecIEKLBHED40w9aiuOf3CnMDqGSTilP7p4gvMY4u+qm3zAXN29OHqoldbn j/A8RE9Q1F1H3G+eSltBuug3DBGp0q0EskxiqtfJbzW9G5fwGxM= -----END CERTIFICATE----- ================================================ FILE: cert/server.key ================================================ -----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA0knkNpmugSA3fgfoDe6rmoNGUl78QuFZya2SPntxhvlT9Pf0 Lt0SOoZ+FRFv80S5htigRv7j+UPEk6+fSqpeIkY+3Rq95waFBSmCDKQSPg1l7pbX 9YhfzVnW0XpAlmulQOrgwPVLcoARO+dMO/RtzqW9P9gMNvypgwoY1lRMhAqm5x2s h632QNUitc43iJwkv08OL/MW7dJ7p94awbtIBa/VkifMXrCQSvykJBzYBpv1HYGx sOydVzyplqF8ueKJ/vIPGJFtwR8/g/hwntgIPpPVXK/tsMKfFIQn5v6PgiHldXAd R4rbAb2us1DpnixIyu/WhKjFV8aYZ0ccSEE3QQIDAQABAoIBAG/JthbMdbbRAI7v 9w1I/lKCTKTHN8T59PhAXAj5KG2/J0GHenhbLzCLhIUAowmoVBP6HqH/KAO/YcW8 y6oujSIdQ5fYenFQxu/qk+bSZZw1FSXTbHRrDbqlcowjOCh+ivfKpLYO8A+rQv4c RCtvEdyTwNoqqLumbxppCLEPWSmrZOuw/EegeDMRspMpPNsFsk7mcl2w3jJjiX9D NB/yHZZzbZoTf/ayT/ca6FueKqPF52jIiuDzOncE1PqQ8hiPrXFIh4yZYCn1IpnK 48hotm3NSixpnag6UziwCRSoPsUCue8h2h3Tr690Lr/7LzILdtBJ+4Qxs3mU8Crz +bM7Xo0CgYEA9K94Gp0gyIxEiIPQ/zcOLeY2y3gUpS5LNaM6lxm82u4nsrC4FQJZ H72kV6YxvedmC1JZcYc6WiaAelkv9GqSekTMFv05rTsA4zQX59habsXPa5r3vzds NzgdjhDfwvWZCp3QXDG1n0wEMKJleG9+CK7khQ4doHmjQtCt0w16AxMCgYEA3AM9 qxJSOADePq0G4fJ+4jAr4MgsMBsWaGEWU0Z7pBaTj+hm0ULiwShWy9/bbxw+zZgL VqE0cCiqKsMZMFtZvwX89fIN71YLkyTbl5Y/Lb65HKfKI8a8LGSNNaAd6CG9vy2C krqDKoHILCQdBpT7tSi2vF57+uDxJDH6+VyZ0tsCgYEAsVE7o2W87TihLaEA4wJ9 1wtfKCJUK8QZorwwaHGxZ6JwyFDChg8WkSb4IsCAiZNYYtoBkYEi61O9hWx+kQxu LAcRM5O8qWn54azNqikil+Xnw54g7cR3OqkC2gImdf1PM99bsIQhj1giLTBygk2h sx8y4a1yEOo1QuVBIpJAmlsCgYEAv3NehXAC9dLjkny0oYeIHEG43PizYwUfQaNC byLFUquGqtKcLfrbISR+KxjYdV6J1BQ7wZ2z6Omp8l4lnCvR8+U9E7QXpi4lEl0f bVCEF8WAhcwInYtBkgvJyWFUxPwfhq4OkqoUm7elvauLSn/4bNNJ+K7riguWK14G vFl1TcMCgYEA9EDTbpBl1oXICe2xevuh1HJQ1eBXAXP0l3hy0h76czBoBlnoF13A 6TOy6iSE3tpEwGPZZ33goKZdKyBLXG3TmemthWMxjBHc31C55gpIIgYPlW4Blv35 djt8AlxF68VKIhY7CkaGhNmUpdSSfANHyirfw9rx70IRwRJfnZ5MN+M= -----END RSA PRIVATE KEY----- ================================================ FILE: cmake/ios.toolchain.cmake ================================================ # This file is part of the ios-cmake project. It was retrieved from # https://github.com/leetal/ios-cmake.git, which is a fork of # https://github.com/gerstrong/ios-cmake.git, which is a fork of # https://github.com/cristeab/ios-cmake.git, which is a fork of # https://code.google.com/p/ios-cmake/. Which in turn is based off of # the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which # are included with CMake 2.8.4 # # The ios-cmake project is licensed under the new BSD license. # # Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software, # Kitware, Inc., Insight Software Consortium. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # This file is based on the Platform/Darwin.cmake and # Platform/UnixPaths.cmake files which are included with CMake 2.8.4 # It has been altered for iOS development. # # Updated by Alex Stewart (alexs.mac@gmail.com) # # ***************************************************************************** # Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com) # under the BSD-3-Clause license # https://github.com/leetal/ios-cmake # ***************************************************************************** # # INFORMATION / HELP # ############################################################################### # OPTIONS # ############################################################################### # # PLATFORM: (default "OS64") # OS = Build for iPhoneOS. # OS64 = Build for arm64 iphoneOS. # OS64COMBINED = Build for arm64 x86_64 iphoneOS + iphoneOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) # SIMULATOR = Build for x86 i386 iphoneOS Simulator. # SIMULATOR64 = Build for x86_64 iphoneOS Simulator. # SIMULATORARM64 = Build for arm64 iphoneOS Simulator. # TVOS = Build for arm64 tvOS. # TVOSCOMBINED = Build for arm64 x86_64 tvOS + tvOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) # SIMULATOR_TVOS = Build for x86_64 tvOS Simulator. # WATCHOS = Build for armv7k arm64_32 for watchOS. # WATCHOSCOMBINED = Build for armv7k arm64_32 x86_64 watchOS + watchOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) # SIMULATOR_WATCHOS = Build for x86_64 for watchOS Simulator. # MAC = Build for x86_64 macOS. # MAC_ARM64 = Build for Apple Silicon macOS. # MAC_UNIVERSAL = Combined build for x86_64 and Apple Silicon on macOS. # MAC_CATALYST = Build for x86_64 macOS with Catalyst support (iOS toolchain on macOS). # Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS # MAC_CATALYST_ARM64 = Build for Apple Silicon macOS with Catalyst support (iOS toolchain on macOS). # Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS # # CMAKE_OSX_SYSROOT: Path to the SDK to use. By default this is # automatically determined from PLATFORM and xcodebuild, but # can also be manually specified (although this should not be required). # # CMAKE_DEVELOPER_ROOT: Path to the Developer directory for the platform # being compiled for. By default, this is automatically determined from # CMAKE_OSX_SYSROOT, but can also be manually specified (although this should # not be required). # # DEPLOYMENT_TARGET: Minimum SDK version to target. Default 2.0 on watchOS and 9.0 on tvOS+iOS # # NAMED_LANGUAGE_SUPPORT: # ON (default) = Will require "enable_language(OBJC) and/or enable_language(OBJCXX)" for full OBJC|OBJCXX support # OFF = Will embed the OBJC and OBJCXX flags into the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (legacy behavior, CMake version < 3.16) # # ENABLE_BITCODE: (ON|OFF) Enables or disables bitcode support. Default ON # # ENABLE_ARC: (ON|OFF) Enables or disables ARC support. Default ON (ARC enabled by default) # # ENABLE_VISIBILITY: (ON|OFF) Enables or disables symbol visibility support. Default OFF (visibility hidden by default) # # ENABLE_STRICT_TRY_COMPILE: (ON|OFF) Enables or disables strict try_compile() on all Check* directives (will run linker # to actually check if linking is possible). Default OFF (will set CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY) # # ARCHS: (armv7 armv7s armv7k arm64 arm64_32 i386 x86_64) If specified, will override the default architectures for the given PLATFORM # OS = armv7 armv7s arm64 (if applicable) # OS64 = arm64 (if applicable) # SIMULATOR = i386 # SIMULATOR64 = x86_64 # SIMULATORARM64 = arm64 # TVOS = arm64 # SIMULATOR_TVOS = x86_64 (i386 has since long been deprecated) # WATCHOS = armv7k arm64_32 (if applicable) # SIMULATOR_WATCHOS = x86_64 (i386 has since long been deprecated) # MAC = x86_64 # MAC_ARM64 = arm64 # MAC_UNIVERSAL = x86_64 arm64 # MAC_CATALYST = x86_64 # MAC_CATALYST_ARM64 = arm64 # # NOTE: When manually specifying ARCHS, put a semi-colon between the entries. E.g., -DARCHS="armv7;arm64" # ############################################################################### # END OPTIONS # ############################################################################### # # This toolchain defines the following properties (available via get_property()) for use externally: # # PLATFORM: The currently targeted platform. # XCODE_VERSION: Version number (not including Build version) of Xcode detected. # SDK_VERSION: Version of SDK being used. # OSX_ARCHITECTURES: Architectures being compiled for (generated from PLATFORM). # APPLE_TARGET_TRIPLE: Used by autoconf build systems. NOTE: If "ARCHS" is overridden, this will *NOT* be set! # # This toolchain defines the following macros for use externally: # # set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT) # A convenience macro for setting xcode specific properties on targets. # Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel # example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all"). # # find_host_package (PROGRAM ARGS) # A macro used to find executable programs on the host system, not within the # environment. Thanks to the android-cmake project for providing the # command. # cmake_minimum_required(VERSION 3.8.0) # CMake invokes the toolchain file twice during the first build, but only once during subsequent rebuilds. if(DEFINED ENV{_IOS_TOOLCHAIN_HAS_RUN}) return() endif() set(ENV{_IOS_TOOLCHAIN_HAS_RUN} true) # List of supported platform values list(APPEND _supported_platforms "OS" "OS64" "OS64COMBINED" "SIMULATOR" "SIMULATOR64" "SIMULATORARM64" "TVOS" "TVOSCOMBINED" "SIMULATOR_TVOS" "WATCHOS" "WATCHOSCOMBINED" "SIMULATOR_WATCHOS" "MAC" "MAC_ARM64" "MAC_UNIVERSAL" "MAC_CATALYST" "MAC_CATALYST_ARM64") # Cache what generator is used set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}") # Check if using a CMake version capable of building combined FAT builds (simulator and target slices combined in one static lib) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") set(MODERN_CMAKE YES) endif() # Get the Xcode version being used. # Problem: CMake runs toolchain files multiple times, but can't read cache variables on some runs. # Workaround: On the first run (in which cache variables are always accessible), set an intermediary environment variable. # # NOTE: This pattern is used in many places in this toolchain to speed up checks of all sorts if(DEFINED XCODE_VERSION_INT) # Environment variables are always preserved. set(ENV{_XCODE_VERSION_INT} "${XCODE_VERSION_INT}") elseif(DEFINED ENV{_XCODE_VERSION_INT}) set(XCODE_VERSION_INT "$ENV{_XCODE_VERSION_INT}") elseif(NOT DEFINED XCODE_VERSION_INT) find_program(XCODEBUILD_EXECUTABLE xcodebuild) if(NOT XCODEBUILD_EXECUTABLE) message(FATAL_ERROR "xcodebuild not found. Please install either the standalone commandline tools or Xcode.") endif() execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version OUTPUT_VARIABLE XCODE_VERSION_INT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION_INT "${XCODE_VERSION_INT}") string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION_INT "${XCODE_VERSION_INT}") set(XCODE_VERSION_INT "${XCODE_VERSION_INT}" CACHE INTERNAL "") endif() # Assuming that xcode 12.0 is installed you most probably have ios sdk 14.0 or later installed (tested on Big Sur) # if you don't set a deployment target it will be set the way you only get 64-bit builds if(NOT DEFINED DEPLOYMENT_TARGET AND XCODE_VERSION_INT VERSION_GREATER 12.0) # Temporarily fix the arm64 issues in CMake install-combined by excluding arm64 for simulator builds (needed for Apple Silicon...) set(CMAKE_XCODE_ATTRIBUTE_EXCLUDED_ARCHS[sdk=iphonesimulator*] "arm64") endif() # Check if the platform variable is set if(DEFINED PLATFORM) # Environment variables are always preserved. set(ENV{_PLATFORM} "${PLATFORM}") elseif(DEFINED ENV{_PLATFORM}) set(PLATFORM "$ENV{_PLATFORM}") elseif(NOT DEFINED PLATFORM) message(FATAL_ERROR "PLATFORM argument not set. Bailing configure since I don't know what target you want to build for!") endif () if(PLATFORM MATCHES ".*COMBINED" AND NOT CMAKE_GENERATOR MATCHES "Xcode") message(FATAL_ERROR "The combined builds support requires Xcode to be used as a generator via '-G Xcode' command-line argument in CMake") endif() # Safeguard that the platform value is set and is one of the supported values list(FIND _supported_platforms ${PLATFORM} contains_PLATFORM) if("${contains_PLATFORM}" EQUAL "-1") string(REPLACE ";" "\n * " _supported_platforms_formatted "${_supported_platforms}") message(FATAL_ERROR " Invalid PLATFORM specified! Current value: ${PLATFORM}.\n" " Supported PLATFORM values: \n * ${_supported_platforms_formatted}") endif() # Check if Apple Silicon is supported if(PLATFORM MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$|^(MAC_UNIVERSAL)$" AND ${CMAKE_VERSION} VERSION_LESS "3.19.5") message(FATAL_ERROR "Apple Silicon builds requires a minimum of CMake 3.19.5") endif() # Touch the toolchain variable to suppress the "unused variable" warning. # This happens if CMake is invoked with the same command line the second time. if(CMAKE_TOOLCHAIN_FILE) endif() # Fix for PThread library not in path set(CMAKE_THREAD_LIBS_INIT "-lpthread") set(CMAKE_HAVE_THREADS_LIBRARY 1) set(CMAKE_USE_WIN32_THREADS_INIT 0) set(CMAKE_USE_PTHREADS_INIT 1) # Specify named language support defaults. if(NOT DEFINED NAMED_LANGUAGE_SUPPORT AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16") set(NAMED_LANGUAGE_SUPPORT ON) message(STATUS "[DEFAULTS] Using explicit named language support! E.g., enable_language(CXX) is needed in the project files.") elseif(NOT DEFINED NAMED_LANGUAGE_SUPPORT AND ${CMAKE_VERSION} VERSION_LESS "3.16") set(NAMED_LANGUAGE_SUPPORT OFF) message(STATUS "[DEFAULTS] Disabling explicit named language support. Falling back to legacy behavior.") elseif(DEFINED NAMED_LANGUAGE_SUPPORT AND ${CMAKE_VERSION} VERSION_LESS "3.16") message(FATAL_ERROR "CMake named language support for OBJC and OBJCXX was added in CMake 3.16.") endif() set(NAMED_LANGUAGE_SUPPORT_INT ${NAMED_LANGUAGE_SUPPORT} CACHE BOOL "Whether or not to enable explicit named language support" FORCE) # Specify the minimum version of the deployment target. if(NOT DEFINED DEPLOYMENT_TARGET) if (PLATFORM MATCHES "WATCHOS") # Unless specified, SDK version 4.0 is used by default as minimum target version (watchOS). set(DEPLOYMENT_TARGET "4.0") elseif(PLATFORM STREQUAL "MAC") # Unless specified, SDK version 10.13 (High Sierra) is used by default as the minimum target version (macos). set(DEPLOYMENT_TARGET "10.13") elseif(PLATFORM STREQUAL "MAC_ARM64") # Unless specified, SDK version 11.0 (Big Sur) is used by default as the minimum target version (macOS on arm). set(DEPLOYMENT_TARGET "11.0") elseif(PLATFORM STREQUAL "MAC_UNIVERSAL") # Unless specified, SDK version 11.0 (Big Sur) is used by default as minimum target version for universal builds. set(DEPLOYMENT_TARGET "11.0") elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64") # Unless specified, SDK version 13.0 is used by default as the minimum target version (mac catalyst minimum requirement). set(DEPLOYMENT_TARGET "13.1") else() # Unless specified, SDK version 11.0 is used by default as the minimum target version (iOS, tvOS). set(DEPLOYMENT_TARGET "11.0") endif() message(STATUS "[DEFAULTS] Using the default min-version since DEPLOYMENT_TARGET not provided!") elseif(DEFINED DEPLOYMENT_TARGET AND PLATFORM MATCHES "^MAC_CATALYST" AND ${DEPLOYMENT_TARGET} VERSION_LESS "13.1") message(FATAL_ERROR "Mac Catalyst builds requires a minimum deployment target of 13.1!") endif() # Store the DEPLOYMENT_TARGET in the cache set(DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}" CACHE INTERNAL "") # Handle the case where we are targeting iOS and a version above 10.3.4 (32-bit support dropped officially) if(PLATFORM STREQUAL "OS" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) set(PLATFORM "OS64") message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") elseif(PLATFORM STREQUAL "SIMULATOR" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) set(PLATFORM "SIMULATOR64") message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") endif() set(PLATFORM_INT "${PLATFORM}") if(DEFINED ARCHS) string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") endif() # Determine the platform name and architectures for use in xcodebuild commands # from the specified PLATFORM_INT name. if(PLATFORM_INT STREQUAL "OS") set(SDK_NAME iphoneos) if(NOT ARCHS) set(ARCHS armv7 armv7s arm64) set(APPLE_TARGET_TRIPLE_INT arm-apple-ios${DEPLOYMENT_TARGET}) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}) endif() elseif(PLATFORM_INT STREQUAL "OS64") set(SDK_NAME iphoneos) if(NOT ARCHS) if (XCODE_VERSION_INT VERSION_GREATER 10.0) set(ARCHS arm64) # FIXME: Add arm64e when Apple has fixed the integration issues with it, libarclite_iphoneos.a is currently missing bitcode markers for example else() set(ARCHS arm64) endif() set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios${DEPLOYMENT_TARGET}) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}) endif() elseif(PLATFORM_INT STREQUAL "OS64COMBINED") set(SDK_NAME iphoneos) if(MODERN_CMAKE) if(NOT ARCHS) if (XCODE_VERSION_INT VERSION_GREATER 10.0) set(ARCHS arm64 x86_64) # FIXME: Add arm64e when Apple has fixed the integration issues with it, libarclite_iphoneos.a is currently missing bitcode markers for example set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64") else() set(ARCHS arm64 x86_64) set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64") endif() set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-ios${DEPLOYMENT_TARGET}) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}) endif() else() message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the OS64COMBINED setting work") endif() elseif(PLATFORM_INT STREQUAL "SIMULATOR") set(SDK_NAME iphonesimulator) if(NOT ARCHS) set(ARCHS i386) set(APPLE_TARGET_TRIPLE_INT i386-apple-ios${DEPLOYMENT_TARGET}-simulator) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) endif() message(DEPRECATION "SIMULATOR IS DEPRECATED. Consider using SIMULATOR64 instead.") elseif(PLATFORM_INT STREQUAL "SIMULATOR64") set(SDK_NAME iphonesimulator) if(NOT ARCHS) set(ARCHS x86_64) set(APPLE_TARGET_TRIPLE_INT x86_64-apple-ios${DEPLOYMENT_TARGET}-simulator) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) endif() elseif(PLATFORM_INT STREQUAL "SIMULATORARM64") set(SDK_NAME iphonesimulator) if(NOT ARCHS) set(ARCHS arm64) set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios${DEPLOYMENT_TARGET}-simulator) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) endif() elseif(PLATFORM_INT STREQUAL "TVOS") set(SDK_NAME appletvos) if(NOT ARCHS) set(ARCHS arm64) set(APPLE_TARGET_TRIPLE_INT aarch64-apple-tvos${DEPLOYMENT_TARGET}) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}) endif() elseif (PLATFORM_INT STREQUAL "TVOSCOMBINED") set(SDK_NAME appletvos) if(MODERN_CMAKE) if(NOT ARCHS) set(ARCHS arm64 x86_64) set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-tvos${DEPLOYMENT_TARGET}) set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "x86_64") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvos*] "arm64") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvsimulator*] "x86_64") else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}) endif() else() message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the TVOSCOMBINED setting work") endif() elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") set(SDK_NAME appletvsimulator) if(NOT ARCHS) set(ARCHS x86_64) set(APPLE_TARGET_TRIPLE_INT x86_64-apple-tvos${DEPLOYMENT_TARGET}-simulator) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}-simulator) endif() elseif(PLATFORM_INT STREQUAL "WATCHOS") set(SDK_NAME watchos) if(NOT ARCHS) if (XCODE_VERSION_INT VERSION_GREATER 10.0) set(ARCHS armv7k arm64_32) set(APPLE_TARGET_TRIPLE_INT aarch64_32-apple-watchos${DEPLOYMENT_TARGET}) else() set(ARCHS armv7k) set(APPLE_TARGET_TRIPLE_INT arm-apple-watchos${DEPLOYMENT_TARGET}) endif() else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}) endif() elseif(PLATFORM_INT STREQUAL "WATCHOSCOMBINED") set(SDK_NAME watchos) if(MODERN_CMAKE) if(NOT ARCHS) if (XCODE_VERSION_INT VERSION_GREATER 10.0) set(ARCHS armv7k arm64_32 i386) set(APPLE_TARGET_TRIPLE_INT aarch64_32-i386-apple-watchos${DEPLOYMENT_TARGET}) set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k arm64_32") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k arm64_32") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386") else() set(ARCHS armv7k i386) set(APPLE_TARGET_TRIPLE_INT arm-i386-apple-watchos${DEPLOYMENT_TARGET}) set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386") endif() else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}) endif() else() message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the WATCHOSCOMBINED setting work") endif() elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") set(SDK_NAME watchsimulator) if(NOT ARCHS) set(ARCHS i386) set(APPLE_TARGET_TRIPLE_INT i386-apple-watchos${DEPLOYMENT_TARGET}-simulator) else() set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}-simulator) endif() elseif(PLATFORM_INT STREQUAL "MAC" OR PLATFORM_INT STREQUAL "MAC_CATALYST") set(SDK_NAME macosx) if(NOT ARCHS) set(ARCHS x86_64) endif() string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") if(PLATFORM_INT STREQUAL "MAC") set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx${DEPLOYMENT_TARGET}) elseif(PLATFORM_INT STREQUAL "MAC_CATALYST") set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi) endif() elseif(PLATFORM_INT MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$") set(SDK_NAME macosx) if(NOT ARCHS) set(ARCHS arm64) endif() string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") if(PLATFORM_INT STREQUAL "MAC_ARM64") set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx${DEPLOYMENT_TARGET}) elseif(PLATFORM_INT STREQUAL "MAC_CATALYST_ARM64") set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi) endif() elseif(PLATFORM_INT STREQUAL "MAC_UNIVERSAL") set(SDK_NAME macosx) if(NOT ARCHS) set(ARCHS "x86_64;arm64") endif() string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx${DEPLOYMENT_TARGET}) else() message(FATAL_ERROR "Invalid PLATFORM: ${PLATFORM_INT}") endif() string(REPLACE ";" " " ARCHS_SPACED "${ARCHS}") if(MODERN_CMAKE AND PLATFORM_INT MATCHES ".*COMBINED" AND NOT CMAKE_GENERATOR MATCHES "Xcode") message(FATAL_ERROR "The COMBINED options only work with Xcode generator, -G Xcode") endif() if(CMAKE_GENERATOR MATCHES "Xcode" AND PLATFORM_INT MATCHES "^MAC_CATALYST") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx") set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-maccatalyst") if(NOT DEFINED MACOSX_DEPLOYMENT_TARGET) set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "10.15") else() set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}") endif() elseif(CMAKE_GENERATOR MATCHES "Xcode") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}") if(NOT PLATFORM_INT MATCHES ".*COMBINED") set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=${SDK_NAME}*] "${ARCHS_SPACED}") set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=${SDK_NAME}*] "${ARCHS_SPACED}") endif() endif() # If the user did not specify the SDK root to use, then query xcodebuild for it. if(DEFINED CMAKE_OSX_SYSROOT_INT) # Environment variables are always preserved. set(ENV{_CMAKE_OSX_SYSROOT_INT} "${CMAKE_OSX_SYSROOT_INT}") elseif(DEFINED ENV{_CMAKE_OSX_SYSROOT_INT}) set(CMAKE_OSX_SYSROOT_INT "$ENV{_CMAKE_OSX_SYSROOT_INT}") elseif(NOT DEFINED CMAKE_OSX_SYSROOT_INT) execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version -sdk ${SDK_NAME} Path OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) endif() if (NOT DEFINED CMAKE_OSX_SYSROOT_INT AND NOT DEFINED CMAKE_OSX_SYSROOT) message(SEND_ERROR "Please make sure that Xcode is installed and that the toolchain" "is pointing to the correct path. Please run:" "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer" "and see if that fixes the problem for you.") message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} " "does not exist.") elseif(DEFINED CMAKE_OSX_SYSROOT_INT) set(CMAKE_OSX_SYSROOT_INT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") # Specify the location or name of the platform SDK to be used in CMAKE_OSX_SYSROOT. set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") endif() # Use bitcode or not if(NOT DEFINED ENABLE_BITCODE AND NOT ARCHS MATCHES "((^|;|, )(i386|x86_64))+") # Unless specified, enable bitcode support by default message(STATUS "[DEFAULTS] Enabling bitcode support by default. ENABLE_BITCODE not provided!") set(ENABLE_BITCODE ON) elseif(NOT DEFINED ENABLE_BITCODE) message(STATUS "[DEFAULTS] Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!") set(ENABLE_BITCODE OFF) endif() set(ENABLE_BITCODE_INT ${ENABLE_BITCODE} CACHE BOOL "Whether or not to enable bitcode" FORCE) # Use ARC or not if(NOT DEFINED ENABLE_ARC) # Unless specified, enable ARC support by default set(ENABLE_ARC ON) message(STATUS "[DEFAULTS] Enabling ARC support by default. ENABLE_ARC not provided!") endif() set(ENABLE_ARC_INT ${ENABLE_ARC} CACHE BOOL "Whether or not to enable ARC" FORCE) # Use hidden visibility or not if(NOT DEFINED ENABLE_VISIBILITY) # Unless specified, disable symbols visibility by default set(ENABLE_VISIBILITY OFF) message(STATUS "[DEFAULTS] Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!") endif() set(ENABLE_VISIBILITY_INT ${ENABLE_VISIBILITY} CACHE BOOL "Whether or not to hide symbols from the dynamic linker (-fvisibility=hidden)" FORCE) # Set strict compiler checks or not if(NOT DEFINED ENABLE_STRICT_TRY_COMPILE) # Unless specified, disable strict try_compile() set(ENABLE_STRICT_TRY_COMPILE OFF) message(STATUS "[DEFAULTS] Using NON-strict compiler checks by default. ENABLE_STRICT_TRY_COMPILE not provided!") endif() set(ENABLE_STRICT_TRY_COMPILE_INT ${ENABLE_STRICT_TRY_COMPILE} CACHE BOOL "Whether or not to use strict compiler checks" FORCE) # Get the SDK version information. if(DEFINED SDK_VERSION) # Environment variables are always preserved. set(ENV{_SDK_VERSION} "${SDK_VERSION}") elseif(DEFINED ENV{_SDK_VERSION}) set(SDK_VERSION "$ENV{_SDK_VERSION}") elseif(NOT DEFINED SDK_VERSION) execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -sdk ${CMAKE_OSX_SYSROOT_INT} -version SDKVersion OUTPUT_VARIABLE SDK_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) endif() # Find the Developer root for the specific iOS platform being compiled for # from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in # CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain # this information from xcrun or xcodebuild. if (NOT DEFINED CMAKE_DEVELOPER_ROOT AND NOT CMAKE_GENERATOR MATCHES "Xcode") get_filename_component(PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT_INT} PATH) get_filename_component(CMAKE_DEVELOPER_ROOT ${PLATFORM_SDK_DIR} PATH) if (NOT EXISTS "${CMAKE_DEVELOPER_ROOT}") message(FATAL_ERROR "Invalid CMAKE_DEVELOPER_ROOT: ${CMAKE_DEVELOPER_ROOT} does not exist.") endif() endif() # Find the C & C++ compilers for the specified SDK. if(DEFINED CMAKE_C_COMPILER) # Environment variables are always preserved. set(ENV{_CMAKE_C_COMPILER} "${CMAKE_C_COMPILER}") elseif(DEFINED ENV{_CMAKE_C_COMPILER}) set(CMAKE_C_COMPILER "$ENV{_CMAKE_C_COMPILER}") set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) elseif(NOT DEFINED CMAKE_C_COMPILER) execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang OUTPUT_VARIABLE CMAKE_C_COMPILER ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) endif() if(DEFINED CMAKE_CXX_COMPILER) # Environment variables are always preserved. set(ENV{_CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER}") elseif(DEFINED ENV{_CMAKE_CXX_COMPILER}) set(CMAKE_CXX_COMPILER "$ENV{_CMAKE_CXX_COMPILER}") elseif(NOT DEFINED CMAKE_CXX_COMPILER) execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang++ OUTPUT_VARIABLE CMAKE_CXX_COMPILER ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) endif() # Find (Apple's) libtool. if(DEFINED BUILD_LIBTOOL) # Environment variables are always preserved. set(ENV{_BUILD_LIBTOOL} "${BUILD_LIBTOOL}") elseif(DEFINED ENV{_BUILD_LIBTOOL}) set(BUILD_LIBTOOL "$ENV{_BUILD_LIBTOOL}") elseif(NOT DEFINED BUILD_LIBTOOL) execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find libtool OUTPUT_VARIABLE BUILD_LIBTOOL ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) endif() # Find the toolchain's provided install_name_tool if none is found on the host if(DEFINED CMAKE_INSTALL_NAME_TOOL) # Environment variables are always preserved. set(ENV{_CMAKE_INSTALL_NAME_TOOL} "${CMAKE_INSTALL_NAME_TOOL}") elseif(DEFINED ENV{_CMAKE_INSTALL_NAME_TOOL}) set(CMAKE_INSTALL_NAME_TOOL "$ENV{_CMAKE_INSTALL_NAME_TOOL}") elseif(NOT DEFINED CMAKE_INSTALL_NAME_TOOL) execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find install_name_tool OUTPUT_VARIABLE CMAKE_INSTALL_NAME_TOOL_INT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) set(CMAKE_INSTALL_NAME_TOOL ${CMAKE_INSTALL_NAME_TOOL_INT} CACHE INTERNAL "") endif() # Configure libtool to be used instead of ar + ranlib to build static libraries. # This is required on Xcode 7+, but should also work on previous versions of # Xcode. get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) foreach(lang ${languages}) set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "${BUILD_LIBTOOL} -static -o " CACHE INTERNAL "") endforeach() # CMake 3.14+ support building for iOS, watchOS, and tvOS out of the box. if(MODERN_CMAKE) if(SDK_NAME MATCHES "iphone") set(CMAKE_SYSTEM_NAME iOS) elseif(SDK_NAME MATCHES "macosx") set(CMAKE_SYSTEM_NAME Darwin) elseif(SDK_NAME MATCHES "appletv") set(CMAKE_SYSTEM_NAME tvOS) elseif(SDK_NAME MATCHES "watch") set(CMAKE_SYSTEM_NAME watchOS) endif() # Provide flags for a combined FAT library build on newer CMake versions if(PLATFORM_INT MATCHES ".*COMBINED") set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO") set(CMAKE_IOS_INSTALL_COMBINED YES) endif() elseif(NOT DEFINED CMAKE_SYSTEM_NAME AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10") # Legacy code path prior to CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified set(CMAKE_SYSTEM_NAME iOS) elseif(NOT DEFINED CMAKE_SYSTEM_NAME) # Legacy code path before CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified set(CMAKE_SYSTEM_NAME Darwin) endif() # Standard settings. set(CMAKE_SYSTEM_VERSION ${SDK_VERSION} CACHE INTERNAL "") set(UNIX ON CACHE BOOL "") set(APPLE ON CACHE BOOL "") if(PLATFORM STREQUAL "MAC" OR PLATFORM STREQUAL "MAC_ARM64" OR PLATFORM STREQUAL "MAC_UNIVERSAL") set(IOS OFF CACHE BOOL "") set(MACOS ON CACHE BOOL "") elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64") set(IOS ON CACHE BOOL "") set(MACOS ON CACHE BOOL "") else() set(IOS ON CACHE BOOL "") endif() set(CMAKE_AR ar CACHE FILEPATH "" FORCE) set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE) set(CMAKE_STRIP strip CACHE FILEPATH "" FORCE) # Set the architectures for which to build. set(CMAKE_OSX_ARCHITECTURES ${ARCHS} CACHE INTERNAL "") # Change the type of target generated for try_compile() so it'll work when cross-compiling, weak compiler checks if(NOT ENABLE_STRICT_TRY_COMPILE_INT) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) endif() # All iOS/Darwin specific settings - some may be redundant. if (NOT DEFINED CMAKE_MACOSX_BUNDLE) set(CMAKE_MACOSX_BUNDLE YES) endif() set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") set(CMAKE_SHARED_LIBRARY_PREFIX "lib") set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") set(CMAKE_SHARED_MODULE_PREFIX "lib") set(CMAKE_SHARED_MODULE_SUFFIX ".so") set(CMAKE_C_COMPILER_ABI ELF) set(CMAKE_CXX_COMPILER_ABI ELF) set(CMAKE_C_HAS_ISYSROOT 1) set(CMAKE_CXX_HAS_ISYSROOT 1) set(CMAKE_MODULE_EXISTS 1) set(CMAKE_DL_LIBS "") set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") if(ARCHS MATCHES "((^|;|, )(arm64|arm64e|x86_64))+") set(CMAKE_C_SIZEOF_DATA_PTR 8) set(CMAKE_CXX_SIZEOF_DATA_PTR 8) if(ARCHS MATCHES "((^|;|, )(arm64|arm64e))+") set(CMAKE_SYSTEM_PROCESSOR "aarch64") else() set(CMAKE_SYSTEM_PROCESSOR "x86_64") endif() else() set(CMAKE_C_SIZEOF_DATA_PTR 4) set(CMAKE_CXX_SIZEOF_DATA_PTR 4) set(CMAKE_SYSTEM_PROCESSOR "arm") endif() # Note that only Xcode 7+ supports the newer more specific: # -m${SDK_NAME}-version-min flags, older versions of Xcode use: # -m(ios/ios-simulator)-version-min instead. if(${CMAKE_VERSION} VERSION_LESS "3.11") if(PLATFORM_INT STREQUAL "OS" OR PLATFORM_INT STREQUAL "OS64") if(XCODE_VERSION_INT VERSION_LESS 7.0) set(SDK_NAME_VERSION_FLAGS "-mios-version-min=${DEPLOYMENT_TARGET}") else() # Xcode 7.0+ uses flags we can build directly from SDK_NAME. set(SDK_NAME_VERSION_FLAGS "-m${SDK_NAME}-version-min=${DEPLOYMENT_TARGET}") endif() elseif(PLATFORM_INT STREQUAL "TVOS") set(SDK_NAME_VERSION_FLAGS "-mtvos-version-min=${DEPLOYMENT_TARGET}") elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") set(SDK_NAME_VERSION_FLAGS "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}") elseif(PLATFORM_INT STREQUAL "WATCHOS") set(SDK_NAME_VERSION_FLAGS "-mwatchos-version-min=${DEPLOYMENT_TARGET}") elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") set(SDK_NAME_VERSION_FLAGS "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}") elseif(PLATFORM_INT STREQUAL "MAC") set(SDK_NAME_VERSION_FLAGS "-mmacosx-version-min=${DEPLOYMENT_TARGET}") else() # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min. set(SDK_NAME_VERSION_FLAGS "-mios-simulator-version-min=${DEPLOYMENT_TARGET}") endif() elseif(NOT PLATFORM_INT MATCHES "^MAC_CATALYST") # Newer versions of CMake sets the version min flags correctly, skip this for Mac Catalyst targets set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET}) endif() if(DEFINED APPLE_TARGET_TRIPLE_INT) set(APPLE_TARGET_TRIPLE ${APPLE_TARGET_TRIPLE_INT} CACHE INTERNAL "") set(CMAKE_C_COMPILER_TARGET ${APPLE_TARGET_TRIPLE}) set(CMAKE_CXX_COMPILER_TARGET ${APPLE_TARGET_TRIPLE}) set(CMAKE_ASM_COMPILER_TARGET ${APPLE_TARGET_TRIPLE}) endif() if(PLATFORM_INT MATCHES "^MAC_CATALYST") set(C_TARGET_FLAGS "-isystem ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/usr/include -iframework ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/System/Library/Frameworks") endif() if(ENABLE_BITCODE_INT) set(BITCODE "-fembed-bitcode") set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode") set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES") else() set(BITCODE "") set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") endif() if(ENABLE_ARC_INT) set(FOBJC_ARC "-fobjc-arc") set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES") else() set(FOBJC_ARC "-fno-objc-arc") set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO") endif() if(NAMED_LANGUAGE_SUPPORT_INT) set(OBJC_VARS "-fobjc-abi-version=2 -DOBJC_OLD_DISPATCH_PROTOTYPES=0") set(OBJC_LEGACY_VARS "") else() set(OBJC_VARS "") set(OBJC_LEGACY_VARS "-fobjc-abi-version=2 -DOBJC_OLD_DISPATCH_PROTOTYPES=0") endif() if(NOT ENABLE_VISIBILITY_INT) foreach(lang ${languages}) set(CMAKE_${lang}_VISIBILITY_PRESET "hidden" CACHE INTERNAL "") endforeach() set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES") set(VISIBILITY "-fvisibility=hidden -fvisibility-inlines-hidden") else() foreach(lang ${languages}) set(CMAKE_${lang}_VISIBILITY_PRESET "default" CACHE INTERNAL "") endforeach() set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO") set(VISIBILITY "-fvisibility=default") endif() if(DEFINED APPLE_TARGET_TRIPLE) set(APPLE_TARGET_TRIPLE_FLAG "-target ${APPLE_TARGET_TRIPLE}") endif() #Check if Xcode generator is used since that will handle these flags automagically if(CMAKE_GENERATOR MATCHES "Xcode") message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as the generator. Modifying the Xcode build-settings directly instead.") else() set(CMAKE_C_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${OBJC_LEGACY_VARS} ${BITCODE} ${VISIBILITY} ${CMAKE_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "-O0 -g ${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_C_FLAGS_MINSIZEREL}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_C_FLAGS_RELWITHDEBINFO}") set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${OBJC_LEGACY_VARS} ${BITCODE} ${VISIBILITY} ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_CXX_FLAGS_MINSIZEREL}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_CXX_FLAGS_RELEASE}") if(NAMED_LANGUAGE_SUPPORT_INT) set(CMAKE_OBJC_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} ${FOBJC_ARC} ${OBJC_VARS} ${CMAKE_OBJC_FLAGS}") set(CMAKE_OBJC_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJC_FLAGS_DEBUG}") set(CMAKE_OBJC_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJC_FLAGS_MINSIZEREL}") set(CMAKE_OBJC_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJC_FLAGS_RELWITHDEBINFO}") set(CMAKE_OBJC_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJC_FLAGS_RELEASE}") set(CMAKE_OBJCXX_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} ${FOBJC_ARC} ${OBJC_VARS} ${CMAKE_OBJCXX_FLAGS}") set(CMAKE_OBJCXX_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJCXX_FLAGS_DEBUG}") set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJCXX_FLAGS_MINSIZEREL}") set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO}") set(CMAKE_OBJCXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJCXX_FLAGS_RELEASE}") endif() set(CMAKE_C_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") set(CMAKE_CXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") if(NAMED_LANGUAGE_SUPPORT_INT) set(CMAKE_OBJC_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_OBJC_LINK_FLAGS}") set(CMAKE_OBJCXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_OBJCXX_LINK_FLAGS}") endif() set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -arch ${CMAKE_OSX_ARCHITECTURES} ${APPLE_TARGET_TRIPLE_FLAG}") endif() ## Print status messages to inform of the current state message(STATUS "Configuring ${SDK_NAME} build for platform: ${PLATFORM_INT}, architecture(s): ${ARCHS}") message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT_INT}") message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}") message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}") message(STATUS "Using libtool: ${BUILD_LIBTOOL}") message(STATUS "Using install name tool: ${CMAKE_INSTALL_NAME_TOOL}") if(DEFINED APPLE_TARGET_TRIPLE) message(STATUS "Autoconf target triple: ${APPLE_TARGET_TRIPLE}") endif() message(STATUS "Using minimum deployment version: ${DEPLOYMENT_TARGET}" " (SDK version: ${SDK_VERSION})") if(MODERN_CMAKE) message(STATUS "Merging integrated CMake 3.14+ iOS,tvOS,watchOS,macOS toolchain(s) with this toolchain!") if(PLATFORM_INT MATCHES ".*COMBINED") message(STATUS "Will combine built (static) artifacts into FAT lib...") endif() endif() if(CMAKE_GENERATOR MATCHES "Xcode") message(STATUS "Using Xcode version: ${XCODE_VERSION_INT}") endif() message(STATUS "CMake version: ${CMAKE_VERSION}") if(DEFINED SDK_NAME_VERSION_FLAGS) message(STATUS "Using version flags: ${SDK_NAME_VERSION_FLAGS}") endif() message(STATUS "Using a data_ptr size of: ${CMAKE_CXX_SIZEOF_DATA_PTR}") if(ENABLE_BITCODE_INT) message(STATUS "Bitcode: Enabled") else() message(STATUS "Bitcode: Disabled") endif() if(ENABLE_ARC_INT) message(STATUS "ARC: Enabled") else() message(STATUS "ARC: Disabled") endif() if(ENABLE_VISIBILITY_INT) message(STATUS "Hiding symbols: Disabled") else() message(STATUS "Hiding symbols: Enabled") endif() # Set global properties set_property(GLOBAL PROPERTY PLATFORM "${PLATFORM}") set_property(GLOBAL PROPERTY APPLE_TARGET_TRIPLE "${APPLE_TARGET_TRIPLE_INT}") set_property(GLOBAL PROPERTY SDK_VERSION "${SDK_VERSION}") set_property(GLOBAL PROPERTY XCODE_VERSION "${XCODE_VERSION_INT}") set_property(GLOBAL PROPERTY OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") # Export configurable variables for the try_compile() command. set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PLATFORM XCODE_VERSION_INT SDK_VERSION NAMED_LANGUAGE_SUPPORT DEPLOYMENT_TARGET CMAKE_DEVELOPER_ROOT CMAKE_OSX_SYSROOT_INT ENABLE_BITCODE ENABLE_ARC CMAKE_ASM_COMPILER CMAKE_C_COMPILER CMAKE_C_COMPILER_TARGET CMAKE_CXX_COMPILER CMAKE_CXX_COMPILER_TARGET BUILD_LIBTOOL CMAKE_INSTALL_NAME_TOOL CMAKE_C_FLAGS CMAKE_C_DEBUG CMAKE_C_MINSIZEREL CMAKE_C_RELWITHDEBINFO CMAKE_C_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELEASE CMAKE_C_LINK_FLAGS CMAKE_CXX_LINK_FLAGS CMAKE_ASM_FLAGS ) if(NAMED_LANGUAGE_SUPPORT_INT) list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_OBJC_FLAGS CMAKE_OBJC_DEBUG CMAKE_OBJC_MINSIZEREL CMAKE_OBJC_RELWITHDEBINFO CMAKE_OBJC_RELEASE CMAKE_OBJCXX_FLAGS CMAKE_OBJCXX_DEBUG CMAKE_OBJCXX_MINSIZEREL CMAKE_OBJCXX_RELWITHDEBINFO CMAKE_OBJCXX_RELEASE CMAKE_OBJC_LINK_FLAGS CMAKE_OBJCXX_LINK_FLAGS ) endif() set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) set(CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a") set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name") # Set the find root to the SDK developer roots. # Note: CMAKE_FIND_ROOT_PATH is only useful when cross-compiling. Thus, do not set on macOS builds. if(NOT PLATFORM_INT MATCHES "^MAC.*$") list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") set(CMAKE_IGNORE_PATH "/System/Library/Frameworks;/usr/local/lib" CACHE INTERNAL "") endif() # Default to searching for frameworks first. set(CMAKE_FIND_FRAMEWORK FIRST) # Set up the default search directories for frameworks. if(PLATFORM_INT MATCHES "^MAC_CATALYST") set(CMAKE_FRAMEWORK_PATH ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/System/Library/Frameworks ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "") else() set(CMAKE_FRAMEWORK_PATH ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "") endif() # By default, search both the specified iOS SDK and the remainder of the host filesystem. if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "") endif() if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH CACHE INTERNAL "") endif() if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH CACHE INTERNAL "") endif() if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH CACHE INTERNAL "") endif() # # Some helper-macros below to simplify and beautify the CMakeFile # # This little macro lets you set any Xcode specific property. macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION) set(XCODE_RELVERSION_I "${XCODE_RELVERSION}") if(XCODE_RELVERSION_I STREQUAL "All") set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}") else() set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}") endif() endmacro(set_xcode_property) # This macro lets you find executable programs on the host system. macro(find_host_package) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) set(_TOOLCHAIN_IOS ${IOS}) set(IOS OFF) find_package(${ARGN}) set(IOS ${_TOOLCHAIN_IOS}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) endmacro(find_host_package) ================================================ FILE: cmake/libhvConfig.cmake ================================================ include(SelectLibraryConfigurations) find_path(libhv_INCLUDE_DIRS hv/hv.h) message("libhv_INCLUDE_DIRS: " ${libhv_INCLUDE_DIRS}) find_library(libhv_LIBRARY_RELEASE NAMES hv PATHS "${CMAKE_CURRENT_LIST_DIR}/../../lib" NO_DEFAULT_PATH) find_library(libhv_LIBRARY_DEBUG NAMES hv PATHS "${CMAKE_CURRENT_LIST_DIR}/../../debug/lib" NO_DEFAULT_PATH) select_library_configurations(libhv) if(NOT libhv_LIBRARY) set(libhv_FOUND FALSE) set(LIBHV_FOUND FALSE) return() endif() if(WIN32) find_file(libhv_LIBRARY_RELEASE_DLL NAMES hv.dll PATHS "${CMAKE_CURRENT_LIST_DIR}/../../bin" NO_DEFAULT_PATH) find_file(libhv_LIBRARY_DEBUG_DLL NAMES hv.dll PATHS "${CMAKE_CURRENT_LIST_DIR}/../../debug/bin" NO_DEFAULT_PATH) endif() # Manage Release Windows shared if(EXISTS "${libhv_LIBRARY_RELEASE_DLL}") add_library(libhv SHARED IMPORTED) set_target_properties(libhv PROPERTIES IMPORTED_CONFIGURATIONS Release IMPORTED_LOCATION_RELEASE "${libhv_LIBRARY_RELEASE_DLL}" IMPORTED_IMPLIB_RELEASE "${libhv_LIBRARY_RELEASE}" INTERFACE_INCLUDE_DIRECTORIES "${libhv_INCLUDE_DIRS}" ) endif() # Manage Debug Windows shared if(EXISTS "${libhv_LIBRARY_DEBUG_DLL}") if(EXISTS "${libhv_LIBRARY_RELEASE_DLL}") #message("Debug mode") set_target_properties(libhv PROPERTIES IMPORTED_CONFIGURATIONS "Release;Debug" IMPORTED_LOCATION_RELEASE "${libhv_LIBRARY_RELEASE_DLL}" IMPORTED_IMPLIB_RELEASE "${libhv_LIBRARY_RELEASE}" IMPORTED_LOCATION_DEBUG "${libhv_LIBRARY_DEBUG_DLL}" IMPORTED_IMPLIB_DEBUG "${libhv_LIBRARY_DEBUG}" INTERFACE_INCLUDE_DIRECTORIES "${libhv_INCLUDE_DIRS}" ) else() add_library(libhv SHARED IMPORTED) set_target_properties(libhv PROPERTIES IMPORTED_CONFIGURATIONS Debug IMPORTED_LOCATION_DEBUG "${libhv_LIBRARY_DEBUG_DLL}" IMPORTED_IMPLIB_DEBUG "${libhv_LIBRARY_DEBUG}" INTERFACE_INCLUDE_DIRECTORIES "${libhv_INCLUDE_DIRS}" ) endif() endif() # Manage Release Windows static and Linux shared/static if((NOT EXISTS "${libhv_LIBRARY_RELEASE_DLL}") AND (EXISTS "${libhv_LIBRARY_RELEASE}")) add_library(libhv UNKNOWN IMPORTED) set_target_properties(libhv PROPERTIES IMPORTED_CONFIGURATIONS Release IMPORTED_LOCATION_RELEASE "${libhv_LIBRARY_RELEASE}" INTERFACE_INCLUDE_DIRECTORIES "${libhv_INCLUDE_DIRS}" ) endif() # Manage Debug Windows static and Linux shared/static if((NOT EXISTS "${libhv_LIBRARY_DEBUG_DLL}") AND (EXISTS "${libhv_LIBRARY_DEBUG}")) if(EXISTS "${libhv_LIBRARY_RELEASE}") set_target_properties(libhv PROPERTIES IMPORTED_CONFIGURATIONS "Release;Debug" IMPORTED_LOCATION_RELEASE "${libhv_LIBRARY_RELEASE}" IMPORTED_LOCATION_DEBUG "${libhv_LIBRARY_DEBUG}" INTERFACE_INCLUDE_DIRECTORIES "${libhv_INCLUDE_DIRS}" ) else() add_library(libhv UNKNOWN IMPORTED) set_target_properties(libhv PROPERTIES IMPORTED_CONFIGURATIONS Debug IMPORTED_LOCATION_DEBUG "${libhv_LIBRARY_DEBUG}" INTERFACE_INCLUDE_DIRECTORIES "${libhv_INCLUDE_DIRS}" ) endif() endif() set(libhv_FOUND TRUE) set(LIBHV_FOUND TRUE) ================================================ FILE: cmake/utils.cmake ================================================ include(CheckIncludeFiles) macro(check_header header) string(TOUPPER ${header} str1) string(REGEX REPLACE "[/.]" "_" str2 ${str1}) set(str3 HAVE_${str2}) check_include_files(${header} ${str3}) if (${str3}) set(${str3} 1) else() set(${str3} 0) endif() endmacro() include(CheckSymbolExists) macro(check_function function header) string(TOUPPER ${function} str1) set(str2 HAVE_${str1}) check_symbol_exists(${function} ${header} ${str2}) if (${str2}) set(${str2} 1) else() set(${str2} 0) endif() endmacro() macro(list_source_directories srcs) unset(tmp) foreach(dir ${ARGN}) aux_source_directory(${dir} tmp) endforeach() set(${srcs} ${tmp}) list(FILTER ${srcs} EXCLUDE REGEX ".*_test\\.c") endmacro() macro(glob_headers_and_sources files) unset(tmp) foreach(dir ${ARGN}) file(GLOB tmp ${dir}/*.h ${dir}/*.c ${dir}/*.hpp ${dir}/*.cpp) list(APPEND ${files} ${tmp}) endforeach() list(FILTER ${files} EXCLUDE REGEX ".*_test\\.c") endmacro() ================================================ FILE: cmake/vars.cmake ================================================ # see Makefile.vars set(BASE_HEADERS base/hplatform.h base/hdef.h base/hatomic.h base/herr.h base/htime.h base/hmath.h base/hbase.h base/hversion.h base/hsysinfo.h base/hproc.h base/hthread.h base/hmutex.h base/hsocket.h base/hlog.h base/hbuf.h base/hmain.h base/hendian.h ) set(SSL_HEADERS ssl/hssl.h ) set(EVENT_HEADERS event/hloop.h event/nlog.h ) set(UTIL_HEADERS util/base64.h util/md5.h util/sha1.h ) set(CPPUTIL_HEADERS cpputil/hmap.h cpputil/hstring.h cpputil/hfile.h cpputil/hpath.h cpputil/hdir.h cpputil/hurl.h cpputil/hscope.h cpputil/hthreadpool.h cpputil/hasync.h cpputil/hobjectpool.h cpputil/ifconfig.h cpputil/iniparser.h cpputil/json.hpp cpputil/singleton.h cpputil/LRUCache.h cpputil/ThreadLocalStorage.h ) set(EVPP_HEADERS evpp/Buffer.h evpp/Channel.h evpp/Event.h evpp/EventLoop.h evpp/EventLoopThread.h evpp/EventLoopThreadPool.h evpp/Status.h evpp/TcpClient.h evpp/TcpServer.h evpp/UdpClient.h evpp/UdpServer.h ) set(PROTOCOL_HEADERS protocol/icmp.h protocol/dns.h protocol/ftp.h protocol/smtp.h ) set(HTTP_HEADERS http/httpdef.h http/wsdef.h http/http_content.h http/HttpMessage.h http/HttpParser.h http/WebSocketParser.h http/WebSocketChannel.h ) set(HTTP2_HEADERS http/http2def.h http/grpcdef.h ) set(HTTP_CLIENT_HEADERS http/client/HttpClient.h http/client/requests.h http/client/axios.h http/client/AsyncHttpClient.h http/client/WebSocketClient.h) set(HTTP_SERVER_HEADERS http/server/HttpServer.h http/server/HttpService.h http/server/HttpContext.h http/server/HttpResponseWriter.h http/server/WebSocketServer.h ) set(MQTT_HEADERS mqtt/mqtt_protocol.h mqtt/mqtt_client.h ) ================================================ FILE: config.ini ================================================ # Don't modify this file, you should modify config.mk or # run ./configure --with-MODULE --enable-FEATURE PREFIX=/usr/local INSTALL_INCDIR=$(PREFIX)/include/hv INSTALL_LIBDIR=$(PREFIX)/lib BUILD_SHARED=yes BUILD_STATIC=yes # modules # include icmp dns ftp smtp WITH_PROTOCOL=no WITH_EVPP=yes WITH_HTTP=yes WITH_HTTP_SERVER=yes WITH_HTTP_CLIENT=yes WITH_MQTT=no # features # base/hsocket.h: Unix Domain Socket ENABLE_UDS=no # base/RAII.cpp: Windows MiniDumpWriteDump ENABLE_WINDUMP=no # http/http_content.h: KeyValue,QueryParams,MultiPart USE_MULTIMAP=no # dependencies # for http/client WITH_CURL=no # for http2 WITH_NGHTTP2=no # for SSL/TLS WITH_OPENSSL=no WITH_GNUTLS=no WITH_MBEDTLS=no # rudp WITH_KCP=no # event WITH_IO_URING=no ================================================ FILE: configure ================================================ #!/bin/bash . "$(dirname "$0")/scripts/shini.sh" print_help() { shini_parse "config.ini" cat << END Usage: ./configure [--option] ... options: --prefix=PREFIX (DEFAULT: $PREFIX) --incdir=INSTALL_INCDIR (DEFAULT: $PREFIX/include/hv) --libdir=INSTALL_LIBDIR (DEFAULT: $PREFIX/lib) --with-MODULE --without-MODULE --enable-FEATURE --disable-FEATURE build: --enable-shared build shared library? (DEFAULT: $BUILD_SHARED) --disable-shared do not build shared library --enable-static build static library? (DEFAULT: $BUILD_STATIC) --disable-static do not build static library modules: --with-protocol compile protocol module? (DEFAULT: $WITH_PROTOCOL) --with-evpp compile evpp module? (DEFAULT: $WITH_EVPP) --with-http compile http module? (DEFAULT: $WITH_HTTP) --with-http-client compile http client module? (DEFAULT: $WITH_HTTP_CLIENT) --with-http-server compile http server module? (DEFAULT: $WITH_HTTP_SERVER) --with-mqtt compile mqtt module? (DEFAULT: $WITH_MQTT) features: --enable-uds enable Unix Domain Socket? (DEFAULT: $ENABLE_UDS) --enable-windump enable Windows coredump? (DEFAULT: $ENABLE_WINDUMP) dependencies: --with-curl compile with curl? (DEFAULT: $WITH_CURL) --with-nghttp2 compile with nghttp2? (DEFAULT: $WITH_NGHTTP2) --with-openssl compile with openssl? (DEFAULT: $WITH_OPENSSL) --with-gnutls compile with gnutls? (DEFAULT: $WITH_GNUTLS) --with-mbedtls compile with mbedtls? (DEFAULT: $WITH_MBEDTLS) rudp: --with-kcp compile with kcp? (DEFAULT: $WITH_KCP) event: --with-io_uring compile with io_uring? (DEFAULT: $WITH_IO_URING) END } mkdir tmp 2>/dev/null while [ -n "$1" ] do opt="$1" KEY="" VAL=yes case $opt in --help) print_help exit 0 ;; --prefix=*) KEY="PREFIX" VAL=${opt:9} ;; --incdir=*) KEY="INSTALL_INCDIR" VAL=${opt:9} ;; --libdir=*) KEY="INSTALL_LIBDIR" VAL=${opt:9} ;; --enable-shared) KEY="BUILD_SHARED" ;; --disable-shared) KEY="BUILD_SHARED" VAL=no ;; --enable-static) KEY="BUILD_STATIC" ;; --disable-static) KEY="BUILD_STATIC" VAL=no ;; --with-*) KEY="WITH_${opt:7}" ;; --without-*) KEY="WITH_${opt:10}" VAL=no ;; --enable-*) KEY="ENABLE_${opt:9}" ;; --disable-*) KEY="ENABLE_${opt:10}" VAL=no ;; *) print_help exit 255 ;; esac if [ -n $KEY ]; then FEATURE=$(echo "$KEY" | tr "a-z-" "A-Z_") if [ ! -f tmp/config.mk ]; then cp config.ini tmp/config.mk fi shini_write "tmp/config.mk" "" "$FEATURE" "$VAL" fi shift 1 done # config.mk echo "[config.mk]" if [ -f tmp/config.mk ]; then mv tmp/config.mk config.mk shini_write "config.mk" "" "CONFIG_DATE" "$(date +%Y%m%d)" fi cat config.mk echo "" # Checks for compiler echo -e "\nchecking for compiler..." if [ $CROSS_COMPILE ]; then CC=${CROSS_COMPILE}gcc CXX=${CROSS_COMPILE}g++ fi if [ ! $CC ]; then CC=gcc CXX=g++ fi CC_VERSION=`$CC --version 2>&1 | head -n 1` echo "CC = $CC" echo "CXX = $CXX" echo "$CC_VERSION" # Checks for os echo -e "\nchecking for os..." HOST_OS=`uname -s` HOST_ARCH=`uname -m` TARGET_PLATFORM=`$CC -v 2>&1 | grep Target | sed 's/Target: //'` TARGET_ARCH=`echo $TARGET_PLATFORM | awk -F'-' '{print $1}'` case $TARGET_PLATFORM in *mingw*) TARGET_OS=Windows ;; *android*) TARGET_OS=Android ;; *darwin*) TARGET_OS=Darwin ;; *) TARGET_OS=Linux ;; esac echo "HOST_OS = $HOST_OS" echo "HOST_ARCH = $HOST_ARCH" echo "TARGET_PLATFORM = $TARGET_PLATFORM" echo "TARGET_OS = $TARGET_OS" echo "TARGET_ARCH = $TARGET_ARCH" # hconfig.h echo -e "\n>> hconfig.h" confile=hconfig.h cat << END > $confile #ifndef HV_CONFIG_H_ #define HV_CONFIG_H_ END write_define() { cat << END >> hconfig.h #ifndef $macro #define $macro $value #endif END } CheckHeaderExists() { rm tmp/check 2>/dev/null cat << END > tmp/check.c #include <$header> int main() { return 0; } END $CC -o tmp/check tmp/check.c 2>/dev/null if [ -x tmp/check ]; then value=1 else value=0 fi } CheckSymbolExists() { CheckHeaderExists if [ $value -eq 0 ]; then return; fi rm tmp/check 2>/dev/null cat << END > tmp/check.c #include <$header> int $function(void** pp) {return 0;} int main() { void* p; return $function(&p); } END $CC -o tmp/check tmp/check.c 2>/dev/null if [ -x tmp/check ]; then value=0 else value=1 fi } check_header() { echo -n "checking for $header... " CheckHeaderExists if [ $value -eq 0 ]; then echo "no" else echo "yes" fi macro=HAVE_$(echo $header | tr a-z./ A-Z__) write_define } check_function() { echo -n "checking for $function... " CheckSymbolExists if [ $value -eq 0 ]; then echo "no" else echo "yes" fi macro=HAVE_$(echo $function | tr a-z A-Z) write_define } check_option() { value=$(eval echo \$$option) echo "checking for $option=$value" if [ "$value" == "yes" ]; then cat << END >> $confile #define $option 1 END else cat << END >> $confile /* #undef $option */ END fi } # Checks for programs # Checks for libraries # Checks for header files header=stdbool.h && check_header header=stdint.h && check_header header=stdatomic.h && check_header header=sys/types.h && check_header header=sys/stat.h && check_header header=sys/time.h && check_header header=fcntl.h && check_header header=pthread.h && check_header header=endian.h && check_header header=sys/endian.h && check_header # Checks for functions function=gettid && header=unistd.h && check_function function=strlcpy && header=string.h && check_function function=strlcat && header=string.h && check_function function=clock_gettime && header=time.h && check_function function=gettimeofday && header=sys/time.h && check_function function=pthread_spin_lock && header=pthread.h && check_function function=pthread_mutex_timedlock && header=pthread.h && check_function function=sem_timedwait && header=semaphore.h && check_function function=pipe && header=unistd.h && check_function function=socketpair && header=sys/socket.h && check_function function=eventfd && header=sys/eventfd.h && check_function function=setproctitle && header=unistd.h && check_function # Checks for options source config.mk 2>/dev/null option=WITH_OPENSSL && check_option option=WITH_GNUTLS && check_option option=WITH_MBEDTLS && check_option option=ENABLE_UDS && check_option option=USE_MULTIMAP && check_option option=WITH_KCP && check_option option=WITH_IO_URING && check_option # end confile cat << END >> $confile #endif // HV_CONFIG_H_ END echo "configure done." ================================================ FILE: cpputil/LRUCache.h ================================================ #ifndef HV_LRU_CACHE_H_ #define HV_LRU_CACHE_H_ #include #include #include #include #include namespace hv { /** * @brief Thread-safe LRU (Least Recently Used) Cache template * * This template provides a generic LRU cache implementation with the following features: * - Thread-safe operations using mutex * - Configurable capacity with automatic eviction * - O(1) get, put, and remove operations * - Optional eviction callback for cleanup * * @tparam Key The key type (must be hashable) * @tparam Value The value type */ template class LRUCache { public: using key_type = Key; using value_type = Value; using eviction_callback_t = std::function; private: // Double-linked list node for LRU ordering struct Node { Key key; Value value; Node(const Key& k, const Value& v) : key(k), value(v) {} }; using node_list_t = std::list; using node_iterator_t = typename node_list_t::iterator; using hash_map_t = std::unordered_map; public: /** * @brief Construct LRUCache with specified capacity * @param capacity Maximum number of items to cache (default: 100) */ explicit LRUCache(size_t capacity = 100) : capacity_(capacity), eviction_callback_(nullptr) { if (capacity_ == 0) { capacity_ = 1; // Minimum capacity of 1 } } /** * @brief Destructor */ virtual ~LRUCache() { clear(); } // Disable copy constructor and assignment operator LRUCache(const LRUCache&) = delete; LRUCache& operator=(const LRUCache&) = delete; /** * @brief Set eviction callback function * @param callback Function to call when items are evicted */ void set_eviction_callback(eviction_callback_t callback) { std::lock_guard lock(mutex_); eviction_callback_ = callback; } /** * @brief Get value by key * @param key The key to search for * @param value Output parameter for the value * @return true if key exists, false otherwise */ bool get(const Key& key, Value& value) { std::lock_guard lock(mutex_); auto it = hash_map_.find(key); if (it == hash_map_.end()) { return false; } // Move to front (most recently used) move_to_front(it->second); value = it->second->value; return true; } /** * @brief Get value by key (alternative interface) * @param key The key to search for * @return Pointer to value if exists, nullptr otherwise */ Value* get(const Key& key) { std::lock_guard lock(mutex_); auto it = hash_map_.find(key); if (it == hash_map_.end()) { return nullptr; } // Move to front (most recently used) move_to_front(it->second); return &(it->second->value); } /** * @brief Put key-value pair into cache * @param key The key * @param value The value * @return true if new item was added, false if existing item was updated */ bool put(const Key& key, const Value& value) { std::lock_guard lock(mutex_); auto it = hash_map_.find(key); if (it != hash_map_.end()) { // Update existing item it->second->value = value; move_to_front(it->second); return false; } // Add new item if (node_list_.size() >= capacity_) { evict_lru(); } node_list_.emplace_front(key, value); hash_map_[key] = node_list_.begin(); return true; } /** * @brief Remove item by key * @param key The key to remove * @return true if item was removed, false if key not found */ bool remove(const Key& key) { std::lock_guard lock(mutex_); auto it = hash_map_.find(key); if (it == hash_map_.end()) { return false; } // Call eviction callback if set if (eviction_callback_) { eviction_callback_(it->second->key, it->second->value); } node_list_.erase(it->second); hash_map_.erase(it); return true; } /** * @brief Check if key exists in cache * @param key The key to check * @return true if key exists, false otherwise */ bool contains(const Key& key) const { std::lock_guard lock(mutex_); return hash_map_.find(key) != hash_map_.end(); } /** * @brief Clear all items from cache */ void clear() { std::lock_guard lock(mutex_); if (eviction_callback_) { for (const auto& node : node_list_) { eviction_callback_(node.key, node.value); } } node_list_.clear(); hash_map_.clear(); } /** * @brief Get current cache size * @return Number of items in cache */ size_t size() const { std::lock_guard lock(mutex_); return node_list_.size(); } /** * @brief Get cache capacity * @return Maximum number of items cache can hold */ size_t capacity() const { return capacity_; } /** * @brief Check if cache is empty * @return true if cache is empty, false otherwise */ bool empty() const { std::lock_guard lock(mutex_); return node_list_.empty(); } /** * @brief Set new capacity (may trigger eviction) * @param new_capacity New capacity value */ void set_capacity(size_t new_capacity) { if (new_capacity == 0) { new_capacity = 1; // Minimum capacity of 1 } std::lock_guard lock(mutex_); capacity_ = new_capacity; // Evict excess items if necessary while (node_list_.size() > capacity_) { evict_lru(); } } /** * @brief Apply a function to all cached items (for iteration) * @param func Function to apply to each key-value pair * Note: This is provided for compatibility but should be used carefully * as it may affect performance due to locking */ template void for_each(Func func) { std::lock_guard lock(mutex_); for (const auto& node : node_list_) { func(node.key, node.value); } } /** * @brief Remove items that match a predicate * @param predicate Function that returns true for items to remove * @return Number of items removed */ template size_t remove_if(Predicate predicate) { std::lock_guard lock(mutex_); size_t removed_count = 0; auto it = node_list_.begin(); while (it != node_list_.end()) { if (predicate(it->key, it->value)) { // Call eviction callback if set if (eviction_callback_) { eviction_callback_(it->key, it->value); } hash_map_.erase(it->key); it = node_list_.erase(it); removed_count++; } else { ++it; } } return removed_count; } protected: /** * @brief Move node to front of list (most recently used position) * @param it Iterator to the node to move */ void move_to_front(node_iterator_t it) { if (it != node_list_.begin()) { node_list_.splice(node_list_.begin(), node_list_, it); } } /** * @brief Evict least recently used item */ void evict_lru() { if (node_list_.empty()) { return; } auto last = std::prev(node_list_.end()); // Call eviction callback if set if (eviction_callback_) { eviction_callback_(last->key, last->value); } hash_map_.erase(last->key); node_list_.erase(last); } protected: size_t capacity_; // Maximum cache capacity mutable std::mutex mutex_; // Mutex for thread safety node_list_t node_list_; // Doubly-linked list for LRU ordering hash_map_t hash_map_; // Hash map for O(1) access eviction_callback_t eviction_callback_; // Optional eviction callback }; } // namespace hv #endif // HV_LRU_CACHE_H_ ================================================ FILE: cpputil/RAII.cpp ================================================ #include "hplatform.h" #ifdef OS_WIN #ifdef ENABLE_WINDUMP #include #ifdef _MSC_VER #pragma comment(lib,"dbghelp.lib") #endif static LONG UnhandledException(EXCEPTION_POINTERS *pException) { char modulefile[256]; GetModuleFileName(NULL, modulefile, sizeof(modulefile)); char* pos = strrchr(modulefile, '\\'); char* modulefilename = pos + 1; SYSTEMTIME st; GetLocalTime(&st); char filename[256]; snprintf(filename, sizeof(filename), "core_%s_%04d%02d%02d_%02d%02d%02d_%03d.dump", modulefilename, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); HANDLE hDumpFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); MINIDUMP_EXCEPTION_INFORMATION dumpInfo; dumpInfo.ExceptionPointers = pException; dumpInfo.ThreadId = GetCurrentThreadId(); dumpInfo.ClientPointers = TRUE; MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL); CloseHandle(hDumpFile); return EXCEPTION_EXECUTE_HANDLER; } #endif #include "hsocket.h" class WsaRAII { public: WsaRAII() { WSAInit(); #ifdef ENABLE_WINDUMP SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)UnhandledException); #endif } ~WsaRAII() { WSADeinit(); } }; static WsaRAII s_wsa; #endif #ifdef WITH_CURL #include "curl/curl.h" #ifdef _MSC_VER //#pragma comment(lib, "libcurl.a") #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "wldap32.lib") #pragma comment(lib, "advapi32.lib") #pragma comment(lib, "crypt32.lib") #endif class CurlRAII { public: CurlRAII() { curl_global_init(CURL_GLOBAL_ALL); } ~CurlRAII() { curl_global_cleanup(); } }; static CurlRAII s_curl; #endif ================================================ FILE: cpputil/README.md ================================================ ## 目录结构 ``` . ├── hasync.h hv::async实现 ├── hdir.h 目录(ls实现) ├── hfile.h 文件类 ├── hobjectpool.h 对象池 ├── hpath.h 路径操作 ├── hscope.h 作用域模板类 ├── hstring.h 字符串操作 ├── hthreadpool.h 线程池 ├── hurl.h URL操作 ├── ifconfig.h 网络配置(ifconfig实现) ├── iniparser.h INI解析 ├── json.hpp JSON解析 ├── singleton.h 单例模式宏 └── ThreadLocalStorage.h 线程本地存储类 ``` ================================================ FILE: cpputil/ThreadLocalStorage.cpp ================================================ #include "ThreadLocalStorage.h" #include "hthread.h" namespace hv { ThreadLocalStorage ThreadLocalStorage::tls[ThreadLocalStorage::MAX_NUM]; void ThreadLocalStorage::set(int idx, void* val) { return tls[idx].set(val); } void* ThreadLocalStorage::get(int idx) { return tls[idx].get(); } void ThreadLocalStorage::setThreadName(const char* name) { set(THREAD_NAME, (void*)name); } const char* ThreadLocalStorage::threadName() { void* value = get(THREAD_NAME); if (value) { return (char*)value; } static char unnamed[32] = {0}; snprintf(unnamed, sizeof(unnamed)-1, "thread-%ld", hv_gettid()); return unnamed; } } ================================================ FILE: cpputil/ThreadLocalStorage.h ================================================ #ifndef HV_THREAD_LOCAL_STORAGE_H_ #define HV_THREAD_LOCAL_STORAGE_H_ #include "hexport.h" #include "hplatform.h" #ifdef OS_WIN #define hthread_key_t DWORD #define INVALID_HTHREAD_KEY 0xFFFFFFFF #define hthread_key_create(pkey) *pkey = TlsAlloc() #define hthread_key_delete TlsFree #define hthread_get_value TlsGetValue #define hthread_set_value TlsSetValue #else #define hthread_key_t pthread_key_t #define INVALID_HTHREAD_KEY 0xFFFFFFFF #define hthread_key_create(pkey) pthread_key_create(pkey, NULL) #define hthread_key_delete pthread_key_delete #define hthread_get_value pthread_getspecific #define hthread_set_value pthread_setspecific #endif #ifdef __cplusplus namespace hv { class HV_EXPORT ThreadLocalStorage { public: enum { THREAD_NAME = 0, EVENT_LOOP = 1, MAX_NUM = 16, }; ThreadLocalStorage() { hthread_key_create(&key); } ~ThreadLocalStorage() { hthread_key_delete(key); } void set(void* val) { hthread_set_value(key, val); } void* get() { return hthread_get_value(key); } static void set(int idx, void* val); static void* get(int idx); static void setThreadName(const char* name); static const char* threadName(); private: hthread_key_t key; static ThreadLocalStorage tls[MAX_NUM]; }; } #endif #endif // HV_THREAD_LOCAL_STORAGE_H_ ================================================ FILE: cpputil/hasync.cpp ================================================ #include "hasync.h" namespace hv { SINGLETON_IMPL(GlobalThreadPool) } ================================================ FILE: cpputil/hasync.h ================================================ #ifndef HV_ASYNC_H_ #define HV_ASYNC_H_ #include "hexport.h" #include "hthreadpool.h" #include "singleton.h" namespace hv { class HV_EXPORT GlobalThreadPool : public HThreadPool { SINGLETON_DECL(GlobalThreadPool) protected: GlobalThreadPool() : HThreadPool() {} ~GlobalThreadPool() {} }; /* * return a future, calling future.get() will wait task done and return RetType. * async(fn, args...) * async(std::bind(&Class::mem_fn, &obj)) * async(std::mem_fn(&Class::mem_fn, &obj)) * */ template auto async(Fn&& fn, Args&&... args) -> std::future { return GlobalThreadPool::instance()->commit(std::forward(fn), std::forward(args)...); } class async { public: static void startup(int min_threads = DEFAULT_THREAD_POOL_MIN_THREAD_NUM, int max_threads = DEFAULT_THREAD_POOL_MAX_THREAD_NUM, int max_idle_ms = DEFAULT_THREAD_POOL_MAX_IDLE_TIME) { GlobalThreadPool* gtp = GlobalThreadPool::instance(); if (gtp->isStarted()) return; gtp->setMinThreadNum(min_threads); gtp->setMaxThreadNum(max_threads); gtp->setMaxIdleTime(max_idle_ms); gtp->start(); } static void cleanup() { GlobalThreadPool::exitInstance(); } }; } // end namespace hv #endif // HV_ASYNC_H_ ================================================ FILE: cpputil/hdir.cpp ================================================ #include "hdir.h" #include "hplatform.h" #ifdef OS_WIN #include "hstring.h" // import hv::utf8_to_wchar hv::wchar_to_utf8 //FILETIME starts from 1601-01-01 UTC, epoch from 1970-01-01 UTC //FILETIME unit (100ns) #define FILETIME_EPOCH_DIFF 11644473600 // s time_t FileTime2Epoch(FILETIME filetime) { uint64_t ll = (((uint64_t)filetime.dwHighDateTime) << 32) | filetime.dwLowDateTime; ll /= 1e7; // s return ll - FILETIME_EPOCH_DIFF; } #endif static bool less(const hdir_t& lhs, const hdir_t& rhs) { return stricmp(lhs.name, rhs.name) < 0; } int listdir(const char* dir, std::list& dirs) { int dirlen = strlen(dir); if (dirlen > 256) { return -1; } char path[512]; strcpy(path, dir); if (dir[dirlen-1] != '/') { strcat(path, "/"); ++dirlen; } dirs.clear(); #ifdef OS_UNIX // opendir -> readdir -> closedir DIR* dp = opendir(dir); if (dp == NULL) return -1; struct dirent* result = NULL; struct stat st; hdir_t tmp; while ((result = readdir(dp))) { memset(&tmp, 0, sizeof(hdir_t)); strncpy(tmp.name, result->d_name, sizeof(tmp.name)); strncpy(path+dirlen, result->d_name, sizeof(path)-dirlen); if (lstat(path, &st) == 0) { if (S_ISREG(st.st_mode)) tmp.type = 'f'; else if (S_ISDIR(st.st_mode)) tmp.type = 'd'; else if (S_ISLNK(st.st_mode)) tmp.type = 'l'; else if (S_ISBLK(st.st_mode)) tmp.type = 'b'; else if (S_ISCHR(st.st_mode)) tmp.type = 'c'; else if (S_ISSOCK(st.st_mode)) tmp.type = 's'; else if (S_ISFIFO(st.st_mode)) tmp.type = 'p'; else tmp.type = '-'; tmp.mode = st.st_mode & 0777; tmp.size = st.st_size; tmp.atime = st.st_atime; tmp.mtime = st.st_mtime; tmp.ctime = st.st_ctime; } dirs.push_back(tmp); } closedir(dp); #elif defined(OS_WIN) // FindFirstFile -> FindNextFile -> FindClose strcat(path, "*"); WIN32_FIND_DATAW data; HANDLE h = FindFirstFileW(hv::utf8_to_wchar(path).c_str(), &data); if (h == NULL) { return -1; } hdir_t tmp; do { memset(&tmp, 0, sizeof(hdir_t)); strncpy(tmp.name, hv::wchar_to_utf8(data.cFileName).c_str(), sizeof(tmp.name)); tmp.type = 'f'; if (data.dwFileAttributes & _A_SUBDIR) { tmp.type = 'd'; } tmp.mode = 0777; tmp.size = (((uint64_t)data.nFileSizeHigh) << 32) | data.nFileSizeLow; tmp.atime = FileTime2Epoch(data.ftLastAccessTime); tmp.mtime = FileTime2Epoch(data.ftLastWriteTime); tmp.ctime = FileTime2Epoch(data.ftCreationTime); dirs.push_back(tmp); } while (FindNextFileW(h, &data)); FindClose(h); #endif dirs.sort(less); return dirs.size(); } ================================================ FILE: cpputil/hdir.h ================================================ #ifndef HV_DIR_H_ #define HV_DIR_H_ /* *@code int main(int argc, char* argv[]) { const char* dir = "."; if (argc > 1) { dir = argv[1]; } std::list dirs; listdir(dir, dirs); for (auto& item : dirs) { printf("%c%c%c%c%c%c%c%c%c%c\t", item.type, item.mode & 0400 ? 'r' : '-', item.mode & 0200 ? 'w' : '-', item.mode & 0100 ? 'x' : '-', item.mode & 0040 ? 'r' : '-', item.mode & 0020 ? 'w' : '-', item.mode & 0010 ? 'x' : '-', item.mode & 0004 ? 'r' : '-', item.mode & 0002 ? 'w' : '-', item.mode & 0001 ? 'x' : '-'); float hsize; if (item.size < 1024) { printf("%lu\t", item.size); } else if ((hsize = item.size/1024.0f) < 1024.0f) { printf("%.1fK\t", hsize); } else if ((hsize /= 1024.0f) < 1024.0f) { printf("%.1fM\t", hsize); } else { hsize /= 1024.0f; printf("%.1fG\t", hsize); } struct tm* tm = localtime(&item.mtime); printf("%04d-%02d-%02d %02d:%02d:%02d\t", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%s%s\n", item.name, item.type == 'd' ? "/" : ""); } return 0; } */ #include #include #include #include "hexport.h" typedef struct hdir_s { char name[256]; char type; // f:file d:dir l:link b:block c:char s:socket p:pipe char reserverd; unsigned short mode; size_t size; time_t atime; time_t mtime; time_t ctime; } hdir_t; // listdir: same as ls on unix, dir on win HV_EXPORT int listdir(const char* dir, std::list& dirs); #endif // HV_DIR_H_ ================================================ FILE: cpputil/hfile.h ================================================ #ifndef HV_FILE_H_ #define HV_FILE_H_ #include // for std::string #include "hplatform.h" // for stat #include "hbuf.h" // for HBuf class HFile { public: HFile() { filepath[0] = '\0'; fp = NULL; } ~HFile() { close(); } int open(const char* filepath, const char* mode) { close(); strncpy(this->filepath, filepath, MAX_PATH - 1); fp = fopen(filepath, mode); return fp ? 0 : errno; } void close() { if (fp) { fclose(fp); fp = NULL; } } bool isopen() { return fp != NULL; } int remove() { close(); return ::remove(filepath); } int rename(const char* newpath) { close(); return ::rename(filepath, newpath); } size_t read(void* ptr, size_t len) { return fread(ptr, 1, len, fp); } size_t write(const void* ptr, size_t len) { return fwrite(ptr, 1, len, fp); } size_t write(const std::string& str) { return write(str.c_str(), str.length()); } int seek(size_t offset, int whence = SEEK_SET) { return fseek(fp, offset, whence); } int tell() { return ftell(fp); } int flush() { return fflush(fp); } static size_t size(const char* filepath) { struct stat st; memset(&st, 0, sizeof(st)); stat(filepath, &st); return st.st_size; } size_t size() { return HFile::size(filepath); } size_t readall(HBuf& buf) { size_t filesize = size(); if (filesize == 0) return 0; buf.resize(filesize); return fread(buf.base, 1, filesize, fp); } size_t readall(std::string& str) { size_t filesize = size(); if (filesize == 0) return 0; str.resize(filesize); return fread((void*)str.data(), 1, filesize, fp); } bool readline(std::string& str) { str.clear(); char ch; while (fread(&ch, 1, 1, fp)) { if (ch == '\n') { // unix: LF return true; } if (ch == '\r') { // dos: CRLF // read LF if (fread(&ch, 1, 1, fp) && ch != '\n') { // mac: CR fseek(fp, -1, SEEK_CUR); } return true; } str += ch; } return str.length() != 0; } int readrange(std::string& str, size_t from = 0, size_t to = 0) { size_t filesize = size(); if (filesize == 0) return 0; if (to == 0 || to >= filesize) to = filesize - 1; size_t readbytes = to - from + 1; str.resize(readbytes); fseek(fp, from, SEEK_SET); return fread((void*)str.data(), 1, readbytes, fp); } public: char filepath[MAX_PATH]; FILE* fp; }; #endif // HV_FILE_H_ ================================================ FILE: cpputil/hmap.h ================================================ #ifndef HV_MAP_H_ #define HV_MAP_H_ #include "hconfig.h" #include #include // MultiMap namespace std { /* int main() { std::MultiMap kvs; kvs["name"] = "hw"; kvs["filename"] = "1.jpg"; kvs["filename"] = "2.jpg"; //kvs.insert(std::pair("name", "hw")); //kvs.insert(std::pair("filename", "1.jpg")); //kvs.insert(std::pair("filename", "2.jpg")); for (auto& pair : kvs) { printf("%s:%s\n", pair.first.c_str(), pair.second.c_str()); } auto iter = kvs.find("filename"); if (iter != kvs.end()) { for (int i = 0; i < kvs.count("filename"); ++i, ++iter) { printf("%s:%s\n", iter->first.c_str(), iter->second.c_str()); } } return 0; } */ template class MultiMap : public multimap { public: Value& operator[](Key key) { auto iter = this->insert(std::pair(key,Value())); return (*iter).second; } }; } #ifdef USE_MULTIMAP #define HV_MAP std::MultiMap #else #define HV_MAP std::map #endif // KeyValue namespace hv { typedef std::map keyval_t; typedef std::MultiMap multi_keyval_t; typedef HV_MAP KeyValue; } #endif // HV_MAP_H_ ================================================ FILE: cpputil/hobjectpool.h ================================================ #ifndef HV_OBJECT_POOL_H_ #define HV_OBJECT_POOL_H_ /* * @usage unittest/objectpool_test.cpp */ #include #include #include #include #define DEFAULT_OBJECT_POOL_INIT_NUM 0 #define DEFAULT_OBJECT_POOL_MAX_NUM 4 #define DEFAULT_OBJECT_POOL_TIMEOUT 3000 // ms template class HObjectFactory { public: static T* create() { return new T; } }; template> class HObjectPool { public: HObjectPool( int init_num = DEFAULT_OBJECT_POOL_INIT_NUM, int max_num = DEFAULT_OBJECT_POOL_MAX_NUM, int timeout = DEFAULT_OBJECT_POOL_TIMEOUT) : _max_num(max_num) , _timeout(timeout) { for (int i = 0; i < init_num; ++i) { T* p = TFactory::create(); if (p) { objects_.push_back(std::shared_ptr(p)); } } _object_num = objects_.size(); } ~HObjectPool() {} int ObjectNum() { return _object_num; } int IdleNum() { return objects_.size(); } int BorrowNum() { return ObjectNum() - IdleNum(); } std::shared_ptr TryBorrow() { std::shared_ptr pObj = NULL; std::lock_guard locker(mutex_); if (!objects_.empty()) { pObj = objects_.front(); objects_.pop_front(); } return pObj; } std::shared_ptr Borrow() { std::shared_ptr pObj = TryBorrow(); if (pObj) { return pObj; } std::unique_lock locker(mutex_); if (_object_num < _max_num) { ++_object_num; // NOTE: unlock to avoid TFactory::create block mutex_.unlock(); T* p = TFactory::create(); mutex_.lock(); if (!p) --_object_num; return std::shared_ptr(p); } if (_timeout > 0) { std::cv_status status = cond_.wait_for(locker, std::chrono::milliseconds(_timeout)); if (status == std::cv_status::timeout) { return NULL; } if (!objects_.empty()) { pObj = objects_.front(); objects_.pop_front(); return pObj; } else { // WARN: No idle object } } return pObj; } void Return(std::shared_ptr& pObj) { if (!pObj) return; std::lock_guard locker(mutex_); objects_.push_back(pObj); cond_.notify_one(); } bool Add(std::shared_ptr& pObj) { std::lock_guard locker(mutex_); if (_object_num >= _max_num) { return false; } objects_.push_back(pObj); ++_object_num; cond_.notify_one(); return true; } bool Remove(std::shared_ptr& pObj) { std::lock_guard locker(mutex_); auto iter = objects_.begin(); while (iter != objects_.end()) { if (*iter == pObj) { iter = objects_.erase(iter); --_object_num; return true; } else { ++iter; } } return false; } void Clear() { std::lock_guard locker(mutex_); objects_.clear(); _object_num = 0; } int _object_num; int _max_num; int _timeout; private: std::list> objects_; std::mutex mutex_; std::condition_variable cond_; }; template> class HPoolObject { public: typedef HObjectPool PoolType; HPoolObject(PoolType& pool) : pool_(pool) { sptr_ = pool_.Borrow(); } ~HPoolObject() { if (sptr_) { pool_.Return(sptr_); } } HPoolObject(const HPoolObject&) = delete; HPoolObject& operator=(const HPoolObject&) = delete; T* get() { return sptr_.get(); } operator bool() { return sptr_.get() != NULL; } T* operator->() { return sptr_.get(); } T operator*() { return *sptr_.get(); } private: PoolType& pool_; std::shared_ptr sptr_; }; #endif // HV_OBJECT_POOL_H_ ================================================ FILE: cpputil/hpath.cpp ================================================ #include "hpath.h" #include "hplatform.h" bool HPath::exists(const char* path) { return access(path, 0) == 0; } bool HPath::isdir(const char* path) { if (access(path, 0) != 0) return false; struct stat st; memset(&st, 0, sizeof(st)); stat(path, &st); return S_ISDIR(st.st_mode); } bool HPath::isfile(const char* path) { if (access(path, 0) != 0) return false; struct stat st; memset(&st, 0, sizeof(st)); stat(path, &st); return S_ISREG(st.st_mode); } bool HPath::islink(const char* path) { #ifdef OS_WIN return HPath::isdir(path) && (GetFileAttributesA(path) & FILE_ATTRIBUTE_REPARSE_POINT); #else if (access(path, 0) != 0) return false; struct stat st; memset(&st, 0, sizeof(st)); lstat(path, &st); return S_ISLNK(st.st_mode); #endif } std::string HPath::basename(const std::string& filepath) { std::string::size_type pos1 = filepath.find_last_not_of("/\\"); if (pos1 == std::string::npos) { return "/"; } std::string::size_type pos2 = filepath.find_last_of("/\\", pos1); if (pos2 == std::string::npos) { pos2 = 0; } else { pos2++; } return filepath.substr(pos2, pos1-pos2+1); } std::string HPath::dirname(const std::string& filepath) { std::string::size_type pos1 = filepath.find_last_not_of("/\\"); if (pos1 == std::string::npos) { return "/"; } std::string::size_type pos2 = filepath.find_last_of("/\\", pos1); if (pos2 == std::string::npos) { return "."; } else if (pos2 == 0) { pos2 = 1; } return filepath.substr(0, pos2); } std::string HPath::filename(const std::string& filepath) { std::string::size_type pos1 = filepath.find_last_of("/\\"); if (pos1 == std::string::npos) { pos1 = 0; } else { pos1++; } std::string file = filepath.substr(pos1); std::string::size_type pos2 = file.find_last_of("."); if (pos2 == std::string::npos) { return file; } return file.substr(0, pos2); } std::string HPath::suffixname(const std::string& filepath) { std::string::size_type pos1 = filepath.find_last_of("/\\"); if (pos1 == std::string::npos) { pos1 = 0; } else { pos1++; } std::string file = filepath.substr(pos1); std::string::size_type pos2 = file.find_last_of("."); if (pos2 == std::string::npos) { return ""; } return file.substr(pos2+1); } std::string HPath::join(const std::string& dir, const std::string& filename) { char separator = '/'; #ifdef OS_WIN if (dir.find_first_of("\\") != std::string::npos) { separator = '\\'; } #endif std::string filepath(dir); if (dir[dir.length()-1] != separator) { filepath += separator; } filepath += filename; return filepath; } ================================================ FILE: cpputil/hpath.h ================================================ #ifndef HV_PATH_H_ #define HV_PATH_H_ #include // for std::string #include "hexport.h" class HV_EXPORT HPath { public: static bool exists(const char* path); static bool isdir(const char* path); static bool isfile(const char* path); static bool islink(const char* path); // filepath = /mnt/share/image/test.jpg // basename = test.jpg // dirname = /mnt/share/image // filename = test // suffixname = jpg static std::string basename(const std::string& filepath); static std::string dirname(const std::string& filepath); static std::string filename(const std::string& filepath); static std::string suffixname(const std::string& filepath); static std::string join(const std::string& dir, const std::string& filename); }; #endif // HV_PATH_H_ ================================================ FILE: cpputil/hscope.h ================================================ #ifndef HV_SCOPE_H_ #define HV_SCOPE_H_ #include typedef std::function Function; #include "hdef.h" // same as golang defer class Defer { public: Defer(Function&& fn) : _fn(std::move(fn)) {} ~Defer() { if(_fn) _fn();} private: Function _fn; }; #define defer(code) Defer STRINGCAT(_defer_, __LINE__)([&](){code}); class ScopeCleanup { public: template ScopeCleanup(Fn&& fn, Args&&... args) { _cleanup = std::bind(std::forward(fn), std::forward(args)...); } ~ScopeCleanup() { _cleanup(); } private: Function _cleanup; }; template class ScopeFree { public: ScopeFree(T* p) : _p(p) {} ~ScopeFree() {SAFE_FREE(_p);} private: T* _p; }; template class ScopeDelete { public: ScopeDelete(T* p) : _p(p) {} ~ScopeDelete() {SAFE_DELETE(_p);} private: T* _p; }; template class ScopeDeleteArray { public: ScopeDeleteArray(T* p) : _p(p) {} ~ScopeDeleteArray() {SAFE_DELETE_ARRAY(_p);} private: T* _p; }; template class ScopeRelease { public: ScopeRelease(T* p) : _p(p) {} ~ScopeRelease() {SAFE_RELEASE(_p);} private: T* _p; }; template class ScopeLock { public: ScopeLock(T& mutex) : _mutex(mutex) {_mutex.lock();} ~ScopeLock() {_mutex.unlock();} private: T& _mutex; }; #endif // HV_SCOPE_H_ ================================================ FILE: cpputil/hstring.cpp ================================================ #include "hstring.h" #include #include #include #include namespace hv { std::string empty_string; std::map empty_map; std::string& toupper(std::string& str) { // std::transform(str.begin(), str.end(), str.begin(), ::toupper); char* p = (char*)str.c_str(); while (*p != '\0') { if (*p >= 'a' && *p <= 'z') { *p &= ~0x20; } ++p; } return str; } std::string& tolower(std::string& str) { // std::transform(str.begin(), str.end(), str.begin(), ::tolower); char* p = (char*)str.c_str(); while (*p != '\0') { if (*p >= 'A' && *p <= 'Z') { *p |= 0x20; } ++p; } return str; } std::string& reverse(std::string& str) { // std::reverse(str.begin(), str.end()); char* b = (char*)str.c_str(); char* e = b + str.length() - 1; char tmp; while (e > b) { tmp = *e; *e = *b; *b = tmp; --e; ++b; } return str; } bool startswith(const std::string& str, const std::string& start) { if (str.length() < start.length()) return false; return str.compare(0, start.length(), start) == 0; } bool endswith(const std::string& str, const std::string& end) { if (str.length() < end.length()) return false; return str.compare(str.length() - end.length(), end.length(), end) == 0; } bool contains(const std::string& str, const std::string& sub) { if (str.length() < sub.length()) return false; return str.find(sub) != std::string::npos; } static inline int vscprintf(const char* fmt, va_list ap) { return vsnprintf(NULL, 0, fmt, ap); } std::string asprintf(const char* fmt, ...) { va_list ap; va_start(ap, fmt); int len = vscprintf(fmt, ap); va_end(ap); std::string str; str.reserve(len+1); // must resize to set str.size str.resize(len); // must recall va_start on unix va_start(ap, fmt); vsnprintf((char*)str.data(), len+1, fmt, ap); va_end(ap); return str; } StringList split(const std::string& str, char delim) { /* std::stringstream ss; ss << str; string item; StringList res; while (std::getline(ss, item, delim)) { res.push_back(item); } return res; */ const char* p = str.c_str(); const char* value = p; StringList res; while (*p != '\0') { if (*p == delim) { res.push_back(std::string(value, p-value)); value = p+1; } ++p; } res.push_back(value); return res; } hv::KeyValue splitKV(const std::string& str, char kv_kv, char k_v) { enum { s_key, s_value, } state = s_key; const char* p = str.c_str(); const char* key = p; const char* value = NULL; int key_len = 0; int value_len = 0; hv::KeyValue kvs; while (*p != '\0') { if (*p == kv_kv) { if (key_len && value_len) { kvs[std::string(key, key_len)] = std::string(value, value_len); key_len = value_len = 0; } state = s_key; key = p+1; } else if (*p == k_v && state != s_value) { state = s_value; value = p+1; } else { state == s_key ? ++key_len : ++value_len; } ++p; } if (key_len && value_len) { kvs[std::string(key, key_len)] = std::string(value, value_len); } return kvs; } std::string trim(const std::string& str, const char* chars) { std::string::size_type pos1 = str.find_first_not_of(chars); if (pos1 == std::string::npos) return ""; std::string::size_type pos2 = str.find_last_not_of(chars); return str.substr(pos1, pos2-pos1+1); } std::string ltrim(const std::string& str, const char* chars) { std::string::size_type pos = str.find_first_not_of(chars); if (pos == std::string::npos) return ""; return str.substr(pos); } std::string rtrim(const std::string& str, const char* chars) { std::string::size_type pos = str.find_last_not_of(chars); return str.substr(0, pos+1); } std::string trim_pairs(const std::string& str, const char* pairs) { const char* s = str.c_str(); const char* e = str.c_str() + str.size() - 1; const char* p = pairs; bool is_pair = false; while (*p != '\0' && *(p+1) != '\0') { if (*s == *p && *e == *(p+1)) { is_pair = true; break; } p += 2; } return is_pair ? str.substr(1, str.size()-2) : str; } std::string replace(const std::string& str, const std::string& find, const std::string& rep) { std::string res(str); std::string::size_type pos = res.find(find); if (pos != std::string::npos) { res.replace(pos, find.size(), rep); } return res; } std::string replaceAll(const std::string& str, const std::string& find, const std::string& rep) { std::string::size_type pos = 0; std::string::size_type a = find.size(); std::string::size_type b = rep.size(); std::string res(str); while ((pos = res.find(find, pos)) != std::string::npos) { res.replace(pos, a, rep); pos += b; } return res; } void NetAddr::from_string(const std::string& ipport) { auto pos = ipport.find_last_of(':'); if (pos != std::string::npos) { ip = trim_pairs(ipport.substr(0, pos), "[]"); std::string strPort = ipport.substr(pos + 1); port = atoi(strPort.c_str()); } else if (ipport.find('.') != std::string::npos) { ip = ipport; port = 0; } else { port = atoi(ipport.c_str()); } } std::string NetAddr::to_string() { return NetAddr::to_string(ip.c_str(), port); } std::string NetAddr::to_string(const char* ip, int port) { const char* fmt = strchr(ip, ':') ? "[%s]:%d" : "%s:%d"; return hv::asprintf(fmt, ip, port); } #ifdef OS_WIN std::string wchar_to_string(const UINT codePage, const std::wstring &wstr) { std::string str(4 * wstr.size() + 1, '\0'); str.resize(WideCharToMultiByte( codePage, 0, wstr.c_str(), wstr.size(), const_cast(str.data()), str.size(), NULL, NULL)); return str; } std::wstring string_to_wchar(const UINT codePage, const std::string &str) { std::wstring wstr(2 * str.size() + 2, '\0'); wstr.resize(MultiByteToWideChar( codePage, 0, str.c_str(), str.size(), const_cast(wstr.data()), wstr.size())); return wstr; } #endif // OS_WIN } // end namespace hv ================================================ FILE: cpputil/hstring.h ================================================ #ifndef HV_STRING_H_ #define HV_STRING_H_ #include #include #include #include #include "hexport.h" #include "hplatform.h" #include "hmap.h" #define SPACE_CHARS " \t\r\n" #define PAIR_CHARS "{}[]()<>\"\"\'\'``" namespace hv { HV_EXPORT extern std::string empty_string; HV_EXPORT extern std::map empty_map; typedef std::vector StringList; // std::map class StringCaseLess : public std::less { public: bool operator()(const std::string& lhs, const std::string& rhs) const { return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; } }; // NOTE: low-version NDK not provide std::to_string template HV_INLINE std::string to_string(const T& t) { std::ostringstream oss; oss << t; return oss.str(); } template HV_INLINE T from_string(const std::string& str) { T t; std::istringstream iss(str); iss >> t; return t; } template HV_INLINE void print(const T& t) { std::cout << t; } template HV_INLINE void println(const T& t) { std::cout << t << std::endl; } HV_EXPORT std::string& toupper(std::string& str); HV_EXPORT std::string& tolower(std::string& str); HV_EXPORT std::string& reverse(std::string& str); HV_EXPORT bool startswith(const std::string& str, const std::string& start); HV_EXPORT bool endswith(const std::string& str, const std::string& end); HV_EXPORT bool contains(const std::string& str, const std::string& sub); HV_EXPORT std::string asprintf(const char* fmt, ...); // x,y,z HV_EXPORT StringList split(const std::string& str, char delim = ','); // k1=v1&k2=v2 HV_EXPORT hv::KeyValue splitKV(const std::string& str, char kv_kv = '&', char k_v = '='); HV_EXPORT std::string trim(const std::string& str, const char* chars = SPACE_CHARS); HV_EXPORT std::string ltrim(const std::string& str, const char* chars = SPACE_CHARS); HV_EXPORT std::string rtrim(const std::string& str, const char* chars = SPACE_CHARS); HV_EXPORT std::string trim_pairs(const std::string& str, const char* pairs = PAIR_CHARS); HV_EXPORT std::string replace(const std::string& str, const std::string& find, const std::string& rep); HV_EXPORT std::string replaceAll(const std::string& str, const std::string& find, const std::string& rep); struct HV_EXPORT NetAddr { std::string ip; int port; NetAddr() : port(0) {} NetAddr(const std::string& _ip, int _port) : ip(_ip), port(_port) {} NetAddr(const std::string& ipport) { from_string(ipport); } void from_string(const std::string& ipport); std::string to_string(); static std::string to_string(const char* ip, int port); }; // windows wchar and utf8/ansi conver #ifdef OS_WIN HV_EXPORT std::string wchar_to_string(const UINT codePage, const std::wstring &wstr); HV_EXPORT std::wstring string_to_wchar(const UINT codePage, const std::string &str); HV_INLINE std::string wchar_to_utf8(const std::wstring &wstr) { return wchar_to_string(CP_UTF8, wstr); } HV_INLINE std::string wchar_to_ansi(const std::wstring &wstr) { return wchar_to_string(CP_ACP, wstr); } HV_INLINE std::wstring utf8_to_wchar(const std::string &str) { return string_to_wchar(CP_UTF8, str); } HV_INLINE std::string utf8_to_ansi(const std::string &str) { return wchar_to_string(CP_ACP, string_to_wchar(CP_UTF8, str)); } HV_INLINE std::string ansi_to_utf8(const std::string &str) { return wchar_to_string(CP_UTF8, string_to_wchar(CP_ACP, str)); } #endif // OS_WIN } // end namespace hv #endif // HV_STRING_H_ ================================================ FILE: cpputil/hthreadpool.h ================================================ #ifndef HV_THREAD_POOL_H_ #define HV_THREAD_POOL_H_ /* * @usage unittest/threadpool_test.cpp */ #include #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_THREAD_POOL_MIN_THREAD_NUM 1 #define DEFAULT_THREAD_POOL_MAX_THREAD_NUM std::thread::hardware_concurrency() #define DEFAULT_THREAD_POOL_MAX_IDLE_TIME 60000 // ms class HThreadPool { public: using Task = std::function; HThreadPool(int min_threads = DEFAULT_THREAD_POOL_MIN_THREAD_NUM, int max_threads = DEFAULT_THREAD_POOL_MAX_THREAD_NUM, int max_idle_ms = DEFAULT_THREAD_POOL_MAX_IDLE_TIME) : min_thread_num(min_threads) , max_thread_num(max_threads) , max_idle_time(max_idle_ms) , status(STOP) , cur_thread_num(0) , idle_thread_num(0) {} virtual ~HThreadPool() { stop(); } void setMinThreadNum(int min_threads) { min_thread_num = min_threads; } void setMaxThreadNum(int max_threads) { max_thread_num = max_threads; } void setMaxIdleTime(int ms) { max_idle_time = ms; } int currentThreadNum() { return cur_thread_num; } int idleThreadNum() { return idle_thread_num; } size_t taskNum() { std::lock_guard locker(task_mutex); return tasks.size(); } bool isStarted() { return status != STOP; } bool isStopped() { return status == STOP; } int start(int start_threads = 0) { if (status != STOP) return -1; status = RUNNING; if (start_threads < min_thread_num) start_threads = min_thread_num; if (start_threads > max_thread_num) start_threads = max_thread_num; for (int i = 0; i < start_threads; ++i) { createThread(); } return 0; } int stop() { if (status == STOP) return -1; status = STOP; task_cond.notify_all(); for (auto& i : threads) { if (i.thread->joinable()) { i.thread->join(); } } threads.clear(); cur_thread_num = 0; idle_thread_num = 0; return 0; } int pause() { if (status == RUNNING) { status = PAUSE; } return 0; } int resume() { if (status == PAUSE) { status = RUNNING; } return 0; } int wait() { while (status != STOP) { if (tasks.empty() && idle_thread_num == cur_thread_num) { break; } std::this_thread::yield(); } return 0; } /* * return a future, calling future.get() will wait task done and return RetType. * commit(fn, args...) * commit(std::bind(&Class::mem_fn, &obj)) * commit(std::mem_fn(&Class::mem_fn, &obj)) * */ template auto commit(Fn&& fn, Args&&... args) -> std::future { if (status == STOP) start(); if (idle_thread_num <= tasks.size() && cur_thread_num < max_thread_num) { createThread(); } using RetType = decltype(fn(args...)); auto task = std::make_shared >( std::bind(std::forward(fn), std::forward(args)...)); std::future future = task->get_future(); { std::lock_guard locker(task_mutex); tasks.emplace([task]{ (*task)(); }); } task_cond.notify_one(); return future; } protected: bool createThread() { if (cur_thread_num >= max_thread_num) return false; std::thread* thread = new std::thread([this] { while (status != STOP) { while (status == PAUSE) { std::this_thread::yield(); } Task task; { std::unique_lock locker(task_mutex); task_cond.wait_for(locker, std::chrono::milliseconds(max_idle_time), [this]() { return status == STOP || !tasks.empty(); }); if (status == STOP) return; if (tasks.empty()) { if (cur_thread_num > min_thread_num) { delThread(std::this_thread::get_id()); return; } continue; } --idle_thread_num; task = std::move(tasks.front()); tasks.pop(); } if (task) { task(); ++idle_thread_num; } } }); addThread(thread); return true; } void addThread(std::thread* thread) { thread_mutex.lock(); ++cur_thread_num; ++idle_thread_num; ThreadData data; data.thread = std::shared_ptr(thread); data.id = thread->get_id(); data.status = RUNNING; data.start_time = time(NULL); data.stop_time = 0; threads.emplace_back(data); thread_mutex.unlock(); } void delThread(std::thread::id id) { time_t now = time(NULL); thread_mutex.lock(); --cur_thread_num; --idle_thread_num; auto iter = threads.begin(); while (iter != threads.end()) { if (iter->status == STOP && now > iter->stop_time) { if (iter->thread->joinable()) { iter->thread->join(); iter = threads.erase(iter); continue; } } else if (iter->id == id) { iter->status = STOP; iter->stop_time = time(NULL); } ++iter; } thread_mutex.unlock(); } public: int min_thread_num; int max_thread_num; int max_idle_time; protected: enum Status { STOP, RUNNING, PAUSE, }; struct ThreadData { std::shared_ptr thread; std::thread::id id; Status status; time_t start_time; time_t stop_time; }; std::atomic status; std::atomic cur_thread_num; std::atomic idle_thread_num; std::list threads; std::mutex thread_mutex; std::queue tasks; std::mutex task_mutex; std::condition_variable task_cond; }; #endif // HV_THREAD_POOL_H_ ================================================ FILE: cpputil/hurl.cpp ================================================ #include "hurl.h" #include "hdef.h" #include "hbase.h" /* static bool Curl_isunreserved(unsigned char in) { switch(in) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '-': case '.': case '_': case '~': return TRUE; default: break; } return FLASE; } */ static inline bool is_unambiguous(char c) { return IS_ALPHANUM(c) || c == '-' || c == '_' || c == '.' || c == '~'; } static inline bool char_in_str(char c, const char* str) { const char* p = str; while (*p && *p != c) ++p; return *p != '\0'; } static inline unsigned char hex2i(char hex) { return hex <= '9' ? hex - '0' : hex <= 'F' ? hex - 'A' + 10 : hex - 'a' + 10; } std::string HUrl::escape(const std::string& str, const char* unescaped_chars) { std::string ostr; static char tab[] = "0123456789ABCDEF"; const unsigned char* p = reinterpret_cast(str.c_str()); char szHex[4] = "%00"; while (*p != '\0') { if (is_unambiguous(*p) || char_in_str(*p, unescaped_chars)) { ostr += *p; } else { szHex[1] = tab[*p >> 4]; szHex[2] = tab[*p & 0xF]; ostr += szHex; } ++p; } return ostr; } std::string HUrl::unescape(const std::string& str) { std::string ostr; const char* p = str.c_str(); while (*p != '\0') { if (*p == '%' && IS_HEX(p[1]) && IS_HEX(p[2])) { ostr += ((hex2i(p[1]) << 4) | hex2i(p[2])); p += 3; } else { if (*p == '+') { ostr += ' '; } else { ostr += *p; } ++p; } } return ostr; } void HUrl::reset() { url.clear(); scheme.clear(); username.clear(); password.clear(); host.clear(); port = 0; path.clear(); query.clear(); fragment.clear(); } bool HUrl::parse(const std::string& url) { reset(); this->url = url; hurl_t stURL; if (hv_parse_url(&stURL, url.c_str()) != 0) { return false; } int len = stURL.fields[HV_URL_SCHEME].len; if (len > 0) { scheme = url.substr(stURL.fields[HV_URL_SCHEME].off, len); } len = stURL.fields[HV_URL_USERNAME].len; if (len > 0) { username = url.substr(stURL.fields[HV_URL_USERNAME].off, len); len = stURL.fields[HV_URL_PASSWORD].len; if (len > 0) { password = url.substr(stURL.fields[HV_URL_PASSWORD].off, len); } } len = stURL.fields[HV_URL_HOST].len; if (len > 0) { host = url.substr(stURL.fields[HV_URL_HOST].off, len); } port = stURL.port; len = stURL.fields[HV_URL_PATH].len; if (len > 0) { path = url.substr(stURL.fields[HV_URL_PATH].off, len); } else { path = "/"; } len = stURL.fields[HV_URL_QUERY].len; if (len > 0) { query = url.substr(stURL.fields[HV_URL_QUERY].off, len); } len = stURL.fields[HV_URL_FRAGMENT].len; if (len > 0) { fragment = url.substr(stURL.fields[HV_URL_FRAGMENT].off, len); } return true; } const std::string& HUrl::dump() { url.clear(); // scheme:// if (!scheme.empty()) { url += scheme; url += "://"; } // user:pswd@ if (!username.empty()) { url += username; if (!password.empty()) { url += ":"; url += password; } url += "@"; } // host:port if (!host.empty()) { url += host; if (port != 80 && port != 443) { char buf[16] = {0}; snprintf(buf, sizeof(buf), ":%d", port); url += buf; } } // /path if (!path.empty()) { url += path; } // ?query if (!query.empty()) { url += '?'; url += query; } // #fragment if (!fragment.empty()) { url += '#'; url += fragment; } return url; } namespace hv { std::string escapeHTML(const std::string& str) { std::string ostr; const char* p = str.c_str(); while (*p != '\0') { switch (*p) { case '<': ostr += "<"; break; case '>': ostr += ">"; break; case '&': ostr += "&"; break; case '\"': ostr += """; break; case '\'': ostr += "'"; break; // case ' ': ostr += " "; break; default: ostr += *p; break; } ++p; } return ostr; } } ================================================ FILE: cpputil/hurl.h ================================================ #ifndef HV_URL_H_ #define HV_URL_H_ #include // import std::string #include "hexport.h" class HV_EXPORT HUrl { public: static std::string escape(const std::string& str, const char* unescaped_chars = ""); static std::string unescape(const std::string& str); HUrl() : port(0) {} ~HUrl() {} void reset(); bool parse(const std::string& url); const std::string& dump(); std::string url; std::string scheme; std::string username; std::string password; std::string host; int port; std::string path; std::string query; std::string fragment; }; namespace hv { HV_INLINE std::string escapeURL(const std::string& url) { return HUrl::escape(url, ":/@[]?=&#+"); } HV_EXPORT std::string escapeHTML(const std::string& str); } // end namespace hv #endif // HV_URL_H_ ================================================ FILE: cpputil/ifconfig.cpp ================================================ #include "ifconfig.h" #include "hplatform.h" #ifdef OS_LINUX #include #include #include #include #include #include #include int ifconfig(std::vector& ifcs) { int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { return -10; } struct ifconf ifc; char buf[1024]; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; int iRet = ioctl(sock, SIOCGIFCONF, &ifc); if (iRet != 0) { close(sock); return iRet; } int cnt = ifc.ifc_len / sizeof(struct ifreq); //printf("ifc.size=%d\n", cnt); if (cnt == 0) { close(sock); return -20; } struct ifreq ifr; ifcs.clear(); ifconfig_t tmp; for (int i = 0; i < cnt; ++i) { // name strcpy(ifr.ifr_name, ifc.ifc_req[i].ifr_name); //printf("name: %s\n", ifr.ifr_name); strncpy(tmp.name, ifr.ifr_name, sizeof(tmp.name)); // flags //iRet = ioctl(sock, SIOCGIFFLAGS, &ifr); //short flags = ifr.ifr_flags; // addr iRet = ioctl(sock, SIOCGIFADDR, &ifr); struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr; char* ip = inet_ntoa(addr->sin_addr); //printf("ip: %s\n", ip); strncpy(tmp.ip, ip, sizeof(tmp.ip)); // netmask iRet = ioctl(sock, SIOCGIFNETMASK, &ifr); addr = (struct sockaddr_in*)&ifr.ifr_netmask; char* netmask = inet_ntoa(addr->sin_addr); //printf("netmask: %s\n", netmask); strncpy(tmp.mask, netmask, sizeof(tmp.mask)); // broadaddr iRet = ioctl(sock, SIOCGIFBRDADDR, &ifr); addr = (struct sockaddr_in*)&ifr.ifr_broadaddr; char* broadaddr = inet_ntoa(addr->sin_addr); //printf("broadaddr: %s\n", broadaddr); strncpy(tmp.broadcast, broadaddr, sizeof(tmp.broadcast)); // hwaddr iRet = ioctl(sock, SIOCGIFHWADDR, &ifr); snprintf(tmp.mac, sizeof(tmp.mac), "%02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)ifr.ifr_hwaddr.sa_data[0], (unsigned char)ifr.ifr_hwaddr.sa_data[1], (unsigned char)ifr.ifr_hwaddr.sa_data[2], (unsigned char)ifr.ifr_hwaddr.sa_data[3], (unsigned char)ifr.ifr_hwaddr.sa_data[4], (unsigned char)ifr.ifr_hwaddr.sa_data[5]); //printf("mac: %s\n", tmp.mac); //printf("\n"); if (strcmp(tmp.ip, "0.0.0.0") == 0 || strcmp(tmp.ip, "127.0.0.1") == 0 || strcmp(tmp.mac, "00:00:00:00:00:00") == 0) { continue; } ifcs.push_back(tmp); } close(sock); return 0; } #elif defined(OS_WIN) #include #include #include #include int ifconfig(std::vector& ifcs) { PIP_ADAPTER_ADDRESSES pAddrs = NULL; ULONG buflen = 0; GetAdaptersAddresses(AF_INET, 0, NULL, pAddrs, &buflen); if (buflen <= 0) return -20; pAddrs = (PIP_ADAPTER_ADDRESSES)malloc(buflen); GetAdaptersAddresses(AF_INET, 0, NULL, pAddrs, &buflen); PIP_ADAPTER_INFO pInfos = NULL; buflen = 0; GetAdaptersInfo(pInfos, &buflen); if (buflen <= 0) { free(pAddrs); return -20; } pInfos = (PIP_ADAPTER_INFO)malloc(buflen); GetAdaptersInfo(pInfos, &buflen); ifconfig_t ifc; std::vector tmp_ifcs; PIP_ADAPTER_ADDRESSES pAddr = pAddrs; char mac[32] = {'\0'}; while (pAddr) { snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x", pAddr->PhysicalAddress[0], pAddr->PhysicalAddress[1], pAddr->PhysicalAddress[2], pAddr->PhysicalAddress[3], pAddr->PhysicalAddress[4], pAddr->PhysicalAddress[5]); memset(&ifc, 0, sizeof(ifc)); strncpy(ifc.name, pAddr->AdapterName, sizeof(ifc.name)); strncpy(ifc.ip, "0.0.0.0", sizeof(ifc.ip)); strncpy(ifc.mask, "255.255.255.255", sizeof(ifc.mask)); strncpy(ifc.mac, mac, sizeof(ifc.mac)); tmp_ifcs.push_back(ifc); pAddr = pAddr->Next; } PIP_ADAPTER_INFO pInfo = pInfos; while (pInfo) { for (auto& item : tmp_ifcs) { if (strcmp(item.name, pInfo->AdapterName) == 0) { // description more friendly strncpy(item.name, pInfo->Description, sizeof(item.name)); strncpy(item.ip, pInfo->IpAddressList.IpAddress.String, sizeof(item.ip)); strncpy(item.mask, pInfo->IpAddressList.IpMask.String, sizeof(item.mask)); } } pInfo = pInfo->Next; } free(pAddrs); free(pInfos); // filter ifcs.clear(); for (auto& item : tmp_ifcs) { if (strcmp(item.ip, "0.0.0.0") == 0 || strcmp(item.ip, "127.0.0.1") == 0 || strcmp(item.mac, "00:00:00:00:00:00") == 0) { continue; } ifcs.push_back(item); } return 0; } #elif defined(OS_MAC) #include #include int ifconfig(std::vector& ifcs) { struct ifaddrs *ifas, *ifap; int ret = getifaddrs(&ifas); if (ret != 0) return ret; ifconfig_s tmp; for (ifap = ifas; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr->sa_family == AF_INET) { // ipv4 struct sockaddr_in* addr = (struct sockaddr_in*)ifap->ifa_addr; char* ip = inet_ntoa(addr->sin_addr); // filter if (strcmp(ip, "0.0.0.0") == 0 || strcmp(ip, "127.0.0.1") == 0) { continue; } memset(&tmp, 0, sizeof(tmp)); strncpy(tmp.name, ifap->ifa_name, sizeof(tmp.name)); strncpy(tmp.ip, ip, sizeof(tmp.ip)); // netmask addr = (struct sockaddr_in*)ifap->ifa_netmask; char* netmask = inet_ntoa(addr->sin_addr); strncpy(tmp.mask, netmask, sizeof(tmp.mask)); // broadaddr addr = (struct sockaddr_in*)ifap->ifa_broadaddr; char* broadaddr = inet_ntoa(addr->sin_addr); strncpy(tmp.broadcast, broadaddr, sizeof(tmp.broadcast)); // push_back ifcs.push_back(tmp); } } for (ifap = ifas; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr->sa_family == AF_LINK) { // hwaddr for (auto iter = ifcs.begin(); iter != ifcs.end(); ++iter) { if (strcmp(iter->name, ifap->ifa_name) == 0) { struct sockaddr_dl* addr = (struct sockaddr_dl*)ifap->ifa_addr; unsigned char* pmac = (unsigned char*)LLADDR(addr); snprintf(iter->mac, sizeof(iter->mac), "%02x:%02x:%02x:%02x:%02x:%02x", pmac[0], pmac[1], pmac[2], pmac[3], pmac[4], pmac[5]); // filter if (strcmp(iter->mac, "00:00:00:00:00:00") == 0) { ifcs.erase(iter); } break; } } } } freeifaddrs(ifas); return 0; } #else int ifconfig(std::vector& ifcs) { return -10; // unimplemented } #endif ================================================ FILE: cpputil/ifconfig.h ================================================ #ifndef HV_IFCONFIG_H_ #define HV_IFCONFIG_H_ #include #include "hexport.h" #ifdef _MSC_VER #pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "ws2_32.lib") #endif typedef struct ifconfig_s { char name[128]; char ip[16]; char mask[16]; char broadcast[16]; char mac[20]; } ifconfig_t; /* * @test std::vector ifcs; ifconfig(ifcs); for (auto& item : ifcs) { printf("%s\nip: %s\nmask: %s\nbroadcast: %s\nmac: %s\n\n", item.name, item.ip, item.mask, item.broadcast, item.mac); } */ HV_EXPORT int ifconfig(std::vector& ifcs); #endif // HV_IFCONFIG_H_ ================================================ FILE: cpputil/iniparser.cpp ================================================ #include "iniparser.h" #include #include "hdef.h" #include "herr.h" #include "hstring.h" #include "hfile.h" #include "hbase.h" using namespace hv; /********************************** # div [section] key = value # span # div ***********************************/ class IniNode { public: enum Type { INI_NODE_TYPE_UNKNOWN, INI_NODE_TYPE_ROOT, INI_NODE_TYPE_SECTION, INI_NODE_TYPE_KEY_VALUE, INI_NODE_TYPE_DIV, INI_NODE_TYPE_SPAN, } type; std::string label; // section|key|comment std::string value; std::list children; virtual ~IniNode() { for (auto pNode : children) { if (pNode) { delete pNode; } } children.clear(); } void Add(IniNode* pNode) { children.push_back(pNode); } void Del(IniNode* pNode) { for (auto iter = children.begin(); iter != children.end(); ++iter) { if ((*iter) == pNode) { delete (*iter); children.erase(iter); return; } } } IniNode* Get(const std::string& label, Type type = INI_NODE_TYPE_KEY_VALUE) { for (auto pNode : children) { if (pNode->type == type && pNode->label == label) { return pNode; } } return NULL; } }; class IniSection : public IniNode { public: IniSection() : IniNode(), section(label) { type = INI_NODE_TYPE_SECTION; } std::string §ion; }; class IniKeyValue : public IniNode { public: IniKeyValue() : IniNode(), key(label) { type = INI_NODE_TYPE_KEY_VALUE; } std::string &key; }; class IniComment : public IniNode { public: IniComment() : IniNode(), comment(label) { } std::string &comment; }; IniParser::IniParser() { _comment = DEFAULT_INI_COMMENT; _delim = DEFAULT_INI_DELIM; root_ = NULL; } IniParser::~IniParser() { Unload(); } int IniParser::Unload() { SAFE_DELETE(root_); return 0; } int IniParser::Reload() { return LoadFromFile(_filepath.c_str()); } int IniParser::LoadFromFile(const char* filepath) { _filepath = filepath; HFile file; if (file.open(filepath, "r") != 0) { return ERR_OPEN_FILE; } std::string str; file.readall(str); const char* c_str = str.c_str(); unsigned char utf8_bom[3] = { 0xEF, 0xBB, 0xBF }; if (str.size() >= 3 && memcmp(c_str, utf8_bom, 3) == 0) { c_str += 3; } return LoadFromMem(c_str); } int IniParser::LoadFromMem(const char* data) { Unload(); root_ = new IniNode; root_->type = IniNode::INI_NODE_TYPE_ROOT; std::stringstream ss; ss << data; std::string strLine; int line = 0; std::string::size_type pos; std::string content, comment, strDiv; IniNode* pScopeNode = root_; IniNode* pNewNode = NULL; while (std::getline(ss, strLine)) { ++line; content = ltrim(strLine); if (content.length() == 0) { // blank line strDiv += '\n'; continue; } // trim_comment comment = ""; pos = content.find_first_of(_comment); if (pos != std::string::npos) { comment = content.substr(pos); content = content.substr(0, pos); } content = rtrim(content); if (content.length() == 0) { strDiv += strLine; strDiv += '\n'; continue; } else if (strDiv.length() != 0) { IniNode* pNode = new IniNode; pNode->type = IniNode::INI_NODE_TYPE_DIV; pNode->label = strDiv; pScopeNode->Add(pNode); strDiv = ""; } if (content[0] == '[') { if (content[content.length()-1] == ']') { // section content = trim(content.substr(1, content.length()-2)); pNewNode = new IniNode; pNewNode->type = IniNode::INI_NODE_TYPE_SECTION; pNewNode->label = content; root_->Add(pNewNode); pScopeNode = pNewNode; } else { // hlogw("format error, line:%d", line); continue; // ignore } } else { pos = content.find_first_of(_delim); if (pos != std::string::npos) { // key-value pNewNode = new IniNode; pNewNode->type = IniNode::INI_NODE_TYPE_KEY_VALUE; pNewNode->label = trim(content.substr(0, pos)); pNewNode->value = trim(content.substr(pos+_delim.length())); pScopeNode->Add(pNewNode); } else { // hlogw("format error, line:%d", line); continue; // ignore } } if (comment.length() != 0) { // tail_comment IniNode* pNode = new IniNode; pNode->type = IniNode::INI_NODE_TYPE_SPAN; pNode->label = comment; pNewNode->Add(pNode); comment = ""; } } // file end comment if (strDiv.length() != 0) { IniNode* pNode = new IniNode; pNode->type = IniNode::INI_NODE_TYPE_DIV; pNode->label = strDiv; root_->Add(pNode); } return 0; } void IniParser::DumpString(IniNode* pNode, std::string& str) { if (pNode == NULL) return; if (pNode->type != IniNode::INI_NODE_TYPE_SPAN) { if (str.length() > 0 && str[str.length()-1] != '\n') { str += '\n'; } } switch (pNode->type) { case IniNode::INI_NODE_TYPE_SECTION: { str += '['; str += pNode->label; str += ']'; } break; case IniNode::INI_NODE_TYPE_KEY_VALUE: { str += asprintf("%s %s %s", pNode->label.c_str(), _delim.c_str(), pNode->value.c_str()); } break; case IniNode::INI_NODE_TYPE_DIV: { str += pNode->label; } break; case IniNode::INI_NODE_TYPE_SPAN: { str += '\t'; str += pNode->label; } break; default: break; } for (auto p : pNode->children) { DumpString(p, str); } } std::string IniParser::DumpString() { std::string str; DumpString(root_, str); return str; } int IniParser::Save() { return SaveAs(_filepath.c_str()); } int IniParser::SaveAs(const char* filepath) { std::string str = DumpString(); if (str.length() == 0) { return 0; } HFile file; if (file.open(filepath, "w") != 0) { return ERR_SAVE_FILE; } file.write(str.c_str(), str.length()); return 0; } std::list IniParser::GetSections() { std::list ret; if (root_ == NULL) return ret; for (auto pNode : root_->children) { if (pNode->type == IniNode::INI_NODE_TYPE_SECTION) { ret.push_back(pNode->label); } } return ret; } std::list IniParser::GetKeys(const std::string& section) { std::list ret; if (root_ == NULL) return ret; IniNode* pSection = root_; if (section.length() != 0) { pSection = root_->Get(section, IniNode::INI_NODE_TYPE_SECTION); if (pSection == NULL) return ret; } for (auto pNode : pSection->children) { if (pNode->type == IniNode::INI_NODE_TYPE_KEY_VALUE) { ret.push_back(pNode->label); } } return ret; } std::string IniParser::GetValue(const std::string& key, const std::string& section) { if (root_ == NULL) return ""; IniNode* pSection = root_; if (section.length() != 0) { pSection = root_->Get(section, IniNode::INI_NODE_TYPE_SECTION); if (pSection == NULL) return ""; } IniNode* pKV = pSection->Get(key, IniNode::INI_NODE_TYPE_KEY_VALUE); if (pKV == NULL) return ""; return pKV->value; } void IniParser::SetValue(const std::string& key, const std::string& value, const std::string& section) { if (root_ == NULL) { root_ = new IniNode; } IniNode* pSection = root_; if (section.length() != 0) { pSection = root_->Get(section, IniNode::INI_NODE_TYPE_SECTION); if (pSection == NULL) { pSection = new IniNode; pSection->type = IniNode::INI_NODE_TYPE_SECTION; pSection->label = section; root_->Add(pSection); } } IniNode* pKV = pSection->Get(key, IniNode::INI_NODE_TYPE_KEY_VALUE); if (pKV == NULL) { pKV = new IniNode; pKV->type = IniNode::INI_NODE_TYPE_KEY_VALUE; pKV->label = key; pSection->Add(pKV); } pKV->value = value; } template<> HV_EXPORT bool IniParser::Get(const std::string& key, const std::string& section, bool defvalue) { std::string str = GetValue(key, section); return str.empty() ? defvalue : hv_getboolean(str.c_str()); } template<> HV_EXPORT int IniParser::Get(const std::string& key, const std::string& section, int defvalue) { std::string str = GetValue(key, section); return str.empty() ? defvalue : atoi(str.c_str()); } template<> HV_EXPORT float IniParser::Get(const std::string& key, const std::string& section, float defvalue) { std::string str = GetValue(key, section); return str.empty() ? defvalue : atof(str.c_str()); } template<> HV_EXPORT void IniParser::Set(const std::string& key, const bool& value, const std::string& section) { SetValue(key, value ? "true" : "false", section); } template<> HV_EXPORT void IniParser::Set(const std::string& key, const int& value, const std::string& section) { SetValue(key, asprintf("%d", value), section); } template<> HV_EXPORT void IniParser::Set(const std::string& key, const float& value, const std::string& section) { SetValue(key, asprintf("%f", value), section); } ================================================ FILE: cpputil/iniparser.h ================================================ #ifndef HV_INI_PARSER_H_ #define HV_INI_PARSER_H_ #include #include #include "hexport.h" #define DEFAULT_INI_COMMENT "#" #define DEFAULT_INI_DELIM "=" // fwd class IniNode; class HV_EXPORT IniParser { public: IniParser(); ~IniParser(); int LoadFromFile(const char* filepath); int LoadFromMem(const char* data); int Unload(); int Reload(); std::string DumpString(); int Save(); int SaveAs(const char* filepath); std::list GetSections(); std::list GetKeys(const std::string& section = ""); std::string GetValue(const std::string& key, const std::string& section = ""); void SetValue(const std::string& key, const std::string& value, const std::string& section = ""); // T = [bool, int, float] template T Get(const std::string& key, const std::string& section = "", T defvalue = 0); // T = [bool, int, float] template void Set(const std::string& key, const T& value, const std::string& section = ""); protected: void DumpString(IniNode* pNode, std::string& str); public: std::string _comment; std::string _delim; std::string _filepath; private: IniNode* root_; }; #endif // HV_INI_PARSER_H_ ================================================ FILE: cpputil/json.hpp ================================================ // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT /****************************************************************************\ * Note on documentation: The source files contain links to the online * * documentation of the public API at https://json.nlohmann.me. This URL * * contains the most recent documentation and should also be applicable to * * previous versions; documentation for deprecated functions is not * * removed, but marked deprecated. See "Generate documentation" section in * * file docs/README.md. * \****************************************************************************/ #ifndef INCLUDE_NLOHMANN_JSON_HPP_ #define INCLUDE_NLOHMANN_JSON_HPP_ #include // all_of, find, for_each #include // nullptr_t, ptrdiff_t, size_t #include // hash, less #include // initializer_list #ifndef JSON_NO_IO #include // istream, ostream #endif // JSON_NO_IO #include // random_access_iterator_tag #include // unique_ptr #include // string, stoi, to_string #include // declval, forward, move, pair, swap #include // vector // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // This file contains all macro definitions affecting or depending on the ABI #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 #warning "Already included a different version of the library!" #endif #endif #endif #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) #define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum) #define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) #ifndef JSON_DIAGNOSTICS #define JSON_DIAGNOSTICS 0 #endif #ifndef JSON_DIAGNOSTIC_POSITIONS #define JSON_DIAGNOSTIC_POSITIONS 0 #endif #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 #endif #if JSON_DIAGNOSTICS #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag #else #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS #endif #if JSON_DIAGNOSTIC_POSITIONS #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp #else #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS #endif #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp #else #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON #endif #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 #endif // Construct the namespace ABI tags component #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \ NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) #define NLOHMANN_JSON_ABI_TAGS \ NLOHMANN_JSON_ABI_TAGS_CONCAT( \ NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) // Construct the namespace version component #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ _v ## major ## _ ## minor ## _ ## patch #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) #if NLOHMANN_JSON_NAMESPACE_NO_VERSION #define NLOHMANN_JSON_NAMESPACE_VERSION #else #define NLOHMANN_JSON_NAMESPACE_VERSION \ NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ NLOHMANN_JSON_VERSION_MINOR, \ NLOHMANN_JSON_VERSION_PATCH) #endif // Combine namespace components #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) #ifndef NLOHMANN_JSON_NAMESPACE #define NLOHMANN_JSON_NAMESPACE \ nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ NLOHMANN_JSON_ABI_TAGS, \ NLOHMANN_JSON_NAMESPACE_VERSION) #endif #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN #define NLOHMANN_JSON_NAMESPACE_BEGIN \ namespace nlohmann \ { \ inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ NLOHMANN_JSON_ABI_TAGS, \ NLOHMANN_JSON_NAMESPACE_VERSION) \ { #endif #ifndef NLOHMANN_JSON_NAMESPACE_END #define NLOHMANN_JSON_NAMESPACE_END \ } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ } // namespace nlohmann #endif // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // transform #include // array #include // forward_list #include // inserter, front_inserter, end #include // map #ifdef JSON_HAS_CPP_17 #include // optional #endif #include // string #include // tuple, make_tuple #include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible #include // unordered_map #include // pair, declval #include // valarray // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // nullptr_t #include // exception #if JSON_DIAGNOSTICS #include // accumulate #endif #include // runtime_error #include // to_string #include // vector // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // array #include // size_t #include // uint8_t #include // string // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // declval, pair // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { template struct make_void { using type = void; }; template using void_t = typename make_void::type; } // namespace detail NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { // https://en.cppreference.com/w/cpp/experimental/is_detected 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 Op, class... Args> struct detector { using value_t = std::false_type; using type = Default; }; template class Op, class... Args> struct detector>, Op, Args...> { using value_t = std::true_type; using type = Op; }; template class Op, class... Args> using is_detected = typename detector::value_t; template class Op, class... Args> struct is_detected_lazy : is_detected { }; template class Op, class... Args> using detected_t = typename detector::type; template class Op, class... Args> using detected_or = detector; template class Op, class... Args> using detected_or_t = typename detected_or::type; template class Op, class... Args> using is_detected_exact = std::is_same>; template class Op, class... Args> using is_detected_convertible = std::is_convertible, To>; } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson // SPDX-License-Identifier: MIT /* Hedley - https://nemequ.github.io/hedley * Created by Evan Nemerson */ #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(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(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(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 #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 #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) */ // This file contains all internal macro definitions (except those affecting ABI) // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them // #include // 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_23) && !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_23 #define JSON_HAS_CPP_20 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) #define JSON_HAS_CPP_20 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 201103L) || (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 #ifdef __has_include #if __has_include() #include #endif #endif #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) #ifdef JSON_HAS_CPP_17 #if defined(__cpp_lib_filesystem) #define JSON_HAS_FILESYSTEM 1 #elif defined(__cpp_lib_experimental_filesystem) #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #elif !defined(__has_include) #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #elif __has_include() #define JSON_HAS_FILESYSTEM 1 #elif __has_include() #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #endif // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support #if defined(__clang_major__) && __clang_major__ < 7 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support #if defined(_MSC_VER) && _MSC_VER < 1914 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before iOS 13 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before macOS Catalina #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif #endif #endif #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 #endif #ifndef JSON_HAS_FILESYSTEM #define JSON_HAS_FILESYSTEM 0 #endif #ifndef JSON_HAS_THREE_WAY_COMPARISON #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L #define JSON_HAS_THREE_WAY_COMPARISON 1 #else #define JSON_HAS_THREE_WAY_COMPARISON 0 #endif #endif #ifndef JSON_HAS_RANGES // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 #define JSON_HAS_RANGES 0 #elif defined(__cpp_lib_ranges) #define JSON_HAS_RANGES 1 #else #define JSON_HAS_RANGES 0 #endif #endif #ifndef JSON_HAS_STATIC_RTTI #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 #define JSON_HAS_STATIC_RTTI 1 #else #define JSON_HAS_STATIC_RTTI 0 #endif #endif #ifdef JSON_HAS_CPP_17 #define JSON_INLINE_VARIABLE inline #else #define JSON_INLINE_VARIABLE #endif #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] #else #define JSON_NO_UNIQUE_ADDRESS #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 disabling 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 #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 overriding assert #if !defined(JSON_ASSERT) #include // 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 \ inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [e](const std::pair& ej_pair) -> bool \ { \ return ej_pair.first == e; \ }); \ j = ((it != std::end(m)) ? it : std::begin(m))->second; \ } \ template \ inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [&j](const std::pair& 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 class ObjectType, \ template class ArrayType, \ class StringType, class BooleanType, class NumberIntegerType, \ class NumberUnsignedType, class NumberFloatType, \ template class AllocatorType, \ template class JSONSerializer, \ class BinaryType, \ class CustomBaseClass> #define NLOHMANN_BASIC_JSON_TPL \ basic_json // 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); #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1; /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE @since version 3.9.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT @since version 3.11.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE @since version 3.11.3 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE @since version 3.9.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& 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_WITH_DEFAULT @since version 3.11.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE @since version 3.11.3 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } // inspired from https://stackoverflow.com/a/26745591 // allows calling 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 \ using result_of_##std_name = decltype(std_name(std::declval()...)); \ } \ \ namespace detail2 { \ struct std_name##_tag \ { \ }; \ \ template \ std_name##_tag std_name(T&&...); \ \ template \ using result_of_##std_name = decltype(std_name(std::declval()...)); \ \ template \ struct would_call_std_##std_name \ { \ static constexpr auto const value = ::nlohmann::detail:: \ is_detected_exact::value; \ }; \ } /* namespace detail2 */ \ \ template \ struct would_call_std_##std_name : detail2::would_call_std_##std_name \ { \ } #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_DISABLE_ENUM_SERIALIZATION #define JSON_DISABLE_ENUM_SERIALIZATION 0 #endif #ifndef JSON_USE_GLOBAL_UDLS #define JSON_USE_GLOBAL_UDLS 1 #endif #if JSON_HAS_THREE_WAY_COMPARISON #include // partial_ordering #endif NLOHMANN_JSON_NAMESPACE_BEGIN 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 */ #if JSON_HAS_THREE_WAY_COMPARISON inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* #else inline bool operator<(const value_t lhs, const value_t rhs) noexcept #endif { static constexpr std::array 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(lhs); const auto r_index = static_cast(rhs); #if JSON_HAS_THREE_WAY_COMPARISON if (l_index < order.size() && r_index < order.size()) { return order[l_index] <=> order[r_index]; // *NOPAD* } return std::partial_ordering::unordered; #else return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; #endif } // GCC selects the built-in operator< over an operator rewritten from // a user-defined spaceship operator // Clang, MSVC, and ICC select the rewritten candidate // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) inline bool operator<(const value_t lhs, const value_t rhs) noexcept { return std::is_lt(lhs <=> rhs); // *NOPAD* } #endif } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN 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 */ template inline void replace_substring(StringType& s, const StringType& f, const StringType& t) { JSON_ASSERT(!f.empty()); for (auto pos = s.find(f); // find first occurrence of f pos != StringType::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. */ template inline StringType escape(StringType s) { replace_substring(s, StringType{"~"}, StringType{"~0"}); replace_substring(s, StringType{"/"}, StringType{"~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. */ template static void unescape(StringType& s) { replace_substring(s, StringType{"~1"}, StringType{"/"}); replace_substring(s, StringType{"~0"}, StringType{"~"}); } } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // size_t // #include NLOHMANN_JSON_NAMESPACE_BEGIN 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 NLOHMANN_JSON_NAMESPACE_END // #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-FileCopyrightText: 2018 The Abseil Authors // SPDX-License-Identifier: MIT #include // array #include // size_t #include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type #include // index_sequence, make_index_sequence, index_sequence_for // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { template using uncvref_t = typename std::remove_cv::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 using enable_if_t = typename std::enable_if::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` 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); // // 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()); // } template 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 using index_sequence = integer_sequence; namespace utility_internal { template struct Extend; // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. template struct Extend, SeqSize, 0> { using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; }; template struct Extend, SeqSize, 1> { using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; }; // Recursion helper for 'make_integer_sequence'. // 'Gen::type' is an alias for 'integer_sequence'. template struct Gen { using type = typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; }; template struct Gen { using type = integer_sequence; }; } // namespace utility_internal // Compile-time sequences of integers // make_integer_sequence // // This template alias is equivalent to // `integer_sequence`, and is designed to be a drop-in // replacement for C++14's `std::make_integer_sequence`. template using make_integer_sequence = typename utility_internal::Gen::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 using make_index_sequence = make_integer_sequence; // 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 using index_sequence_for = make_index_sequence; //// END OF CODE FROM GOOGLE ABSEIL #endif // dispatch utility (taken from ranges-v3) template struct priority_tag : priority_tag < N - 1 > {}; template<> struct priority_tag<0> {}; // taken from ranges-v3 template struct static_const { static JSON_INLINE_VARIABLE constexpr T value{}; }; #ifndef JSON_HAS_CPP_17 template constexpr T static_const::value; #endif template constexpr std::array make_array(Args&& ... args) { return std::array {{static_cast(std::forward(args))...}}; } } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // numeric_limits #include // char_traits #include // tuple #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // random_access_iterator_tag // #include // #include // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { template struct iterator_types {}; template struct iterator_types < It, void_t> { 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 struct iterator_traits { }; template struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> : iterator_types { }; template struct iterator_traits::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 NLOHMANN_JSON_NAMESPACE_END // #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); NLOHMANN_JSON_NAMESPACE_END // #include // #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ #include // int64_t, uint64_t #include // map #include // allocator #include // string #include // vector // #include /*! @brief namespace for Niels Lohmann @see https://github.com/nlohmann @since version 1.0.0 */ NLOHMANN_JSON_NAMESPACE_BEGIN /*! @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 struct adl_serializer; /// a class to store JSON values /// @sa https://json.nlohmann.me/api/basic_json/ template class ObjectType = std::map, template 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 class AllocatorType = std::allocator, template class JSONSerializer = adl_serializer, class BinaryType = std::vector, // cppcheck-suppress syntaxError class CustomBaseClass = void> class basic_json; /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document /// @sa https://json.nlohmann.me/api/json_pointer/ template class json_pointer; /*! @brief default specialization @sa https://json.nlohmann.me/api/json/ */ using json = basic_json<>; /// @brief a minimal map-like container that preserves insertion order /// @sa https://json.nlohmann.me/api/ordered_map/ template struct ordered_map; /// @brief specialization that maintains the insertion order of object keys /// @sa https://json.nlohmann.me/api/ordered_json/ using ordered_json = basic_json; NLOHMANN_JSON_NAMESPACE_END #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ NLOHMANN_JSON_NAMESPACE_BEGIN /*! @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()))) // // In this case, T has to be properly CV-qualified to constraint the function arguments // (e.g. to_json(BasicJsonType&, const T&)) template struct is_basic_json : std::false_type {}; NLOHMANN_BASIC_JSON_TPL_DECLARATION struct is_basic_json : std::true_type {}; // used by exceptions create() member functions // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t // false_type otherwise template struct is_basic_json_context : std::integral_constant < bool, is_basic_json::type>::type>::value || std::is_same::value > {}; ////////////////////// // json_ref helpers // ////////////////////// template class json_ref; template struct is_json_ref : std::false_type {}; template struct is_json_ref> : std::true_type {}; ////////////////////////// // aliases for detected // ////////////////////////// template using mapped_type_t = typename T::mapped_type; template using key_type_t = typename T::key_type; template using value_type_t = typename T::value_type; template using difference_type_t = typename T::difference_type; template using pointer_t = typename T::pointer; template using reference_t = typename T::reference; template using iterator_category_t = typename T::iterator_category; template using to_json_function = decltype(T::to_json(std::declval()...)); template using from_json_function = decltype(T::from_json(std::declval()...)); template using get_template_function = decltype(std::declval().template get()); // trait checking if JSONSerializer::from_json(json const&, udt&) exists template struct has_from_json : std::false_type {}; // trait checking if j.get 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 struct is_getable { static constexpr bool value = is_detected::value; }; template struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; static constexpr bool value = is_detected_exact::value; }; // This trait checks if JSONSerializer::from_json(json const&) exists // this overload is used for non-default-constructible user-defined-types template struct has_non_default_from_json : std::false_type {}; template struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; static constexpr bool value = is_detected_exact::value; }; // This trait checks if BasicJsonType::json_serializer::to_json exists // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. template struct has_to_json : std::false_type {}; template struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; static constexpr bool value = is_detected_exact::value; }; template using detect_key_compare = typename T::key_compare; template struct has_key_compare : std::integral_constant::value> {}; // obtains the actual object key comparator template struct actual_object_comparator { using object_t = typename BasicJsonType::object_t; using object_comparator_t = typename BasicJsonType::default_object_comparator_t; using type = typename std::conditional < has_key_compare::value, typename object_t::key_compare, object_comparator_t>::type; }; template using actual_object_comparator_t = typename actual_object_comparator::type; ///////////////// // char_traits // ///////////////// // Primary template of char_traits calls std char_traits template struct char_traits : std::char_traits {}; // Explicitly define char traits for unsigned char since it is not standard template<> struct char_traits : std::char_traits { using char_type = unsigned char; using int_type = uint64_t; // Redefine to_int_type function static int_type to_int_type(char_type c) noexcept { return static_cast(c); } static char_type to_char_type(int_type i) noexcept { return static_cast(i); } static constexpr int_type eof() noexcept { return static_cast(std::char_traits::eof()); } }; // Explicitly define char traits for signed char since it is not standard template<> struct char_traits : std::char_traits { using char_type = signed char; using int_type = uint64_t; // Redefine to_int_type function static int_type to_int_type(char_type c) noexcept { return static_cast(c); } static char_type to_char_type(int_type i) noexcept { return static_cast(i); } static constexpr int_type eof() noexcept { return static_cast(std::char_traits::eof()); } }; /////////////////// // is_ functions // /////////////////// // https://en.cppreference.com/w/cpp/types/conjunction template struct conjunction : std::true_type { }; template struct conjunction : B { }; template struct conjunction : std::conditional(B::value), conjunction, B>::type {}; // https://en.cppreference.com/w/cpp/types/negation template 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 struct is_default_constructible : std::is_default_constructible {}; template struct is_default_constructible> : conjunction, is_default_constructible> {}; template struct is_default_constructible> : conjunction, is_default_constructible> {}; template struct is_default_constructible> : conjunction...> {}; template struct is_default_constructible> : conjunction...> {}; template struct is_constructible : std::is_constructible {}; template struct is_constructible> : is_default_constructible> {}; template struct is_constructible> : is_default_constructible> {}; template struct is_constructible> : is_default_constructible> {}; template struct is_constructible> : is_default_constructible> {}; template struct is_iterator_traits : std::false_type {}; template struct is_iterator_traits> { private: using traits = iterator_traits; public: static constexpr auto value = is_detected::value && is_detected::value && is_detected::value && is_detected::value && is_detected::value; }; template struct is_range { private: using t_ref = typename std::add_lvalue_reference::type; using iterator = detected_t; using sentinel = detected_t; // 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>::value; public: static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; }; template using iterator_t = enable_if_t::value, result_of_begin())>>; template using range_value_t = value_type_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 struct is_complete_type : std::false_type {}; template struct is_complete_type : std::true_type {}; template struct is_compatible_object_type_impl : std::false_type {}; template struct is_compatible_object_type_impl < BasicJsonType, CompatibleObjectType, enable_if_t < is_detected::value&& is_detected::value >> { using object_t = typename BasicJsonType::object_t; // macOS's is_constructible does not play well with nonesuch... static constexpr bool value = is_constructible::value && is_constructible::value; }; template struct is_compatible_object_type : is_compatible_object_type_impl {}; template struct is_constructible_object_type_impl : std::false_type {}; template struct is_constructible_object_type_impl < BasicJsonType, ConstructibleObjectType, enable_if_t < is_detected::value&& is_detected::value >> { using object_t = typename BasicJsonType::object_t; static constexpr bool value = (is_default_constructible::value && (std::is_move_assignable::value || std::is_copy_assignable::value) && (is_constructible::value && std::is_same < typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type >::value)) || (has_from_json::value || has_non_default_from_json < BasicJsonType, typename ConstructibleObjectType::mapped_type >::value); }; template struct is_constructible_object_type : is_constructible_object_type_impl {}; template struct is_compatible_string_type { static constexpr auto value = is_constructible::value; }; template struct is_constructible_string_type { // launder type through decltype() to fix compilation failure on ICPC #ifdef __INTEL_COMPILER using laundered_type = decltype(std::declval()); #else using laundered_type = ConstructibleStringType; #endif static constexpr auto value = conjunction < is_constructible, is_detected_exact>::value; }; template struct is_compatible_array_type_impl : std::false_type {}; template struct is_compatible_array_type_impl < BasicJsonType, CompatibleArrayType, enable_if_t < is_detected::value&& is_iterator_traits>>::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>::value >> { static constexpr bool value = is_constructible>::value; }; template struct is_compatible_array_type : is_compatible_array_type_impl {}; template struct is_constructible_array_type_impl : std::false_type {}; template struct is_constructible_array_type_impl < BasicJsonType, ConstructibleArrayType, enable_if_t::value >> : std::true_type {}; template struct is_constructible_array_type_impl < BasicJsonType, ConstructibleArrayType, enable_if_t < !std::is_same::value&& !is_compatible_string_type::value&& is_default_constructible::value&& (std::is_move_assignable::value || std::is_copy_assignable::value)&& is_detected::value&& is_iterator_traits>>::value&& is_detected::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>::value&& is_complete_type < detected_t>::value >> { using value_type = range_value_t; static constexpr bool value = std::is_same::value || has_from_json::value || has_non_default_from_json < BasicJsonType, value_type >::value; }; template struct is_constructible_array_type : is_constructible_array_type_impl {}; template struct is_compatible_integer_type_impl : std::false_type {}; template struct is_compatible_integer_type_impl < RealIntegerType, CompatibleNumberIntegerType, enable_if_t < std::is_integral::value&& std::is_integral::value&& !std::is_same::value >> { // is there an assert somewhere on overflows? using RealLimits = std::numeric_limits; using CompatibleLimits = std::numeric_limits; static constexpr auto value = is_constructible::value && CompatibleLimits::is_integer && RealLimits::is_signed == CompatibleLimits::is_signed; }; template struct is_compatible_integer_type : is_compatible_integer_type_impl {}; template struct is_compatible_type_impl: std::false_type {}; template struct is_compatible_type_impl < BasicJsonType, CompatibleType, enable_if_t::value >> { static constexpr bool value = has_to_json::value; }; template struct is_compatible_type : is_compatible_type_impl {}; template struct is_constructible_tuple : std::false_type {}; template struct is_constructible_tuple> : conjunction...> {}; template struct is_json_iterator_of : std::false_type {}; template struct is_json_iterator_of : std::true_type {}; template struct is_json_iterator_of : std::true_type {}; // checks if a given type T is a template specialization of Primary template