1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-16 07:07:13 +02:00

Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions

33
vendor/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,33 @@
add_subdirectory(ConcurrentQueue)
add_subdirectory(Fmt)
add_subdirectory(Squirrel)
add_subdirectory(SimpleIni)
add_subdirectory(TinyDir)
set(USE_SYSTEM_CURL ON CACHE INTERNAL "" FORCE)
set(BUILD_CPR_TESTS OFF CACHE INTERNAL "" FORCE)
set(BUILD_CPR_TESTS_SSL OFF CACHE INTERNAL "" FORCE)
set(GENERATE_COVERAGE OFF CACHE INTERNAL "" FORCE)
add_subdirectory(CPR)
#set(POCO_STATIC ON CACHE INTERNAL "" FORCE)
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE)
set(ENABLE_FOUNDATION ON CACHE INTERNAL "" FORCE)
set(ENABLE_ENCODINGS ON CACHE INTERNAL "" FORCE)
set(ENABLE_ENCODINGS_COMPILER OFF CACHE INTERNAL "" FORCE)
set(ENABLE_XML ON CACHE INTERNAL "" FORCE)
set(ENABLE_JSON ON CACHE INTERNAL "" FORCE)
set(ENABLE_MONGODB ON CACHE INTERNAL "" FORCE)
set(ENABLE_DATA_SQLITE ON CACHE INTERNAL "" FORCE)
set(ENABLE_REDIS ON CACHE INTERNAL "" FORCE)
set(ENABLE_PDF OFF CACHE INTERNAL "" FORCE)
set(ENABLE_UTIL ON CACHE INTERNAL "" FORCE)
set(ENABLE_NET ON CACHE INTERNAL "" FORCE)
set(ENABLE_NETSSL ON CACHE INTERNAL "" FORCE)
set(ENABLE_SEVENZIP OFF CACHE INTERNAL "" FORCE)
set(ENABLE_ZIP ON CACHE INTERNAL "" FORCE)
set(ENABLE_CPPPARSER OFF CACHE INTERNAL "" FORCE)
set(ENABLE_POCODOC OFF CACHE INTERNAL "" FORCE)
set(ENABLE_PAGECOMPILER OFF CACHE INTERNAL "" FORCE)
set(ENABLE_PAGECOMPILER_FILE2PAGE OFF CACHE INTERNAL "" FORCE)
set(ENABLE_TESTS OFF CACHE INTERNAL "" FORCE)
set(POCO_UNBUNDLED OFF CACHE INTERNAL "" FORCE)
add_subdirectory(POCO)

200
vendor/CPR/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,200 @@
cmake_minimum_required(VERSION 3.15)
project(cpr VERSION 1.5.1 LANGUAGES CXX)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake")
# Avoid the dll boilerplate code for windows
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
set(CPR_LIBRARIES cpr CACHE INTERNAL "")
macro(cpr_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT)
option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT})
if(DEFINED ENV{${OPTION_NAME}})
# Allow setting the option through an environment variable
set(${OPTION_NAME} $ENV{${OPTION_NAME}})
endif()
if(${OPTION_NAME})
add_definitions(-D${OPTION_NAME})
endif()
message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}")
endmacro()
option(${BUILD_SHARED_LIBS} "Build libraries as shared libraries" OFF)
message(STATUS "C++ Requests CMake Options")
message(STATUS "=======================================================")
cpr_option(USE_SYSTEM_CURL "If ON, this project will look in the system paths for an installed curl library" ON)
cpr_option(BUILD_CPR_TESTS "Set to ON to build cpr tests." OFF)
cpr_option(BUILD_CPR_TESTS_SSL "Set to ON to build cpr ssl tests" ${BUILD_CPR_TESTS})
cpr_option(GENERATE_COVERAGE "Set to ON to generate coverage reports." OFF)
cpr_option(CPR_CURL_NOSIGNAL "Set to ON to disable use of signals in libcurl." OFF)
cpr_option(USE_SYSTEM_GTEST "If ON, this project will look in the system paths for an installed gtest library" OFF)
cpr_option(USE_OPENSSL "Use OpenSSL code. Experimental" ON)
cpr_option(USE_WINSSL "Use WIN_SSL backend. Experimental" OFF)
message(STATUS "=======================================================")
if (USE_OPENSSL AND USE_WINSSL)
message(FATAL_ERROR "It's only possible to use one SSL backend")
endif()
if ((NOT WIN32) AND USE_WINSSL)
message(FATAL_ERROR "Only use WINSSL with windows")
endif()
include(GNUInstallDirs)
include(FetchContent)
include(cmake/code_coverage.cmake)
include(cmake/sanitizer.cmake)
include(cmake/gcc_analyze.cmake)
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (NOT isMultiConfig)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${ALLOWED_BUILD_TYPES}")
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
elseif(NOT CMAKE_BUILD_TYPE IN_LIST ALLOWED_BUILD_TYPES)
message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
endif()
else ()
unset(CMAKE_BUILD_TYPE)
foreach(TYPE ${ALLOWED_BUILD_TYPES})
if (NOT ${TYPE} IN_LIST CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES ${TYPE})
endif()
endforeach()
endif()
# Curl configuration
if(USE_SYSTEM_CURL)
find_package(CURL REQUIRED COMPONENTS HTTP HTTPS SSL )
if (CURL_FOUND)
set(SSL_ENABLED ON CACHE INTERNAL "" FORCE)
else()
find_package(CURL REQUIRED COMPONENTS HTTP)
if(CURL_FOUND)
set(SSL_ENABLED OFF CACHE INTERNAL "" FORCE)
endif()
endif()
endif()
if(NOT USE_SYSTEM_CURL OR NOT CURL_FOUND)
message(STATUS "Not using system Curl, using built-in curl project instead.")
set(BUILD_CURL_EXE OFF CACHE INTERNAL "" FORCE)
set(BUILD_TESTING OFF CACHE INTERNAL "" FORCE)
set(HTTP_ONLY ON CACHE INTERNAL "" FORCE)
if (USE_WINSSL OR USE_OPENSSL)
set(SSL_ENABLED ON CACHE INTERNAL "" FORCE)
else()
set(CURL_CA_PATH "none" CACHE INTERNAL "" FORCE)
endif()
if(USE_WINSSL)
#set(CMAKE_USE_WINSSL ON CACHE INTERNAL "" FORCE)
set(CMAKE_USE_SCHANNEL ON CACHE INTERNAL "" FORCE)
set(CURL_CA_PATH "none" CACHE INTERNAL "" FORCE)
endif()
if(USE_OPENSSL)
set(CMAKE_USE_OPENSSL ON CACHE INTERNAL "" FORCE)
endif()
# Show progress of FetchContent:
#set(FETCHCONTENT_QUIET OFF CACHE INTERNAL "" FORCE)
#FetchContent_Declare(curl
# URL https://github.com/curl/curl/releases/download/curl-7_69_1/curl-7.69.1.tar.xz
# URL_HASH SHA256=03c7d5e6697f7b7e40ada1b2256e565a555657398e6c1fcfa4cb251ccd819d4f # the file hash for curl-7.69.1.tar.xz
# USES_TERMINAL_DOWNLOAD TRUE) # <---- This is needed only for Ninja to show download progress
#FetchContent_MakeAvailable(curl)
#### add_library(curl_int INTERFACE)
#### target_link_libraries(curl_int INTERFACE libcurl)
#### target_include_directories(curl_int INTERFACE ${curl_SOURCE_DIR}/include ${curl_BINARY_DIR}/include/curl)
#### add_library(CURL::libcurl ALIAS curl_int)
# Group under the "external" project folder in IDEs such as Visual Studio.
#if(BUILD_CURL_EXE)
# set_property(TARGET curl PROPERTY FOLDER "external")
#endif()
#set_property(TARGET libcurl PROPERTY FOLDER "external")
endif()
# GTest configuration
if(BUILD_CPR_TESTS)
if(USE_SYSTEM_GTEST)
find_package(GTest)
endif()
if(NOT USE_SYSTEM_GTEST OR NOT GTEST_FOUND)
message(STATUS "Not using system gtest, using built-in googletest project instead.")
if(MSVC)
# By default, GTest compiles on Windows in CRT static linkage mode. We use this
# variable to force it into using the CRT in dynamic linkage (DLL), just as CPR
# does.
set(gtest_force_shared_crt ON CACHE BOOL "Force gtest to use the shared c runtime")
endif()
FetchContent_Declare(googletest
URL https://github.com/google/googletest/archive/release-1.10.0.tar.gz
URL_HASH SHA256=9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb # the file hash for release-1.10.0.tar.gz
USES_TERMINAL_DOWNLOAD TRUE) # <---- This is needed only for Ninja to show download progress
FetchContent_MakeAvailable(googletest)
add_library(gtest_int INTERFACE)
target_link_libraries(gtest_int INTERFACE gtest)
target_include_directories(gtest_int INTERFACE ${googletest_SOURCE_DIR}/include)
add_library(GTest::GTest ALIAS gtest_int)
# Group under the "tests/gtest" project folder in IDEs such as Visual Studio.
set_property(TARGET gtest PROPERTY FOLDER "tests/gtest")
set_property(TARGET gtest_main PROPERTY FOLDER "tests/gtest")
endif()
endif()
# Mongoose configuration
if(BUILD_CPR_TESTS)
message(STATUS "Building mongoose project for test support.")
if (SSL_ENABLED)
find_package(OpenSSL)
if (OPENSSL_FOUND)
set(ENABLE_SSL_TESTS ${BUILD_CPR_TESTS_SSL} CACHE INTERNAL "")
else()
set(ENABLE_SSL_TESTS OFF CACHE INTERNAL "")
endif()
else()
set(ENABLE_SSL_TESTS OFF CACHE INTERNAL "")
endif()
FetchContent_Declare(mongoose
URL https://github.com/cesanta/mongoose/archive/6.18.tar.gz
URL_HASH SHA256=f5c10346abc9c72f7cac7885d853ca064fb09aad57580433941a8fd7a3543769 # the hash for 6.18.tar.gz
USES_TERMINAL_DOWNLOAD TRUE) # <---- This is needed only for Ninja to show download progress
# We can not use FetchContent_MakeAvailable, since we need to patch mongoose to use CMake
if (NOT mongoose_POPULATED)
FetchContent_POPULATE(mongoose)
file(INSTALL cmake/mongoose.CMakeLists.txt DESTINATION ${mongoose_SOURCE_DIR})
file(RENAME ${mongoose_SOURCE_DIR}/mongoose.CMakeLists.txt ${mongoose_SOURCE_DIR}/CMakeLists.txt)
add_subdirectory(${mongoose_SOURCE_DIR} ${mongoose_BINARY_DIR})
endif()
# Group under the "external" project folder in IDEs such as Visual Studio.
set_property(TARGET mongoose PROPERTY FOLDER "external")
endif()
add_subdirectory(cpr)
add_subdirectory(include)
if(BUILD_CPR_TESTS)
enable_testing()
add_subdirectory(test)
endif()

27
vendor/CPR/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,27 @@
# Contributing to C++ Requests
Please fork this repository and contribute back using [pull requests](https://github.com/whoshuu/cpr/pulls). Features can be requested using [issues](https://github.com/whoshuu/cpr/issues). All code, comments, and critiques are greatly appreciated.
## Formatting
To avoid unproductive debates on formatting, this project uses `clang-format` to ensure a consistent style across all source files. Currently, `clang-format` 3.8 is the version of `clang-format` we use. The format file can be found [here](https://github.com/whoshuu/cpr/blob/master/.clang-format). To install `clang-format` on Ubuntu, run this:
```
apt-get install clang-format-3.8
```
To install `clang-format` on OS X, run this:
```
brew install clang-format
```
Note that `brew` might install a later version of `clang-format`, but it should be mostly compatible with what's run on the Travis servers.
To run `clang-format` on every source file, run this in the root directory:
```
./format-check.sh
```
This should indicate which files need formatting and also show a diff of the requested changes. More specific usage instructions can be found on the official [LLVM website](http://releases.llvm.org/3.8.0/tools/clang/docs/ClangFormat.html).

21
vendor/CPR/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 Huu Nguyen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

141
vendor/CPR/README.md vendored Normal file
View File

@ -0,0 +1,141 @@
# C++ Requests: Curl for People <img align="right" height="40" src="http://i.imgur.com/d9Xtyts.png">
[![Documentation](https://img.shields.io/badge/docs-online-informational?style=flat&link=https://whoshuu.github.io/cpr/)](https://whoshuu.github.io/cpr/)
![CI](https://github.com/whoshuu/cpr/workflows/CI/badge.svg)
## Announcements
The cpr project has new maintainers: [Fabian Sauter](https://github.com/com8) and [Tim Stack](https://github.com/tstack).
## TLDR
C++ Requests is a simple wrapper around [libcurl](http://curl.haxx.se/libcurl) inspired by the excellent [Python Requests](https://github.com/kennethreitz/requests) project.
Despite its name, libcurl's easy interface is anything but, and making mistakes misusing it is a common source of error and frustration. Using the more expressive language facilities of C++11, this library captures the essence of making network calls into a few concise idioms.
Here's a quick GET request:
```c++
#include <cpr/cpr.h>
int main(int argc, char** argv) {
cpr::Response r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"},
cpr::Authentication{"user", "pass"},
cpr::Parameters{{"anon", "true"}, {"key", "value"}});
r.status_code; // 200
r.header["content-type"]; // application/json; charset=utf-8
r.text; // JSON text string
}
```
And here's [less functional, more complicated code, without cpr](https://gist.github.com/whoshuu/2dc858b8730079602044).
## Documentation
[![Documentation](https://img.shields.io/badge/docs-online-informational?style=for-the-badge&link=https://whoshuu.github.io/cpr/)](https://whoshuu.github.io/cpr/)
You can find the latest documentation [here](https://whoshuu.github.io/cpr). It's a work in progress, but it should give you a better idea of how to use the library than the [tests](https://github.com/whoshuu/cpr/tree/master/test) currently do.
## Features
C++ Requests currently supports:
* Custom headers
* Url encoded parameters
* Url encoded POST values
* Multipart form POST upload
* File POST upload
* Basic authentication
* Bearer authentication
* Digest authentication
* NTLM authentication
* Connection and request timeout specification
* Timeout for low speed connection
* Asynchronous requests
* :cookie: support!
* Proxy support
* Callback interfaces
* PUT methods
* DELETE methods
* HEAD methods
* OPTIONS methods
* PATCH methods
* Thread Safe access to [libCurl](https://curl.haxx.se/libcurl/c/threadsafe.html)
* OpenSSL and WinSSL support for HTTPS requests
## Planned
For a quick overview about the planed features, have a look at the next [Milestones](https://github.com/whoshuu/cpr/milestones).
## Usage
If you already have a project you need to integrate C++ Requests with, the primary way is to use CMake `fetch_content`.
Add the following to your `CMakeLists.txt`.
```cmake
include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/whoshuu/cpr.git GIT_TAG c8d33915dbd88ad6c92b258869b03aba06587ff9) # the commit hash for 1.5.0
FetchContent_MakeAvailable(cpr)
```
This will produce the target `cpr::cpr` which you can link against the typical way:
```cmake
target_link_libraries(your_target_name PRIVATE cpr::cpr)
```
That should do it!
There's no need to handle `libcurl` yourself. All dependencies are taken care of for you.
## Requirements
The only explicit requirements are:
* a `C++11` compatible compiler such as Clang or GCC. The minimum required version of GCC is unknown, so if anyone has trouble building this library with a specific version of GCC, do let me know
* If you would like to perform https requests `OpenSSL` and its development libraries are required.
## Building cpr - Using vcpkg
You can download and install cpr using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
```Bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install cpr
```
The `cpr` port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Building cpr - Using Conan
You can download and install `cpr` using the [Conan](https://conan.io/) package manager. Setup your CMakeLists.txt (see [Conan documentation](https://docs.conan.io/en/latest/integrations/build_system.html) on how to use MSBuild, Meson and others) like this:
```CMake
project(myproject CXX)
add_executable(${PROJECT_NAME} main.cpp)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) # Include Conan-generated file
conan_basic_setup(TARGETS) # Introduce Conan-generated targets
target_link_libraries(${PROJECT_NAME} CONAN_PKG::cpr)
```
Create `conanfile.txt` in your source dir:
```
[requires]
cpr/1.5.0
[generators]
cmake
```
Install and run Conan, then build your project as always:
```Bash
pip install conan
mkdir build
cd build
conan install ../ --build=missing
cmake ../
cmake --build .
```
The `cpr` package in Conan is kept up to date by Conan contributors. If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the `conan-center-index` repository.

29
vendor/CPR/cmake/code_coverage.cmake vendored Normal file
View File

@ -0,0 +1,29 @@
# Code coverage
if(BUILD_CPR_TESTS AND GENERATE_COVERAGE)
set(CMAKE_BUILD_TYPE COVERAGE CACHE INTERNAL "Coverage enabled build")
message(STATUS "Enabling gcov support")
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(COVERAGE_FLAG "--coverage")
endif()
set(CMAKE_CXX_FLAGS_COVERAGE
"-g -O0 ${COVERAGE_FLAG} -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE)
set(CMAKE_C_FLAGS_COVERAGE
"-g -O0 ${COVERAGE_FLAG} -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C compiler during coverage builds."
FORCE)
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used for linking binaries during coverage builds."
FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
FORCE)
mark_as_advanced(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
endif()

12
vendor/CPR/cmake/gcc_analyze.cmake vendored Normal file
View File

@ -0,0 +1,12 @@
include(CheckCXXCompilerFlag)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
check_cxx_compiler_flag("-fanalyzer" HAS_GCC_STATIC_ANALYZER)
if(HAS_GCC_STATIC_ANALYZER AND NOT ENABLE_LINTING)
option(ENABLE_GCC_STATIC_ANALYZER "Enable linting with the GCC static analyzer" OFF)
if(ENABLE_GCC_STATIC_ANALYZER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fanalyzer")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -fanalyzer")
endif()
endif()
endif()

View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.15)
project(mongoose C)
add_library(mongoose STATIC mongoose.c)
target_include_directories(mongoose PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
if(ENABLE_SSL_TESTS)
# Enable mongoose SSL
target_compile_definitions(mongoose PUBLIC MG_ENABLE_SSL)
target_link_libraries(mongoose PRIVATE OpenSSL::SSL)
endif()

65
vendor/CPR/cmake/sanitizer.cmake vendored Normal file
View File

@ -0,0 +1,65 @@
include(CheckCXXCompilerFlag)
include(CheckCXXSourceRuns)
set(ALLOWED_BUILD_TYPES Debug Release RelWithDebInfo MinSizeRel)
set(ALL_SAN_FLAGS "")
# Thread sanitizer
set(THREAD_SAN_FLAGS "-fsanitize=thread")
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${THREAD_SAN_FLAGS}")
check_cxx_source_runs("int main() { return 0; }" THREAD_SANITIZER_AVAILABLE)
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
if(THREAD_SANITIZER_AVAILABLE)
list(APPEND ALLOWED_BUILD_TYPES ThreadSan)
# Do not add Thread sanitizer to all sanitizer because it is incompatible with other sanitizer
endif()
set(CMAKE_C_FLAGS_THREADSAN "${CMAKE_C_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during thread sanitizer builds." FORCE)
set(CMAKE_CXX_FLAGS_THREADSAN "${CMAKE_CXX_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during thread sanitizer builds." FORCE)
# Address sanitizer
set(ADDR_SAN_FLAGS "-fsanitize=address")
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${ADDR_SAN_FLAGS}")
check_cxx_source_runs("int main() { return 0; }" ADDRESS_SANITIZER_AVAILABLE)
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
if(ADDRESS_SANITIZER_AVAILABLE)
list(APPEND ALLOWED_BUILD_TYPES AddrSan)
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${ADDR_SAN_FLAGS}")
endif()
set(CMAKE_C_FLAGS_ADDRSAN "${CMAKE_C_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during address sanitizer builds." FORCE)
set(CMAKE_CXX_FLAGS_ADDRSAN "${CMAKE_CXX_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during address sanitizer builds." FORCE)
# Leak sanitizer
set(LEAK_SAN_FLAGS "-fsanitize=leak")
check_cxx_compiler_flag(${LEAK_SAN_FLAGS} LEAK_SANITIZER_AVAILABLE)
if(LEAK_SANITIZER_AVAILABLE)
list(APPEND ALLOWED_BUILD_TYPES LeakSan)
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${LEAK_SAN_FLAGS}")
endif()
set(CMAKE_C_FLAGS_LEAKSAN "${CMAKE_C_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C compiler during leak sanitizer builds." FORCE)
set(CMAKE_CXX_FLAGS_LEAKSAN "${CMAKE_CXX_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C++ compiler during leak sanitizer builds." FORCE)
# Undefined behavior sanitizer
set(UDEF_SAN_FLAGS "-fsanitize=undefined")
check_cxx_compiler_flag(${UDEF_SAN_FLAGS} UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
if(UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
list(APPEND ALLOWED_BUILD_TYPES UdefSan)
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${UDEF_SAN_FLAGS}")
endif()
set(CMAKE_C_FLAGS_UDEFSAN "${CMAKE_C_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during undefined behaviour sanitizer builds." FORCE)
set(CMAKE_CXX_FLAGS_UDEFSAN "${CMAKE_CXX_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during undefined behaviour sanitizer builds." FORCE)
# All sanitizer (without thread sanitizer)
if(NOT ALL_SAN_FLAGS STREQUAL "")
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${ALL_SAN_FLAGS}")
check_cxx_source_runs("int main() { return 0; }" ALL_SANITIZERS_AVAILABLE)
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
if(ALL_SANITIZERS_AVAILABLE)
list(APPEND ALLOWED_BUILD_TYPES AllSan)
endif()
endif()
set(CMAKE_C_FLAGS_ALLSAN "${CMAKE_C_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during most possible sanitizer builds." FORCE)
set(CMAKE_CXX_FLAGS_ALLSAN "${CMAKE_CXX_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during most possible sanitizer builds." FORCE)

26
vendor/CPR/cpr-config.cmake vendored Normal file
View File

@ -0,0 +1,26 @@
# - C++ Requests, Curl for People
# This module is a libcurl wrapper written in modern C++.
# It provides an easy, intuitive, and efficient interface to
# a host of networking methods.
#
# Finding this module will define the following variables:
# CPR_FOUND - True if the core library has been found
# CPR_LIBRARIES - Path to the core library archive
# CPR_INCLUDE_DIRS - Path to the include directories. Gives access
# to cpr.h, which must be included in every
# file that uses this interface
find_path(CPR_INCLUDE_DIR
NAMES cpr.h)
find_library(CPR_LIBRARY
NAMES cpr
HINTS ${CPR_LIBRARY_ROOT})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CPR REQUIRED_VARS CPR_LIBRARY CPR_INCLUDE_DIR)
if(CPR_FOUND)
set(CPR_LIBRARIES ${CPR_LIBRARY})
set(CPR_INCLUDE_DIRS ${CPR_INCLUDE_DIR})
endif()

32
vendor/CPR/cpr/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.15)
add_library(cpr
auth.cpp
bearer.cpp
cookies.cpp
cprtypes.cpp
curl_container.cpp
curlholder.cpp
error.cpp
multipart.cpp
parameters.cpp
payload.cpp
proxies.cpp
session.cpp
timeout.cpp
unix_socket.cpp
util.cpp
response.cpp
)
add_library(cpr::cpr ALIAS cpr)
target_link_libraries(cpr PUBLIC CURL::libcurl) # todo should be private, but first dependencys in ssl_options need to be removed
# Set version for shared libraries.
set_target_properties(cpr
PROPERTIES
VERSION ${${PROJECT_NAME}_VERSION}
SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR})
install(TARGETS cpr)

7
vendor/CPR/cpr/auth.cpp vendored Normal file
View File

@ -0,0 +1,7 @@
#include "cpr/auth.h"
namespace cpr {
const char* Authentication::GetAuthString() const noexcept {
return auth_string_.c_str();
}
} // namespace cpr

11
vendor/CPR/cpr/bearer.cpp vendored Normal file
View File

@ -0,0 +1,11 @@
#include "cpr/bearer.h"
namespace cpr {
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
const char* Bearer::GetToken() const noexcept {
return token_string_.c_str();
}
#endif
} // namespace cpr

51
vendor/CPR/cpr/cookies.cpp vendored Normal file
View File

@ -0,0 +1,51 @@
#include "cpr/cookies.h"
namespace cpr {
std::string Cookies::GetEncoded(const CurlHolder& holder) const {
std::stringstream stream;
for (const std::pair<const std::string, std::string>& item : map_) {
// Depending on if encoding is set to "true", we will URL-encode cookies
stream << (encode ? holder.urlEncode(item.first) : item.first) << "=";
// special case version 1 cookies, which can be distinguished by
// beginning and trailing quotes
if (!item.second.empty() && item.second.front() == '"' && item.second.back() == '"') {
stream << item.second;
} else {
// Depending on if encoding is set to "true", we will URL-encode cookies
stream << (encode ? holder.urlEncode(item.second) : item.second);
}
stream << "; ";
}
return stream.str();
}
std::string& Cookies::operator[](const std::string& key) {
return map_[key];
}
Cookies::iterator Cookies::begin() {
return map_.begin();
}
Cookies::iterator Cookies::end() {
return map_.end();
}
Cookies::const_iterator Cookies::begin() const {
return map_.begin();
}
Cookies::const_iterator Cookies::end() const {
return map_.end();
}
Cookies::const_iterator Cookies::cbegin() const {
return map_.cbegin();
}
Cookies::const_iterator Cookies::cend() const {
return map_.cend();
}
} // namespace cpr

12
vendor/CPR/cpr/cprtypes.cpp vendored Normal file
View File

@ -0,0 +1,12 @@
#include "cpr/cprtypes.h"
#include <algorithm>
#include <cctype>
namespace cpr {
bool CaseInsensitiveCompare::operator()(const std::string& a, const std::string& b) const noexcept {
return std::lexicographical_compare(
a.begin(), a.end(), b.begin(), b.end(),
[](unsigned char ac, unsigned char bc) { return std::tolower(ac) < std::tolower(bc); });
}
} // namespace cpr

59
vendor/CPR/cpr/curl_container.cpp vendored Normal file
View File

@ -0,0 +1,59 @@
#include "cpr/curl_container.h"
namespace cpr {
template <class T>
CurlContainer<T>::CurlContainer(const std::initializer_list<T>& containerList)
: containerList_(containerList) {}
template <class T>
void CurlContainer<T>::Add(const std::initializer_list<T>& containerList) {
for (const T& element : containerList) {
containerList_.push_back(std::move(element));
}
}
template <class T>
void CurlContainer<T>::Add(const T& element) {
containerList_.push_back(std::move(element));
}
template <>
const std::string CurlContainer<Parameter>::GetContent(const CurlHolder& holder) const {
std::string content{};
for (const Parameter& parameter : containerList_) {
if (!content.empty()) {
content += "&";
}
std::string escapedKey = holder.urlEncode(parameter.key);
if (parameter.value.empty()) {
content += escapedKey;
} else {
std::string escapedValue = holder.urlEncode(parameter.value);
content += escapedKey + "=";
content += escapedValue;
}
};
return content;
}
template <>
const std::string CurlContainer<Pair>::GetContent(const CurlHolder& holder) const {
std::string content{};
for (const cpr::Pair& element : containerList_) {
if (!content.empty()) {
content += "&";
}
std::string escaped = holder.urlEncode(element.value);
content += element.key + "=" + escaped;
}
return content;
}
template class CurlContainer<Pair>;
template class CurlContainer<Parameter>;
} // namespace cpr

54
vendor/CPR/cpr/curlholder.cpp vendored Normal file
View File

@ -0,0 +1,54 @@
#include "cpr/curlholder.h"
#include <cassert>
namespace cpr {
// It does not make sense to make a std::mutex const.
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
std::mutex CurlHolder::curl_easy_init_mutex_{};
#ifndef _WIN32 // There is no thread sanitizer on windows
__attribute__((no_sanitize("thread")))
#endif
CurlHolder::CurlHolder() {
/**
* Allow multithreaded access to CPR by locking curl_easy_init().
* curl_easy_init() is not thread safe.
* References:
* https://curl.haxx.se/libcurl/c/curl_easy_init.html
* https://curl.haxx.se/libcurl/c/threadsafe.html
**/
curl_easy_init_mutex_.lock();
handle = curl_easy_init();
curl_easy_init_mutex_.unlock();
assert(handle);
} // namespace cpr
CurlHolder::~CurlHolder() {
curl_easy_cleanup(handle);
curl_slist_free_all(chunk);
curl_formfree(formpost);
}
std::string CurlHolder::urlEncode(const std::string& s) const {
assert(handle);
char* output = curl_easy_escape(handle, s.c_str(), s.length());
if (output) {
std::string result = output;
curl_free(output);
return result;
}
return "";
}
std::string CurlHolder::urlDecode(const std::string& s) const {
assert(handle);
char* output = curl_easy_unescape(handle, s.c_str(), s.length(), nullptr);
if (output) {
std::string result = output;
curl_free(output);
return result;
}
return "";
}
} // namespace cpr

68
vendor/CPR/cpr/error.cpp vendored Normal file
View File

@ -0,0 +1,68 @@
#include "cpr/error.h"
#include <curl/curl.h>
namespace cpr {
ErrorCode Error::getErrorCodeForCurlError(std::int32_t curl_code) {
switch (curl_code) {
case CURLE_OK:
return ErrorCode::OK;
case CURLE_UNSUPPORTED_PROTOCOL:
return ErrorCode::UNSUPPORTED_PROTOCOL;
case CURLE_URL_MALFORMAT:
return ErrorCode::INVALID_URL_FORMAT;
case CURLE_COULDNT_RESOLVE_PROXY:
return ErrorCode::PROXY_RESOLUTION_FAILURE;
case CURLE_COULDNT_RESOLVE_HOST:
return ErrorCode::HOST_RESOLUTION_FAILURE;
case CURLE_COULDNT_CONNECT:
return ErrorCode::CONNECTION_FAILURE;
case CURLE_OPERATION_TIMEDOUT:
return ErrorCode::OPERATION_TIMEDOUT;
case CURLE_SSL_CONNECT_ERROR:
return ErrorCode::SSL_CONNECT_ERROR;
#if LIBCURL_VERSION_NUM < 0x073e00
case CURLE_PEER_FAILED_VERIFICATION:
return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR;
#endif
case CURLE_ABORTED_BY_CALLBACK:
case CURLE_WRITE_ERROR:
return ErrorCode::REQUEST_CANCELLED;
case CURLE_GOT_NOTHING:
return ErrorCode::EMPTY_RESPONSE;
case CURLE_SSL_ENGINE_NOTFOUND:
case CURLE_SSL_ENGINE_SETFAILED:
return ErrorCode::GENERIC_SSL_ERROR;
case CURLE_SEND_ERROR:
return ErrorCode::NETWORK_SEND_FAILURE;
case CURLE_RECV_ERROR:
return ErrorCode::NETWORK_RECEIVE_ERROR;
case CURLE_SSL_CERTPROBLEM:
return ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR;
case CURLE_SSL_CIPHER:
return ErrorCode::GENERIC_SSL_ERROR;
#if LIBCURL_VERSION_NUM >= 0x073e00
case CURLE_PEER_FAILED_VERIFICATION:
return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR;
#else
case CURLE_SSL_CACERT:
return ErrorCode::SSL_CACERT_ERROR;
#endif
case CURLE_USE_SSL_FAILED:
case CURLE_SSL_ENGINE_INITFAILED:
return ErrorCode::GENERIC_SSL_ERROR;
case CURLE_SSL_CACERT_BADFILE:
return ErrorCode::SSL_CACERT_ERROR;
case CURLE_SSL_SHUTDOWN_FAILED:
return ErrorCode::GENERIC_SSL_ERROR;
case CURLE_SSL_CRL_BADFILE:
case CURLE_SSL_ISSUER_ERROR:
return ErrorCode::SSL_CACERT_ERROR;
case CURLE_TOO_MANY_REDIRECTS:
return ErrorCode::OK;
default:
return ErrorCode::INTERNAL_ERROR;
}
}
} // namespace cpr

5
vendor/CPR/cpr/multipart.cpp vendored Normal file
View File

@ -0,0 +1,5 @@
#include "cpr/multipart.h"
namespace cpr {
Multipart::Multipart(const std::initializer_list<Part>& parts) : parts{parts} {}
} // namespace cpr

10
vendor/CPR/cpr/parameters.cpp vendored Normal file
View File

@ -0,0 +1,10 @@
#include "cpr/parameters.h"
#include <initializer_list>
#include <string>
#include "cpr/util.h"
namespace cpr {
Parameters::Parameters(const std::initializer_list<Parameter>& parameters) : CurlContainer<Parameter>(parameters) {}
} // namespace cpr

10
vendor/CPR/cpr/payload.cpp vendored Normal file
View File

@ -0,0 +1,10 @@
#include "cpr/payload.h"
#include <initializer_list>
#include <string>
#include "cpr/util.h"
namespace cpr {
Payload::Payload(const std::initializer_list<Pair>& pairs) : CurlContainer<Pair>(pairs) {}
} // namespace cpr

21
vendor/CPR/cpr/proxies.cpp vendored Normal file
View File

@ -0,0 +1,21 @@
#include "cpr/proxies.h"
#include <initializer_list>
#include <map>
#include <string>
#include <utility>
namespace cpr {
Proxies::Proxies(const std::initializer_list<std::pair<const std::string, std::string>>& hosts)
: hosts_{hosts} {}
bool Proxies::has(const std::string& protocol) const {
return hosts_.count(protocol) > 0;
}
const std::string& Proxies::operator[](const std::string& protocol) {
return hosts_[protocol];
}
} // namespace cpr

46
vendor/CPR/cpr/response.cpp vendored Normal file
View File

@ -0,0 +1,46 @@
#include "cpr/response.h"
namespace cpr {
Response::Response(std::shared_ptr<CurlHolder> curl, std::string&& p_text,
std::string&& p_header_string, Cookies&& p_cookies = Cookies{},
Error&& p_error = Error{})
: curl_(std::move(curl)), text(std::move(p_text)), cookies(std::move(p_cookies)),
error(std::move(p_error)) {
header = cpr::util::parseHeader(p_header_string, &status_line, &reason);
assert(curl_);
assert(curl_->handle);
curl_easy_getinfo(curl_->handle, CURLINFO_RESPONSE_CODE, &status_code);
curl_easy_getinfo(curl_->handle, CURLINFO_TOTAL_TIME, &elapsed);
char* url_string{nullptr};
curl_easy_getinfo(curl_->handle, CURLINFO_EFFECTIVE_URL, &url_string);
url = Url(url_string);
#if LIBCURL_VERSION_NUM >= 0x073700
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_DOWNLOAD_T, &downloaded_bytes);
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_UPLOAD_T, &uploaded_bytes);
#else
double downloaded_bytes_double, uploaded_bytes_double;
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_DOWNLOAD, &downloaded_bytes_double);
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_UPLOAD, &uploaded_bytes_double);
downloaded_bytes = downloaded_bytes_double;
uploaded_bytes = uploaded_bytes_double;
#endif
curl_easy_getinfo(curl_->handle, CURLINFO_REDIRECT_COUNT, &redirect_count);
}
std::vector<std::string> Response::GetCertInfo() {
assert(curl_);
assert(curl_->handle);
curl_certinfo* ci{nullptr};
curl_easy_getinfo(curl_->handle, CURLINFO_CERTINFO, &ci);
std::vector<std::string> info;
info.resize(ci->num_of_certs);
for (size_t i = 0; i < ci->num_of_certs; i++) {
// No way around here.
// NOLINTNEXTLINE (cppcoreguidelines-pro-bounds-pointer-arithmetic)
info[i] = std::string{ci->certinfo[i]->data};
}
return info;
}
} // namespace cpr

693
vendor/CPR/cpr/session.cpp vendored Normal file
View File

@ -0,0 +1,693 @@
#include "cpr/session.h"
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <string>
#include <curl/curl.h>
#include "cpr/curlholder.h"
#include "cpr/util.h"
namespace cpr {
// Ignored here since libcurl reqires a long:
// NOLINTNEXTLINE(google-runtime-int)
constexpr long ON = 1L;
// Ignored here since libcurl reqires a long:
// NOLINTNEXTLINE(google-runtime-int)
constexpr long OFF = 0L;
class Session::Impl {
public:
Impl();
void SetUrl(const Url& url);
void SetParameters(const Parameters& parameters);
void SetParameters(Parameters&& parameters);
void SetHeader(const Header& header);
void SetTimeout(const Timeout& timeout);
void SetConnectTimeout(const ConnectTimeout& timeout);
void SetAuth(const Authentication& auth);
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
void SetBearer(const Bearer& token);
#endif
void SetDigest(const Digest& auth);
void SetUserAgent(const UserAgent& ua);
void SetPayload(Payload&& payload);
void SetPayload(const Payload& payload);
void SetProxies(Proxies&& proxies);
void SetProxies(const Proxies& proxies);
void SetMultipart(Multipart&& multipart);
void SetMultipart(const Multipart& multipart);
void SetNTLM(const NTLM& auth);
void SetRedirect(const bool& redirect);
void SetMaxRedirects(const MaxRedirects& max_redirects);
void SetCookies(const Cookies& cookies);
void SetBody(Body&& body);
void SetBody(const Body& body);
void SetReadCallback(const ReadCallback& read);
void SetHeaderCallback(const HeaderCallback& header);
void SetWriteCallback(const WriteCallback& write);
void SetProgressCallback(const ProgressCallback& progress);
void SetDebugCallback(const DebugCallback& debug);
void SetLowSpeed(const LowSpeed& low_speed);
void SetVerifySsl(const VerifySsl& verify);
void SetLimitRate(const LimitRate& limit_rate);
void SetUnixSocket(const UnixSocket& unix_socket);
void SetVerbose(const Verbose& verbose);
void SetSslOptions(const SslOptions& options);
Response Delete();
Response Download(const WriteCallback& write);
Response Download(std::ofstream& file);
Response Get();
Response Head();
Response Options();
Response Patch();
Response Post();
Response Put();
private:
bool hasBodyOrPayload_{false};
std::shared_ptr<CurlHolder> curl_;
Url url_;
Parameters parameters_;
Proxies proxies_;
ReadCallback readcb_;
HeaderCallback headercb_;
WriteCallback writecb_;
ProgressCallback progresscb_;
DebugCallback debugcb_;
Response makeDownloadRequest();
Response makeRequest();
static void freeHolder(CurlHolder* holder);
};
Session::Impl::Impl() : curl_(new CurlHolder()) {
// Set up some sensible defaults
curl_version_info_data* version_info = curl_version_info(CURLVERSION_NOW);
std::string version = "curl/" + std::string{version_info->version};
curl_easy_setopt(curl_->handle, CURLOPT_USERAGENT, version.c_str());
curl_easy_setopt(curl_->handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl_->handle, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl_->handle, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(curl_->handle, CURLOPT_ERRORBUFFER, curl_->error.data());
curl_easy_setopt(curl_->handle, CURLOPT_COOKIEFILE, "");
#ifdef CPR_CURL_NOSIGNAL
curl_easy_setopt(curl_->handle, CURLOPT_NOSIGNAL, 1L);
#endif
#if LIBCURL_VERSION_MAJOR >= 7
#if LIBCURL_VERSION_MINOR >= 25
#if LIBCURL_VERSION_PATCH >= 0
curl_easy_setopt(curl_->handle, CURLOPT_TCP_KEEPALIVE, 1L);
#endif
#endif
#endif
}
void Session::Impl::SetUrl(const Url& url) {
url_ = url;
}
void Session::Impl::SetParameters(const Parameters& parameters) {
parameters_ = parameters;
}
void Session::Impl::SetParameters(Parameters&& parameters) {
parameters_ = std::move(parameters);
}
void Session::Impl::SetHeader(const Header& header) {
curl_slist* chunk = nullptr;
for (const std::pair<const std::string, std::string>& item : header) {
std::string header_string = item.first;
if (item.second.empty()) {
header_string += ";";
} else {
header_string += ": " + item.second;
}
curl_slist* temp = curl_slist_append(chunk, header_string.c_str());
if (temp) {
chunk = temp;
}
}
curl_easy_setopt(curl_->handle, CURLOPT_HTTPHEADER, chunk);
curl_slist_free_all(curl_->chunk);
curl_->chunk = chunk;
}
void Session::Impl::SetTimeout(const Timeout& timeout) {
curl_easy_setopt(curl_->handle, CURLOPT_TIMEOUT_MS, timeout.Milliseconds());
}
void Session::Impl::SetConnectTimeout(const ConnectTimeout& timeout) {
curl_easy_setopt(curl_->handle, CURLOPT_CONNECTTIMEOUT_MS, timeout.Milliseconds());
}
void Session::Impl::SetVerbose(const Verbose& verbose) {
curl_easy_setopt(curl_->handle, CURLOPT_VERBOSE, verbose.verbose ? ON : OFF);
}
void Session::Impl::SetAuth(const Authentication& auth) {
// Ignore here since this has been defined by libcurl.
// NOLINTNEXTLINE(hicpp-signed-bitwise)
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
}
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
void Session::Impl::SetBearer(const Bearer& token) {
// Ignore here since this has been defined by libcurl.
// NOLINTNEXTLINE(hicpp-signed-bitwise)
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
curl_easy_setopt(curl_->handle, CURLOPT_XOAUTH2_BEARER, token.GetToken());
}
#endif
void Session::Impl::SetDigest(const Digest& auth) {
// Ignore here since this has been defined by libcurl.
// NOLINTNEXTLINE(hicpp-signed-bitwise)
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
}
void Session::Impl::SetUserAgent(const UserAgent& ua) {
curl_easy_setopt(curl_->handle, CURLOPT_USERAGENT, ua.c_str());
}
void Session::Impl::SetPayload(Payload&& payload) {
hasBodyOrPayload_ = true;
const std::string content = payload.GetContent(*curl_);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
}
void Session::Impl::SetPayload(const Payload& payload) {
hasBodyOrPayload_ = true;
const std::string content = payload.GetContent(*curl_);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
}
void Session::Impl::SetProxies(const Proxies& proxies) {
proxies_ = proxies;
}
void Session::Impl::SetProxies(Proxies&& proxies) {
proxies_ = std::move(proxies);
}
void Session::Impl::SetMultipart(Multipart&& multipart) {
curl_httppost* formpost = nullptr;
curl_httppost* lastptr = nullptr;
for (const Part& part : multipart.parts) {
std::vector<curl_forms> formdata;
if (part.is_buffer) {
// Do not use formdata, to prevent having to use reinterpreter_cast:
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER,
part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH,
part.datalen, CURLFORM_END);
} else {
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
if (part.is_file) {
formdata.push_back({CURLFORM_FILE, part.value.c_str()});
} else {
formdata.push_back({CURLFORM_COPYCONTENTS, part.value.c_str()});
}
}
if (!part.content_type.empty()) {
formdata.push_back({CURLFORM_CONTENTTYPE, part.content_type.c_str()});
}
formdata.push_back({CURLFORM_END, nullptr});
curl_formadd(&formpost, &lastptr, CURLFORM_ARRAY, formdata.data(), CURLFORM_END);
}
curl_easy_setopt(curl_->handle, CURLOPT_HTTPPOST, formpost);
hasBodyOrPayload_ = true;
curl_formfree(curl_->formpost);
curl_->formpost = formpost;
}
void Session::Impl::SetMultipart(const Multipart& multipart) {
curl_httppost* formpost = nullptr;
curl_httppost* lastptr = nullptr;
for (const Part& part : multipart.parts) {
std::vector<curl_forms> formdata;
if (part.is_buffer) {
// Do not use formdata, to prevent having to use reinterpreter_cast:
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER,
part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH,
part.datalen, CURLFORM_END);
} else {
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
if (part.is_file) {
formdata.push_back({CURLFORM_FILE, part.value.c_str()});
} else {
formdata.push_back({CURLFORM_COPYCONTENTS, part.value.c_str()});
}
}
if (!part.content_type.empty()) {
formdata.push_back({CURLFORM_CONTENTTYPE, part.content_type.c_str()});
}
formdata.push_back({CURLFORM_END, nullptr});
curl_formadd(&formpost, &lastptr, CURLFORM_ARRAY, formdata.data(), CURLFORM_END);
}
curl_easy_setopt(curl_->handle, CURLOPT_HTTPPOST, formpost);
hasBodyOrPayload_ = true;
curl_formfree(curl_->formpost);
curl_->formpost = formpost;
}
void Session::Impl::SetLimitRate(const LimitRate& limit_rate) {
curl_easy_setopt(curl_->handle, CURLOPT_MAX_RECV_SPEED_LARGE, limit_rate.downrate);
curl_easy_setopt(curl_->handle, CURLOPT_MAX_SEND_SPEED_LARGE, limit_rate.uprate);
}
void Session::Impl::SetNTLM(const NTLM& auth) {
// Ignore here since this has been defined by libcurl.
// NOLINTNEXTLINE(hicpp-signed-bitwise)
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
}
void Session::Impl::SetRedirect(const bool& redirect) {
curl_easy_setopt(curl_->handle, CURLOPT_FOLLOWLOCATION, std::int32_t(redirect));
}
void Session::Impl::SetMaxRedirects(const MaxRedirects& max_redirects) {
curl_easy_setopt(curl_->handle, CURLOPT_MAXREDIRS, max_redirects.number_of_redirects);
}
void Session::Impl::SetCookies(const Cookies& cookies) {
curl_easy_setopt(curl_->handle, CURLOPT_COOKIELIST, "ALL");
curl_easy_setopt(curl_->handle, CURLOPT_COOKIE, cookies.GetEncoded(*curl_).c_str());
}
void Session::Impl::SetBody(Body&& body) {
hasBodyOrPayload_ = true;
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(body.str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, body.c_str());
}
void Session::Impl::SetBody(const Body& body) {
hasBodyOrPayload_ = true;
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(body.str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDS, body.c_str());
}
void Session::Impl::SetReadCallback(const ReadCallback& read) {
readcb_ = read;
curl_easy_setopt(curl_->handle, CURLOPT_INFILESIZE_LARGE, read.size);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, read.size);
curl_easy_setopt(curl_->handle, CURLOPT_READFUNCTION, cpr::util::readUserFunction);
curl_easy_setopt(curl_->handle, CURLOPT_READDATA, &readcb_);
if (read.size == -1) {
SetHeader({{"Transfer-Encoding", "chunked"}});
}
}
void Session::Impl::SetHeaderCallback(const HeaderCallback& header) {
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::headerUserFunction);
headercb_ = header;
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &headercb_);
}
void Session::Impl::SetWriteCallback(const WriteCallback& write) {
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeUserFunction);
writecb_ = write;
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &writecb_);
}
void Session::Impl::SetProgressCallback(const ProgressCallback& progress) {
progresscb_ = progress;
#if LIBCURL_VERSION_NUM < 0x072000
curl_easy_setopt(curl_->handle, CURLOPT_PROGRESSFUNCTION, cpr::util::progressUserFunction);
curl_easy_setopt(curl_->handle, CURLOPT_PROGRESSDATA, &progresscb_);
#else
curl_easy_setopt(curl_->handle, CURLOPT_XFERINFOFUNCTION, cpr::util::progressUserFunction);
curl_easy_setopt(curl_->handle, CURLOPT_XFERINFODATA, &progresscb_);
#endif
curl_easy_setopt(curl_->handle, CURLOPT_NOPROGRESS, 0L);
}
void Session::Impl::SetDebugCallback(const DebugCallback& debug) {
curl_easy_setopt(curl_->handle, CURLOPT_DEBUGFUNCTION, cpr::util::debugUserFunction);
debugcb_ = debug;
curl_easy_setopt(curl_->handle, CURLOPT_DEBUGDATA, &debugcb_);
curl_easy_setopt(curl_->handle, CURLOPT_VERBOSE, 1L);
}
void Session::Impl::SetLowSpeed(const LowSpeed& low_speed) {
curl_easy_setopt(curl_->handle, CURLOPT_LOW_SPEED_LIMIT, low_speed.limit);
curl_easy_setopt(curl_->handle, CURLOPT_LOW_SPEED_TIME, low_speed.time);
}
void Session::Impl::SetVerifySsl(const VerifySsl& verify) {
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYPEER, verify ? ON : OFF);
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYHOST, verify ? 2L : 0L);
}
void Session::Impl::SetUnixSocket(const UnixSocket& unix_socket) {
curl_easy_setopt(curl_->handle, CURLOPT_UNIX_SOCKET_PATH, unix_socket.GetUnixSocketString());
}
void Session::Impl::SetSslOptions(const SslOptions& options) {
if (!options.cert_file.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_SSLCERT, options.cert_file.c_str());
if (!options.cert_type.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_SSLCERTTYPE, options.cert_type.c_str());
}
}
if (!options.key_file.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_SSLKEY, options.key_file.c_str());
if (!options.key_type.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_SSLKEYTYPE, options.key_type.c_str());
}
if (!options.key_pass.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_KEYPASSWD, options.key_pass.c_str());
}
}
#if SUPPORT_ALPN
curl_easy_setopt(curl_->handle, CURLOPT_SSL_ENABLE_ALPN, options.enable_alpn ? ON : OFF);
#endif
#if SUPPORT_NPN
curl_easy_setopt(curl_->handle, CURLOPT_SSL_ENABLE_NPN, options.enable_npn ? ON : OFF);
#endif
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYPEER, options.verify_peer ? ON : OFF);
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYHOST, options.verify_host ? 2L : 0L);
#if LIBCURL_VERSION_NUM >= 0x072900
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYSTATUS, options.verify_status ? ON : OFF);
#endif
curl_easy_setopt(curl_->handle, CURLOPT_SSLVERSION,
// Ignore here since this has been defined by libcurl.
// NOLINTNEXTLINE(hicpp-signed-bitwise)
options.ssl_version
#if SUPPORT_MAX_TLS_VERSION
| options.max_version
#endif
);
if (!options.ca_info.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_CAINFO, options.ca_info.c_str());
}
if (!options.ca_path.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_CAPATH, options.ca_path.c_str());
}
if (!options.crl_file.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_CRLFILE, options.crl_file.c_str());
}
if (!options.ciphers.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_SSL_CIPHER_LIST, options.ciphers.c_str());
}
#if SUPPORT_TLSv13_CIPHERS
if (!options.tls13_ciphers.empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_TLS13_CIPHERS, options.ciphers.c_str());
}
#endif
#if SUPPORT_SESSIONID_CACHE
curl_easy_setopt(curl_->handle, CURLOPT_SSL_SESSIONID_CACHE,
options.session_id_cache ? ON : OFF);
#endif
}
Response Session::Impl::Delete() {
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "DELETE");
return makeRequest();
}
Response Session::Impl::Download(const WriteCallback& write) {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "GET");
SetWriteCallback(write);
return makeDownloadRequest();
}
Response Session::Impl::Download(std::ofstream& file) {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeFileFunction);
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &file);
return makeDownloadRequest();
}
Response Session::Impl::Get() {
// In case there is a body or payload for this request, we create a custom GET-Request since a
// GET-Request with body is based on the HTTP RFC **not** a leagal request.
if (hasBodyOrPayload_) {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "GET");
} else {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1L);
}
return makeRequest();
}
Response Session::Impl::Head() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 1L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
return makeRequest();
}
Response Session::Impl::Options() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
return makeRequest();
}
Response Session::Impl::Patch() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "PATCH");
return makeRequest();
}
Response Session::Impl::Post() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
// In case there is no body or payload set it to an empty post:
if (hasBodyOrPayload_) {
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
} else {
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDS, readcb_.callback ? nullptr : "");
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "POST");
}
return makeRequest();
}
Response Session::Impl::Put() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "PUT");
return makeRequest();
}
Response Session::Impl::makeDownloadRequest() {
assert(curl_->handle);
const std::string parametersContent = parameters_.GetContent(*curl_);
if (!parametersContent.empty()) {
Url new_url{url_ + "?" + parametersContent};
curl_easy_setopt(curl_->handle, CURLOPT_URL, new_url.c_str());
} else {
curl_easy_setopt(curl_->handle, CURLOPT_URL, url_.c_str());
}
std::string protocol = url_.str().substr(0, url_.str().find(':'));
if (proxies_.has(protocol)) {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, proxies_[protocol].c_str());
} else {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, "");
}
curl_->error[0] = '\0';
std::string header_string;
if (headercb_.callback) {
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::headerUserFunction);
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &headercb_);
} else {
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::writeFunction);
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &header_string);
}
CURLcode curl_error = curl_easy_perform(curl_->handle);
curl_slist* raw_cookies{nullptr};
curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies);
Cookies cookies = util::parseCookies(raw_cookies);
curl_slist_free_all(raw_cookies);
std::string errorMsg = curl_->error.data();
return Response(curl_, "", std::move(header_string), std::move(cookies),
Error(curl_error, std::move(errorMsg)));
}
Response Session::Impl::makeRequest() {
assert(curl_->handle);
const std::string parametersContent = parameters_.GetContent(*curl_);
if (!parametersContent.empty()) {
Url new_url{url_ + "?" + parametersContent};
curl_easy_setopt(curl_->handle, CURLOPT_URL, new_url.c_str());
} else {
curl_easy_setopt(curl_->handle, CURLOPT_URL, url_.c_str());
}
std::string protocol = url_.str().substr(0, url_.str().find(':'));
if (proxies_.has(protocol)) {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, proxies_[protocol].c_str());
} else {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, nullptr);
}
#if LIBCURL_VERSION_MAJOR >= 7
#if LIBCURL_VERSION_MINOR >= 21
/* enable all supported built-in compressions */
curl_easy_setopt(curl_->handle, CURLOPT_ACCEPT_ENCODING, "");
#endif
#endif
curl_->error[0] = '\0';
std::string response_string;
std::string header_string;
if (!this->writecb_.callback) {
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &response_string);
}
if (!this->headercb_.callback) {
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::writeFunction);
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &header_string);
}
// Enable so we are able to retrive certificate information:
curl_easy_setopt(curl_->handle, CURLOPT_CERTINFO, 1L);
CURLcode curl_error = curl_easy_perform(curl_->handle);
curl_slist* raw_cookies{nullptr};
curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies);
Cookies cookies = util::parseCookies(raw_cookies);
curl_slist_free_all(raw_cookies);
// Reset the has no body property:
hasBodyOrPayload_ = false;
std::string errorMsg = curl_->error.data();
return Response(curl_, std::move(response_string), std::move(header_string), std::move(cookies),
Error(curl_error, std::move(errorMsg)));
}
// clang-format off
Session::Session() : pimpl_(new Impl()) {}
Session::~Session() = default;
void Session::SetReadCallback(const ReadCallback& read) { pimpl_->SetReadCallback(read); }
void Session::SetHeaderCallback(const HeaderCallback& header) { pimpl_->SetHeaderCallback(header); }
void Session::SetWriteCallback(const WriteCallback& write) { pimpl_->SetWriteCallback(write); }
void Session::SetProgressCallback(const ProgressCallback& progress) { pimpl_->SetProgressCallback(progress); }
void Session::SetUrl(const Url& url) { pimpl_->SetUrl(url); }
void Session::SetParameters(const Parameters& parameters) { pimpl_->SetParameters(parameters); }
void Session::SetParameters(Parameters&& parameters) { pimpl_->SetParameters(std::move(parameters)); }
void Session::SetHeader(const Header& header) { pimpl_->SetHeader(header); }
void Session::SetTimeout(const Timeout& timeout) { pimpl_->SetTimeout(timeout); }
void Session::SetConnectTimeout(const ConnectTimeout& timeout) { pimpl_->SetConnectTimeout(timeout); }
void Session::SetAuth(const Authentication& auth) { pimpl_->SetAuth(auth); }
void Session::SetDigest(const Digest& auth) { pimpl_->SetDigest(auth); }
void Session::SetUserAgent(const UserAgent& ua) { pimpl_->SetUserAgent(ua); }
void Session::SetPayload(const Payload& payload) { pimpl_->SetPayload(payload); }
void Session::SetPayload(Payload&& payload) { pimpl_->SetPayload(std::move(payload)); }
void Session::SetProxies(const Proxies& proxies) { pimpl_->SetProxies(proxies); }
void Session::SetProxies(Proxies&& proxies) { pimpl_->SetProxies(std::move(proxies)); }
void Session::SetMultipart(const Multipart& multipart) { pimpl_->SetMultipart(multipart); }
void Session::SetMultipart(Multipart&& multipart) { pimpl_->SetMultipart(std::move(multipart)); }
void Session::SetNTLM(const NTLM& auth) { pimpl_->SetNTLM(auth); }
void Session::SetRedirect(const bool& redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetMaxRedirects(const MaxRedirects& max_redirects) { pimpl_->SetMaxRedirects(max_redirects); }
void Session::SetCookies(const Cookies& cookies) { pimpl_->SetCookies(cookies); }
void Session::SetBody(const Body& body) { pimpl_->SetBody(body); }
void Session::SetBody(Body&& body) { pimpl_->SetBody(std::move(body)); }
void Session::SetLowSpeed(const LowSpeed& low_speed) { pimpl_->SetLowSpeed(low_speed); }
void Session::SetVerifySsl(const VerifySsl& verify) { pimpl_->SetVerifySsl(verify); }
void Session::SetUnixSocket(const UnixSocket& unix_socket) { pimpl_->SetUnixSocket(unix_socket); }
void Session::SetSslOptions(const SslOptions& options) { pimpl_->SetSslOptions(options); }
void Session::SetVerbose(const Verbose& verbose) { pimpl_->SetVerbose(verbose); }
void Session::SetOption(const ReadCallback& read) { pimpl_->SetReadCallback(read); }
void Session::SetOption(const HeaderCallback& header) { pimpl_->SetHeaderCallback(header); }
void Session::SetOption(const WriteCallback& write) { pimpl_->SetWriteCallback(write); }
void Session::SetOption(const ProgressCallback& progress) { pimpl_->SetProgressCallback(progress); }
void Session::SetOption(const DebugCallback& debug) { pimpl_->SetDebugCallback(debug); }
void Session::SetOption(const Url& url) { pimpl_->SetUrl(url); }
void Session::SetOption(const Parameters& parameters) { pimpl_->SetParameters(parameters); }
void Session::SetOption(Parameters&& parameters) { pimpl_->SetParameters(std::move(parameters)); }
void Session::SetOption(const Header& header) { pimpl_->SetHeader(header); }
void Session::SetOption(const Timeout& timeout) { pimpl_->SetTimeout(timeout); }
void Session::SetOption(const ConnectTimeout& timeout) { pimpl_->SetConnectTimeout(timeout); }
void Session::SetOption(const Authentication& auth) { pimpl_->SetAuth(auth); }
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
void Session::SetOption(const Bearer& auth) { pimpl_->SetBearer(auth); }
#endif
void Session::SetOption(const Digest& auth) { pimpl_->SetDigest(auth); }
void Session::SetOption(const UserAgent& ua) { pimpl_->SetUserAgent(ua); }
void Session::SetOption(const Payload& payload) { pimpl_->SetPayload(payload); }
void Session::SetOption(Payload&& payload) { pimpl_->SetPayload(std::move(payload)); }
void Session::SetOption(const Proxies& proxies) { pimpl_->SetProxies(proxies); }
void Session::SetOption(Proxies&& proxies) { pimpl_->SetProxies(std::move(proxies)); }
void Session::SetOption(const Multipart& multipart) { pimpl_->SetMultipart(multipart); }
void Session::SetOption(Multipart&& multipart) { pimpl_->SetMultipart(std::move(multipart)); }
void Session::SetOption(const NTLM& auth) { pimpl_->SetNTLM(auth); }
void Session::SetOption(const bool& redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetOption(const MaxRedirects& max_redirects) { pimpl_->SetMaxRedirects(max_redirects); }
void Session::SetOption(const Cookies& cookies) { pimpl_->SetCookies(cookies); }
void Session::SetOption(const Body& body) { pimpl_->SetBody(body); }
void Session::SetOption(Body&& body) { pimpl_->SetBody(std::move(body)); }
void Session::SetOption(const LowSpeed& low_speed) { pimpl_->SetLowSpeed(low_speed); }
void Session::SetOption(const VerifySsl& verify) { pimpl_->SetVerifySsl(verify); }
void Session::SetOption(const Verbose& verbose) { pimpl_->SetVerbose(verbose); }
void Session::SetOption(const UnixSocket& unix_socket) { pimpl_->SetUnixSocket(unix_socket); }
void Session::SetOption(const SslOptions& options) { pimpl_->SetSslOptions(options); }
Response Session::Delete() { return pimpl_->Delete(); }
Response Session::Download(const WriteCallback& write) { return pimpl_->Download(write); }
Response Session::Download(std::ofstream& file) { return pimpl_->Download(file); }
Response Session::Get() { return pimpl_->Get(); }
Response Session::Head() { return pimpl_->Head(); }
Response Session::Options() { return pimpl_->Options(); }
Response Session::Patch() { return pimpl_->Patch(); }
Response Session::Post() { return pimpl_->Post(); }
Response Session::Put() { return pimpl_->Put(); }
// clang-format on
} // namespace cpr

34
vendor/CPR/cpr/timeout.cpp vendored Normal file
View File

@ -0,0 +1,34 @@
#include "cpr/timeout.h"
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <string>
namespace cpr {
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
long Timeout::Milliseconds() const {
static_assert(std::is_same<std::chrono::milliseconds, decltype(ms)>::value,
"Following casting expects milliseconds.");
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
if (ms.count() > std::numeric_limits<long>::max()) {
throw std::overflow_error(
"cpr::Timeout: timeout value overflow: " + std::to_string(ms.count()) + " ms.");
}
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
if (ms.count() < std::numeric_limits<long>::min()) {
throw std::underflow_error(
"cpr::Timeout: timeout value underflow: " + std::to_string(ms.count()) + " ms.");
}
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
return static_cast<long>(ms.count());
}
} // namespace cpr

8
vendor/CPR/cpr/unix_socket.cpp vendored Normal file
View File

@ -0,0 +1,8 @@
#include "cpr/unix_socket.h"
namespace cpr {
const char* UnixSocket::GetUnixSocketString() const noexcept {
return unix_socket_.data();
}
} // namespace cpr

164
vendor/CPR/cpr/util.cpp vendored Normal file
View File

@ -0,0 +1,164 @@
#include "cpr/util.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
namespace cpr {
namespace util {
Cookies parseCookies(curl_slist* raw_cookies) {
Cookies cookies;
for (curl_slist* nc = raw_cookies; nc; nc = nc->next) {
std::vector<std::string> tokens = cpr::util::split(nc->data, '\t');
std::string value = tokens.back();
tokens.pop_back();
cookies[tokens.back()] = value;
}
return cookies;
}
Header parseHeader(const std::string& headers, std::string* status_line, std::string* reason) {
Header header;
std::vector<std::string> lines;
std::istringstream stream(headers);
{
std::string line;
while (std::getline(stream, line, '\n')) {
lines.push_back(line);
}
}
for (std::string& line : lines) {
// NOLINTNEXTLINE (cppcoreguidelines-avoid-magic-numbers)
if (line.substr(0, 5) == "HTTP/") {
// set the status_line if it was given
if ((status_line != nullptr) || (reason != nullptr)) {
line.resize(std::min<size_t>(line.size(), line.find_last_not_of("\t\n\r ") + 1));
if (status_line != nullptr) {
*status_line = line;
}
// set the reason if it was given
if (reason != nullptr) {
size_t pos1 = line.find_first_of("\t ");
size_t pos2 = std::string::npos;
if (pos1 != std::string::npos) {
pos2 = line.find_first_of("\t ", pos1 + 1);
}
if (pos2 != std::string::npos) {
line.erase(0, pos2 + 1);
*reason = line;
}
}
}
header.clear();
}
if (line.length() > 0) {
size_t found = line.find(':');
if (found != std::string::npos) {
std::string value = line.substr(found + 1);
value.erase(0, value.find_first_not_of("\t "));
value.resize(std::min<size_t>(value.size(), value.find_last_not_of("\t\n\r ") + 1));
header[line.substr(0, found)] = value;
}
}
}
return header;
}
std::vector<std::string> split(const std::string& to_split, char delimiter) {
std::vector<std::string> tokens;
std::stringstream stream(to_split);
std::string item;
while (std::getline(stream, item, delimiter)) {
tokens.push_back(item);
}
return tokens;
}
size_t readUserFunction(char* ptr, size_t size, size_t nitems, const ReadCallback* read) {
size *= nitems;
return read->callback(ptr, size) ? size : CURL_READFUNC_ABORT;
}
size_t headerUserFunction(char* ptr, size_t size, size_t nmemb, const HeaderCallback* header) {
size *= nmemb;
return header->callback({ptr, size}) ? size : 0;
}
size_t writeFunction(char* ptr, size_t size, size_t nmemb, std::string* data) {
size *= nmemb;
data->append(ptr, size);
return size;
}
size_t writeFileFunction(char* ptr, size_t size, size_t nmemb, std::ofstream* file) {
size *= nmemb;
file->write(ptr, size);
return size;
}
size_t writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallback* write) {
size *= nmemb;
return write->callback({ptr, size}) ? size : 0;
}
#if LIBCURL_VERSION_NUM < 0x072000
int progressUserFunction(const ProgressCallback* progress, double dltotal, double dlnow,
double ultotal, double ulnow) {
#else
int progressUserFunction(const ProgressCallback* progress, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow) {
#endif
return progress->callback(dltotal, dlnow, ultotal, ulnow) ? 0 : 1;
}
int debugUserFunction(CURL* /*handle*/, curl_infotype type, char* data, size_t size,
const DebugCallback* debug) {
debug->callback(DebugCallback::InfoType(type), std::string(data, size));
return 0;
}
/**
* Creates a temporary CurlHolder object and uses it to escape the given string.
* If you plan to use this methode on a regular basis think about creating a CurlHolder
* object and calling urlEncode(std::string) on it.
*
* Example:
* CurlHolder holder;
* std::string input = "Hello World!";
* std::string result = holder.urlEncode(input);
**/
std::string urlEncode(const std::string& s) {
CurlHolder holder; // Create a temporary new holder for URL encoding
return holder.urlEncode(s);
}
/**
* Creates a temporary CurlHolder object and uses it to unescape the given string.
* If you plan to use this methode on a regular basis think about creating a CurlHolder
* object and calling urlDecode(std::string) on it.
*
* Example:
* CurlHolder holder;
* std::string input = "Hello%20World%21";
* std::string result = holder.urlDecode(input);
**/
std::string urlDecode(const std::string& s) {
CurlHolder holder; // Create a temporary new holder for URL decoding
return holder.urlDecode(s);
}
} // namespace util
} // namespace cpr

36
vendor/CPR/include/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.15)
target_include_directories(cpr PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
target_sources(cpr PRIVATE
# Header files (useful in IDEs)
cpr/api.h
cpr/auth.h
cpr/bearer.h
cpr/body.h
cpr/cookies.h
cpr/cpr.h
cpr/cprtypes.h
cpr/curlholder.h
cpr/curlholder.h
cpr/digest.h
cpr/error.h
cpr/limit_rate.h
cpr/max_redirects.h
cpr/multipart.h
cpr/ntlm.h
cpr/parameters.h
cpr/payload.h
cpr/proxies.h
cpr/response.h
cpr/session.h
cpr/ssl_options.h
cpr/timeout.h
cpr/unix_socket.h
cpr/util.h
cpr/verbose.h
)
install(DIRECTORY cpr DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

229
vendor/CPR/include/cpr/api.h vendored Normal file
View File

@ -0,0 +1,229 @@
#ifndef CPR_API_H
#define CPR_API_H
#include <fstream>
#include <functional>
#include <future>
#include <string>
#include <utility>
#include "cpr/auth.h"
#include "cpr/bearer.h"
#include "cpr/cprtypes.h"
#include "cpr/digest.h"
#include "cpr/multipart.h"
#include "cpr/ntlm.h"
#include "cpr/payload.h"
#include "cpr/response.h"
#include "cpr/session.h"
#include <utility>
namespace cpr {
using AsyncResponse = std::future<Response>;
namespace priv {
template <typename T>
void set_option(Session& session, T&& t) {
session.SetOption(std::forward<T>(t));
}
template <typename T, typename... Ts>
void set_option(Session& session, T&& t, Ts&&... ts) {
set_option(session, std::forward<T>(t));
set_option(session, std::forward<Ts>(ts)...);
}
} // namespace priv
// Get methods
template <typename... Ts>
Response Get(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Get();
}
// Get async methods
template <typename... Ts>
AsyncResponse GetAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Get(std::move(ts)...); }, std::move(ts)...);
}
// Get callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto GetCallback(Then then, Ts... ts) -> std::future<decltype(then(Get(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Get(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Post methods
template <typename... Ts>
Response Post(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Post();
}
// Post async methods
template <typename... Ts>
AsyncResponse PostAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Post(std::move(ts)...); }, std::move(ts)...);
}
// Post callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto PostCallback(Then then, Ts... ts) -> std::future<decltype(then(Post(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Post(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Put methods
template <typename... Ts>
Response Put(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Put();
}
// Put async methods
template <typename... Ts>
AsyncResponse PutAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Put(std::move(ts)...); }, std::move(ts)...);
}
// Put callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto PutCallback(Then then, Ts... ts) -> std::future<decltype(then(Put(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Put(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Head methods
template <typename... Ts>
Response Head(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Head();
}
// Head async methods
template <typename... Ts>
AsyncResponse HeadAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Head(std::move(ts)...); }, std::move(ts)...);
}
// Head callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto HeadCallback(Then then, Ts... ts) -> std::future<decltype(then(Head(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Head(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Delete methods
template <typename... Ts>
Response Delete(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Delete();
}
// Delete async methods
template <typename... Ts>
AsyncResponse DeleteAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Delete(std::move(ts)...); },
std::move(ts)...);
}
// Delete callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto DeleteCallback(Then then, Ts... ts) -> std::future<decltype(then(Delete(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Delete(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Options methods
template <typename... Ts>
Response Options(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Options();
}
// Options async methods
template <typename... Ts>
AsyncResponse OptionsAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Options(std::move(ts)...); },
std::move(ts)...);
}
// Options callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto OptionsCallback(Then then, Ts... ts)
-> std::future<decltype(then(Options(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Options(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Patch methods
template <typename... Ts>
Response Patch(Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Patch();
}
// Patch async methods
template <typename... Ts>
AsyncResponse PatchAsync(Ts... ts) {
return std::async(
std::launch::async, [](Ts... ts) { return Patch(std::move(ts)...); }, std::move(ts)...);
}
// Patch callback methods
template <typename Then, typename... Ts>
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto PatchCallback(Then then, Ts... ts) -> std::future<decltype(then(Patch(std::move(ts)...)))> {
return std::async(
std::launch::async, [](Then then, Ts... ts) { return then(Patch(std::move(ts)...)); },
std::move(then), std::move(ts)...);
}
// Download methods
template <typename... Ts>
Response Download(std::ofstream& file, Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Download(file);
}
// Download with user callback
template <typename... Ts>
Response Download(const WriteCallback& write, Ts&&... ts) {
Session session;
priv::set_option(session, std::forward<Ts>(ts)...);
return session.Download(write);
}
} // namespace cpr
#endif

31
vendor/CPR/include/cpr/auth.h vendored Normal file
View File

@ -0,0 +1,31 @@
#ifndef CPR_AUTH_H
#define CPR_AUTH_H
#include <string>
#include <utility>
namespace cpr {
class Authentication {
public:
Authentication(const std::string& username, const std::string& password)
: auth_string_{username + ":" + password} {}
Authentication(std::string&& username, std::string&& password)
: auth_string_{std::move(username) + ":" + std::move(password)} {}
Authentication(const Authentication& other) = default;
Authentication(Authentication&& old) noexcept = default;
virtual ~Authentication() noexcept = default;
Authentication& operator=(Authentication&& old) noexcept = default;
Authentication& operator=(const Authentication& other) = default;
virtual const char* GetAuthString() const noexcept;
protected:
std::string auth_string_;
};
} // namespace cpr
#endif

36
vendor/CPR/include/cpr/bearer.h vendored Normal file
View File

@ -0,0 +1,36 @@
#ifndef CPR_BEARER_H
#define CPR_BEARER_H
#include <string>
#include <curl/curlver.h>
#include <utility>
namespace cpr {
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
class Bearer {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Bearer(const std::string& token) : token_string_{token} {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Bearer(std::string&& token) : token_string_{std::move(token)} {}
Bearer(const Bearer& other) = default;
Bearer(Bearer&& old) noexcept = default;
virtual ~Bearer() noexcept = default;
Bearer& operator=(Bearer&& old) noexcept = default;
Bearer& operator=(const Bearer& other) = default;
virtual const char* GetToken() const noexcept;
protected:
std::string token_string_;
};
#endif
} // namespace cpr
#endif

32
vendor/CPR/include/cpr/body.h vendored Normal file
View File

@ -0,0 +1,32 @@
#ifndef CPR_BODY_H
#define CPR_BODY_H
#include <initializer_list>
#include <string>
#include "cpr/cprtypes.h"
namespace cpr {
class Body : public StringHolder<Body> {
public:
Body() : StringHolder<Body>() {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Body(const std::string& body) : StringHolder<Body>(body) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Body(std::string&& body) : StringHolder<Body>(std::move(body)) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Body(const char* body) : StringHolder<Body>(body) {}
Body(const char* str, size_t len) : StringHolder<Body>(str, len) {}
Body(const std::initializer_list<std::string> args) : StringHolder<Body>(args) {}
Body(const Body& other) = default;
Body(Body&& old) noexcept = default;
~Body() override = default;
Body& operator=(Body&& old) noexcept = default;
Body& operator=(const Body& other) = default;
};
} // namespace cpr
#endif

78
vendor/CPR/include/cpr/callback.h vendored Normal file
View File

@ -0,0 +1,78 @@
#ifndef CPR_CALLBACK_H
#define CPR_CALLBACK_H
#include "cprtypes.h"
#include <functional>
#include <utility>
namespace cpr {
class ReadCallback {
public:
ReadCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ReadCallback(std::function<bool(char* buffer, size_t& size)> callback)
: size{-1}, callback{std::move(callback)} {}
ReadCallback(cpr_off_t size, std::function<bool(char* buffer, size_t& size)> callback)
: size{size}, callback{std::move(callback)} {}
cpr_off_t size{};
std::function<bool(char* buffer, size_t& size)> callback;
};
class HeaderCallback {
public:
HeaderCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
HeaderCallback(std::function<bool(std::string header)> callback)
: callback(std::move(callback)) {}
std::function<bool(std::string header)> callback;
};
class WriteCallback {
public:
WriteCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
WriteCallback(std::function<bool(std::string data)> callback) : callback(std::move(callback)) {}
std::function<bool(std::string data)> callback;
};
class ProgressCallback {
public:
ProgressCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ProgressCallback(std::function<bool(size_t downloadTotal, size_t downloadNow,
size_t uploadTotal, size_t uploadNow)>
callback)
: callback(std::move(callback)) {}
std::function<bool(size_t downloadTotal, size_t downloadNow, size_t uploadTotal,
size_t uploadNow)>
callback;
};
class DebugCallback {
public:
enum class InfoType {
TEXT = 0,
HEADER_IN = 1,
HEADER_OUT = 2,
DATA_IN = 3,
DATA_OUT = 4,
SSL_DATA_IN = 5,
SSL_DATA_OUT = 6,
};
DebugCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
DebugCallback(std::function<void(InfoType type, std::string data)> callback)
: callback(std::move(callback)) {}
std::function<void(InfoType type, std::string data)> callback;
};
} // namespace cpr
#endif

View File

@ -0,0 +1,18 @@
#ifndef CPR_CONNECT_TIMEOUT_H
#define CPR_CONNECT_TIMEOUT_H
#include "cpr/timeout.h"
namespace cpr {
class ConnectTimeout : public Timeout {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ConnectTimeout(const std::chrono::milliseconds& duration) : Timeout{duration} {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ConnectTimeout(const std::int32_t& milliseconds) : Timeout{milliseconds} {}
};
} // namespace cpr
#endif

55
vendor/CPR/include/cpr/cookies.h vendored Normal file
View File

@ -0,0 +1,55 @@
#ifndef CPR_COOKIES_H
#define CPR_COOKIES_H
#include "cpr/curlholder.h"
#include <initializer_list>
#include <map>
#include <sstream>
#include <string>
namespace cpr {
class Cookies {
public:
/**
* Should we URL-encode cookies when making a request.
* Based on RFC6265, it is recommended but not mandatory to encode cookies.
*
* -------
* To maximize compatibility with user agents, servers that wish to
* store arbitrary data in a cookie-value SHOULD encode that data, for
* example, using Base64 [RFC4648].
* -------
* Source: RFC6265 (https://www.ietf.org/rfc/rfc6265.txt)
**/
bool encode{true};
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Cookies(bool encode = true) : encode(encode) {}
Cookies(const std::initializer_list<std::pair<const std::string, std::string>>& pairs,
bool encode = true)
: encode(encode), map_{pairs} {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Cookies(const std::map<std::string, std::string>& map, bool encode = true)
: encode(encode), map_{map} {}
std::string& operator[](const std::string& key);
std::string GetEncoded(const CurlHolder& holder) const;
using iterator = std::map<std::string, std::string>::iterator;
using const_iterator = std::map<std::string, std::string>::const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
protected:
std::map<std::string, std::string> map_;
};
} // namespace cpr
#endif

13
vendor/CPR/include/cpr/cpr.h vendored Normal file
View File

@ -0,0 +1,13 @@
#ifndef CPR_CPR_H
#define CPR_CPR_H
#include "cpr/api.h"
#include "cpr/auth.h"
#include "cpr/cprtypes.h"
#include "cpr/response.h"
#include "cpr/session.h"
#include "cpr/status_codes.h"
#define CPR_LIBCURL_VERSION_NUM LIBCURL_VERSION_NUM
#endif

133
vendor/CPR/include/cpr/cprtypes.h vendored Normal file
View File

@ -0,0 +1,133 @@
#ifndef CPR_CPR_TYPES_H
#define CPR_CPR_TYPES_H
#include <curl/curl.h>
#include <initializer_list>
#include <map>
#include <memory>
#include <numeric>
#include <string>
namespace cpr {
/**
* Wrapper around "curl_off_t" to prevent applications from having to link against libcurl.
**/
using cpr_off_t = curl_off_t;
template <class T>
class StringHolder {
public:
StringHolder() = default;
explicit StringHolder(const std::string& str) : str_(str) {}
explicit StringHolder(std::string&& str) : str_(std::move(str)) {}
explicit StringHolder(const char* str) : str_(str) {}
StringHolder(const char* str, size_t len) : str_(str, len) {}
StringHolder(const std::initializer_list<std::string> args) {
str_ = std::accumulate(args.begin(), args.end(), str_);
}
StringHolder(const StringHolder& other) = default;
StringHolder(StringHolder&& old) noexcept = default;
virtual ~StringHolder() = default;
StringHolder& operator=(StringHolder&& old) noexcept = default;
StringHolder& operator=(const StringHolder& other) = default;
explicit operator std::string() const {
return str_;
}
T operator+(const char* rhs) const {
return T(str_ + rhs);
}
T operator+(const std::string& rhs) const {
return T(str_ + rhs);
}
T operator+(const StringHolder<T>& rhs) const {
return T(str_ + rhs.str_);
}
void operator+=(const char* rhs) {
str_ += rhs;
}
void operator+=(const std::string& rhs) {
str_ += rhs;
}
void operator+=(const StringHolder<T>& rhs) {
str_ += rhs;
}
bool operator==(const char* rhs) const {
return str_ == rhs;
}
bool operator==(const std::string& rhs) const {
return str_ == rhs;
}
bool operator==(const StringHolder<T>& rhs) const {
return str_ == rhs.str_;
}
bool operator!=(const char* rhs) const {
return str_.c_str() != rhs;
}
bool operator!=(const std::string& rhs) const {
return str_ != rhs;
}
bool operator!=(const StringHolder<T>& rhs) const {
return str_ != rhs.str_;
}
const std::string& str() {
return str_;
}
const std::string& str() const {
return str_;
}
const char* c_str() const {
return str_.c_str();
}
const char* data() const {
return str_.data();
}
protected:
std::string str_{};
};
template <class T>
std::ostream& operator<<(std::ostream& os, const StringHolder<T>& s) {
os << s.str();
return os;
}
class Url : public StringHolder<Url> {
public:
Url() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Url(const std::string& url) : StringHolder<Url>(url) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Url(std::string&& url) : StringHolder<Url>(std::move(url)) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Url(const char* url) : StringHolder<Url>(url) {}
Url(const char* str, size_t len) : StringHolder<Url>(std::string(str, len)) {}
Url(const std::initializer_list<std::string> args) : StringHolder<Url>(args) {}
Url(const Url& other) = default;
Url(Url&& old) noexcept = default;
~Url() override = default;
Url& operator=(Url&& old) noexcept = default;
Url& operator=(const Url& other) = default;
};
struct CaseInsensitiveCompare {
bool operator()(const std::string& a, const std::string& b) const noexcept;
};
using Header = std::map<std::string, std::string, CaseInsensitiveCompare>;
} // namespace cpr
#endif

50
vendor/CPR/include/cpr/curl_container.h vendored Normal file
View File

@ -0,0 +1,50 @@
#ifndef CURL_CONTAINER_H
#define CURL_CONTAINER_H
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>
#include "cpr/curlholder.h"
namespace cpr {
struct Parameter {
Parameter(const std::string& key, const std::string& value) : key{key}, value{value} {}
Parameter(std::string&& key, std::string&& value)
: key{std::move(key)}, value{std::move(value)} {}
std::string key;
std::string value;
};
struct Pair {
Pair(const std::string& p_key, const std::string& p_value) : key(p_key), value(p_value) {}
Pair(std::string&& p_key, std::string&& p_value)
: key(std::move(p_key)), value(std::move(p_value)) {}
std::string key;
std::string value;
};
template <class T>
class CurlContainer {
public:
CurlContainer() = default;
CurlContainer(const std::initializer_list<T>&);
void Add(const std::initializer_list<T>&);
void Add(const T&);
const std::string GetContent(const CurlHolder&) const;
protected:
std::vector<T> containerList_;
};
} // namespace cpr
#endif //

50
vendor/CPR/include/cpr/curlholder.h vendored Normal file
View File

@ -0,0 +1,50 @@
#ifndef CPR_CURL_HOLDER_H
#define CPR_CURL_HOLDER_H
#include <array>
#include <mutex>
#include <string>
#include <curl/curl.h>
namespace cpr {
struct CurlHolder {
private:
/**
* Mutex for curl_easy_init().
* curl_easy_init() is not thread save.
* References:
* https://curl.haxx.se/libcurl/c/curl_easy_init.html
* https://curl.haxx.se/libcurl/c/threadsafe.html
**/
// It does not make sense to make a std::mutex const.
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
static std::mutex curl_easy_init_mutex_;
public:
CURL* handle{nullptr};
struct curl_slist* chunk{nullptr};
struct curl_httppost* formpost{nullptr};
std::array<char, CURL_ERROR_SIZE> error{};
CurlHolder();
CurlHolder(const CurlHolder& other) = default;
CurlHolder(CurlHolder&& old) noexcept = default;
~CurlHolder();
CurlHolder& operator=(CurlHolder&& old) noexcept = default;
CurlHolder& operator=(const CurlHolder& other) = default;
/**
* Uses curl_easy_escape(...) for escaping the given string.
**/
std::string urlEncode(const std::string& s) const;
/**
* Uses curl_easy_unescape(...) for unescaping the given string.
**/
std::string urlDecode(const std::string& s) const;
};
} // namespace cpr
#endif

15
vendor/CPR/include/cpr/digest.h vendored Normal file
View File

@ -0,0 +1,15 @@
#ifndef CPR_DIGEST_H
#define CPR_DIGEST_H
#include "cpr/auth.h"
namespace cpr {
class Digest : public Authentication {
public:
Digest(const std::string& username, const std::string& password)
: Authentication{username, password} {}
};
} // namespace cpr
#endif

54
vendor/CPR/include/cpr/error.h vendored Normal file
View File

@ -0,0 +1,54 @@
#ifndef CPR_ERROR_H
#define CPR_ERROR_H
#include <cstdint>
#include <string>
#include "cpr/cprtypes.h"
#include <utility>
namespace cpr {
enum class ErrorCode {
OK = 0,
CONNECTION_FAILURE,
EMPTY_RESPONSE,
HOST_RESOLUTION_FAILURE,
INTERNAL_ERROR,
INVALID_URL_FORMAT,
NETWORK_RECEIVE_ERROR,
NETWORK_SEND_FAILURE,
OPERATION_TIMEDOUT,
PROXY_RESOLUTION_FAILURE,
SSL_CONNECT_ERROR,
SSL_LOCAL_CERTIFICATE_ERROR,
SSL_REMOTE_CERTIFICATE_ERROR,
SSL_CACERT_ERROR,
GENERIC_SSL_ERROR,
UNSUPPORTED_PROTOCOL,
REQUEST_CANCELLED,
UNKNOWN_ERROR = 1000,
};
class Error {
public:
ErrorCode code = ErrorCode::OK;
std::string message{};
Error() = default;
Error(const std::int32_t& curl_code, std::string&& p_error_message)
: code{getErrorCodeForCurlError(curl_code)},
message(std::move(p_error_message)) {}
explicit operator bool() const {
return code != ErrorCode::OK;
}
private:
static ErrorCode getErrorCodeForCurlError(std::int32_t curl_code);
};
} // namespace cpr
#endif

19
vendor/CPR/include/cpr/limit_rate.h vendored Normal file
View File

@ -0,0 +1,19 @@
#ifndef CPR_SPEED_LIMIT_H
#define CPR_SPEED_LIMIT_H
#include <cstdint>
namespace cpr {
class LimitRate {
public:
LimitRate(const std::int64_t downrate, const std::int64_t uprate)
: downrate(downrate), uprate(uprate) {}
std::int64_t downrate = 0;
std::int64_t uprate = 0;
};
} // namespace cpr
#endif

18
vendor/CPR/include/cpr/low_speed.h vendored Normal file
View File

@ -0,0 +1,18 @@
#ifndef CPR_LOW_SPEED_H
#define CPR_LOW_SPEED_H
#include <cstdint>
namespace cpr {
class LowSpeed {
public:
LowSpeed(const std::int32_t limit, const std::int32_t time) : limit(limit), time(time) {}
std::int32_t limit;
std::int32_t time;
};
} // namespace cpr
#endif

18
vendor/CPR/include/cpr/max_redirects.h vendored Normal file
View File

@ -0,0 +1,18 @@
#ifndef CPR_MAX_REDIRECTS_H
#define CPR_MAX_REDIRECTS_H
#include <cstdint>
namespace cpr {
class MaxRedirects {
public:
explicit MaxRedirects(const std::int32_t number_of_redirects)
: number_of_redirects(number_of_redirects) {}
std::int32_t number_of_redirects;
};
} // namespace cpr
#endif

79
vendor/CPR/include/cpr/multipart.h vendored Normal file
View File

@ -0,0 +1,79 @@
#ifndef CPR_MULTIPART_H
#define CPR_MULTIPART_H
#include <cstdint>
#include <initializer_list>
#include <string>
#include <type_traits>
#include <vector>
namespace cpr {
struct File {
explicit File(std::string&& filepath) : filepath(std::move(filepath)) {}
explicit File(const std::string& filepath) : filepath(filepath) {}
const std::string filepath;
};
struct Buffer {
using data_t = const unsigned char*;
template <typename Iterator>
Buffer(Iterator begin, Iterator end, std::string&& filename)
// Ignored here since libcurl reqires a long.
// There is also no way around the reinterpret_cast.
// NOLINTNEXTLINE(google-runtime-int, cppcoreguidelines-pro-type-reinterpret-cast)
: data{reinterpret_cast<data_t>(&(*begin))}, datalen{static_cast<long>(
std::distance(begin, end))},
filename(std::move(filename)) {
is_random_access_iterator(begin, end);
static_assert(sizeof(*begin) == 1, "only byte buffers can be used");
}
template <typename Iterator>
typename std::enable_if<std::is_same<typename std::iterator_traits<Iterator>::iterator_category,
std::random_access_iterator_tag>::value>::type
is_random_access_iterator(Iterator /* begin */, Iterator /* end */) {}
data_t data;
// Ignored here since libcurl reqires a long:
// NOLINTNEXTLINE(google-runtime-int)
long datalen;
const std::string filename;
};
struct Part {
Part(const std::string& name, const std::string& value, const std::string& content_type = {})
: name{name}, value{value},
content_type{content_type}, is_file{false}, is_buffer{false} {}
Part(const std::string& name, const std::int32_t& value, const std::string& content_type = {})
: name{name}, value{std::to_string(value)},
content_type{content_type}, is_file{false}, is_buffer{false} {}
Part(const std::string& name, const File& file, const std::string& content_type = {})
: name{name}, value{file.filepath},
content_type{content_type}, is_file{true}, is_buffer{false} {}
Part(const std::string& name, const Buffer& buffer, const std::string& content_type = {})
: name{name}, value{buffer.filename}, content_type{content_type}, data{buffer.data},
datalen{buffer.datalen}, is_file{false}, is_buffer{true} {}
std::string name;
std::string value;
std::string content_type;
Buffer::data_t data{nullptr};
// Ignored here since libcurl reqires a long:
// NOLINTNEXTLINE(google-runtime-int)
long datalen{0};
bool is_file;
bool is_buffer;
};
class Multipart {
public:
Multipart(const std::initializer_list<Part>& parts);
std::vector<Part> parts;
};
} // namespace cpr
#endif

15
vendor/CPR/include/cpr/ntlm.h vendored Normal file
View File

@ -0,0 +1,15 @@
#ifndef CPR_NTLM_H
#define CPR_NTLM_H
#include "cpr/auth.h"
namespace cpr {
class NTLM : public Authentication {
public:
NTLM(const std::string& username, const std::string& password)
: Authentication{username, password} {}
};
} // namespace cpr
#endif

20
vendor/CPR/include/cpr/parameters.h vendored Normal file
View File

@ -0,0 +1,20 @@
#ifndef CPR_PARAMETERS_H
#define CPR_PARAMETERS_H
#include <initializer_list>
#include "cpr/curl_container.h"
namespace cpr {
class Parameters : public CurlContainer<Parameter> {
protected:
using CurlContainer<Parameter>::containerList_;
public:
Parameters() = default;
Parameters(const std::initializer_list<Parameter>& parameters);
};
} // namespace cpr
#endif

25
vendor/CPR/include/cpr/payload.h vendored Normal file
View File

@ -0,0 +1,25 @@
#ifndef CPR_PAYLOAD_H
#define CPR_PAYLOAD_H
#include <initializer_list>
#include "cpr/curl_container.h"
namespace cpr {
class Payload : public CurlContainer<Pair> {
protected:
using CurlContainer<Pair>::containerList_;
public:
template <class It>
Payload(const It begin, const It end) {
for (It pair = begin; pair != end; ++pair) {
Add(*pair);
}
}
Payload(const std::initializer_list<Pair>& pairs);
};
} // namespace cpr
#endif

22
vendor/CPR/include/cpr/proxies.h vendored Normal file
View File

@ -0,0 +1,22 @@
#ifndef CPR_PROXIES_H
#define CPR_PROXIES_H
#include <initializer_list>
#include <map>
#include <string>
namespace cpr {
class Proxies {
public:
Proxies() = default;
Proxies(const std::initializer_list<std::pair<const std::string, std::string>>& hosts);
bool has(const std::string& protocol) const;
const std::string& operator[](const std::string& protocol);
protected:
std::map<std::string, std::string> hosts_;
};
} // namespace cpr
#endif

56
vendor/CPR/include/cpr/response.h vendored Normal file
View File

@ -0,0 +1,56 @@
#ifndef CPR_RESPONSE_H
#define CPR_RESPONSE_H
#include <cassert>
#include <cstdint>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "cpr/cookies.h"
#include "cpr/cprtypes.h"
#include "cpr/error.h"
#include "cpr/ssl_options.h"
#include "cpr/util.h"
namespace cpr {
class Response {
protected:
std::shared_ptr<CurlHolder> curl_{nullptr};
public:
// Ignored here since libcurl uses a long for this.
// NOLINTNEXTLINE(google-runtime-int)
long status_code{};
std::string text{};
Header header{};
Url url{};
double elapsed{};
Cookies cookies{};
Error error{};
std::string raw_header{};
std::string status_line{};
std::string reason{};
cpr_off_t uploaded_bytes{};
cpr_off_t downloaded_bytes{};
// Ignored here since libcurl uses a long for this.
// NOLINTNEXTLINE(google-runtime-int)
long redirect_count{};
Response() = default;
Response(std::shared_ptr<CurlHolder> curl, std::string&& p_text, std::string&& p_header_string,
Cookies&& p_cookies, Error&& p_error);
std::vector<std::string> GetCertInfo();
Response(const Response& other) = default;
Response(Response&& old) noexcept = default;
~Response() noexcept = default;
Response& operator=(Response&& old) noexcept = default;
Response& operator=(const Response& other) = default;
};
} // namespace cpr
#endif

132
vendor/CPR/include/cpr/session.h vendored Normal file
View File

@ -0,0 +1,132 @@
#ifndef CPR_SESSION_H
#define CPR_SESSION_H
#include <cstdint>
#include <fstream>
#include <memory>
#include "cpr/auth.h"
#include "cpr/bearer.h"
#include "cpr/body.h"
#include "cpr/callback.h"
#include "cpr/connect_timeout.h"
#include "cpr/cookies.h"
#include "cpr/cprtypes.h"
#include "cpr/digest.h"
#include "cpr/limit_rate.h"
#include "cpr/low_speed.h"
#include "cpr/max_redirects.h"
#include "cpr/multipart.h"
#include "cpr/ntlm.h"
#include "cpr/parameters.h"
#include "cpr/payload.h"
#include "cpr/proxies.h"
#include "cpr/response.h"
#include "cpr/ssl_options.h"
#include "cpr/timeout.h"
#include "cpr/unix_socket.h"
#include "cpr/user_agent.h"
#include "cpr/verbose.h"
namespace cpr {
class Session {
public:
Session();
Session(Session&& old) noexcept = default;
Session(const Session& other) = delete;
~Session();
Session& operator=(Session&& old) noexcept = default;
Session& operator=(const Session& other) = delete;
void SetUrl(const Url& url);
void SetParameters(const Parameters& parameters);
void SetParameters(Parameters&& parameters);
void SetHeader(const Header& header);
void SetTimeout(const Timeout& timeout);
void SetConnectTimeout(const ConnectTimeout& timeout);
void SetAuth(const Authentication& auth);
void SetDigest(const Digest& auth);
void SetUserAgent(const UserAgent& ua);
void SetPayload(Payload&& payload);
void SetPayload(const Payload& payload);
void SetProxies(Proxies&& proxies);
void SetProxies(const Proxies& proxies);
void SetMultipart(Multipart&& multipart);
void SetMultipart(const Multipart& multipart);
void SetNTLM(const NTLM& auth);
void SetRedirect(const bool& redirect);
void SetMaxRedirects(const MaxRedirects& max_redirects);
void SetCookies(const Cookies& cookies);
void SetBody(Body&& body);
void SetBody(const Body& body);
void SetLowSpeed(const LowSpeed& low_speed);
void SetVerifySsl(const VerifySsl& verify);
void SetUnixSocket(const UnixSocket& unix_socket);
void SetSslOptions(const SslOptions& options);
void SetReadCallback(const ReadCallback& read);
void SetHeaderCallback(const HeaderCallback& header);
void SetWriteCallback(const WriteCallback& write);
void SetProgressCallback(const ProgressCallback& progress);
void SetDebugCallback(const DebugCallback& debug);
void SetVerbose(const Verbose& verbose);
// Used in templated functions
void SetOption(const Url& url);
void SetOption(const Parameters& parameters);
void SetOption(Parameters&& parameters);
void SetOption(const Header& header);
void SetOption(const Timeout& timeout);
void SetOption(const ConnectTimeout& timeout);
void SetOption(const Authentication& auth);
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
void SetOption(const Bearer& auth);
#endif
void SetOption(const Digest& auth);
void SetOption(const UserAgent& ua);
void SetOption(Payload&& payload);
void SetOption(const Payload& payload);
void SetOption(const LimitRate& limit_rate);
void SetOption(Proxies&& proxies);
void SetOption(const Proxies& proxies);
void SetOption(Multipart&& multipart);
void SetOption(const Multipart& multipart);
void SetOption(const NTLM& auth);
void SetOption(const bool& redirect);
void SetOption(const MaxRedirects& max_redirects);
void SetOption(const Cookies& cookies);
void SetOption(Body&& body);
void SetOption(const Body& body);
void SetOption(const ReadCallback& read);
void SetOption(const HeaderCallback& header);
void SetOption(const WriteCallback& write);
void SetOption(const ProgressCallback& progress);
void SetOption(const DebugCallback& debug);
void SetOption(const LowSpeed& low_speed);
void SetOption(const VerifySsl& verify);
void SetOption(const Verbose& verbose);
void SetOption(const UnixSocket& unix_socket);
void SetOption(const SslOptions& options);
Response Delete();
Response Download(const WriteCallback& write);
Response Download(std::ofstream& file);
Response Get();
Response Head();
Response Options();
Response Patch();
Response Post();
Response Put();
private:
class Impl;
std::unique_ptr<Impl> pimpl_;
};
} // namespace cpr
#endif

516
vendor/CPR/include/cpr/ssl_options.h vendored Normal file
View File

@ -0,0 +1,516 @@
#ifndef CPR_SSLOPTIONS_H
#define CPR_SSLOPTIONS_H
#include <string>
#include <curl/curl.h>
#include <utility>
#define __LIBCURL_VERSION_GTE(major, minor) \
((LIBCURL_VERSION_MAJOR > (major)) || \
((LIBCURL_VERSION_MAJOR == (major)) && (LIBCURL_VERSION_MINOR >= (minor))))
#define __LIBCURL_VERSION_LT(major, minor) \
((LIBCURL_VERSION_MAJOR < (major)) || \
((LIBCURL_VERSION_MAJOR == (major)) && (LIBCURL_VERSION_MINOR < (minor))))
#ifndef SUPPORT_ALPN
#define SUPPORT_ALPN __LIBCURL_VERSION_GTE(7, 36)
#endif
#ifndef SUPPORT_NPN
#define SUPPORT_NPN __LIBCURL_VERSION_GTE(7, 36)
#endif
#ifndef SUPPORT_SSLv2
#define SUPPORT_SSLv2 __LIBCURL_VERSION_LT(7, 19)
#endif
#ifndef SUPPORT_SSLv3
#define SUPPORT_SSLv3 __LIBCURL_VERSION_LT(7, 39)
#endif
#ifndef SUPPORT_TLSv1_0
#define SUPPORT_TLSv1_0 __LIBCURL_VERSION_GTE(7, 34)
#endif
#ifndef SUPPORT_TLSv1_1
#define SUPPORT_TLSv1_1 __LIBCURL_VERSION_GTE(7, 34)
#endif
#ifndef SUPPORT_TLSv1_2
#define SUPPORT_TLSv1_2 __LIBCURL_VERSION_GTE(7, 34)
#endif
#ifndef SUPPORT_TLSv1_3
#define SUPPORT_TLSv1_3 __LIBCURL_VERSION_GTE(7, 52)
#endif
#ifndef SUPPORT_MAX_TLS_VERSION
#define SUPPORT_MAX_TLS_VERSION __LIBCURL_VERSION_GTE(7, 54)
#endif
#ifndef SUPPORT_MAX_TLSv1_1
#define SUPPORT_MAX_TLSv1_1 __LIBCURL_VERSION_GTE(7, 54)
#endif
#ifndef SUPPORT_MAX_TLSv1_2
#define SUPPORT_MAX_TLSv1_2 __LIBCURL_VERSION_GTE(7, 54)
#endif
#ifndef SUPPORT_MAX_TLSv1_3
#define SUPPORT_MAX_TLSv1_3 __LIBCURL_VERSION_GTE(7, 54)
#endif
#ifndef SUPPORT_TLSv13_CIPHERS
#define SUPPORT_TLSv13_CIPHERS __LIBCURL_VERSION_GTE(7, 61)
#endif
#ifndef SUPPORT_SESSIONID_CACHE
#define SUPPORT_SESSIONID_CACHE __LIBCURL_VERSION_GTE(7, 16)
#endif
#ifndef SUPPORT_SSL_FALSESTART
#define SUPPORT_SSL_FALSESTART __LIBCURL_VERSION_GTE(7, 42)
#endif
namespace cpr {
class VerifySsl {
public:
VerifySsl() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
VerifySsl(bool verify) : verify(verify) {}
explicit operator bool() const {
return verify;
}
bool verify = true;
};
namespace ssl {
// set SSL client certificate
class CertFile {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
CertFile(std::string&& p_filename) : filename(std::move(p_filename)) {}
const std::string filename;
virtual const char* GetCertType() const {
return "PEM";
}
};
using PemCert = CertFile;
class DerCert : public CertFile {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
DerCert(std::string&& p_filename) : CertFile(std::move(p_filename)) {}
const char* GetCertType() const override {
return "DER";
}
};
// specify private keyfile for TLS and SSL client cert
class KeyFile {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
KeyFile(std::string&& p_filename) : filename(std::move(p_filename)) {}
template <typename FileType, typename PassType>
KeyFile(FileType&& p_filename, PassType p_password)
: filename(std::forward<FileType>(p_filename)), password(std::move(p_password)) {}
std::string filename;
std::string password;
virtual const char* GetKeyType() const {
return "PEM";
}
};
using PemKey = KeyFile;
class DerKey : public KeyFile {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
DerKey(std::string&& p_filename) : KeyFile(std::move(p_filename)) {}
template <typename FileType, typename PassType>
DerKey(FileType&& p_filename, PassType p_password)
: KeyFile(std::forward<FileType>(p_filename), std::move(p_password)) {}
const char* GetKeyType() const override {
return "DER";
}
};
#if SUPPORT_ALPN
// This option enables/disables ALPN in the SSL handshake (if the SSL backend libcurl is built to
// use supports it), which can be used to negotiate http2.
class ALPN {
public:
ALPN() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ALPN(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = true;
};
#endif // SUPPORT_ALPN
#if SUPPORT_NPN
// This option enables/disables NPN in the SSL handshake (if the SSL backend libcurl is built to
// use supports it), which can be used to negotiate http2.
class NPN {
public:
NPN() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
NPN(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = true;
};
#endif // SUPPORT_NPN
// This option determines whether libcurl verifies that the server cert is for the server it is
// known as.
class VerifyHost {
public:
VerifyHost() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
VerifyHost(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = true;
};
// This option determines whether libcurl verifies the authenticity of the peer's certificate.
class VerifyPeer {
public:
VerifyPeer() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
VerifyPeer(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = true;
};
// This option determines whether libcurl verifies the status of the server cert using the
// "Certificate Status Request" TLS extension (aka. OCSP stapling).
class VerifyStatus {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
VerifyStatus(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = false;
};
// TLS v1.0 or later
struct TLSv1 {};
#if SUPPORT_SSLv2
// SSL v2 (but not SSLv3)
struct SSLv2 {};
#endif
#if SUPPORT_SSLv3
// SSL v3 (but not SSLv2)
struct SSLv3 {};
#endif
#if SUPPORT_TLSv1_0
// TLS v1.0 or later (Added in 7.34.0)
struct TLSv1_0 {};
#endif
#if SUPPORT_TLSv1_1
// TLS v1.1 or later (Added in 7.34.0)
struct TLSv1_1 {};
#endif
#if SUPPORT_TLSv1_2
// TLS v1.2 or later (Added in 7.34.0)
struct TLSv1_2 {};
#endif
#if SUPPORT_TLSv1_3
// TLS v1.3 or later (Added in 7.52.0)
struct TLSv1_3 {};
#endif
#if SUPPORT_MAX_TLS_VERSION
// The flag defines the maximum supported TLS version by libcurl, or the default value from the SSL
// library is used.
struct MaxTLSVersion {};
#endif
#if SUPPORT_MAX_TLSv1_0
// The flag defines maximum supported TLS version as TLSv1.0. (Added in 7.54.0)
struct MaxTLSv1_0 {};
#endif
#if SUPPORT_MAX_TLSv1_1
// The flag defines maximum supported TLS version as TLSv1.1. (Added in 7.54.0)
struct MaxTLSv1_1 {};
#endif
#if SUPPORT_MAX_TLSv1_2
// The flag defines maximum supported TLS version as TLSv1.2. (Added in 7.54.0)
struct MaxTLSv1_2 {};
#endif
#if SUPPORT_MAX_TLSv1_3
// The flag defines maximum supported TLS version as TLSv1.3. (Added in 7.54.0)
struct MaxTLSv1_3 {};
#endif
// path to Certificate Authority (CA) bundle
class CaInfo {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
CaInfo(std::string&& p_filename) : filename(std::move(p_filename)) {}
std::string filename;
};
// specify directory holding CA certificates
class CaPath {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
CaPath(std::string&& p_filename) : filename(std::move(p_filename)) {}
std::string filename;
};
// specify a Certificate Revocation List file
class Crl {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Crl(std::string&& p_filename) : filename(std::move(p_filename)) {}
std::string filename;
};
// specify ciphers to use for TLS
class Ciphers {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Ciphers(std::string&& p_ciphers) : ciphers(std::move(p_ciphers)) {}
std::string ciphers;
};
#if SUPPORT_TLSv13_CIPHERS
// specify ciphers suites to use for TLS 1.3
class TLS13_Ciphers {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
TLS13_Ciphers(std::string&& p_ciphers) : ciphers(std::move(p_ciphers)) {}
std::string ciphers;
};
#endif
#if SUPPORT_SESSIONID_CACHE
// enable/disable use of the SSL session-ID cache
class SessionIdCache {
public:
SessionIdCache() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
SessionIdCache(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = true;
};
#endif
#if SUPPORT_SSL_FALSESTART
class SslFastStart {
public:
SslFastStart() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
SslFastStart(bool enabled) : enabled(enabled) {}
explicit operator bool() const {
return enabled;
}
bool enabled = false;
};
#endif
} // namespace ssl
struct SslOptions {
std::string cert_file{};
std::string cert_type{};
std::string key_file{};
std::string key_type{};
std::string key_pass{};
#if SUPPORT_ALPN
bool enable_alpn = true;
#endif // SUPPORT_ALPN
#if SUPPORT_NPN
bool enable_npn = true;
#endif // SUPPORT_ALPN
bool verify_host = true;
bool verify_peer = true;
bool verify_status = false;
int ssl_version = CURL_SSLVERSION_DEFAULT;
#if SUPPORT_MAX_TLS_VERSION
int max_version = CURL_SSLVERSION_MAX_DEFAULT;
#endif
std::string ca_info{};
std::string ca_path{};
std::string crl_file{};
std::string ciphers{};
#if SUPPORT_TLSv13_CIPHERS
std::string tls13_ciphers{};
#endif
#if SUPPORT_SESSIONID_CACHE
bool session_id_cache = true;
#endif
SslOptions() = default;
SslOptions(const SslOptions &) = default;
SslOptions(SslOptions &&) noexcept = default;
~SslOptions() = default;
SslOptions & operator = (const SslOptions &) = default;
SslOptions & operator = (SslOptions &&) noexcept = default;
void SetOption(const ssl::CertFile& opt) {
cert_file = opt.filename;
cert_type = opt.GetCertType();
}
void SetOption(const ssl::KeyFile& opt) {
key_file = opt.filename;
key_type = opt.GetKeyType();
key_pass = opt.password;
}
#if SUPPORT_ALPN
void SetOption(const ssl::ALPN& opt) {
enable_alpn = opt.enabled;
}
#endif // SUPPORT_ALPN
#if SUPPORT_NPN
void SetOption(const ssl::NPN& opt) {
enable_npn = opt.enabled;
}
#endif // SUPPORT_NPN
void SetOption(const ssl::VerifyHost& opt) {
verify_host = opt.enabled;
}
void SetOption(const ssl::VerifyPeer& opt) {
verify_peer = opt.enabled;
}
void SetOption(const ssl::VerifyStatus& opt) {
verify_status = opt.enabled;
}
void SetOption(const ssl::TLSv1& /*opt*/) {
ssl_version = CURL_SSLVERSION_TLSv1;
}
#if SUPPORT_SSLv2
void SetOption(const ssl::SSLv2& /*opt*/) {
ssl_version = CURL_SSLVERSION_SSLv2;
}
#endif
#if SUPPORT_SSLv3
void SetOption(const ssl::SSLv3& /*opt*/) {
ssl_version = CURL_SSLVERSION_SSLv3;
}
#endif
#if SUPPORT_TLSv1_0
void SetOption(const ssl::TLSv1_0& /*opt*/) {
ssl_version = CURL_SSLVERSION_TLSv1_0;
}
#endif
#if SUPPORT_TLSv1_1
void SetOption(const ssl::TLSv1_1& /*opt*/) {
ssl_version = CURL_SSLVERSION_TLSv1_1;
}
#endif
#if SUPPORT_TLSv1_2
void SetOption(const ssl::TLSv1_2& /*opt*/) {
ssl_version = CURL_SSLVERSION_TLSv1_2;
}
#endif
#if SUPPORT_TLSv1_3
void SetOption(const ssl::TLSv1_3& /*opt*/) {
ssl_version = CURL_SSLVERSION_TLSv1_3;
}
#endif
#if SUPPORT_MAX_TLS_VERSION
void SetOption(const ssl::MaxTLSVersion& /*opt*/) {
max_version = CURL_SSLVERSION_DEFAULT;
}
#endif
#if SUPPORT_MAX_TLSv1_0
void SetOption(const ssl::MaxTLSv1_0& opt) {
max_version = CURL_SSLVERSION_MAX_TLSv1_0;
}
#endif
#if SUPPORT_MAX_TLSv1_1
void SetOption(const ssl::MaxTLSv1_1& /*opt*/) {
max_version = CURL_SSLVERSION_MAX_TLSv1_1;
}
#endif
#if SUPPORT_MAX_TLSv1_2
void SetOption(const ssl::MaxTLSv1_2& /*opt*/) {
max_version = CURL_SSLVERSION_MAX_TLSv1_2;
}
#endif
#if SUPPORT_MAX_TLSv1_3
void SetOption(const ssl::MaxTLSv1_3& /*opt*/) {
max_version = CURL_SSLVERSION_MAX_TLSv1_3;
}
#endif
void SetOption(const ssl::CaInfo& opt) {
ca_info = opt.filename;
}
void SetOption(const ssl::CaPath& opt) {
ca_path = opt.filename;
}
void SetOption(const ssl::Crl& opt) {
crl_file = opt.filename;
}
void SetOption(const ssl::Ciphers& opt) {
ciphers = opt.ciphers;
}
#if SUPPORT_TLSv13_CIPHERS
void SetOption(const ssl::TLS13_Ciphers& opt) {
tls13_ciphers = opt.ciphers;
}
#endif
#if SUPPORT_SESSIONID_CACHE
void SetOption(const ssl::SessionIdCache& opt) {
session_id_cache = opt.enabled;
}
#endif
};
namespace priv {
template <typename T>
void set_ssl_option(SslOptions& opts, T&& t) {
opts.SetOption(std::forward<T>(t));
}
template <typename T, typename... Ts>
void set_ssl_option(SslOptions& opts, T&& t, Ts&&... ts) {
set_ssl_option(opts, std::forward<T>(t));
set_ssl_option(opts, std::move(ts)...);
}
} // namespace priv
template <typename... Ts>
SslOptions Ssl(Ts&&... ts) {
SslOptions opts;
priv::set_ssl_option(opts, std::move(ts)...);
return opts;
}
} // namespace cpr
#endif

100
vendor/CPR/include/cpr/status_codes.h vendored Normal file
View File

@ -0,0 +1,100 @@
#ifndef _CPR_STATUS_CODES
#define _CPR_STATUS_CODES
#include <cstdint>
namespace cpr {
namespace status {
// Information responses
constexpr std::int32_t HTTP_CONTINUE = 100;
constexpr std::int32_t HTTP_SWITCHING_PROTOCOL = 101;
constexpr std::int32_t HTTP_PROCESSING = 102;
constexpr std::int32_t HTTP_EARLY_HINTS = 103;
// Successful responses
constexpr std::int32_t HTTP_OK = 200;
constexpr std::int32_t HTTP_CREATED = 201;
constexpr std::int32_t HTTP_ACCEPTED = 202;
constexpr std::int32_t HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
constexpr std::int32_t HTTP_NO_CONTENT = 204;
constexpr std::int32_t HTTP_RESET_CONTENT = 205;
constexpr std::int32_t HTTP_PARTIAL_CONTENT = 206;
constexpr std::int32_t HTTP_MULTI_STATUS = 207;
constexpr std::int32_t HTTP_ALREADY_REPORTED = 208;
constexpr std::int32_t HTTP_IM_USED = 226;
// Redirection messages
constexpr std::int32_t HTTP_MULTIPLE_CHOICE = 300;
constexpr std::int32_t HTTP_MOVED_PERMANENTLY = 301;
constexpr std::int32_t HTTP_FOUND = 302;
constexpr std::int32_t HTTP_SEE_OTHER = 303;
constexpr std::int32_t HTTP_NOT_MODIFIED = 304;
constexpr std::int32_t HTTP_USE_PROXY = 305;
constexpr std::int32_t HTTP_UNUSED = 306;
constexpr std::int32_t HTTP_TEMPORARY_REDIRECT = 307;
constexpr std::int32_t HTTP_PERMANENT_REDIRECT = 308;
// Client error responses
constexpr std::int32_t HTTP_BAD_REQUEST = 400;
constexpr std::int32_t HTTP_UNAUTHORIZED = 401;
constexpr std::int32_t HTTP_PAYMENT_REQUIRED = 402;
constexpr std::int32_t HTTP_FORBIDDEN = 403;
constexpr std::int32_t HTTP_NOT_FOUND = 404;
constexpr std::int32_t HTTP_METHOD_NOT_ALLOWED = 405;
constexpr std::int32_t HTTP_NOT_ACCEPTABLE = 406;
constexpr std::int32_t HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
constexpr std::int32_t HTTP_REQUEST_TIMEOUT = 408;
constexpr std::int32_t HTTP_CONFLICT = 409;
constexpr std::int32_t HTTP_GONE = 410;
constexpr std::int32_t HTTP_LENGTH_REQUIRED = 411;
constexpr std::int32_t HTTP_PRECONDITION_FAILED = 412;
constexpr std::int32_t HTTP_PAYLOAD_TOO_LARGE = 413;
constexpr std::int32_t HTTP_URI_TOO_LONG = 414;
constexpr std::int32_t HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
constexpr std::int32_t HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
constexpr std::int32_t HTTP_EXPECTATION_FAILED = 417;
constexpr std::int32_t HTTP_IM_A_TEAPOT = 418;
constexpr std::int32_t HTTP_MISDIRECTED_REQUEST = 421;
constexpr std::int32_t HTTP_UNPROCESSABLE_ENTITY = 422;
constexpr std::int32_t HTTP_LOCKED = 423;
constexpr std::int32_t HTTP_FAILED_DEPENDENCY = 424;
constexpr std::int32_t HTTP_TOO_EARLY = 425;
constexpr std::int32_t HTTP_UPGRADE_REQUIRED = 426;
constexpr std::int32_t HTTP_PRECONDITION_REQUIRED = 428;
constexpr std::int32_t HTTP_TOO_MANY_REQUESTS = 429;
constexpr std::int32_t HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
constexpr std::int32_t HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
// Server response errors
constexpr std::int32_t HTTP_INTERNAL_SERVER_ERROR = 500;
constexpr std::int32_t HTTP_NOT_IMPLEMENTED = 501;
constexpr std::int32_t HTTP_BAD_GATEWAY = 502;
constexpr std::int32_t HTTP_SERVICE_UNAVAILABLE = 503;
constexpr std::int32_t HTTP_GATEWAY_TIMEOUT = 504;
constexpr std::int32_t HTTP_HTTP_VERSION_NOT_SUPPORTED = 505;
constexpr std::int32_t HTTP_VARIANT_ALSO_NEGOTIATES = 506;
constexpr std::int32_t HTTP_INSUFFICIENT_STORAGE = 507;
constexpr std::int32_t HTTP_LOOP_DETECTED = 508;
constexpr std::int32_t HTTP_NOT_EXTENDED = 510;
constexpr std::int32_t HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;
constexpr std::int32_t INFO_CODE_OFFSET = 100;
constexpr std::int32_t SUCCESS_CODE_OFFSET = 200;
constexpr std::int32_t REDIRECT_CODE_OFFSET = 300;
constexpr std::int32_t CLIENT_ERROR_CODE_OFFSET = 400;
constexpr std::int32_t SERVER_ERROR_CODE_OFFSET = 500;
constexpr std::int32_t MISC_CODE_OFFSET = 600;
constexpr bool is_informational(const std::int32_t code) {
return (code >= INFO_CODE_OFFSET && code < SUCCESS_CODE_OFFSET);
}
constexpr bool is_success(const std::int32_t code) {
return (code >= SUCCESS_CODE_OFFSET && code < REDIRECT_CODE_OFFSET);
}
constexpr bool is_redirect(const std::int32_t code) {
return (code >= REDIRECT_CODE_OFFSET && code < CLIENT_ERROR_CODE_OFFSET);
}
constexpr bool is_client_error(const std::int32_t code) {
return (code >= CLIENT_ERROR_CODE_OFFSET && code < SERVER_ERROR_CODE_OFFSET);
}
constexpr bool is_server_error(const std::int32_t code) {
return (code >= SERVER_ERROR_CODE_OFFSET && code < MISC_CODE_OFFSET);
}
} // namespace status
} // namespace cpr
#endif

25
vendor/CPR/include/cpr/timeout.h vendored Normal file
View File

@ -0,0 +1,25 @@
#ifndef CPR_TIMEOUT_H
#define CPR_TIMEOUT_H
#include <chrono>
#include <cstdint>
namespace cpr {
class Timeout {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Timeout(const std::chrono::milliseconds& duration) : ms{duration} {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Timeout(const std::int32_t& milliseconds) : Timeout{std::chrono::milliseconds(milliseconds)} {}
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
long Milliseconds() const;
std::chrono::milliseconds ms;
};
} // namespace cpr
#endif

21
vendor/CPR/include/cpr/unix_socket.h vendored Normal file
View File

@ -0,0 +1,21 @@
#ifndef CPR_UNIX_SOCKET_H
#define CPR_UNIX_SOCKET_H
#include <string>
namespace cpr {
class UnixSocket {
public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
UnixSocket(std::string&& unix_socket) : unix_socket_(std::move(unix_socket)) {}
const char* GetUnixSocketString() const noexcept;
private:
const std::string unix_socket_;
};
} // namespace cpr
#endif

31
vendor/CPR/include/cpr/user_agent.h vendored Normal file
View File

@ -0,0 +1,31 @@
#ifndef CPR_USERAGENT_H
#define CPR_USERAGENT_H
#include <initializer_list>
#include <string>
#include "cpr/cprtypes.h"
namespace cpr {
class UserAgent : public StringHolder<UserAgent> {
public:
UserAgent() : StringHolder<UserAgent>() {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
UserAgent(const std::string& useragent) : StringHolder<UserAgent>(useragent) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
UserAgent(std::string&& useragent) : StringHolder<UserAgent>(std::move(useragent)) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
UserAgent(const char* useragent) : StringHolder<UserAgent>(useragent) {}
UserAgent(const char* str, size_t len) : StringHolder<UserAgent>(str, len) {}
UserAgent(const std::initializer_list<std::string> args) : StringHolder<UserAgent>(args) {}
UserAgent(const UserAgent& other) = default;
UserAgent(UserAgent&& old) noexcept = default;
~UserAgent() override = default;
UserAgent& operator=(UserAgent&& old) noexcept = default;
UserAgent& operator=(const UserAgent& other) = default;
};
} // namespace cpr
#endif

40
vendor/CPR/include/cpr/util.h vendored Normal file
View File

@ -0,0 +1,40 @@
#ifndef CPR_UTIL_H
#define CPR_UTIL_H
#include <fstream>
#include <string>
#include <vector>
#include "cpr/callback.h"
#include "cpr/cookies.h"
#include "cpr/cprtypes.h"
#include "cpr/curlholder.h"
namespace cpr {
namespace util {
Header parseHeader(const std::string& headers, std::string* status_line = nullptr,
std::string* reason = nullptr);
Cookies parseCookies(curl_slist* raw_cookies);
size_t readUserFunction(char* ptr, size_t size, size_t nitems, const ReadCallback* read);
size_t headerUserFunction(char* ptr, size_t size, size_t nmemb, const HeaderCallback* header);
size_t writeFunction(char* ptr, size_t size, size_t nmemb, std::string* data);
size_t writeFileFunction(char* ptr, size_t size, size_t nmemb, std::ofstream* file);
size_t writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallback* write);
#if LIBCURL_VERSION_NUM < 0x072000
int progressUserFunction(const ProgressCallback* progress, double dltotal, double dlnow,
double ultotal, double ulnow);
#else
int progressUserFunction(const ProgressCallback* progress, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow);
#endif
int debugUserFunction(CURL* handle, curl_infotype type, char* data, size_t size,
const DebugCallback* debug);
std::vector<std::string> split(const std::string& to_split, char delimiter);
std::string urlEncode(const std::string& s);
std::string urlDecode(const std::string& s);
} // namespace util
} // namespace cpr
#endif

18
vendor/CPR/include/cpr/verbose.h vendored Normal file
View File

@ -0,0 +1,18 @@
#ifndef CPR_VERBOSE_H_
#define CPR_VERBOSE_H_
namespace cpr {
class Verbose {
public:
Verbose() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Verbose(const bool verbose) : verbose{verbose} {}
bool verbose = true;
};
} // namespace cpr
#endif /* CPR_VERBOSE_H_ */

12
vendor/ConcurrentQueue/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,12 @@
# Create the ConcurrentQueue library
add_library(ConcurrentQueue STATIC
include/concurrentqueue.h
include/lightweightsemaphore.h
include/blockingconcurrentqueue.h
concurrentqueue.cpp
)
# Configure include folders
target_include_directories(ConcurrentQueue PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(ConcurrentQueue PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Configure macro options
target_compile_definitions(ConcurrentQueue PRIVATE _WIN32_WINNT=0x0601)

61
vendor/ConcurrentQueue/LICENSE.md vendored Normal file
View File

@ -0,0 +1,61 @@
This license file applies to everything in this repository except that which
is explicitly annotated as being written by other authors, i.e. the Boost
queue (included in the benchmarks for comparison), Intel's TBB library (ditto),
the CDSChecker tool (used for verification), the Relacy model checker (ditto),
and Jeff Preshing's semaphore implementation (used in the blocking queue) which
has a zlib license (embedded in lightweightsempahore.h).
---
Simplified BSD License:
Copyright (c) 2013-2016, Cameron Desrochers.
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.
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.
---
I have also chosen to dual-license under the Boost Software License as an alternative to
the Simplified BSD license above:
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1 @@
#include <concurrentqueue.h>

View File

@ -0,0 +1,582 @@
// Provides an efficient blocking version of moodycamel::ConcurrentQueue.
// ©2015-2020 Cameron Desrochers. Distributed under the terms of the simplified
// BSD license, available at the top of concurrentqueue.h.
// Also dual-licensed under the Boost Software License (see LICENSE.md)
// Uses Jeff Preshing's semaphore implementation (under the terms of its
// separate zlib license, see lightweightsemaphore.h).
#pragma once
#include "concurrentqueue.h"
#include "lightweightsemaphore.h"
#include <type_traits>
#include <cerrno>
#include <memory>
#include <chrono>
#include <ctime>
namespace moodycamel
{
// This is a blocking version of the queue. It has an almost identical interface to
// the normal non-blocking version, with the addition of various wait_dequeue() methods
// and the removal of producer-specific dequeue methods.
template<typename T, typename Traits = ConcurrentQueueDefaultTraits>
class BlockingConcurrentQueue
{
private:
typedef ::moodycamel::ConcurrentQueue<T, Traits> ConcurrentQueue;
typedef ::moodycamel::LightweightSemaphore LightweightSemaphore;
public:
typedef typename ConcurrentQueue::producer_token_t producer_token_t;
typedef typename ConcurrentQueue::consumer_token_t consumer_token_t;
typedef typename ConcurrentQueue::index_t index_t;
typedef typename ConcurrentQueue::size_t size_t;
typedef typename std::make_signed<size_t>::type ssize_t;
static const size_t BLOCK_SIZE = ConcurrentQueue::BLOCK_SIZE;
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = ConcurrentQueue::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD;
static const size_t EXPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::EXPLICIT_INITIAL_INDEX_SIZE;
static const size_t IMPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::IMPLICIT_INITIAL_INDEX_SIZE;
static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = ConcurrentQueue::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE;
static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = ConcurrentQueue::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE;
static const size_t MAX_SUBQUEUE_SIZE = ConcurrentQueue::MAX_SUBQUEUE_SIZE;
public:
// Creates a queue with at least `capacity` element slots; note that the
// actual number of elements that can be inserted without additional memory
// allocation depends on the number of producers and the block size (e.g. if
// the block size is equal to `capacity`, only a single block will be allocated
// up-front, which means only a single producer will be able to enqueue elements
// without an extra allocation -- blocks aren't shared between producers).
// This method is not thread safe -- it is up to the user to ensure that the
// queue is fully constructed before it starts being used by other threads (this
// includes making the memory effects of construction visible, possibly with a
// memory barrier).
explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
: inner(capacity), sema(create<LightweightSemaphore>(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
{
assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
if (!sema) {
MOODYCAMEL_THROW(std::bad_alloc());
}
}
BlockingConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers)
: inner(minCapacity, maxExplicitProducers, maxImplicitProducers), sema(create<LightweightSemaphore>(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
{
assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
if (!sema) {
MOODYCAMEL_THROW(std::bad_alloc());
}
}
// Disable copying and copy assignment
BlockingConcurrentQueue(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
BlockingConcurrentQueue& operator=(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
// Moving is supported, but note that it is *not* a thread-safe operation.
// Nobody can use the queue while it's being moved, and the memory effects
// of that move must be propagated to other threads before they can use it.
// Note: When a queue is moved, its tokens are still valid but can only be
// used with the destination queue (i.e. semantically they are moved along
// with the queue itself).
BlockingConcurrentQueue(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
: inner(std::move(other.inner)), sema(std::move(other.sema))
{ }
inline BlockingConcurrentQueue& operator=(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
{
return swap_internal(other);
}
// Swaps this queue's state with the other's. Not thread-safe.
// Swapping two queues does not invalidate their tokens, however
// the tokens that were created for one queue must be used with
// only the swapped queue (i.e. the tokens are tied to the
// queue's movable state, not the object itself).
inline void swap(BlockingConcurrentQueue& other) MOODYCAMEL_NOEXCEPT
{
swap_internal(other);
}
private:
BlockingConcurrentQueue& swap_internal(BlockingConcurrentQueue& other)
{
if (this == &other) {
return *this;
}
inner.swap(other.inner);
sema.swap(other.sema);
return *this;
}
public:
// Enqueues a single item (by copying it).
// Allocates memory if required. Only fails if memory allocation fails (or implicit
// production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
// or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
// Thread-safe.
inline bool enqueue(T const& item)
{
if ((details::likely)(inner.enqueue(item))) {
sema->signal();
return true;
}
return false;
}
// Enqueues a single item (by moving it, if possible).
// Allocates memory if required. Only fails if memory allocation fails (or implicit
// production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
// or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
// Thread-safe.
inline bool enqueue(T&& item)
{
if ((details::likely)(inner.enqueue(std::move(item)))) {
sema->signal();
return true;
}
return false;
}
// Enqueues a single item (by copying it) using an explicit producer token.
// Allocates memory if required. Only fails if memory allocation fails (or
// Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
// Thread-safe.
inline bool enqueue(producer_token_t const& token, T const& item)
{
if ((details::likely)(inner.enqueue(token, item))) {
sema->signal();
return true;
}
return false;
}
// Enqueues a single item (by moving it, if possible) using an explicit producer token.
// Allocates memory if required. Only fails if memory allocation fails (or
// Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
// Thread-safe.
inline bool enqueue(producer_token_t const& token, T&& item)
{
if ((details::likely)(inner.enqueue(token, std::move(item)))) {
sema->signal();
return true;
}
return false;
}
// Enqueues several items.
// Allocates memory if required. Only fails if memory allocation fails (or
// implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
// is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
// Note: Use std::make_move_iterator if the elements should be moved instead of copied.
// Thread-safe.
template<typename It>
inline bool enqueue_bulk(It itemFirst, size_t count)
{
if ((details::likely)(inner.enqueue_bulk(std::forward<It>(itemFirst), count))) {
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
return true;
}
return false;
}
// Enqueues several items using an explicit producer token.
// Allocates memory if required. Only fails if memory allocation fails
// (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
// Note: Use std::make_move_iterator if the elements should be moved
// instead of copied.
// Thread-safe.
template<typename It>
inline bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
{
if ((details::likely)(inner.enqueue_bulk(token, std::forward<It>(itemFirst), count))) {
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
return true;
}
return false;
}
// Enqueues a single item (by copying it).
// Does not allocate memory. Fails if not enough room to enqueue (or implicit
// production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
// is 0).
// Thread-safe.
inline bool try_enqueue(T const& item)
{
if (inner.try_enqueue(item)) {
sema->signal();
return true;
}
return false;
}
// Enqueues a single item (by moving it, if possible).
// Does not allocate memory (except for one-time implicit producer).
// Fails if not enough room to enqueue (or implicit production is
// disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
// Thread-safe.
inline bool try_enqueue(T&& item)
{
if (inner.try_enqueue(std::move(item))) {
sema->signal();
return true;
}
return false;
}
// Enqueues a single item (by copying it) using an explicit producer token.
// Does not allocate memory. Fails if not enough room to enqueue.
// Thread-safe.
inline bool try_enqueue(producer_token_t const& token, T const& item)
{
if (inner.try_enqueue(token, item)) {
sema->signal();
return true;
}
return false;
}
// Enqueues a single item (by moving it, if possible) using an explicit producer token.
// Does not allocate memory. Fails if not enough room to enqueue.
// Thread-safe.
inline bool try_enqueue(producer_token_t const& token, T&& item)
{
if (inner.try_enqueue(token, std::move(item))) {
sema->signal();
return true;
}
return false;
}
// Enqueues several items.
// Does not allocate memory (except for one-time implicit producer).
// Fails if not enough room to enqueue (or implicit production is
// disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
// Note: Use std::make_move_iterator if the elements should be moved
// instead of copied.
// Thread-safe.
template<typename It>
inline bool try_enqueue_bulk(It itemFirst, size_t count)
{
if (inner.try_enqueue_bulk(std::forward<It>(itemFirst), count)) {
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
return true;
}
return false;
}
// Enqueues several items using an explicit producer token.
// Does not allocate memory. Fails if not enough room to enqueue.
// Note: Use std::make_move_iterator if the elements should be moved
// instead of copied.
// Thread-safe.
template<typename It>
inline bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
{
if (inner.try_enqueue_bulk(token, std::forward<It>(itemFirst), count)) {
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
return true;
}
return false;
}
// Attempts to dequeue from the queue.
// Returns false if all producer streams appeared empty at the time they
// were checked (so, the queue is likely but not guaranteed to be empty).
// Never allocates. Thread-safe.
template<typename U>
inline bool try_dequeue(U& item)
{
if (sema->tryWait()) {
while (!inner.try_dequeue(item)) {
continue;
}
return true;
}
return false;
}
// Attempts to dequeue from the queue using an explicit consumer token.
// Returns false if all producer streams appeared empty at the time they
// were checked (so, the queue is likely but not guaranteed to be empty).
// Never allocates. Thread-safe.
template<typename U>
inline bool try_dequeue(consumer_token_t& token, U& item)
{
if (sema->tryWait()) {
while (!inner.try_dequeue(token, item)) {
continue;
}
return true;
}
return false;
}
// Attempts to dequeue several elements from the queue.
// Returns the number of items actually dequeued.
// Returns 0 if all producer streams appeared empty at the time they
// were checked (so, the queue is likely but not guaranteed to be empty).
// Never allocates. Thread-safe.
template<typename It>
inline size_t try_dequeue_bulk(It itemFirst, size_t max)
{
size_t count = 0;
max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
while (count != max) {
count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
}
return count;
}
// Attempts to dequeue several elements from the queue using an explicit consumer token.
// Returns the number of items actually dequeued.
// Returns 0 if all producer streams appeared empty at the time they
// were checked (so, the queue is likely but not guaranteed to be empty).
// Never allocates. Thread-safe.
template<typename It>
inline size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
{
size_t count = 0;
max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
while (count != max) {
count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
}
return count;
}
// Blocks the current thread until there's something to dequeue, then
// dequeues it.
// Never allocates. Thread-safe.
template<typename U>
inline void wait_dequeue(U& item)
{
while (!sema->wait()) {
continue;
}
while (!inner.try_dequeue(item)) {
continue;
}
}
// Blocks the current thread until either there's something to dequeue
// or the timeout (specified in microseconds) expires. Returns false
// without setting `item` if the timeout expires, otherwise assigns
// to `item` and returns true.
// Using a negative timeout indicates an indefinite timeout,
// and is thus functionally equivalent to calling wait_dequeue.
// Never allocates. Thread-safe.
template<typename U>
inline bool wait_dequeue_timed(U& item, std::int64_t timeout_usecs)
{
if (!sema->wait(timeout_usecs)) {
return false;
}
while (!inner.try_dequeue(item)) {
continue;
}
return true;
}
// Blocks the current thread until either there's something to dequeue
// or the timeout expires. Returns false without setting `item` if the
// timeout expires, otherwise assigns to `item` and returns true.
// Never allocates. Thread-safe.
template<typename U, typename Rep, typename Period>
inline bool wait_dequeue_timed(U& item, std::chrono::duration<Rep, Period> const& timeout)
{
return wait_dequeue_timed(item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
}
// Blocks the current thread until there's something to dequeue, then
// dequeues it using an explicit consumer token.
// Never allocates. Thread-safe.
template<typename U>
inline void wait_dequeue(consumer_token_t& token, U& item)
{
while (!sema->wait()) {
continue;
}
while (!inner.try_dequeue(token, item)) {
continue;
}
}
// Blocks the current thread until either there's something to dequeue
// or the timeout (specified in microseconds) expires. Returns false
// without setting `item` if the timeout expires, otherwise assigns
// to `item` and returns true.
// Using a negative timeout indicates an indefinite timeout,
// and is thus functionally equivalent to calling wait_dequeue.
// Never allocates. Thread-safe.
template<typename U>
inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::int64_t timeout_usecs)
{
if (!sema->wait(timeout_usecs)) {
return false;
}
while (!inner.try_dequeue(token, item)) {
continue;
}
return true;
}
// Blocks the current thread until either there's something to dequeue
// or the timeout expires. Returns false without setting `item` if the
// timeout expires, otherwise assigns to `item` and returns true.
// Never allocates. Thread-safe.
template<typename U, typename Rep, typename Period>
inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::chrono::duration<Rep, Period> const& timeout)
{
return wait_dequeue_timed(token, item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
}
// Attempts to dequeue several elements from the queue.
// Returns the number of items actually dequeued, which will
// always be at least one (this method blocks until the queue
// is non-empty) and at most max.
// Never allocates. Thread-safe.
template<typename It>
inline size_t wait_dequeue_bulk(It itemFirst, size_t max)
{
size_t count = 0;
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
while (count != max) {
count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
}
return count;
}
// Attempts to dequeue several elements from the queue.
// Returns the number of items actually dequeued, which can
// be 0 if the timeout expires while waiting for elements,
// and at most max.
// Using a negative timeout indicates an indefinite timeout,
// and is thus functionally equivalent to calling wait_dequeue_bulk.
// Never allocates. Thread-safe.
template<typename It>
inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs)
{
size_t count = 0;
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs);
while (count != max) {
count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
}
return count;
}
// Attempts to dequeue several elements from the queue.
// Returns the number of items actually dequeued, which can
// be 0 if the timeout expires while waiting for elements,
// and at most max.
// Never allocates. Thread-safe.
template<typename It, typename Rep, typename Period>
inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
{
return wait_dequeue_bulk_timed<It&>(itemFirst, max, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
}
// Attempts to dequeue several elements from the queue using an explicit consumer token.
// Returns the number of items actually dequeued, which will
// always be at least one (this method blocks until the queue
// is non-empty) and at most max.
// Never allocates. Thread-safe.
template<typename It>
inline size_t wait_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
{
size_t count = 0;
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
while (count != max) {
count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
}
return count;
}
// Attempts to dequeue several elements from the queue using an explicit consumer token.
// Returns the number of items actually dequeued, which can
// be 0 if the timeout expires while waiting for elements,
// and at most max.
// Using a negative timeout indicates an indefinite timeout,
// and is thus functionally equivalent to calling wait_dequeue_bulk.
// Never allocates. Thread-safe.
template<typename It>
inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::int64_t timeout_usecs)
{
size_t count = 0;
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs);
while (count != max) {
count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
}
return count;
}
// Attempts to dequeue several elements from the queue using an explicit consumer token.
// Returns the number of items actually dequeued, which can
// be 0 if the timeout expires while waiting for elements,
// and at most max.
// Never allocates. Thread-safe.
template<typename It, typename Rep, typename Period>
inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
{
return wait_dequeue_bulk_timed<It&>(token, itemFirst, max, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
}
// Returns an estimate of the total number of elements currently in the queue. This
// estimate is only accurate if the queue has completely stabilized before it is called
// (i.e. all enqueue and dequeue operations have completed and their memory effects are
// visible on the calling thread, and no further operations start while this method is
// being called).
// Thread-safe.
inline size_t size_approx() const
{
return (size_t)sema->availableApprox();
}
// Returns true if the underlying atomic variables used by
// the queue are lock-free (they should be on most platforms).
// Thread-safe.
static bool is_lock_free()
{
return ConcurrentQueue::is_lock_free();
}
private:
template<typename U, typename A1, typename A2>
static inline U* create(A1&& a1, A2&& a2)
{
void* p = (Traits::malloc)(sizeof(U));
return p != nullptr ? new (p) U(std::forward<A1>(a1), std::forward<A2>(a2)) : nullptr;
}
template<typename U>
static inline void destroy(U* p)
{
if (p != nullptr) {
p->~U();
}
(Traits::free)(p);
}
private:
ConcurrentQueue inner;
std::unique_ptr<LightweightSemaphore, void (*)(LightweightSemaphore*)> sema;
};
template<typename T, typename Traits>
inline void swap(BlockingConcurrentQueue<T, Traits>& a, BlockingConcurrentQueue<T, Traits>& b) MOODYCAMEL_NOEXCEPT
{
a.swap(b);
}
} // end namespace moodycamel

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,411 @@
// Provides an efficient implementation of a semaphore (LightweightSemaphore).
// This is an extension of Jeff Preshing's sempahore implementation (licensed
// under the terms of its separate zlib license) that has been adapted and
// extended by Cameron Desrochers.
#pragma once
#include <cstddef> // For std::size_t
#include <atomic>
#include <type_traits> // For std::make_signed<T>
#if defined(_WIN32)
// Avoid including windows.h in a header; we only need a handful of
// items, so we'll redeclare them here (this is relatively safe since
// the API generally has to remain stable between Windows versions).
// I know this is an ugly hack but it still beats polluting the global
// namespace with thousands of generic names or adding a .cpp for nothing.
extern "C" {
struct _SECURITY_ATTRIBUTES;
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes, long lInitialCount, long lMaximumCount, const wchar_t* lpName);
__declspec(dllimport) int __stdcall CloseHandle(void* hObject);
__declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void* hHandle, unsigned long dwMilliseconds);
__declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore, long lReleaseCount, long* lpPreviousCount);
}
#elif defined(__MACH__)
#include <mach/mach.h>
#elif defined(__unix__)
#include <semaphore.h>
#endif
namespace moodycamel
{
namespace details
{
// Code in the mpmc_sema namespace below is an adaptation of Jeff Preshing's
// portable + lightweight semaphore implementations, originally from
// https://github.com/preshing/cpp11-on-multicore/blob/master/common/sema.h
// LICENSE:
// Copyright (c) 2015 Jeff Preshing
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgement in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
#if defined(_WIN32)
class Semaphore
{
private:
void* m_hSema;
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
public:
Semaphore(int initialCount = 0)
{
assert(initialCount >= 0);
const long maxLong = 0x7fffffff;
m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr);
assert(m_hSema);
}
~Semaphore()
{
CloseHandle(m_hSema);
}
bool wait()
{
const unsigned long infinite = 0xffffffff;
return WaitForSingleObject(m_hSema, infinite) == 0;
}
bool try_wait()
{
return WaitForSingleObject(m_hSema, 0) == 0;
}
bool timed_wait(std::uint64_t usecs)
{
return WaitForSingleObject(m_hSema, (unsigned long)(usecs / 1000)) == 0;
}
void signal(int count = 1)
{
while (!ReleaseSemaphore(m_hSema, count, nullptr));
}
};
#elif defined(__MACH__)
//---------------------------------------------------------
// Semaphore (Apple iOS and OSX)
// Can't use POSIX semaphores due to http://lists.apple.com/archives/darwin-kernel/2009/Apr/msg00010.html
//---------------------------------------------------------
class Semaphore
{
private:
semaphore_t m_sema;
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
public:
Semaphore(int initialCount = 0)
{
assert(initialCount >= 0);
kern_return_t rc = semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
assert(rc == KERN_SUCCESS);
(void)rc;
}
~Semaphore()
{
semaphore_destroy(mach_task_self(), m_sema);
}
bool wait()
{
return semaphore_wait(m_sema) == KERN_SUCCESS;
}
bool try_wait()
{
return timed_wait(0);
}
bool timed_wait(std::uint64_t timeout_usecs)
{
mach_timespec_t ts;
ts.tv_sec = static_cast<unsigned int>(timeout_usecs / 1000000);
ts.tv_nsec = (timeout_usecs % 1000000) * 1000;
// added in OSX 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/modules/Darwin.html
kern_return_t rc = semaphore_timedwait(m_sema, ts);
return rc == KERN_SUCCESS;
}
void signal()
{
while (semaphore_signal(m_sema) != KERN_SUCCESS);
}
void signal(int count)
{
while (count-- > 0)
{
while (semaphore_signal(m_sema) != KERN_SUCCESS);
}
}
};
#elif defined(__unix__)
//---------------------------------------------------------
// Semaphore (POSIX, Linux)
//---------------------------------------------------------
class Semaphore
{
private:
sem_t m_sema;
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
public:
Semaphore(int initialCount = 0)
{
assert(initialCount >= 0);
int rc = sem_init(&m_sema, 0, initialCount);
assert(rc == 0);
(void)rc;
}
~Semaphore()
{
sem_destroy(&m_sema);
}
bool wait()
{
// http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
int rc;
do {
rc = sem_wait(&m_sema);
} while (rc == -1 && errno == EINTR);
return rc == 0;
}
bool try_wait()
{
int rc;
do {
rc = sem_trywait(&m_sema);
} while (rc == -1 && errno == EINTR);
return rc == 0;
}
bool timed_wait(std::uint64_t usecs)
{
struct timespec ts;
const int usecs_in_1_sec = 1000000;
const int nsecs_in_1_sec = 1000000000;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += (time_t)(usecs / usecs_in_1_sec);
ts.tv_nsec += (long)(usecs % usecs_in_1_sec) * 1000;
// sem_timedwait bombs if you have more than 1e9 in tv_nsec
// so we have to clean things up before passing it in
if (ts.tv_nsec >= nsecs_in_1_sec) {
ts.tv_nsec -= nsecs_in_1_sec;
++ts.tv_sec;
}
int rc;
do {
rc = sem_timedwait(&m_sema, &ts);
} while (rc == -1 && errno == EINTR);
return rc == 0;
}
void signal()
{
while (sem_post(&m_sema) == -1);
}
void signal(int count)
{
while (count-- > 0)
{
while (sem_post(&m_sema) == -1);
}
}
};
#else
#error Unsupported platform! (No semaphore wrapper available)
#endif
} // end namespace details
//---------------------------------------------------------
// LightweightSemaphore
//---------------------------------------------------------
class LightweightSemaphore
{
public:
typedef std::make_signed<std::size_t>::type ssize_t;
private:
std::atomic<ssize_t> m_count;
details::Semaphore m_sema;
int m_maxSpins;
bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
{
ssize_t oldCount;
int spin = m_maxSpins;
while (--spin >= 0)
{
oldCount = m_count.load(std::memory_order_relaxed);
if ((oldCount > 0) && m_count.compare_exchange_strong(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed))
return true;
std::atomic_signal_fence(std::memory_order_acquire); // Prevent the compiler from collapsing the loop.
}
oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
if (oldCount > 0)
return true;
if (timeout_usecs < 0)
{
if (m_sema.wait())
return true;
}
if (timeout_usecs > 0 && m_sema.timed_wait((std::uint64_t)timeout_usecs))
return true;
// At this point, we've timed out waiting for the semaphore, but the
// count is still decremented indicating we may still be waiting on
// it. So we have to re-adjust the count, but only if the semaphore
// wasn't signaled enough times for us too since then. If it was, we
// need to release the semaphore too.
while (true)
{
oldCount = m_count.load(std::memory_order_acquire);
if (oldCount >= 0 && m_sema.try_wait())
return true;
if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed))
return false;
}
}
ssize_t waitManyWithPartialSpinning(ssize_t max, std::int64_t timeout_usecs = -1)
{
assert(max > 0);
ssize_t oldCount;
int spin = m_maxSpins;
while (--spin >= 0)
{
oldCount = m_count.load(std::memory_order_relaxed);
if (oldCount > 0)
{
ssize_t newCount = oldCount > max ? oldCount - max : 0;
if (m_count.compare_exchange_strong(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed))
return oldCount - newCount;
}
std::atomic_signal_fence(std::memory_order_acquire);
}
oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
if (oldCount <= 0)
{
if ((timeout_usecs == 0) || (timeout_usecs < 0 && !m_sema.wait()) || (timeout_usecs > 0 && !m_sema.timed_wait((std::uint64_t)timeout_usecs)))
{
while (true)
{
oldCount = m_count.load(std::memory_order_acquire);
if (oldCount >= 0 && m_sema.try_wait())
break;
if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed))
return 0;
}
}
}
if (max > 1)
return 1 + tryWaitMany(max - 1);
return 1;
}
public:
LightweightSemaphore(ssize_t initialCount = 0, int maxSpins = 10000) : m_count(initialCount), m_maxSpins(maxSpins)
{
assert(initialCount >= 0);
assert(maxSpins >= 0);
}
bool tryWait()
{
ssize_t oldCount = m_count.load(std::memory_order_relaxed);
while (oldCount > 0)
{
if (m_count.compare_exchange_weak(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed))
return true;
}
return false;
}
bool wait()
{
return tryWait() || waitWithPartialSpinning();
}
bool wait(std::int64_t timeout_usecs)
{
return tryWait() || waitWithPartialSpinning(timeout_usecs);
}
// Acquires between 0 and (greedily) max, inclusive
ssize_t tryWaitMany(ssize_t max)
{
assert(max >= 0);
ssize_t oldCount = m_count.load(std::memory_order_relaxed);
while (oldCount > 0)
{
ssize_t newCount = oldCount > max ? oldCount - max : 0;
if (m_count.compare_exchange_weak(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed))
return oldCount - newCount;
}
return 0;
}
// Acquires at least one, and (greedily) at most max
ssize_t waitMany(ssize_t max, std::int64_t timeout_usecs)
{
assert(max >= 0);
ssize_t result = tryWaitMany(max);
if (result == 0 && max > 0)
result = waitManyWithPartialSpinning(max, timeout_usecs);
return result;
}
ssize_t waitMany(ssize_t max)
{
ssize_t result = waitMany(max, -1);
assert(result > 0);
return result;
}
void signal(ssize_t count = 1)
{
assert(count >= 0);
ssize_t oldCount = m_count.fetch_add(count, std::memory_order_release);
ssize_t toRelease = -oldCount < count ? -oldCount : count;
if (toRelease > 0)
{
m_sema.signal((int)toRelease);
}
}
std::size_t availableApprox() const
{
ssize_t count = m_count.load(std::memory_order_relaxed);
return count > 0 ? static_cast<std::size_t>(count) : 0;
}
};
} // end namespace moodycamel

22
vendor/Fmt/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,22 @@
# Create library
add_library(FmtLib STATIC
include/fmt/chrono.h
include/fmt/color.h
include/fmt/compile.h
include/fmt/core.h
include/fmt/format-inl.h
include/fmt/format.h
include/fmt/locale.h
include/fmt/os.h
include/fmt/ostream.h
include/fmt/posix.h
include/fmt/printf.h
include/fmt/ranges.h
format.cc
os.cc
)
# Configure include folders
target_include_directories(FmtLib PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(FmtLib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
# Configure macro options
target_compile_definitions(FmtLib PRIVATE _WIN32_WINNT=0x0601)

27
vendor/Fmt/LICENSE.rst vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2012 - present, Victor Zverovich
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.

99
vendor/Fmt/format.cc vendored Normal file
View File

@ -0,0 +1,99 @@
// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/format-inl.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
T value) {
#ifdef FMT_FUZZ
if (precision > 100000)
throw std::runtime_error(
"fuzz mode - avoid large allocation inside snprintf");
#endif
// Suppress the warning about nonliteral format string.
int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
return precision < 0 ? snprintf_ptr(buf, size, format, value)
: snprintf_ptr(buf, size, format, precision, value);
}
template FMT_API dragonbox::decimal_fp<float> dragonbox::to_decimal(float x)
FMT_NOEXCEPT;
template FMT_API dragonbox::decimal_fp<double> dragonbox::to_decimal(double x)
FMT_NOEXCEPT;
// DEPRECATED! This function exists for ABI compatibility.
template <typename Char>
typename basic_format_context<std::back_insert_iterator<buffer<Char>>,
Char>::iterator
vformat_to(buffer<Char>& buf, basic_string_view<Char> format_str,
basic_format_args<basic_format_context<
std::back_insert_iterator<buffer<type_identity_t<Char>>>,
type_identity_t<Char>>>
args) {
using iterator = std::back_insert_iterator<buffer<char>>;
using context = basic_format_context<
std::back_insert_iterator<buffer<type_identity_t<Char>>>,
type_identity_t<Char>>;
auto out = iterator(buf);
format_handler<iterator, Char, context> h(out, format_str, args, {});
parse_format_string<false>(format_str, h);
return out;
}
template basic_format_context<std::back_insert_iterator<buffer<char>>,
char>::iterator
vformat_to(buffer<char>&, string_view,
basic_format_args<basic_format_context<
std::back_insert_iterator<buffer<type_identity_t<char>>>,
type_identity_t<char>>>);
} // namespace detail
template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;
// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, detail::float_specs,
detail::buffer<char>&) = detail::format_float;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API detail::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
#endif
// Explicit instantiations for char.
template FMT_API std::string detail::grouping_impl<char>(locale_ref);
template FMT_API char detail::thousands_sep_impl(locale_ref);
template FMT_API char detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<char>::append(const char*, const char*);
template FMT_API void detail::vformat_to(
detail::buffer<char>&, string_view,
basic_format_args<FMT_BUFFER_CONTEXT(char)>, detail::locale_ref);
template FMT_API int detail::snprintf_float(double, int, detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::snprintf_float(long double, int,
detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::format_float(double, int, detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::format_float(long double, int, detail::float_specs,
detail::buffer<char>&);
// Explicit instantiations for wchar_t.
template FMT_API std::string detail::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t detail::thousands_sep_impl(locale_ref);
template FMT_API wchar_t detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,
const wchar_t*);
FMT_END_NAMESPACE

1118
vendor/Fmt/include/fmt/chrono.h vendored Normal file

File diff suppressed because it is too large Load Diff

603
vendor/Fmt/include/fmt/color.h vendored Normal file
View File

@ -0,0 +1,603 @@
// Formatting library for C++ - color support
//
// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_COLOR_H_
#define FMT_COLOR_H_
#include "format.h"
FMT_BEGIN_NAMESPACE
enum class color : uint32_t {
alice_blue = 0xF0F8FF, // rgb(240,248,255)
antique_white = 0xFAEBD7, // rgb(250,235,215)
aqua = 0x00FFFF, // rgb(0,255,255)
aquamarine = 0x7FFFD4, // rgb(127,255,212)
azure = 0xF0FFFF, // rgb(240,255,255)
beige = 0xF5F5DC, // rgb(245,245,220)
bisque = 0xFFE4C4, // rgb(255,228,196)
black = 0x000000, // rgb(0,0,0)
blanched_almond = 0xFFEBCD, // rgb(255,235,205)
blue = 0x0000FF, // rgb(0,0,255)
blue_violet = 0x8A2BE2, // rgb(138,43,226)
brown = 0xA52A2A, // rgb(165,42,42)
burly_wood = 0xDEB887, // rgb(222,184,135)
cadet_blue = 0x5F9EA0, // rgb(95,158,160)
chartreuse = 0x7FFF00, // rgb(127,255,0)
chocolate = 0xD2691E, // rgb(210,105,30)
coral = 0xFF7F50, // rgb(255,127,80)
cornflower_blue = 0x6495ED, // rgb(100,149,237)
cornsilk = 0xFFF8DC, // rgb(255,248,220)
crimson = 0xDC143C, // rgb(220,20,60)
cyan = 0x00FFFF, // rgb(0,255,255)
dark_blue = 0x00008B, // rgb(0,0,139)
dark_cyan = 0x008B8B, // rgb(0,139,139)
dark_golden_rod = 0xB8860B, // rgb(184,134,11)
dark_gray = 0xA9A9A9, // rgb(169,169,169)
dark_green = 0x006400, // rgb(0,100,0)
dark_khaki = 0xBDB76B, // rgb(189,183,107)
dark_magenta = 0x8B008B, // rgb(139,0,139)
dark_olive_green = 0x556B2F, // rgb(85,107,47)
dark_orange = 0xFF8C00, // rgb(255,140,0)
dark_orchid = 0x9932CC, // rgb(153,50,204)
dark_red = 0x8B0000, // rgb(139,0,0)
dark_salmon = 0xE9967A, // rgb(233,150,122)
dark_sea_green = 0x8FBC8F, // rgb(143,188,143)
dark_slate_blue = 0x483D8B, // rgb(72,61,139)
dark_slate_gray = 0x2F4F4F, // rgb(47,79,79)
dark_turquoise = 0x00CED1, // rgb(0,206,209)
dark_violet = 0x9400D3, // rgb(148,0,211)
deep_pink = 0xFF1493, // rgb(255,20,147)
deep_sky_blue = 0x00BFFF, // rgb(0,191,255)
dim_gray = 0x696969, // rgb(105,105,105)
dodger_blue = 0x1E90FF, // rgb(30,144,255)
fire_brick = 0xB22222, // rgb(178,34,34)
floral_white = 0xFFFAF0, // rgb(255,250,240)
forest_green = 0x228B22, // rgb(34,139,34)
fuchsia = 0xFF00FF, // rgb(255,0,255)
gainsboro = 0xDCDCDC, // rgb(220,220,220)
ghost_white = 0xF8F8FF, // rgb(248,248,255)
gold = 0xFFD700, // rgb(255,215,0)
golden_rod = 0xDAA520, // rgb(218,165,32)
gray = 0x808080, // rgb(128,128,128)
green = 0x008000, // rgb(0,128,0)
green_yellow = 0xADFF2F, // rgb(173,255,47)
honey_dew = 0xF0FFF0, // rgb(240,255,240)
hot_pink = 0xFF69B4, // rgb(255,105,180)
indian_red = 0xCD5C5C, // rgb(205,92,92)
indigo = 0x4B0082, // rgb(75,0,130)
ivory = 0xFFFFF0, // rgb(255,255,240)
khaki = 0xF0E68C, // rgb(240,230,140)
lavender = 0xE6E6FA, // rgb(230,230,250)
lavender_blush = 0xFFF0F5, // rgb(255,240,245)
lawn_green = 0x7CFC00, // rgb(124,252,0)
lemon_chiffon = 0xFFFACD, // rgb(255,250,205)
light_blue = 0xADD8E6, // rgb(173,216,230)
light_coral = 0xF08080, // rgb(240,128,128)
light_cyan = 0xE0FFFF, // rgb(224,255,255)
light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210)
light_gray = 0xD3D3D3, // rgb(211,211,211)
light_green = 0x90EE90, // rgb(144,238,144)
light_pink = 0xFFB6C1, // rgb(255,182,193)
light_salmon = 0xFFA07A, // rgb(255,160,122)
light_sea_green = 0x20B2AA, // rgb(32,178,170)
light_sky_blue = 0x87CEFA, // rgb(135,206,250)
light_slate_gray = 0x778899, // rgb(119,136,153)
light_steel_blue = 0xB0C4DE, // rgb(176,196,222)
light_yellow = 0xFFFFE0, // rgb(255,255,224)
lime = 0x00FF00, // rgb(0,255,0)
lime_green = 0x32CD32, // rgb(50,205,50)
linen = 0xFAF0E6, // rgb(250,240,230)
magenta = 0xFF00FF, // rgb(255,0,255)
maroon = 0x800000, // rgb(128,0,0)
medium_aquamarine = 0x66CDAA, // rgb(102,205,170)
medium_blue = 0x0000CD, // rgb(0,0,205)
medium_orchid = 0xBA55D3, // rgb(186,85,211)
medium_purple = 0x9370DB, // rgb(147,112,219)
medium_sea_green = 0x3CB371, // rgb(60,179,113)
medium_slate_blue = 0x7B68EE, // rgb(123,104,238)
medium_spring_green = 0x00FA9A, // rgb(0,250,154)
medium_turquoise = 0x48D1CC, // rgb(72,209,204)
medium_violet_red = 0xC71585, // rgb(199,21,133)
midnight_blue = 0x191970, // rgb(25,25,112)
mint_cream = 0xF5FFFA, // rgb(245,255,250)
misty_rose = 0xFFE4E1, // rgb(255,228,225)
moccasin = 0xFFE4B5, // rgb(255,228,181)
navajo_white = 0xFFDEAD, // rgb(255,222,173)
navy = 0x000080, // rgb(0,0,128)
old_lace = 0xFDF5E6, // rgb(253,245,230)
olive = 0x808000, // rgb(128,128,0)
olive_drab = 0x6B8E23, // rgb(107,142,35)
orange = 0xFFA500, // rgb(255,165,0)
orange_red = 0xFF4500, // rgb(255,69,0)
orchid = 0xDA70D6, // rgb(218,112,214)
pale_golden_rod = 0xEEE8AA, // rgb(238,232,170)
pale_green = 0x98FB98, // rgb(152,251,152)
pale_turquoise = 0xAFEEEE, // rgb(175,238,238)
pale_violet_red = 0xDB7093, // rgb(219,112,147)
papaya_whip = 0xFFEFD5, // rgb(255,239,213)
peach_puff = 0xFFDAB9, // rgb(255,218,185)
peru = 0xCD853F, // rgb(205,133,63)
pink = 0xFFC0CB, // rgb(255,192,203)
plum = 0xDDA0DD, // rgb(221,160,221)
powder_blue = 0xB0E0E6, // rgb(176,224,230)
purple = 0x800080, // rgb(128,0,128)
rebecca_purple = 0x663399, // rgb(102,51,153)
red = 0xFF0000, // rgb(255,0,0)
rosy_brown = 0xBC8F8F, // rgb(188,143,143)
royal_blue = 0x4169E1, // rgb(65,105,225)
saddle_brown = 0x8B4513, // rgb(139,69,19)
salmon = 0xFA8072, // rgb(250,128,114)
sandy_brown = 0xF4A460, // rgb(244,164,96)
sea_green = 0x2E8B57, // rgb(46,139,87)
sea_shell = 0xFFF5EE, // rgb(255,245,238)
sienna = 0xA0522D, // rgb(160,82,45)
silver = 0xC0C0C0, // rgb(192,192,192)
sky_blue = 0x87CEEB, // rgb(135,206,235)
slate_blue = 0x6A5ACD, // rgb(106,90,205)
slate_gray = 0x708090, // rgb(112,128,144)
snow = 0xFFFAFA, // rgb(255,250,250)
spring_green = 0x00FF7F, // rgb(0,255,127)
steel_blue = 0x4682B4, // rgb(70,130,180)
tan = 0xD2B48C, // rgb(210,180,140)
teal = 0x008080, // rgb(0,128,128)
thistle = 0xD8BFD8, // rgb(216,191,216)
tomato = 0xFF6347, // rgb(255,99,71)
turquoise = 0x40E0D0, // rgb(64,224,208)
violet = 0xEE82EE, // rgb(238,130,238)
wheat = 0xF5DEB3, // rgb(245,222,179)
white = 0xFFFFFF, // rgb(255,255,255)
white_smoke = 0xF5F5F5, // rgb(245,245,245)
yellow = 0xFFFF00, // rgb(255,255,0)
yellow_green = 0x9ACD32 // rgb(154,205,50)
}; // enum class color
enum class terminal_color : uint8_t {
black = 30,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
bright_black = 90,
bright_red,
bright_green,
bright_yellow,
bright_blue,
bright_magenta,
bright_cyan,
bright_white
};
enum class emphasis : uint8_t {
bold = 1,
italic = 1 << 1,
underline = 1 << 2,
strikethrough = 1 << 3
};
// rgb is a struct for red, green and blue colors.
// Using the name "rgb" makes some editors show the color in a tooltip.
struct rgb {
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
FMT_CONSTEXPR rgb(uint32_t hex)
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
FMT_CONSTEXPR rgb(color hex)
: r((uint32_t(hex) >> 16) & 0xFF),
g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {}
uint8_t r;
uint8_t g;
uint8_t b;
};
namespace detail {
// color is a struct of either a rgb color or a terminal color.
struct color_type {
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
value{} {
value.rgb_color = static_cast<uint32_t>(rgb_color);
}
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
}
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
value{} {
value.term_color = static_cast<uint8_t>(term_color);
}
bool is_rgb;
union color_union {
uint8_t term_color;
uint32_t rgb_color;
} value;
};
} // namespace detail
// Experimental text formatting support.
class text_style {
public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
: set_foreground_color(),
set_background_color(),
ems(em) {}
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
FMT_THROW(format_error("can't OR a terminal color"));
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
FMT_THROW(format_error("can't OR a terminal color"));
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
}
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
static_cast<uint8_t>(rhs.ems));
return *this;
}
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
const text_style& rhs) {
return lhs |= rhs;
}
FMT_CONSTEXPR text_style& operator&=(const text_style& rhs) {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
FMT_THROW(format_error("can't AND a terminal color"));
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
FMT_THROW(format_error("can't AND a terminal color"));
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
}
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) &
static_cast<uint8_t>(rhs.ems));
return *this;
}
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
const text_style& rhs) {
return lhs &= rhs;
}
FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT {
return set_foreground_color;
}
FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT {
return set_background_color;
}
FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT {
return static_cast<uint8_t>(ems) != 0;
}
FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT {
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
return foreground_color;
}
FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT {
FMT_ASSERT(has_background(), "no background specified for this style");
return background_color;
}
FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT {
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
return ems;
}
private:
FMT_CONSTEXPR text_style(bool is_foreground,
detail::color_type text_color) FMT_NOEXCEPT
: set_foreground_color(),
set_background_color(),
ems() {
if (is_foreground) {
foreground_color = text_color;
set_foreground_color = true;
} else {
background_color = text_color;
set_background_color = true;
}
}
friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground)
FMT_NOEXCEPT;
friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background)
FMT_NOEXCEPT;
detail::color_type foreground_color;
detail::color_type background_color;
bool set_foreground_color;
bool set_background_color;
emphasis ems;
};
FMT_CONSTEXPR text_style fg(detail::color_type foreground) FMT_NOEXCEPT {
return text_style(/*is_foreground=*/true, foreground);
}
FMT_CONSTEXPR text_style bg(detail::color_type background) FMT_NOEXCEPT {
return text_style(/*is_foreground=*/false, background);
}
FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT {
return text_style(lhs) | rhs;
}
namespace detail {
template <typename Char> struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
const char* esc) FMT_NOEXCEPT {
// If we have a terminal color, we need to output another escape code
// sequence.
if (!text_color.is_rgb) {
bool is_background = esc == detail::data::background_color;
uint32_t value = text_color.value.term_color;
// Background ASCII codes are the same as the foreground ones but with
// 10 more.
if (is_background) value += 10u;
size_t index = 0;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
if (value >= 100u) {
buffer[index++] = static_cast<Char>('1');
value %= 100u;
}
buffer[index++] = static_cast<Char>('0' + value / 10u);
buffer[index++] = static_cast<Char>('0' + value % 10u);
buffer[index++] = static_cast<Char>('m');
buffer[index++] = static_cast<Char>('\0');
return;
}
for (int i = 0; i < 7; i++) {
buffer[i] = static_cast<Char>(esc[i]);
}
rgb color(text_color.value.rgb_color);
to_esc(color.r, buffer + 7, ';');
to_esc(color.g, buffer + 11, ';');
to_esc(color.b, buffer + 15, 'm');
buffer[19] = static_cast<Char>(0);
}
FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
uint8_t em_codes[4] = {};
uint8_t em_bits = static_cast<uint8_t>(em);
if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
em_codes[3] = 9;
size_t index = 0;
for (int i = 0; i < 4; ++i) {
if (!em_codes[i]) continue;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
buffer[index++] = static_cast<Char>('m');
}
buffer[index++] = static_cast<Char>(0);
}
FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; }
FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; }
FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT {
return buffer + std::char_traits<Char>::length(buffer);
}
private:
Char buffer[7u + 3u * 4u + 1u];
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
char delimiter) FMT_NOEXCEPT {
out[0] = static_cast<Char>('0' + c / 100);
out[1] = static_cast<Char>('0' + c / 10 % 10);
out[2] = static_cast<Char>('0' + c % 10);
out[3] = static_cast<Char>(delimiter);
}
};
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
detail::color_type foreground) FMT_NOEXCEPT {
return ansi_color_escape<Char>(foreground, detail::data::foreground_color);
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
detail::color_type background) FMT_NOEXCEPT {
return ansi_color_escape<Char>(background, detail::data::background_color);
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
return ansi_color_escape<Char>(em);
}
template <typename Char>
inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT {
std::fputs(chars, stream);
}
template <>
inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT {
std::fputws(chars, stream);
}
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
fputs(detail::data::reset_color, stream);
}
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
fputs(detail::data::wreset_color, stream);
}
template <typename Char>
inline void reset_color(buffer<Char>& buffer) FMT_NOEXCEPT {
const char* begin = data::reset_color;
const char* end = begin + sizeof(data::reset_color) - 1;
buffer.append(begin, end);
}
template <typename Char>
void vformat_to(buffer<Char>& buf, const text_style& ts,
basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
buf.append(emphasis.begin(), emphasis.end());
}
if (ts.has_foreground()) {
has_style = true;
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
buf.append(foreground.begin(), foreground.end());
}
if (ts.has_background()) {
has_style = true;
auto background = detail::make_background_color<Char>(ts.get_background());
buf.append(background.begin(), background.end());
}
detail::vformat_to(buf, format_str, args);
if (has_style) detail::reset_color<Char>(buf);
}
} // namespace detail
template <typename S, typename Char = char_t<S>>
void vprint(std::FILE* f, const text_style& ts, const S& format,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, to_string_view(format), args);
buf.push_back(Char(0));
detail::fputs(buf.data(), f);
}
/**
\rst
Formats a string and prints it to the specified file stream using ANSI
escape sequences to specify text formatting.
**Example**::
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
"Elapsed time: {0:.2f} seconds", 1.23);
\endrst
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
void print(std::FILE* f, const text_style& ts, const S& format_str,
const Args&... args) {
vprint(f, ts, format_str,
fmt::make_args_checked<Args...>(format_str, args...));
}
/**
Formats a string and prints it to stdout using ANSI escape sequences to
specify text formatting.
Example:
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
"Elapsed time: {0:.2f} seconds", 1.23);
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
void print(const text_style& ts, const S& format_str, const Args&... args) {
return print(stdout, ts, format_str, args...);
}
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
const text_style& ts, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, to_string_view(format_str), args);
return fmt::to_string(buf);
}
/**
\rst
Formats arguments and returns the result as a string using ANSI
escape sequences to specify text formatting.
**Example**::
#include <fmt/color.h>
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
"The answer is {}", 42);
\endrst
*/
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
const Args&... args) {
return vformat(ts, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
/**
Formats a string with the given text_style and writes the output to ``out``.
*/
template <typename OutputIt, typename Char,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
OutputIt vformat_to(
OutputIt out, const text_style& ts, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
detail::vformat_to(buf, ts, format_str, args);
return detail::get_iterator(buf);
}
/**
\rst
Formats arguments with the given text_style, writes the result to the output
iterator ``out`` and returns the iterator past the end of the output range.
**Example**::
std::vector<char> out;
fmt::format_to(std::back_inserter(out),
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
\endrst
*/
template <typename OutputIt, typename S, typename... Args,
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value&&
detail::is_string<S>::value>
inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
Args&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
return vformat_to(out, ts, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
FMT_END_NAMESPACE
#endif // FMT_COLOR_H_

701
vendor/Fmt/include/fmt/compile.h vendored Normal file
View File

@ -0,0 +1,701 @@
// Formatting library for C++ - experimental format string compilation
//
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_COMPILE_H_
#define FMT_COMPILE_H_
#include <vector>
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
// A compile-time string which is compiled into fast formatting code.
class compiled_string {};
template <typename S>
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
/**
\rst
Converts a string literal *s* into a format string that will be parsed at
compile time and converted into efficient formatting code. Requires C++17
``constexpr if`` compiler support.
**Example**::
// Converts 42 into std::string using the most efficient method and no
// runtime format string processing.
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
\endrst
*/
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
template <typename T, typename... Tail>
const T& first(const T& value, const Tail&...) {
return value;
}
// Part of a compiled format string. It can be either literal text or a
// replacement field.
template <typename Char> struct format_part {
enum class kind { arg_index, arg_name, text, replacement };
struct replacement {
arg_ref<Char> arg_id;
dynamic_format_specs<Char> specs;
};
kind part_kind;
union value {
int arg_index;
basic_string_view<Char> str;
replacement repl;
FMT_CONSTEXPR value(int index = 0) : arg_index(index) {}
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
FMT_CONSTEXPR value(replacement r) : repl(r) {}
} val;
// Position past the end of the argument id.
const Char* arg_id_end = nullptr;
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
: part_kind(k), val(v) {}
static FMT_CONSTEXPR format_part make_arg_index(int index) {
return format_part(kind::arg_index, index);
}
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
return format_part(kind::arg_name, name);
}
static FMT_CONSTEXPR format_part make_text(basic_string_view<Char> text) {
return format_part(kind::text, text);
}
static FMT_CONSTEXPR format_part make_replacement(replacement repl) {
return format_part(kind::replacement, repl);
}
};
template <typename Char> struct part_counter {
unsigned num_parts = 0;
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
if (begin != end) ++num_parts;
}
FMT_CONSTEXPR int on_arg_id() { return ++num_parts, 0; }
FMT_CONSTEXPR int on_arg_id(int) { return ++num_parts, 0; }
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char>) {
return ++num_parts, 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
const Char* end) {
// Find the matching brace.
unsigned brace_counter = 0;
for (; begin != end; ++begin) {
if (*begin == '{') {
++brace_counter;
} else if (*begin == '}') {
if (brace_counter == 0u) break;
--brace_counter;
}
}
return begin;
}
FMT_CONSTEXPR void on_error(const char*) {}
};
// Counts the number of parts in a format string.
template <typename Char>
FMT_CONSTEXPR unsigned count_parts(basic_string_view<Char> format_str) {
part_counter<Char> counter;
parse_format_string<true>(format_str, counter);
return counter.num_parts;
}
template <typename Char, typename PartHandler>
class format_string_compiler : public error_handler {
private:
using part = format_part<Char>;
PartHandler handler_;
part part_;
basic_string_view<Char> format_str_;
basic_format_parse_context<Char> parse_context_;
public:
FMT_CONSTEXPR format_string_compiler(basic_string_view<Char> format_str,
PartHandler handler)
: handler_(handler),
format_str_(format_str),
parse_context_(format_str) {}
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
if (begin != end)
handler_(part::make_text({begin, to_unsigned(end - begin)}));
}
FMT_CONSTEXPR int on_arg_id() {
part_ = part::make_arg_index(parse_context_.next_arg_id());
return 0;
}
FMT_CONSTEXPR int on_arg_id(int id) {
parse_context_.check_arg_id(id);
part_ = part::make_arg_index(id);
return 0;
}
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char> id) {
part_ = part::make_arg_name(id);
return 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) {
part_.arg_id_end = ptr;
handler_(part_);
}
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
const Char* end) {
auto repl = typename part::replacement();
dynamic_specs_handler<basic_format_parse_context<Char>> handler(
repl.specs, parse_context_);
auto it = parse_format_specs(begin, end, handler);
if (*it != '}') on_error("missing '}' in format string");
repl.arg_id = part_.part_kind == part::kind::arg_index
? arg_ref<Char>(part_.val.arg_index)
: arg_ref<Char>(part_.val.str);
auto part = part::make_replacement(repl);
part.arg_id_end = begin;
handler_(part);
return it;
}
};
// Compiles a format string and invokes handler(part) for each parsed part.
template <bool IS_CONSTEXPR, typename Char, typename PartHandler>
FMT_CONSTEXPR void compile_format_string(basic_string_view<Char> format_str,
PartHandler handler) {
parse_format_string<IS_CONSTEXPR>(
format_str,
format_string_compiler<Char, PartHandler>(format_str, handler));
}
template <typename OutputIt, typename Context, typename Id>
void format_arg(
basic_format_parse_context<typename Context::char_type>& parse_ctx,
Context& ctx, Id arg_id) {
ctx.advance_to(visit_format_arg(
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
ctx.arg(arg_id)));
}
// vformat_to is defined in a subnamespace to prevent ADL.
namespace cf {
template <typename Context, typename OutputIt, typename CompiledFormat>
auto vformat_to(OutputIt out, CompiledFormat& cf,
basic_format_args<Context> args) -> typename Context::iterator {
using char_type = typename Context::char_type;
basic_format_parse_context<char_type> parse_ctx(
to_string_view(cf.format_str_));
Context ctx(out, args);
const auto& parts = cf.parts();
for (auto part_it = std::begin(parts); part_it != std::end(parts);
++part_it) {
const auto& part = *part_it;
const auto& value = part.val;
using format_part_t = format_part<char_type>;
switch (part.part_kind) {
case format_part_t::kind::text: {
const auto text = value.str;
auto output = ctx.out();
auto&& it = reserve(output, text.size());
it = std::copy_n(text.begin(), text.size(), it);
ctx.advance_to(output);
break;
}
case format_part_t::kind::arg_index:
advance_to(parse_ctx, part.arg_id_end);
detail::format_arg<OutputIt>(parse_ctx, ctx, value.arg_index);
break;
case format_part_t::kind::arg_name:
advance_to(parse_ctx, part.arg_id_end);
detail::format_arg<OutputIt>(parse_ctx, ctx, value.str);
break;
case format_part_t::kind::replacement: {
const auto& arg_id_value = value.repl.arg_id.val;
const auto arg = value.repl.arg_id.kind == arg_id_kind::index
? ctx.arg(arg_id_value.index)
: ctx.arg(arg_id_value.name);
auto specs = value.repl.specs;
handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx);
handle_dynamic_spec<precision_checker>(specs.precision,
specs.precision_ref, ctx);
error_handler h;
numeric_specs_checker<error_handler> checker(h, arg.type());
if (specs.align == align::numeric) checker.require_numeric_argument();
if (specs.sign != sign::none) checker.check_sign();
if (specs.alt) checker.require_numeric_argument();
if (specs.precision >= 0) checker.check_precision();
advance_to(parse_ctx, part.arg_id_end);
ctx.advance_to(
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
ctx, nullptr, &specs),
arg));
break;
}
}
}
return ctx.out();
}
} // namespace cf
struct basic_compiled_format {};
template <typename S, typename = void>
struct compiled_format_base : basic_compiled_format {
using char_type = char_t<S>;
using parts_container = std::vector<detail::format_part<char_type>>;
parts_container compiled_parts;
explicit compiled_format_base(basic_string_view<char_type> format_str) {
compile_format_string<false>(format_str,
[this](const format_part<char_type>& part) {
compiled_parts.push_back(part);
});
}
const parts_container& parts() const { return compiled_parts; }
};
template <typename Char, unsigned N> struct format_part_array {
format_part<Char> data[N] = {};
FMT_CONSTEXPR format_part_array() = default;
};
template <typename Char, unsigned N>
FMT_CONSTEXPR format_part_array<Char, N> compile_to_parts(
basic_string_view<Char> format_str) {
format_part_array<Char, N> parts;
unsigned counter = 0;
// This is not a lambda for compatibility with older compilers.
struct {
format_part<Char>* parts;
unsigned* counter;
FMT_CONSTEXPR void operator()(const format_part<Char>& part) {
parts[(*counter)++] = part;
}
} collector{parts.data, &counter};
compile_format_string<true>(format_str, collector);
if (counter < N) {
parts.data[counter] =
format_part<Char>::make_text(basic_string_view<Char>());
}
return parts;
}
template <typename T> constexpr const T& constexpr_max(const T& a, const T& b) {
return (a < b) ? b : a;
}
template <typename S>
struct compiled_format_base<S, enable_if_t<is_compile_string<S>::value>>
: basic_compiled_format {
using char_type = char_t<S>;
FMT_CONSTEXPR explicit compiled_format_base(basic_string_view<char_type>) {}
// Workaround for old compilers. Format string compilation will not be
// performed there anyway.
#if FMT_USE_CONSTEXPR
static FMT_CONSTEXPR_DECL const unsigned num_format_parts =
constexpr_max(count_parts(to_string_view(S())), 1u);
#else
static const unsigned num_format_parts = 1;
#endif
using parts_container = format_part<char_type>[num_format_parts];
const parts_container& parts() const {
static FMT_CONSTEXPR_DECL const auto compiled_parts =
compile_to_parts<char_type, num_format_parts>(
detail::to_string_view(S()));
return compiled_parts.data;
}
};
template <typename S, typename... Args>
class compiled_format : private compiled_format_base<S> {
public:
using typename compiled_format_base<S>::char_type;
private:
basic_string_view<char_type> format_str_;
template <typename Context, typename OutputIt, typename CompiledFormat>
friend auto cf::vformat_to(OutputIt out, CompiledFormat& cf,
basic_format_args<Context> args) ->
typename Context::iterator;
public:
compiled_format() = delete;
explicit constexpr compiled_format(basic_string_view<char_type> format_str)
: compiled_format_base<S>(format_str), format_str_(format_str) {}
};
#ifdef __cpp_if_constexpr
template <typename... Args> struct type_list {};
// Returns a reference to the argument at index N from [first, rest...].
template <int N, typename T, typename... Args>
constexpr const auto& get([[maybe_unused]] const T& first,
[[maybe_unused]] const Args&... rest) {
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
if constexpr (N == 0)
return first;
else
return get<N - 1>(rest...);
}
template <int N, typename> struct get_type_impl;
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
using type = remove_cvref_t<decltype(get<N>(std::declval<Args>()...))>;
};
template <int N, typename T>
using get_type = typename get_type_impl<N, T>::type;
template <typename T> struct is_compiled_format : std::false_type {};
template <typename Char> struct text {
basic_string_view<Char> data;
using char_type = Char;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&...) const {
return write<Char>(out, data);
}
};
template <typename Char>
struct is_compiled_format<text<Char>> : std::true_type {};
template <typename Char>
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
size_t size) {
return {{&s[pos], size}};
}
template <typename Char> struct code_unit {
Char value;
using char_type = Char;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&...) const {
return write<Char>(out, value);
}
};
template <typename Char>
struct is_compiled_format<code_unit<Char>> : std::true_type {};
// A replacement field that refers to argument N.
template <typename Char, typename T, int N> struct field {
using char_type = Char;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&... args) const {
// This ensures that the argument type is convertile to `const T&`.
const T& arg = get<N>(args...);
return write<Char>(out, arg);
}
};
template <typename Char, typename T, int N>
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
// A replacement field that refers to argument N and has format specifiers.
template <typename Char, typename T, int N> struct spec_field {
using char_type = Char;
mutable formatter<T, Char> fmt;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&... args) const {
// This ensures that the argument type is convertile to `const T&`.
const T& arg = get<N>(args...);
const auto& vargs =
make_format_args<basic_format_context<OutputIt, Char>>(args...);
basic_format_context<OutputIt, Char> ctx(out, vargs);
return fmt.format(arg, ctx);
}
};
template <typename Char, typename T, int N>
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
template <typename L, typename R> struct concat {
L lhs;
R rhs;
using char_type = typename L::char_type;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&... args) const {
out = lhs.format(out, args...);
return rhs.format(out, args...);
}
};
template <typename L, typename R>
struct is_compiled_format<concat<L, R>> : std::true_type {};
template <typename L, typename R>
constexpr concat<L, R> make_concat(L lhs, R rhs) {
return {lhs, rhs};
}
struct unknown_format {};
template <typename Char>
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
for (size_t size = str.size(); pos != size; ++pos) {
if (str[pos] == '{' || str[pos] == '}') break;
}
return pos;
}
template <typename Args, size_t POS, int ID, typename S>
constexpr auto compile_format_string(S format_str);
template <typename Args, size_t POS, int ID, typename T, typename S>
constexpr auto parse_tail(T head, S format_str) {
if constexpr (POS !=
basic_string_view<typename S::char_type>(format_str).size()) {
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
unknown_format>())
return tail;
else
return make_concat(head, tail);
} else {
return head;
}
}
template <typename T, typename Char> struct parse_specs_result {
formatter<T, Char> fmt;
size_t end;
int next_arg_id;
};
template <typename T, typename Char>
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
size_t pos, int arg_id) {
str.remove_prefix(pos);
auto ctx = basic_format_parse_context<Char>(str, {}, arg_id + 1);
auto f = formatter<T, Char>();
auto end = f.parse(ctx);
return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
}
// Compiles a non-empty format string and returns the compiled representation
// or unknown_format() on unrecognized input.
template <typename Args, size_t POS, int ID, typename S>
constexpr auto compile_format_string(S format_str) {
using char_type = typename S::char_type;
constexpr basic_string_view<char_type> str = format_str;
if constexpr (str[POS] == '{') {
if (POS + 1 == str.size())
throw format_error("unmatched '{' in format string");
if constexpr (str[POS + 1] == '{') {
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
} else if constexpr (str[POS + 1] == '}') {
using type = get_type<ID, Args>;
return parse_tail<Args, POS + 2, ID + 1>(field<char_type, type, ID>(),
format_str);
} else if constexpr (str[POS + 1] == ':') {
using type = get_type<ID, Args>;
constexpr auto result = parse_specs<type>(str, POS + 2, ID);
return parse_tail<Args, result.end, result.next_arg_id>(
spec_field<char_type, type, ID>{result.fmt}, format_str);
} else {
return unknown_format();
}
} else if constexpr (str[POS] == '}') {
if (POS + 1 == str.size())
throw format_error("unmatched '}' in format string");
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
} else {
constexpr auto end = parse_text(str, POS + 1);
if constexpr (end - POS > 1) {
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
format_str);
} else {
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
format_str);
}
}
}
template <typename... Args, typename S,
FMT_ENABLE_IF(is_compile_string<S>::value ||
detail::is_compiled_string<S>::value)>
constexpr auto compile(S format_str) {
constexpr basic_string_view<typename S::char_type> str = format_str;
if constexpr (str.size() == 0) {
return detail::make_text(str, 0, 0);
} else {
constexpr auto result =
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
format_str);
if constexpr (std::is_same<remove_cvref_t<decltype(result)>,
detail::unknown_format>()) {
return detail::compiled_format<S, Args...>(to_string_view(format_str));
} else {
return result;
}
}
}
#else
template <typename... Args, typename S,
FMT_ENABLE_IF(is_compile_string<S>::value)>
constexpr auto compile(S format_str) -> detail::compiled_format<S, Args...> {
return detail::compiled_format<S, Args...>(to_string_view(format_str));
}
#endif // __cpp_if_constexpr
// Compiles the format string which must be a string literal.
template <typename... Args, typename Char, size_t N>
auto compile(const Char (&format_str)[N])
-> detail::compiled_format<const Char*, Args...> {
return detail::compiled_format<const Char*, Args...>(
basic_string_view<Char>(format_str, N - 1));
}
} // namespace detail
// DEPRECATED! use FMT_COMPILE instead.
template <typename... Args>
FMT_DEPRECATED auto compile(const Args&... args)
-> decltype(detail::compile(args...)) {
return detail::compile(args...);
}
#if FMT_USE_CONSTEXPR
# ifdef __cpp_if_constexpr
template <typename CompiledFormat, typename... Args,
typename Char = typename CompiledFormat::char_type,
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
const Args&... args) {
basic_memory_buffer<Char> buffer;
cf.format(detail::buffer_appender<Char>(buffer), args...);
return to_string(buffer);
}
template <typename OutputIt, typename CompiledFormat, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
const Args&... args) {
return cf.format(out, args...);
}
# endif // __cpp_if_constexpr
#endif // FMT_USE_CONSTEXPR
template <typename CompiledFormat, typename... Args,
typename Char = typename CompiledFormat::char_type,
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
CompiledFormat>::value)>
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
basic_memory_buffer<Char> buffer;
using context = buffer_context<Char>;
detail::cf::vformat_to<context>(detail::buffer_appender<Char>(buffer), cf,
make_format_args<context>(args...));
return to_string(buffer);
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
Args&&... args) {
#ifdef __cpp_if_constexpr
if constexpr (std::is_same<typename S::char_type, char>::value) {
constexpr basic_string_view<typename S::char_type> str = S();
if (str.size() == 2 && str[0] == '{' && str[1] == '}')
return fmt::to_string(detail::first(args...));
}
#endif
constexpr auto compiled = detail::compile<Args...>(S());
return format(compiled, std::forward<Args>(args)...);
}
template <typename OutputIt, typename CompiledFormat, typename... Args,
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
CompiledFormat>::value)>
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
const Args&... args) {
using char_type = typename CompiledFormat::char_type;
using context = format_context_t<OutputIt, char_type>;
return detail::cf::vformat_to<context>(out, cf,
make_format_args<context>(args...));
}
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
OutputIt format_to(OutputIt out, const S&, const Args&... args) {
constexpr auto compiled = detail::compile<Args...>(S());
return format_to(out, compiled, args...);
}
template <typename OutputIt, typename CompiledFormat, typename... Args>
auto format_to_n(OutputIt out, size_t n, const CompiledFormat& cf,
const Args&... args) ->
typename std::enable_if<
detail::is_output_iterator<OutputIt,
typename CompiledFormat::char_type>::value &&
std::is_base_of<detail::basic_compiled_format,
CompiledFormat>::value,
format_to_n_result<OutputIt>>::type {
auto it =
format_to(detail::truncating_iterator<OutputIt>(out, n), cf, args...);
return {it.base(), it.count()};
}
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n, const S&,
const Args&... args) {
constexpr auto compiled = detail::compile<Args...>(S());
auto it = format_to(detail::truncating_iterator<OutputIt>(out, n), compiled,
args...);
return {it.base(), it.count()};
}
template <typename CompiledFormat, typename... Args>
size_t formatted_size(const CompiledFormat& cf, const Args&... args) {
return format_to(detail::counting_iterator(), cf, args...).count();
}
FMT_END_NAMESPACE
#endif // FMT_COMPILE_H_

2122
vendor/Fmt/include/fmt/core.h vendored Normal file

File diff suppressed because it is too large Load Diff

2801
vendor/Fmt/include/fmt/format-inl.h vendored Normal file

File diff suppressed because it is too large Load Diff

3960
vendor/Fmt/include/fmt/format.h vendored Normal file

File diff suppressed because it is too large Load Diff

64
vendor/Fmt/include/fmt/locale.h vendored Normal file
View File

@ -0,0 +1,64 @@
// Formatting library for C++ - std::locale support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_LOCALE_H_
#define FMT_LOCALE_H_
#include <locale>
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Char>
std::basic_string<Char> vformat(
const std::locale& loc, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc));
return fmt::to_string(buffer);
}
} // namespace detail
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
const std::locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
return detail::vformat(loc, to_string_view(format_str), args);
}
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const std::locale& loc,
const S& format_str, Args&&... args) {
return detail::vformat(loc, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
template <typename S, typename OutputIt, typename... Args,
typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
inline OutputIt vformat_to(
OutputIt out, const std::locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
vformat_to(buf, to_string_view(format_str), args, detail::locale_ref(loc));
return detail::get_iterator(buf);
}
template <typename OutputIt, typename S, typename... Args,
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value>
inline auto format_to(OutputIt out, const std::locale& loc,
const S& format_str, Args&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
return vformat_to(out, loc, to_string_view(format_str), vargs);
}
FMT_END_NAMESPACE
#endif // FMT_LOCALE_H_

480
vendor/Fmt/include/fmt/os.h vendored Normal file
View File

@ -0,0 +1,480 @@
// Formatting library for C++ - optional OS-specific functionality
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_OS_H_
#define FMT_OS_H_
#if defined(__MINGW32__) || defined(__CYGWIN__)
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
# undef __STRICT_ANSI__
#endif
#include <cerrno>
#include <clocale> // for locale_t
#include <cstddef>
#include <cstdio>
#include <cstdlib> // for strtod_l
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#endif
#include "format.h"
// UWP doesn't provide _pipe.
#if FMT_HAS_INCLUDE("winapifamily.h")
# include <winapifamily.h>
#endif
#if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
defined(__linux__)) && \
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
# include <fcntl.h> // for O_RDONLY
# define FMT_USE_FCNTL 1
#else
# define FMT_USE_FCNTL 0
#endif
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) ::call
# ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
(result) = (expression); \
} while ((result) == (error_result) && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
FMT_BEGIN_NAMESPACE
/**
\rst
A reference to a null-terminated string. It can be constructed from a C
string or ``std::string``.
You can use one of the following type aliases for common character types:
+---------------+-----------------------------+
| Type | Definition |
+===============+=============================+
| cstring_view | basic_cstring_view<char> |
+---------------+-----------------------------+
| wcstring_view | basic_cstring_view<wchar_t> |
+---------------+-----------------------------+
This class is most useful as a parameter type to allow passing
different types of strings to a function, for example::
template <typename... Args>
std::string format(cstring_view format_str, const Args & ... args);
format("{}", 42);
format(std::string("{}"), 42);
\endrst
*/
template <typename Char> class basic_cstring_view {
private:
const Char* data_;
public:
/** Constructs a string reference object from a C string. */
basic_cstring_view(const Char* s) : data_(s) {}
/**
\rst
Constructs a string reference from an ``std::string`` object.
\endrst
*/
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
/** Returns the pointer to a C string. */
const Char* c_str() const { return data_; }
};
using cstring_view = basic_cstring_view<char>;
using wcstring_view = basic_cstring_view<wchar_t>;
// An error code.
class error_code {
private:
int value_;
public:
explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
int get() const FMT_NOEXCEPT { return value_; }
};
#ifdef _WIN32
namespace detail {
// A converter from UTF-16 to UTF-8.
// It is only provided for Windows since other systems support UTF-8 natively.
class utf16_to_utf8 {
private:
memory_buffer buffer_;
public:
utf16_to_utf8() {}
FMT_API explicit utf16_to_utf8(wstring_view s);
operator string_view() const { return string_view(&buffer_[0], size()); }
size_t size() const { return buffer_.size() - 1; }
const char* c_str() const { return &buffer_[0]; }
std::string str() const { return std::string(&buffer_[0], size()); }
// Performs conversion returning a system error code instead of
// throwing exception on conversion error. This method may still throw
// in case of memory allocation error.
FMT_API int convert(wstring_view s);
};
FMT_API void format_windows_error(buffer<char>& out, int error_code,
string_view message) FMT_NOEXCEPT;
} // namespace detail
/** A Windows error. */
class windows_error : public system_error {
private:
FMT_API void init(int error_code, string_view format_str, format_args args);
public:
/**
\rst
Constructs a :class:`fmt::windows_error` object with the description
of the form
.. parsed-literal::
*<message>*: *<system-message>*
where *<message>* is the formatted message and *<system-message>* is the
system message corresponding to the error code.
*error_code* is a Windows error code as given by ``GetLastError``.
If *error_code* is not a valid error code such as -1, the system message
will look like "error -1".
**Example**::
// This throws a windows_error with the description
// cannot open file 'madeup': The system cannot find the file specified.
// or similar (system message may vary).
const char *filename = "madeup";
LPOFSTRUCT of = LPOFSTRUCT();
HFILE file = OpenFile(filename, &of, OF_READ);
if (file == HFILE_ERROR) {
throw fmt::windows_error(GetLastError(),
"cannot open file '{}'", filename);
}
\endrst
*/
template <typename... Args>
windows_error(int error_code, string_view message, const Args&... args) {
init(error_code, message, make_format_args(args...));
}
};
// Reports a Windows error without throwing an exception.
// Can be used to report errors from destructors.
FMT_API void report_windows_error(int error_code,
string_view message) FMT_NOEXCEPT;
#endif // _WIN32
// A buffered file.
class buffered_file {
private:
FILE* file_;
friend class file;
explicit buffered_file(FILE* f) : file_(f) {}
public:
buffered_file(const buffered_file&) = delete;
void operator=(const buffered_file&) = delete;
// Constructs a buffered_file object which doesn't represent any file.
buffered_file() FMT_NOEXCEPT : file_(nullptr) {}
// Destroys the object closing the file it represents if any.
FMT_API ~buffered_file() FMT_NOEXCEPT;
public:
buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = nullptr;
}
buffered_file& operator=(buffered_file&& other) {
close();
file_ = other.file_;
other.file_ = nullptr;
return *this;
}
// Opens a file.
FMT_API buffered_file(cstring_view filename, cstring_view mode);
// Closes the file.
FMT_API void close();
// Returns the pointer to a FILE object representing this file.
FILE* get() const FMT_NOEXCEPT { return file_; }
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
FMT_API int(fileno)() const;
void vprint(string_view format_str, format_args args) {
fmt::vprint(file_, format_str, args);
}
template <typename... Args>
inline void print(string_view format_str, const Args&... args) {
vprint(format_str, make_format_args(args...));
}
};
#if FMT_USE_FCNTL
// A file. Closed file is represented by a file object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::system_error in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class file {
private:
int fd_; // File descriptor.
// Constructs a file object with a given descriptor.
explicit file(int fd) : fd_(fd) {}
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist.
APPEND = FMT_POSIX(O_APPEND) // Open in append mode.
};
// Constructs a file object which doesn't represent any file.
file() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a file object representing this file.
FMT_API file(cstring_view path, int oflag);
public:
file(const file&) = delete;
void operator=(const file&) = delete;
file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
file& operator=(file&& other) FMT_NOEXCEPT {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
// Destroys the object closing the file it represents if any.
FMT_API ~file() FMT_NOEXCEPT;
// Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file.
FMT_API void close();
// Returns the file size. The size has signed type for consistency with
// stat::st_size.
FMT_API long long size() const;
// Attempts to read count bytes from the file into the specified buffer.
FMT_API size_t read(void* buffer, size_t count);
// Attempts to write count bytes from the specified buffer to the file.
FMT_API size_t write(const void* buffer, size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
FMT_API static file dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
FMT_API void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
FMT_API static void pipe(file& read_end, file& write_end);
// Creates a buffered_file object associated with this file and detaches
// this file object from the file.
FMT_API buffered_file fdopen(const char* mode);
};
// Returns the memory page size.
long getpagesize();
namespace detail {
struct buffer_size {
size_t value = 0;
buffer_size operator=(size_t val) const {
auto bs = buffer_size();
bs.value = val;
return bs;
}
};
struct ostream_params {
int oflag = file::WRONLY | file::CREATE;
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
ostream_params() {}
template <typename... T>
ostream_params(T... params, int oflag) : ostream_params(params...) {
this->oflag = oflag;
}
template <typename... T>
ostream_params(T... params, detail::buffer_size bs)
: ostream_params(params...) {
this->buffer_size = bs.value;
}
};
} // namespace detail
static constexpr detail::buffer_size buffer_size;
// A fast output stream which is not thread-safe.
class ostream final : private detail::buffer<char> {
private:
file file_;
void flush() {
if (size() == 0) return;
file_.write(data(), size());
clear();
}
FMT_API void grow(size_t) override final;
ostream(cstring_view path, const detail::ostream_params& params)
: file_(path, params.oflag) {
set(new char[params.buffer_size], params.buffer_size);
}
public:
ostream(ostream&& other)
: detail::buffer<char>(other.data(), other.size(), other.capacity()),
file_(std::move(other.file_)) {
other.set(nullptr, 0);
}
~ostream() {
flush();
delete[] data();
}
template <typename... T>
friend ostream output_file(cstring_view path, T... params);
void close() {
flush();
file_.close();
}
template <typename S, typename... Args>
void print(const S& format_str, const Args&... args) {
format_to(detail::buffer_appender<char>(*this), format_str, args...);
}
};
/**
Opens a file for writing. Supported parameters passed in `params`:
* ``<integer>``: Output flags (``file::WRONLY | file::CREATE`` by default)
* ``buffer_size=<integer>``: Output buffer size
*/
template <typename... T>
inline ostream output_file(cstring_view path, T... params) {
return {path, detail::ostream_params(params...)};
}
#endif // FMT_USE_FCNTL
#ifdef FMT_LOCALE
// A "C" numeric locale.
class locale {
private:
# ifdef _WIN32
using locale_t = _locale_t;
static void freelocale(locale_t loc) { _free_locale(loc); }
static double strtod_l(const char* nptr, char** endptr, _locale_t loc) {
return _strtod_l(nptr, endptr, loc);
}
# endif
locale_t locale_;
public:
using type = locale_t;
locale(const locale&) = delete;
void operator=(const locale&) = delete;
locale() {
# ifndef _WIN32
locale_ = FMT_SYSTEM(newlocale(LC_NUMERIC_MASK, "C", nullptr));
# else
locale_ = _create_locale(LC_NUMERIC, "C");
# endif
if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
}
~locale() { freelocale(locale_); }
type get() const { return locale_; }
// Converts string to floating-point number and advances str past the end
// of the parsed input.
double strtod(const char*& str) const {
char* end = nullptr;
double result = strtod_l(str, &end, locale_);
str = end;
return result;
}
};
using Locale FMT_DEPRECATED_ALIAS = locale;
#endif // FMT_LOCALE
FMT_END_NAMESPACE
#endif // FMT_OS_H_

177
vendor/Fmt/include/fmt/ostream.h vendored Normal file
View File

@ -0,0 +1,177 @@
// Formatting library for C++ - std::ostream support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include <ostream>
#include "format.h"
FMT_BEGIN_NAMESPACE
template <typename Char> class basic_printf_parse_context;
template <typename OutputIt, typename Char> class basic_printf_context;
namespace detail {
template <class Char> class formatbuf : public std::basic_streambuf<Char> {
private:
using int_type = typename std::basic_streambuf<Char>::int_type;
using traits_type = typename std::basic_streambuf<Char>::traits_type;
buffer<Char>& buffer_;
public:
formatbuf(buffer<Char>& buf) : buffer_(buf) {}
protected:
// The put-area is actually always empty. This makes the implementation
// simpler and has the advantage that the streambuf and the buffer are always
// in sync and sputc never writes into uninitialized memory. The obvious
// disadvantage is that each call to sputc always results in a (virtual) call
// to overflow. There is no disadvantage here for sputn since this always
// results in a call to xsputn.
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
if (!traits_type::eq_int_type(ch, traits_type::eof()))
buffer_.push_back(static_cast<Char>(ch));
return ch;
}
std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE {
buffer_.append(s, s + count);
return count;
}
};
struct converter {
template <typename T, FMT_ENABLE_IF(is_integral<T>::value)> converter(T);
};
template <typename Char> struct test_stream : std::basic_ostream<Char> {
private:
void_t<> operator<<(converter);
};
// Hide insertion operators for built-in types.
template <typename Char, typename Traits>
void_t<> operator<<(std::basic_ostream<Char, Traits>&, Char);
template <typename Char, typename Traits>
void_t<> operator<<(std::basic_ostream<Char, Traits>&, char);
template <typename Traits>
void_t<> operator<<(std::basic_ostream<char, Traits>&, char);
template <typename Traits>
void_t<> operator<<(std::basic_ostream<char, Traits>&, signed char);
template <typename Traits>
void_t<> operator<<(std::basic_ostream<char, Traits>&, unsigned char);
// Checks if T has a user-defined operator<< (e.g. not a member of
// std::ostream).
template <typename T, typename Char> class is_streamable {
private:
template <typename U>
static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
<< std::declval<U>()),
void_t<>>::value>
test(int);
template <typename> static std::false_type test(...);
using result = decltype(test<T>(0));
public:
static const bool value = result::value;
};
// Write the content of buf to os.
template <typename Char>
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
const Char* buf_data = buf.data();
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
unsigned_streamsize size = buf.size();
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
do {
unsigned_streamsize n = size <= max_size ? size : max_size;
os.write(buf_data, static_cast<std::streamsize>(n));
buf_data += n;
size -= n;
} while (size != 0);
}
template <typename Char, typename T>
void format_value(buffer<Char>& buf, const T& value,
locale_ref loc = locale_ref()) {
formatbuf<Char> format_buf(buf);
std::basic_ostream<Char> output(&format_buf);
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
if (loc) output.imbue(loc.get<std::locale>());
#endif
output << value;
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
buf.try_resize(buf.size());
}
// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
: private formatter<basic_string_view<Char>, Char> {
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
return formatter<basic_string_view<Char>, Char>::parse(ctx);
}
template <typename ParseCtx,
FMT_ENABLE_IF(std::is_same<
ParseCtx, basic_printf_parse_context<Char>>::value)>
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename OutputIt>
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
-> OutputIt {
basic_memory_buffer<Char> buffer;
format_value(buffer, value, ctx.locale());
basic_string_view<Char> str(buffer.data(), buffer.size());
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
}
template <typename OutputIt>
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
-> OutputIt {
basic_memory_buffer<Char> buffer;
format_value(buffer, value, ctx.locale());
return std::copy(buffer.begin(), buffer.end(), ctx.out());
}
};
} // namespace detail
template <typename Char>
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
detail::vformat_to(buffer, format_str, args);
detail::write_buffer(os, buffer);
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fmt::print(cerr, "Don't {}!", "panic");
\endrst
*/
template <typename S, typename... Args,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
vprint(os, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
FMT_END_NAMESPACE
#endif // FMT_OSTREAM_H_

2
vendor/Fmt/include/fmt/posix.h vendored Normal file
View File

@ -0,0 +1,2 @@
#include "os.h"
#warning "fmt/posix.h is deprecated; use fmt/os.h instead"

751
vendor/Fmt/include/fmt/printf.h vendored Normal file
View File

@ -0,0 +1,751 @@
// Formatting library for C++ - legacy printf implementation
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_
#include <algorithm> // std::max
#include <limits> // std::numeric_limits
#include "ostream.h"
FMT_BEGIN_NAMESPACE
namespace detail {
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned> struct int_checker {
template <typename T> static bool fits_in_int(T value) {
unsigned max = max_value<int>();
return value <= max;
}
static bool fits_in_int(bool) { return true; }
};
template <> struct int_checker<true> {
template <typename T> static bool fits_in_int(T value) {
return value >= (std::numeric_limits<int>::min)() &&
value <= max_value<int>();
}
static bool fits_in_int(int) { return true; }
};
class printf_precision_handler {
public:
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
int operator()(T value) {
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(format_error("number is too big"));
return (std::max)(static_cast<int>(value), 0);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
int operator()(T) {
FMT_THROW(format_error("precision is not integer"));
return 0;
}
};
// An argument visitor that returns true iff arg is a zero integer.
class is_zero_int {
public:
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
bool operator()(T value) {
return value == 0;
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
bool operator()(T) {
return false;
}
};
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
template <typename T, typename Context> class arg_converter {
private:
using char_type = typename Context::char_type;
basic_format_arg<Context>& arg_;
char_type type_;
public:
arg_converter(basic_format_arg<Context>& arg, char_type type)
: arg_(arg), type_(type) {}
void operator()(bool value) {
if (type_ != 's') operator()<bool>(value);
}
template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
void operator()(U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
if (const_check(sizeof(target_type) <= sizeof(int))) {
// Extra casts are used to silence warnings.
if (is_signed) {
arg_ = detail::make_arg<Context>(
static_cast<int>(static_cast<target_type>(value)));
} else {
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
arg_ = detail::make_arg<Context>(
static_cast<unsigned>(static_cast<unsigned_type>(value)));
}
} else {
if (is_signed) {
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
arg_ = detail::make_arg<Context>(static_cast<long long>(value));
} else {
arg_ = detail::make_arg<Context>(
static_cast<typename make_unsigned_or_bool<U>::type>(value));
}
}
}
template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
void operator()(U) {} // No conversion needed for non-integral types.
};
// Converts an integer argument to T for printf, if T is an integral type.
// If T is void, the argument is converted to corresponding signed or unsigned
// type depending on the type specifier: 'd' and 'i' - signed, other -
// unsigned).
template <typename T, typename Context, typename Char>
void convert_arg(basic_format_arg<Context>& arg, Char type) {
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
}
// Converts an integer argument to char for printf.
template <typename Context> class char_converter {
private:
basic_format_arg<Context>& arg_;
public:
explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
void operator()(T value) {
arg_ = detail::make_arg<Context>(
static_cast<typename Context::char_type>(value));
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
void operator()(T) {} // No conversion needed for non-integral types.
};
// An argument visitor that return a pointer to a C string if argument is a
// string or null otherwise.
template <typename Char> struct get_cstring {
template <typename T> const Char* operator()(T) { return nullptr; }
const Char* operator()(const Char* s) { return s; }
};
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char> class printf_width_handler {
private:
using format_specs = basic_format_specs<Char>;
format_specs& specs_;
public:
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
unsigned operator()(T value) {
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
if (detail::is_negative(value)) {
specs_.align = align::left;
width = 0 - width;
}
unsigned int_max = max_value<int>();
if (width > int_max) FMT_THROW(format_error("number is too big"));
return static_cast<unsigned>(width);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
unsigned operator()(T) {
FMT_THROW(format_error("width is not integer"));
return 0;
}
};
template <typename Char, typename Context>
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
basic_format_args<Context> args) {
Context(buffer_appender<Char>(buf), format, args).format();
}
} // namespace detail
// For printing into memory_buffer.
template <typename Char, typename Context>
FMT_DEPRECATED void printf(detail::buffer<Char>& buf,
basic_string_view<Char> format,
basic_format_args<Context> args) {
return detail::vprintf(buf, format, args);
}
using detail::vprintf;
template <typename Char>
class basic_printf_parse_context : public basic_format_parse_context<Char> {
using basic_format_parse_context<Char>::basic_format_parse_context;
};
template <typename OutputIt, typename Char> class basic_printf_context;
/**
\rst
The ``printf`` argument formatter.
\endrst
*/
template <typename OutputIt, typename Char>
class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
public:
using iterator = OutputIt;
private:
using char_type = Char;
using base = detail::arg_formatter_base<OutputIt, Char>;
using context_type = basic_printf_context<OutputIt, Char>;
context_type& context_;
void write_null_pointer(char) {
this->specs()->type = 0;
this->write("(nil)");
}
void write_null_pointer(wchar_t) {
this->specs()->type = 0;
this->write(L"(nil)");
}
public:
using format_specs = typename base::format_specs;
/**
\rst
Constructs an argument formatter object.
*buffer* is a reference to the output buffer and *specs* contains format
specifier information for standard argument types.
\endrst
*/
printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
: base(iter, &specs, detail::locale_ref()), context_(ctx) {}
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integral<T>::value)>
iterator operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if (std::is_same<T, bool>::value) {
format_specs& fmt_specs = *this->specs();
if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
fmt_specs.type = 0;
this->write(value != 0);
} else if (std::is_same<T, char_type>::value) {
format_specs& fmt_specs = *this->specs();
if (fmt_specs.type && fmt_specs.type != 'c')
return (*this)(static_cast<int>(value));
fmt_specs.sign = sign::none;
fmt_specs.alt = false;
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
// align::numeric needs to be overwritten here since the '0' flag is
// ignored for non-numeric types
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
fmt_specs.align = align::right;
return base::operator()(value);
} else {
return base::operator()(value);
}
return this->out();
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
iterator operator()(T value) {
return base::operator()(value);
}
/** Formats a null-terminated C string. */
iterator operator()(const char* value) {
if (value)
base::operator()(value);
else if (this->specs()->type == 'p')
write_null_pointer(char_type());
else
this->write("(null)");
return this->out();
}
/** Formats a null-terminated wide C string. */
iterator operator()(const wchar_t* value) {
if (value)
base::operator()(value);
else if (this->specs()->type == 'p')
write_null_pointer(char_type());
else
this->write(L"(null)");
return this->out();
}
iterator operator()(basic_string_view<char_type> value) {
return base::operator()(value);
}
iterator operator()(monostate value) { return base::operator()(value); }
/** Formats a pointer. */
iterator operator()(const void* value) {
if (value) return base::operator()(value);
this->specs()->type = 0;
write_null_pointer(char_type());
return this->out();
}
/** Formats an argument of a custom (user-defined) type. */
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
handle.format(context_.parse_context(), context_);
return this->out();
}
};
template <typename T> struct printf_formatter {
printf_formatter() = delete;
template <typename ParseContext>
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
detail::format_value(detail::get_container(ctx.out()), value);
return ctx.out();
}
};
/**
This template formats data and writes the output through an output iterator.
*/
template <typename OutputIt, typename Char> class basic_printf_context {
public:
/** The character type for the output. */
using char_type = Char;
using iterator = OutputIt;
using format_arg = basic_format_arg<basic_printf_context>;
using parse_context_type = basic_printf_parse_context<Char>;
template <typename T> using formatter_type = printf_formatter<T>;
private:
using format_specs = basic_format_specs<char_type>;
OutputIt out_;
basic_format_args<basic_printf_context> args_;
parse_context_type parse_ctx_;
static void parse_flags(format_specs& specs, const Char*& it,
const Char* end);
// Returns the argument with specified index or, if arg_index is -1, the next
// argument.
format_arg get_arg(int arg_index = -1);
// Parses argument index, flags and width and returns the argument index.
int parse_header(const Char*& it, const Char* end, format_specs& specs);
public:
/**
\rst
Constructs a ``printf_context`` object. References to the arguments are
stored in the context object so make sure they have appropriate lifetimes.
\endrst
*/
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
basic_format_args<basic_printf_context> args)
: out_(out), args_(args), parse_ctx_(format_str) {}
OutputIt out() { return out_; }
void advance_to(OutputIt it) { out_ = it; }
detail::locale_ref locale() { return {}; }
format_arg arg(int id) const { return args_.get(id); }
parse_context_type& parse_context() { return parse_ctx_; }
FMT_CONSTEXPR void on_error(const char* message) {
parse_ctx_.on_error(message);
}
/** Formats stored arguments and writes the output to the range. */
template <typename ArgFormatter = printf_arg_formatter<OutputIt, Char>>
OutputIt format();
};
template <typename OutputIt, typename Char>
void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
const Char*& it,
const Char* end) {
for (; it != end; ++it) {
switch (*it) {
case '-':
specs.align = align::left;
break;
case '+':
specs.sign = sign::plus;
break;
case '0':
specs.fill[0] = '0';
break;
case ' ':
if (specs.sign != sign::plus) {
specs.sign = sign::space;
}
break;
case '#':
specs.alt = true;
break;
default:
return;
}
}
}
template <typename OutputIt, typename Char>
typename basic_printf_context<OutputIt, Char>::format_arg
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
if (arg_index < 0)
arg_index = parse_ctx_.next_arg_id();
else
parse_ctx_.check_arg_id(--arg_index);
return detail::get_arg(*this, arg_index);
}
template <typename OutputIt, typename Char>
int basic_printf_context<OutputIt, Char>::parse_header(const Char*& it,
const Char* end,
format_specs& specs) {
int arg_index = -1;
char_type c = *it;
if (c >= '0' && c <= '9') {
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
detail::error_handler eh;
int value = parse_nonnegative_int(it, end, eh);
if (it != end && *it == '$') { // value is an argument index
++it;
arg_index = value;
} else {
if (c == '0') specs.fill[0] = '0';
if (value != 0) {
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
specs.width = value;
return arg_index;
}
}
}
parse_flags(specs, it, end);
// Parse width.
if (it != end) {
if (*it >= '0' && *it <= '9') {
detail::error_handler eh;
specs.width = parse_nonnegative_int(it, end, eh);
} else if (*it == '*') {
++it;
specs.width = static_cast<int>(visit_format_arg(
detail::printf_width_handler<char_type>(specs), get_arg()));
}
}
return arg_index;
}
template <typename OutputIt, typename Char>
template <typename ArgFormatter>
OutputIt basic_printf_context<OutputIt, Char>::format() {
auto out = this->out();
const Char* start = parse_ctx_.begin();
const Char* end = parse_ctx_.end();
auto it = start;
while (it != end) {
char_type c = *it++;
if (c != '%') continue;
if (it != end && *it == c) {
out = std::copy(start, it, out);
start = ++it;
continue;
}
out = std::copy(start, it - 1, out);
format_specs specs;
specs.align = align::right;
// Parse argument index, flags and width.
int arg_index = parse_header(it, end, specs);
if (arg_index == 0) on_error("argument not found");
// Parse precision.
if (it != end && *it == '.') {
++it;
c = it != end ? *it : 0;
if ('0' <= c && c <= '9') {
detail::error_handler eh;
specs.precision = parse_nonnegative_int(it, end, eh);
} else if (c == '*') {
++it;
specs.precision = static_cast<int>(
visit_format_arg(detail::printf_precision_handler(), get_arg()));
} else {
specs.precision = 0;
}
}
format_arg arg = get_arg(arg_index);
// For d, i, o, u, x, and X conversion specifiers, if a precision is
// specified, the '0' flag is ignored
if (specs.precision >= 0 && arg.is_integral())
specs.fill[0] =
' '; // Ignore '0' flag for non-numeric types or if '-' present.
if (specs.precision >= 0 && arg.type() == detail::type::cstring_type) {
auto str = visit_format_arg(detail::get_cstring<Char>(), arg);
auto str_end = str + specs.precision;
auto nul = std::find(str, str_end, Char());
arg = detail::make_arg<basic_printf_context>(basic_string_view<Char>(
str,
detail::to_unsigned(nul != str_end ? nul - str : specs.precision)));
}
if (specs.alt && visit_format_arg(detail::is_zero_int(), arg))
specs.alt = false;
if (specs.fill[0] == '0') {
if (arg.is_arithmetic() && specs.align != align::left)
specs.align = align::numeric;
else
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
// flag is also present.
}
// Parse length and convert the argument to the required type.
c = it != end ? *it++ : 0;
char_type t = it != end ? *it : 0;
using detail::convert_arg;
switch (c) {
case 'h':
if (t == 'h') {
++it;
t = it != end ? *it : 0;
convert_arg<signed char>(arg, t);
} else {
convert_arg<short>(arg, t);
}
break;
case 'l':
if (t == 'l') {
++it;
t = it != end ? *it : 0;
convert_arg<long long>(arg, t);
} else {
convert_arg<long>(arg, t);
}
break;
case 'j':
convert_arg<intmax_t>(arg, t);
break;
case 'z':
convert_arg<size_t>(arg, t);
break;
case 't':
convert_arg<std::ptrdiff_t>(arg, t);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--it;
convert_arg<void>(arg, c);
}
// Parse type.
if (it == end) FMT_THROW(format_error("invalid format string"));
specs.type = static_cast<char>(*it++);
if (arg.is_integral()) {
// Normalize type.
switch (specs.type) {
case 'i':
case 'u':
specs.type = 'd';
break;
case 'c':
visit_format_arg(detail::char_converter<basic_printf_context>(arg),
arg);
break;
}
}
start = it;
// Format argument.
out = visit_format_arg(ArgFormatter(out, specs, *this), arg);
}
return std::copy(start, it, out);
}
template <typename Char>
using basic_printf_context_t =
basic_printf_context<detail::buffer_appender<Char>, Char>;
using printf_context = basic_printf_context_t<char>;
using wprintf_context = basic_printf_context_t<wchar_t>;
using printf_args = basic_format_args<printf_context>;
using wprintf_args = basic_format_args<wprintf_context>;
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::printf_args`.
\endrst
*/
template <typename... Args>
inline format_arg_store<printf_context, Args...> make_printf_args(
const Args&... args) {
return {args...};
}
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::wprintf_args`.
\endrst
*/
template <typename... Args>
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
const Args&... args) {
return {args...};
}
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vsprintf(
const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(format), args);
return to_string(buffer);
}
/**
\rst
Formats arguments and returns the result as a string.
**Example**::
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
*/
template <typename S, typename... Args,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
using context = basic_printf_context_t<Char>;
return vsprintf(to_string_view(format), make_format_args<context>(args...));
}
template <typename S, typename Char = char_t<S>>
inline int vfprintf(
std::FILE* f, const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(format), args);
size_t size = buffer.size();
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
? -1
: static_cast<int>(size);
}
/**
\rst
Prints formatted data to the file *f*.
**Example**::
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
*/
template <typename S, typename... Args,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
using context = basic_printf_context_t<Char>;
return vfprintf(f, to_string_view(format),
make_format_args<context>(args...));
}
template <typename S, typename Char = char_t<S>>
inline int vprintf(
const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
return vfprintf(stdout, to_string_view(format), args);
}
/**
\rst
Prints formatted data to ``stdout``.
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
inline int printf(const S& format_str, const Args&... args) {
using context = basic_printf_context_t<char_t<S>>;
return vprintf(to_string_view(format_str),
make_format_args<context>(args...));
}
template <typename S, typename Char = char_t<S>>
inline int vfprintf(
std::basic_ostream<Char>& os, const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(format), args);
detail::write_buffer(os, buffer);
return static_cast<int>(buffer.size());
}
/** Formats arguments and writes the output to the range. */
template <typename ArgFormatter, typename Char,
typename Context =
basic_printf_context<typename ArgFormatter::iterator, Char>>
typename ArgFormatter::iterator vprintf(
detail::buffer<Char>& out, basic_string_view<Char> format_str,
basic_format_args<type_identity_t<Context>> args) {
typename ArgFormatter::iterator iter(out);
Context(iter, format_str, args).template format<ArgFormatter>();
return iter;
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fmt::fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
template <typename S, typename... Args, typename Char = char_t<S>>
inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
const Args&... args) {
using context = basic_printf_context_t<Char>;
return vfprintf(os, to_string_view(format_str),
make_format_args<context>(args...));
}
FMT_END_NAMESPACE
#endif // FMT_PRINTF_H_

396
vendor/Fmt/include/fmt/ranges.h vendored Normal file
View File

@ -0,0 +1,396 @@
// Formatting library for C++ - experimental range support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
//
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
// All Rights Reserved
// {fmt} support for ranges, containers and types tuple interface.
#ifndef FMT_RANGES_H_
#define FMT_RANGES_H_
#include <initializer_list>
#include <type_traits>
#include "format.h"
// output only up to N items from the range.
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
#endif
FMT_BEGIN_NAMESPACE
template <typename Char> struct formatting_base {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
};
template <typename Char, typename Enable = void>
struct formatting_range : formatting_base<Char> {
static FMT_CONSTEXPR_DECL const size_t range_length_limit =
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the
// range.
Char prefix;
Char delimiter;
Char postfix;
formatting_range() : prefix('{'), delimiter(','), postfix('}') {}
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
};
template <typename Char, typename Enable = void>
struct formatting_tuple : formatting_base<Char> {
Char prefix;
Char delimiter;
Char postfix;
formatting_tuple() : prefix('('), delimiter(','), postfix(')') {}
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
};
namespace detail {
template <typename RangeT, typename OutputIterator>
OutputIterator copy(const RangeT& range, OutputIterator out) {
for (auto it = range.begin(), end = range.end(); it != end; ++it)
*out++ = *it;
return out;
}
template <typename OutputIterator>
OutputIterator copy(const char* str, OutputIterator out) {
while (*str) *out++ = *str++;
return out;
}
template <typename OutputIterator>
OutputIterator copy(char ch, OutputIterator out) {
*out++ = ch;
return out;
}
/// Return true value if T has std::string interface, like std::string_view.
template <typename T> class is_like_std_string {
template <typename U>
static auto check(U* p)
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
template <typename> static void check(...);
public:
static FMT_CONSTEXPR_DECL const bool value =
is_string<T>::value || !std::is_void<decltype(check<T>(nullptr))>::value;
};
template <typename Char>
struct is_like_std_string<fmt::basic_string_view<Char>> : std::true_type {};
template <typename... Ts> struct conditional_helper {};
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
template <typename T>
struct is_range_<
T, conditional_t<false,
conditional_helper<decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>,
void>> : std::true_type {};
#endif
/// tuple_size and tuple_element check.
template <typename T> class is_tuple_like_ {
template <typename U>
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
template <typename> static void check(...);
public:
static FMT_CONSTEXPR_DECL const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value;
};
// Check for integer_sequence
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900
template <typename T, T... N>
using integer_sequence = std::integer_sequence<T, N...>;
template <size_t... N> using index_sequence = std::index_sequence<N...>;
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
#else
template <typename T, T... N> struct integer_sequence {
using value_type = T;
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
};
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
template <typename T, size_t N, T... Ns>
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
template <typename T, T... Ns>
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
template <size_t N>
using make_index_sequence = make_integer_sequence<size_t, N>;
#endif
template <class Tuple, class F, size_t... Is>
void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) FMT_NOEXCEPT {
using std::get;
// using free function get<I>(T) now.
const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
(void)_; // blocks warnings
}
template <class T>
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
T const&) {
return {};
}
template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) {
const auto indexes = get_indexes(tup);
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
}
template <typename Range>
using value_type = remove_cvref_t<decltype(*std::declval<Range>().begin())>;
template <typename Arg, FMT_ENABLE_IF(!is_like_std_string<
typename std::decay<Arg>::type>::value)>
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
return add_space ? " {}" : "{}";
}
template <typename Arg, FMT_ENABLE_IF(is_like_std_string<
typename std::decay<Arg>::type>::value)>
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
return add_space ? " \"{}\"" : "\"{}\"";
}
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) {
return add_space ? " \"{}\"" : "\"{}\"";
}
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
return add_space ? L" \"{}\"" : L"\"{}\"";
}
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) {
return add_space ? " '{}'" : "'{}'";
}
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
return add_space ? L" '{}'" : L"'{}'";
}
} // namespace detail
template <typename T> struct is_tuple_like {
static FMT_CONSTEXPR_DECL const bool value =
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
};
template <typename TupleT, typename Char>
struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
private:
// C++11 generic lambda for format()
template <typename FormatContext> struct format_each {
template <typename T> void operator()(const T& v) {
if (i > 0) {
if (formatting.add_prepostfix_space) {
*out++ = ' ';
}
out = detail::copy(formatting.delimiter, out);
}
out = format_to(out,
detail::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), v),
v);
++i;
}
formatting_tuple<Char>& formatting;
size_t& i;
typename std::add_lvalue_reference<decltype(
std::declval<FormatContext>().out())>::type out;
};
public:
formatting_tuple<Char> formatting;
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return formatting.parse(ctx);
}
template <typename FormatContext = format_context>
auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) {
auto out = ctx.out();
size_t i = 0;
detail::copy(formatting.prefix, out);
detail::for_each(values, format_each<FormatContext>{formatting, i, out});
if (formatting.add_prepostfix_space) {
*out++ = ' ';
}
detail::copy(formatting.postfix, out);
return ctx.out();
}
};
template <typename T, typename Char> struct is_range {
static FMT_CONSTEXPR_DECL const bool value =
detail::is_range_<T>::value && !detail::is_like_std_string<T>::value &&
!std::is_convertible<T, std::basic_string<Char>>::value &&
!std::is_constructible<detail::std_string_view<Char>, T>::value;
};
template <typename T, typename Char>
struct formatter<
T, Char,
enable_if_t<fmt::is_range<T, Char>::value
// Workaround a bug in MSVC 2017 and earlier.
#if !FMT_MSC_VER || FMT_MSC_VER >= 1927
&&
(has_formatter<detail::value_type<T>, format_context>::value ||
detail::has_fallback_formatter<detail::value_type<T>,
format_context>::value)
#endif
>> {
formatting_range<Char> formatting;
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return formatting.parse(ctx);
}
template <typename FormatContext>
typename FormatContext::iterator format(const T& values, FormatContext& ctx) {
auto out = detail::copy(formatting.prefix, ctx.out());
size_t i = 0;
auto it = values.begin();
auto end = values.end();
for (; it != end; ++it) {
if (i > 0) {
if (formatting.add_prepostfix_space) *out++ = ' ';
out = detail::copy(formatting.delimiter, out);
}
out = format_to(out,
detail::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), *it),
*it);
if (++i > formatting.range_length_limit) {
out = format_to(out, " ... <other elements>");
break;
}
}
if (formatting.add_prepostfix_space) *out++ = ' ';
return detail::copy(formatting.postfix, out);
}
};
template <typename Char, typename... T> struct tuple_arg_join : detail::view {
const std::tuple<T...>& tuple;
basic_string_view<Char> sep;
tuple_arg_join(const std::tuple<T...>& t, basic_string_view<Char> s)
: tuple{t}, sep{s} {}
};
template <typename Char, typename... T>
struct formatter<tuple_arg_join<Char, T...>, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
typename FormatContext::iterator format(
const tuple_arg_join<Char, T...>& value, FormatContext& ctx) {
return format(value, ctx, detail::make_index_sequence<sizeof...(T)>{});
}
private:
template <typename FormatContext, size_t... N>
typename FormatContext::iterator format(
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
detail::index_sequence<N...>) {
return format_args(value, ctx, std::get<N>(value.tuple)...);
}
template <typename FormatContext>
typename FormatContext::iterator format_args(
const tuple_arg_join<Char, T...>&, FormatContext& ctx) {
// NOTE: for compilers that support C++17, this empty function instantiation
// can be replaced with a constexpr branch in the variadic overload.
return ctx.out();
}
template <typename FormatContext, typename Arg, typename... Args>
typename FormatContext::iterator format_args(
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
const Arg& arg, const Args&... args) {
using base = formatter<typename std::decay<Arg>::type, Char>;
auto out = ctx.out();
out = base{}.format(arg, ctx);
if (sizeof...(Args) > 0) {
out = std::copy(value.sep.begin(), value.sep.end(), out);
ctx.advance_to(out);
return format_args(value, ctx, args...);
}
return out;
}
};
/**
\rst
Returns an object that formats `tuple` with elements separated by `sep`.
**Example**::
std::tuple<int, char> t = {1, 'a'};
fmt::print("{}", fmt::join(t, ", "));
// Output: "1, a"
\endrst
*/
template <typename... T>
FMT_CONSTEXPR tuple_arg_join<char, T...> join(const std::tuple<T...>& tuple,
string_view sep) {
return {tuple, sep};
}
template <typename... T>
FMT_CONSTEXPR tuple_arg_join<wchar_t, T...> join(const std::tuple<T...>& tuple,
wstring_view sep) {
return {tuple, sep};
}
/**
\rst
Returns an object that formats `initializer_list` with elements separated by
`sep`.
**Example**::
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
// Output: "1, 2, 3"
\endrst
*/
template <typename T>
arg_join<const T*, const T*, char> join(std::initializer_list<T> list,
string_view sep) {
return join(std::begin(list), std::end(list), sep);
}
template <typename T>
arg_join<const T*, const T*, wchar_t> join(std::initializer_list<T> list,
wstring_view sep) {
return join(std::begin(list), std::end(list), sep);
}
FMT_END_NAMESPACE
#endif // FMT_RANGES_H_

322
vendor/Fmt/os.cc vendored Normal file
View File

@ -0,0 +1,322 @@
// Formatting library for C++ - optional OS-specific functionality
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
// Disable bogus MSVC warnings.
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "fmt/os.h"
#include <climits>
#if FMT_USE_FCNTL
# include <sys/stat.h>
# include <sys/types.h>
# ifndef _WIN32
# include <unistd.h>
# else
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <io.h>
# include <windows.h>
# define O_CREAT _O_CREAT
# define O_TRUNC _O_TRUNC
# ifndef S_IRUSR
# define S_IRUSR _S_IREAD
# endif
# ifndef S_IWUSR
# define S_IWUSR _S_IWRITE
# endif
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
# endif
# endif // _WIN32
#endif // FMT_USE_FCNTL
#ifdef _WIN32
# include <windows.h>
#endif
#ifdef fileno
# undef fileno
#endif
namespace {
#ifdef _WIN32
// Return type of read and write functions.
using RWResult = int;
// On Windows the count argument to read and write is unsigned, so convert
// it from size_t preventing integer overflow.
inline unsigned convert_rwcount(std::size_t count) {
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
}
#elif FMT_USE_FCNTL
// Return type of read and write functions.
using RWResult = ssize_t;
inline std::size_t convert_rwcount(std::size_t count) { return count; }
#endif
} // namespace
FMT_BEGIN_NAMESPACE
#ifdef _WIN32
detail::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
if (int error_code = convert(s)) {
FMT_THROW(windows_error(error_code,
"cannot convert string from UTF-16 to UTF-8"));
}
}
int detail::utf16_to_utf8::convert(wstring_view s) {
if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER;
int s_size = static_cast<int>(s.size());
if (s_size == 0) {
// WideCharToMultiByte does not support zero length, handle separately.
buffer_.resize(1);
buffer_[0] = 0;
return 0;
}
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0,
nullptr, nullptr);
if (length == 0) return GetLastError();
buffer_.resize(length + 1);
length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0],
length, nullptr, nullptr);
if (length == 0) return GetLastError();
buffer_[length] = 0;
return 0;
}
void windows_error::init(int err_code, string_view format_str,
format_args args) {
error_code_ = err_code;
memory_buffer buffer;
detail::format_windows_error(buffer, err_code, vformat(format_str, args));
std::runtime_error& base = *this;
base = std::runtime_error(to_string(buffer));
}
void detail::format_windows_error(detail::buffer<char>& out, int error_code,
string_view message) FMT_NOEXCEPT {
FMT_TRY {
wmemory_buffer buf;
buf.resize(inline_buffer_size);
for (;;) {
wchar_t* system_message = &buf[0];
int result = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message,
static_cast<uint32_t>(buf.size()), nullptr);
if (result != 0) {
utf16_to_utf8 utf8_message;
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
format_to(buffer_appender<char>(out), "{}: {}", message,
utf8_message);
return;
}
break;
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break; // Can't get error message, report error code instead.
buf.resize(buf.size() * 2);
}
}
FMT_CATCH(...) {}
format_error_code(out, error_code, message);
}
void report_windows_error(int error_code,
fmt::string_view message) FMT_NOEXCEPT {
report_error(detail::format_windows_error, error_code, message);
}
#endif // _WIN32
buffered_file::~buffered_file() FMT_NOEXCEPT {
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
report_system_error(errno, "cannot close file");
}
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),
nullptr);
if (!file_)
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
}
void buffered_file::close() {
if (!file_) return;
int result = FMT_SYSTEM(fclose(file_));
file_ = nullptr;
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
}
// A macro used to prevent expansion of fileno on broken versions of MinGW.
#define FMT_ARGS
int buffered_file::fileno() const {
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor"));
return fd;
}
#if FMT_USE_FCNTL
file::file(cstring_view path, int oflag) {
int mode = S_IRUSR | S_IWUSR;
# if defined(_WIN32) && !defined(__MINGW32__)
fd_ = -1;
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
# else
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
# endif
if (fd_ == -1)
FMT_THROW(system_error(errno, "cannot open file {}", path.c_str()));
}
file::~file() FMT_NOEXCEPT {
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
report_system_error(errno, "cannot close file");
}
void file::close() {
if (fd_ == -1) return;
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
int result = FMT_POSIX_CALL(close(fd_));
fd_ = -1;
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
}
long long file::size() const {
# ifdef _WIN32
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
// is less than 0x0500 as is the case with some default MinGW builds.
// Both functions support large file sizes.
DWORD size_upper = 0;
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
if (size_lower == INVALID_FILE_SIZE) {
DWORD error = GetLastError();
if (error != NO_ERROR)
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
}
unsigned long long long_size = size_upper;
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
# else
using Stat = struct stat;
Stat file_stat = Stat();
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
FMT_THROW(system_error(errno, "cannot get file attributes"));
static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
"return type of file::size is not large enough");
return file_stat.st_size;
# endif
}
std::size_t file::read(void* buffer, std::size_t count) {
RWResult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
if (result < 0) FMT_THROW(system_error(errno, "cannot read from file"));
return detail::to_unsigned(result);
}
std::size_t file::write(const void* buffer, std::size_t count) {
RWResult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
return detail::to_unsigned(result);
}
file file::dup(int fd) {
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
int new_fd = FMT_POSIX_CALL(dup(fd));
if (new_fd == -1)
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd));
return file(new_fd);
}
void file::dup2(int fd) {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) {
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {} to {}",
fd_, fd));
}
}
void file::dup2(int fd, error_code& ec) FMT_NOEXCEPT {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) ec = error_code(errno);
}
void file::pipe(file& read_end, file& write_end) {
// Close the descriptors first to make sure that assignments don't throw
// and there are no leaks.
read_end.close();
write_end.close();
int fds[2] = {};
# ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
# else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
# endif
if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe"));
// The following assignments don't throw because read_fd and write_fd
// are closed.
read_end = file(fds[0]);
write_end = file(fds[1]);
}
buffered_file file::fdopen(const char* mode) {
// Don't retry as fdopen doesn't return EINTR.
# if defined(__MINGW32__) && defined(_POSIX_)
FILE* f = ::fdopen(fd_, mode);
# else
FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));
# endif
if (!f)
FMT_THROW(
system_error(errno, "cannot associate stream with file descriptor"));
buffered_file bf(f);
fd_ = -1;
return bf;
}
long getpagesize() {
# ifdef _WIN32
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
# else
long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size"));
return size;
# endif
}
FMT_API void ostream::grow(size_t) {
if (this->size() == this->capacity()) flush();
}
#endif // FMT_USE_FCNTL
FMT_END_NAMESPACE

View File

@ -0,0 +1,16 @@
vc.project.guid = 9866EE28-0612-4746-BD35-3B15B0AF7267
vc.project.name = ApacheConnector
vc.project.target = mod_poco
vc.project.type = library
vc.project.pocobase = ..
vc.project.outdir = ${vc.project.pocobase}
vc.project.platforms = Win32
vc.project.configurations = debug_shared, release_shared
vc.project.prototype = ApacheConnector_vs90.vcproj
vc.project.compiler.include = ..\\Foundation\\include;..\\Net\\include;..\\Util\\include
vc.project.compiler.defines =
vc.project.compiler.defines.shared = ApacheHandlers_EXPORTS
vc.project.compiler.defines.debug_shared = ${vc.project.compiler.defines.shared}
vc.project.compiler.defines.release_shared = ${vc.project.compiler.defines.shared}
vc.project.linker.dependencies.Win32 = libapr-1.lib libaprutil-1.lib libhttpd.lib
vc.solution.create = true

View File

@ -0,0 +1,29 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApacheConnector", "ApacheConnector_vs140.vcxproj", "{9866EE28-0612-4746-BD35-3B15B0AF7267}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug_shared|Win32 = debug_shared|Win32
release_shared|Win32 = release_shared|Win32
debug_shared|x64 = debug_shared|x64
release_shared|x64 = release_shared|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Build.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.ActiveCfg = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Build.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Deploy.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.ActiveCfg = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.Build.0 = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.Deploy.0 = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.ActiveCfg = release_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.Build.0 = release_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.Deploy.0 = release_shared|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|Win32">
<Configuration>debug_shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="debug_shared|x64">
<Configuration>debug_shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release_shared|Win32">
<Configuration>release_shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release_shared|x64">
<Configuration>release_shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>ApacheConnector</ProjectName>
<ProjectGuid>{9866EE28-0612-4746-BD35-3B15B0AF7267}</ProjectGuid>
<RootNamespace>ApacheConnector</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup>
<_ProjectFileVersion>14.0.25420.1</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">mod_pocod</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">mod_poco</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">mod_pocod</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">mod_poco</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">
<OutDir>..\bin\</OutDir>
<IntDir>obj\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">
<OutDir>..\bin\</OutDir>
<IntDir>obj\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
<OutDir>..\bin64\</OutDir>
<IntDir>obj64\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">
<OutDir>..\bin64\</OutDir>
<IntDir>obj64\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin\mod_pocod.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>..\bin\mod_pocod.pdb</ProgramDatabaseFile>
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<ImportLibrary>..\lib\mod_pocod.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin\mod_poco.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>..\lib\mod_poco.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin64\mod_poco64d.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>..\bin64\mod_poco64d.pdb</ProgramDatabaseFile>
<AdditionalLibraryDirectories>..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<ImportLibrary>..\lib64\mod_pocod.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin64\mod_poco64.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>..\lib64\mod_poco.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="include\ApacheApplication.h"/>
<ClInclude Include="include\ApacheChannel.h"/>
<ClInclude Include="include\ApacheConnector.h"/>
<ClInclude Include="include\ApacheRequestHandlerFactory.h"/>
<ClInclude Include="include\ApacheServerRequest.h"/>
<ClInclude Include="include\ApacheServerResponse.h"/>
<ClInclude Include="include\ApacheStream.h"/>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ApacheApplication.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheChannel.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheConnector.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheRequestHandlerFactory.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheServerRequest.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheServerResponse.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheStream.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{419721b6-82b6-4fbd-9374-ef113ad9af72}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{3646e19a-54e9-4d20-8dc8-713beed72f4d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\ApacheApplication.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheChannel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheConnector.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheRequestHandlerFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheServerRequest.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheServerResponse.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheStream.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ApacheApplication.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheChannel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheConnector.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheRequestHandlerFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheServerRequest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheServerResponse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,29 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApacheConnector", "ApacheConnector_vs150.vcxproj", "{9866EE28-0612-4746-BD35-3B15B0AF7267}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug_shared|Win32 = debug_shared|Win32
release_shared|Win32 = release_shared|Win32
debug_shared|x64 = debug_shared|x64
release_shared|x64 = release_shared|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Build.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.ActiveCfg = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Build.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Deploy.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.ActiveCfg = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.Build.0 = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.Deploy.0 = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.ActiveCfg = release_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.Build.0 = release_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.Deploy.0 = release_shared|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|Win32">
<Configuration>debug_shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="debug_shared|x64">
<Configuration>debug_shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release_shared|Win32">
<Configuration>release_shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release_shared|x64">
<Configuration>release_shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>ApacheConnector</ProjectName>
<ProjectGuid>{9866EE28-0612-4746-BD35-3B15B0AF7267}</ProjectGuid>
<RootNamespace>ApacheConnector</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup>
<_ProjectFileVersion>15.0.28307.799</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">mod_pocod</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">mod_poco</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">mod_pocod</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">mod_poco</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">
<OutDir>..\bin\</OutDir>
<IntDir>obj\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">
<OutDir>..\bin\</OutDir>
<IntDir>obj\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
<OutDir>..\bin64\</OutDir>
<IntDir>obj64\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">
<OutDir>..\bin64\</OutDir>
<IntDir>obj64\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin\mod_pocod.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>..\bin\mod_pocod.pdb</ProgramDatabaseFile>
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<ImportLibrary>..\lib\mod_pocod.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin\mod_poco.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>..\lib\mod_poco.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin64\mod_poco64d.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>..\bin64\mod_poco64d.pdb</ProgramDatabaseFile>
<AdditionalLibraryDirectories>..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<ImportLibrary>..\lib64\mod_pocod.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin64\mod_poco64.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>..\lib64\mod_poco.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="include\ApacheApplication.h"/>
<ClInclude Include="include\ApacheChannel.h"/>
<ClInclude Include="include\ApacheConnector.h"/>
<ClInclude Include="include\ApacheRequestHandlerFactory.h"/>
<ClInclude Include="include\ApacheServerRequest.h"/>
<ClInclude Include="include\ApacheServerResponse.h"/>
<ClInclude Include="include\ApacheStream.h"/>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ApacheApplication.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheChannel.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheConnector.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheRequestHandlerFactory.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheServerRequest.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheServerResponse.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheStream.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{950fc61b-f928-41e6-9c33-00a1848c390a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{802bb162-bac1-460e-a7c4-295cb5f0b0ac}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\ApacheApplication.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheChannel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheConnector.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheRequestHandlerFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheServerRequest.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheServerResponse.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheStream.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ApacheApplication.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheChannel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheConnector.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheRequestHandlerFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheServerRequest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheServerResponse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,29 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApacheConnector", "ApacheConnector_vs160.vcxproj", "{9866EE28-0612-4746-BD35-3B15B0AF7267}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug_shared|Win32 = debug_shared|Win32
release_shared|Win32 = release_shared|Win32
debug_shared|x64 = debug_shared|x64
release_shared|x64 = release_shared|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Build.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.ActiveCfg = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Build.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Deploy.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.ActiveCfg = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.Build.0 = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|x64.Deploy.0 = debug_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.ActiveCfg = release_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.Build.0 = release_shared|x64
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|x64.Deploy.0 = release_shared|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|Win32">
<Configuration>debug_shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="debug_shared|x64">
<Configuration>debug_shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release_shared|Win32">
<Configuration>release_shared</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release_shared|x64">
<Configuration>release_shared</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>ApacheConnector</ProjectName>
<ProjectGuid>{9866EE28-0612-4746-BD35-3B15B0AF7267}</ProjectGuid>
<RootNamespace>ApacheConnector</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup>
<_ProjectFileVersion>15.0.28307.799</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">mod_pocod</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">mod_poco</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">mod_pocod</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">mod_poco</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">
<OutDir>..\bin\</OutDir>
<IntDir>obj\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">
<OutDir>..\bin\</OutDir>
<IntDir>obj\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
<OutDir>..\bin64\</OutDir>
<IntDir>obj64\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">
<OutDir>..\bin64\</OutDir>
<IntDir>obj64\ApacheConnector\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin\mod_pocod.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>..\bin\mod_pocod.pdb</ProgramDatabaseFile>
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<ImportLibrary>..\lib\mod_pocod.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin\mod_poco.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>..\lib\mod_poco.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin64\mod_poco64d.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>..\bin64\mod_poco64d.pdb</ProgramDatabaseFile>
<AdditionalLibraryDirectories>..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<ImportLibrary>..\lib64\mod_pocod.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\bin64\mod_poco64.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>..\lib64\mod_poco.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="include\ApacheApplication.h"/>
<ClInclude Include="include\ApacheChannel.h"/>
<ClInclude Include="include\ApacheConnector.h"/>
<ClInclude Include="include\ApacheRequestHandlerFactory.h"/>
<ClInclude Include="include\ApacheServerRequest.h"/>
<ClInclude Include="include\ApacheServerResponse.h"/>
<ClInclude Include="include\ApacheStream.h"/>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ApacheApplication.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheChannel.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheConnector.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheRequestHandlerFactory.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheServerRequest.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheServerResponse.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ClCompile Include="src\ApacheStream.cpp">
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{a5d13a29-7046-4ca5-878f-0539f1dc950d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{02cb9293-2406-4f18-bf6d-d64bfe0465fe}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\ApacheApplication.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheChannel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheConnector.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheRequestHandlerFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheServerRequest.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheServerResponse.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ApacheStream.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ApacheApplication.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheChannel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheConnector.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheRequestHandlerFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheServerRequest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheServerResponse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ApacheStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApacheConnector", "ApacheConnector_vs90.vcproj", "{9866EE28-0612-4746-BD35-3B15B0AF7267}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug_shared|Win32 = debug_shared|Win32
release_shared|Win32 = release_shared|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Build.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.ActiveCfg = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Build.0 = release_shared|Win32
{9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|Win32.Deploy.0 = release_shared|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
Name="ApacheConnector"
Version="9.00"
ProjectType="Visual C++"
ProjectGUID="{9866EE28-0612-4746-BD35-3B15B0AF7267}"
RootNamespace="ApacheConnector"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<ToolFiles/>
<Configurations>
<Configuration
Name="debug_shared|Win32"
OutputDirectory="obj\$(ConfigurationName)"
IntermediateDirectory="obj\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\Foundation\include;..\Net\include;..\Util\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS"
StringPooling="true"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
BufferSecurityCheck="true"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="0"
DisableSpecificWarnings=""
AdditionalOptions=""/>
<Tool
Name="VCManagedResourceCompilerTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libapr-1.lib libaprutil-1.lib libhttpd.lib"
OutputFile="..\bin\mod_pocod.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\bin\mod_pocod.pdb"
AdditionalLibraryDirectories="..\lib"
SubSystem="1"
ImportLibrary="..\lib\mod_pocod.lib"
TargetMachine="1"
AdditionalOptions=""/>
<Tool
Name="VCALinkTool"/>
<Tool
Name="VCManifestTool"/>
<Tool
Name="VCXDCMakeTool"/>
<Tool
Name="VCBscMakeTool"/>
<Tool
Name="VCFxCopTool"/>
<Tool
Name="VCAppVerifierTool"/>
<Tool
Name="VCPostBuildEventTool"/>
</Configuration>
<Configuration
Name="release_shared|Win32"
OutputDirectory="obj\$(ConfigurationName)"
IntermediateDirectory="obj\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCCLCompilerTool"
Optimization="4"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories=".\include;..\Foundation\include;..\Net\include;..\Util\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS"
StringPooling="true"
RuntimeLibrary="2"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
CompileAs="0"
DisableSpecificWarnings=""
AdditionalOptions=""/>
<Tool
Name="VCManagedResourceCompilerTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libapr-1.lib libaprutil-1.lib libhttpd.lib"
OutputFile="..\bin\mod_poco.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="false"
AdditionalLibraryDirectories="..\lib"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="..\lib\mod_poco.lib"
TargetMachine="1"
AdditionalOptions=""/>
<Tool
Name="VCALinkTool"/>
<Tool
Name="VCManifestTool"/>
<Tool
Name="VCXDCMakeTool"/>
<Tool
Name="VCBscMakeTool"/>
<Tool
Name="VCFxCopTool"/>
<Tool
Name="VCAppVerifierTool"/>
<Tool
Name="VCPostBuildEventTool"/>
</Configuration>
</Configurations>
<References/>
<Files>
<Filter
Name="Header Files">
<File
RelativePath=".\include\ApacheApplication.h"/>
<File
RelativePath=".\include\ApacheChannel.h"/>
<File
RelativePath=".\include\ApacheConnector.h"/>
<File
RelativePath=".\include\ApacheRequestHandlerFactory.h"/>
<File
RelativePath=".\include\ApacheServerRequest.h"/>
<File
RelativePath=".\include\ApacheServerResponse.h"/>
<File
RelativePath=".\include\ApacheStream.h"/>
</Filter>
<Filter
Name="Source Files">
<File
RelativePath=".\src\ApacheApplication.cpp"/>
<File
RelativePath=".\src\ApacheChannel.cpp"/>
<File
RelativePath=".\src\ApacheConnector.cpp"/>
<File
RelativePath=".\src\ApacheRequestHandlerFactory.cpp"/>
<File
RelativePath=".\src\ApacheServerRequest.cpp"/>
<File
RelativePath=".\src\ApacheServerResponse.cpp"/>
<File
RelativePath=".\src\ApacheStream.cpp"/>
</Filter>
</Files>
<Globals/>
</VisualStudioProject>

View File

@ -0,0 +1,26 @@
# Sources
file(GLOB SRCS_G "src/*.cpp")
POCO_SOURCES_AUTO(SRCS ${SRCS_G})
# Headers
file(GLOB_RECURSE HDRS_G "include/*.h")
POCO_HEADERS_AUTO(SRCS ${HDRS_G})
add_library(mod_poco SHARED ${SRCS})
set_target_properties(mod_poco
PROPERTIES
VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION}
DEFINE_SYMBOL ApacheHandlers_EXPORTS)
target_include_directories(mod_poco
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
${APACHE2_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_link_libraries(mod_poco PUBLIC Poco::Util Poco::Net Apache::Apr Apache::Aprutil)
if(ENABLE_TESTS)
add_subdirectory(samples)
endif()

26
vendor/POCO/ApacheConnector/Makefile vendored Normal file
View File

@ -0,0 +1,26 @@
#
# Makefile
#
# Makefile for ApacheConnector
#
include $(POCO_BASE)/build/rules/global
SYSFLAGS += -I/usr/include/apache2 \
-I/usr/include/apr-1.0 -I/usr/include/apr-1 -I/usr/include/apr-0
ifeq ($(OSNAME),Darwin)
SHAREDLIBLINKEXT = .so
DYLIB += -flat_namespace -undefined suppress
endif
objects = ApacheRequestHandlerFactory \
ApacheServerRequest ApacheServerResponse \
ApacheStream ApacheConnector ApacheChannel \
ApacheApplication ApacheChannel
target = mod_poco
target_version = 1
target_libs = PocoUtil PocoNet PocoXML PocoFoundation
include $(POCO_BASE)/build/rules/dylib

View File

@ -0,0 +1,5 @@
Net
Util
XML
JSON
Foundation

View File

@ -0,0 +1,148 @@
POCO ApacheConnector User Guide
POCO ApacheConnector
!!!Introduction
ApacheConnector (<[mod_poco]>) is an Apache module that allows one to write Apache server extensions using
the POCO Net HTTPServer framework. Almost any subclass of Poco::Net::HTTPRequestHandler written
for Poco::Net::HTTPServer can be used with ApacheConnector. For this to work, the request handler
subclass, together with its factory (Poco::Net::HTTPRequestHandlerFactory) must be contained
in a shared library. The ApacheConnector uses the Poco::ClassLoader to load request handler
factories from shared libraries.
!!!Adding ApacheConnector to Apache
ApacheConnector is implemented as an ordinary Apache 2 module, named <[mod_poco]>.
To add <[mod_poco]> to Apache, add the following entry to the Apache configuration
file (usually <[httpd.conf]>):
LoadModule poco_module modules/mod_pocod.so
----
!!!Configuring ApacheConnector
ApacheConnector must be able to find shared libraries containing request handler, as well
as optional configuration files. ApacheConnector provides an Poco::Util::Application class
to request handlers that can be used to access configuration data, loaded from configuration
files.
!!Request Handler Configuration
To have the ApacheConnector load a request handler class, the <[AddPocoRequestHandler]> directive
is used in the Apache configuration file:
AddPocoRequestHandler <FactoryClass> <SharedLibrary> <Path>...
----
The first argument specifies the name of the request handler factory class. The second argument
contains the path of the shared library containing the request handler.
The third (and optionally following) argument(s) specify the URI paths handled by the
request handler. For example:
AddPocoRequestHandler TimeRequestHandlerFactory p:/Poco/ApacheConnector/samples/TimeServer/bin/TimeServerd.dll /time
----
loads the TimeRequestHandlerFactory from TimeServerd.dll. Whenever a request for a URI starting with "/time"
is sent by a client, this request will be handled by the TimeRequestHandler.
!!Configuration Files
ApacheConnector can also load POCO configuration files (.ini, .properties or .xml) for later use by
request handlers. This is done using the <[AddPocoConfig]> directive:
AddPocoConfig <Path>
----
where <Path> specifies the full path to the configuration file.
In a request handler, the configuration properties loaded this way can be accessed using:
Poco::Util::Application& app = Poco::Util::Application::instance();
std::string myProp = app.config().getString("MyProperty");
----
!!!Logging in Request Handlers
ApacheConnector provides a special logging channel that logs to Apache's error log file.
This channel is set as the root channel when the ApacheConnector is loaded, so every
logger will automatically inherit this channel.
!!!A Sample Request Handler
Following is a sample for a request handler implementation. The complete sample project can be found in the
<[samples]> subdirectory of the ApacheConnector directory.
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Timestamp.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/ClassLibrary.h"
using Poco::Net::HTTPRequestHandler;
using Poco::Net::HTTPRequestHandlerFactory;
using Poco::Net::HTTPServerRequest;
using Poco::Net::HTTPServerResponse;
using Poco::Timestamp;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
class TimeRequestHandler: public HTTPRequestHandler
/// Return a HTML document with the current date and time.
{
public:
TimeRequestHandler()
{
}
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
{
Timestamp now;
std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
response.setChunkedTransferEncoding(true);
response.setContentType("text/html");
std::ostream& ostr = response.send();
ostr << "<html><head><title>TimeServer powered by POCO ApacheConnector</title>";
ostr << "<meta http-equiv=\"refresh\" content=\"1\"></head>";
ostr << "<body><p style=\"text-align: center; font-size: 48px;\">";
ostr << dt;
ostr << "</p></body></html>";
}
};
class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory
{
public:
TimeRequestHandlerFactory()
{
}
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
return new TimeRequestHandler;
}
};
POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory)
POCO_EXPORT_CLASS(TimeRequestHandlerFactory)
POCO_END_MANIFEST
----
Both the TimeRequestHandler class and the TimeRequestHandlerFactory class are the same as for
an ordinary Poco::Net::HTTPServer. The only addition in this sample is the definition
of the class loader manifest, which allows the ApacheConnector to load the TimeRequestHandlerFactory
class from the shared library.
To run this sample, the following directives must be added to the Apache configuration files:
LoadModule poco_module p:/Poco/ApacheConnector/bin/mod_poco.so
AddPocoRequestHandler TimeRequestHandlerFactory p:/Poco/ApacheConnector/samples/TimeServer/bin/TimeServer.dll /time
----
You'll have to change the paths to <[mod_poco.so]> and <[TimeServer.dll]> to match your
own environment.
To test the sample, simply direct your favorite web browser to <http://localhost/time>.

View File

@ -0,0 +1,56 @@
//
// ApacheApplication.h
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef ApacheConnector_ApacheApplication_INCLUDED
#define ApacheConnector_ApacheApplication_INCLUDED
#include "ApacheRequestHandlerFactory.h"
#include "Poco/Util/Application.h"
#include "Poco/Mutex.h"
class ApacheApplication: public Poco::Util::Application
{
public:
ApacheApplication();
/// Creates the ApacheApplication and sets the
/// ApacheChannel as the root logger channel.
~ApacheApplication();
/// Destroys the ApacheApplication.
void setup();
/// Initializes the application if called for the first
/// time; does nothing in later calls.
ApacheRequestHandlerFactory& factory();
/// Returns the ApacheRequestHandlerFactory.
static ApacheApplication& instance();
/// Returns the application instance.
private:
bool _ready;
ApacheRequestHandlerFactory _factory;
Poco::FastMutex _mutex;
};
//
// inlines
//
inline ApacheRequestHandlerFactory& ApacheApplication::factory()
{
return _factory;
}
#endif // ApacheConnector_ApacheApplication_INCLUDED

View File

@ -0,0 +1,30 @@
//
// ApacheChannel.h
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef ApacheConnector_ApacheChannel_INCLUDED
#define ApacheConnector_ApacheChannel_INCLUDED
#include "Poco/Channel.h"
class ApacheChannel: public Poco::Channel
/// This class implements a logging channel
/// that uses the Apache logging facilities.
{
public:
ApacheChannel();
~ApacheChannel();
void log(const Poco::Message& msg);
};
#endif // ApacheConnector_ApacheChannel_INCLUDED

View File

@ -0,0 +1,95 @@
//
// ApacheConnector.h
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef ApacheConnector_ApacheConnector_INCLUDED
#define ApacheConnector_ApacheConnector_INCLUDED
#include <string>
struct request_rec;
class ApacheServerRequest;
class ApacheRequestRec
/// This class wraps an Apache request_rec.
{
public:
ApacheRequestRec(request_rec* _pRec);
/// Creates the ApacheRequestRec;
bool haveRequestBody();
/// Returns true if the request contains a body.
int readRequest(char* buffer, int length);
/// Read up to length bytes from request body into buffer.
/// Returns the number of bytes read, 0 if eof or -1 if an error occured.
void writeResponse(const char* buffer, int length);
/// Writes the given characters as response to the given request_rec.
void addHeader(const std::string& key, const std::string& value);
/// Adds the given key / value pair to the outgoing headers of the
/// http response.
void setContentType(const std::string& mediaType);
/// Sets the response content type.
void redirect(const std::string& uri, int status);
/// Redirects the response to the given uri.
void sendErrorResponse(int status);
/// Sends an error response with the given HTTP status code.
int sendFile(const std::string& path, unsigned int fileSize, const std::string& mediaType);
/// Sends the file given by fileName as response.
void copyHeaders(ApacheServerRequest& request);
/// Copies the request uri and header fields from the Apache request
/// to the ApacheServerRequest.
bool secure();
/// Returns true if the request is using a secure
/// connection. Returns false if no secure connection
/// is used, or if it is not known whether a secure
/// connection is used.
void setStatus(int status);
/// Set specific HTTP status code for the request.
private:
request_rec* _pRec;
};
class ApacheConnector
/// This class provides static methods wrapping the
/// Apache API.
{
public:
enum LogLevel
{
PRIO_FATAL = 1, /// A fatal error. The application will most likely terminate. This is the highest priority.
PRIO_CRITICAL, /// A critical error. The application might not be able to continue running successfully.
PRIO_ERROR, /// An error. An operation did not complete successfully, but the application as a whole is not affected.
PRIO_WARNING, /// A warning. An operation completed with an unexpected result.
PRIO_NOTICE, /// A notice, which is an information with just a higher priority.
PRIO_INFORMATION, /// An informational message, usually denoting the successful completion of an operation.
PRIO_DEBUG, /// A debugging message.
PRIO_TRACE /// A tracing message. This is the lowest priority.
};
static void log(const char* file, int line, int level, int status, const char* text);
/// Log the given message.
};
#endif // ApacheConnector_ApacheConnector_INCLUDED

View File

@ -0,0 +1,55 @@
//
// ApacheRequestHandlerFactory.h
//
// Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
#define ApacheConnector_ApacheRequestHandlerFactory_INCLUDED
#include "ApacheServerRequest.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/ClassLoader.h"
#include "Poco/Mutex.h"
#include <map>
class ApacheRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{
public:
ApacheRequestHandlerFactory();
/// Constructs the ApacheRequestHandlerFactory
~ApacheRequestHandlerFactory();
/// Destructor of the ApacheRequestHandlerFactory
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
/// Creates a new request handler for the given HTTP request.
bool mustHandle(const std::string& uri);
/// Returns 1 if the given uri must be handled by the
/// poco_mapper module, 0 otherwise.
void handleURIs(const std::string& uris);
/// Parses the given string for dllName, factoryName and the URIs to handle
/// by the request-handler
void addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri);
/// Adds the request handler from the given dll with the given name and
/// registers that handler with the given uri
private:
typedef std::map<std::string, Poco::Net::HTTPRequestHandlerFactory*> RequestHandlerFactories;
RequestHandlerFactories _requestHandlers;
Poco::ClassLoader<Poco::Net::HTTPRequestHandlerFactory> _loader;
Poco::FastMutex _mutex;
};
#endif // ApacheConnector_ApacheRequestHandlerFactory_INCLUDED

Some files were not shown because too many files have changed in this diff Show More