diff --git a/ECTrainer1/ECTrainer1.vcxproj b/ECTrainer1/ECTrainer1.vcxproj
index 1e66a28..6cf539f 100644
--- a/ECTrainer1/ECTrainer1.vcxproj
+++ b/ECTrainer1/ECTrainer1.vcxproj
@@ -63,19 +63,19 @@
-
+
-
+
-
+
-
+
diff --git a/ECTrainer1/ECTrainer1Dlg.cpp b/ECTrainer1/ECTrainer1Dlg.cpp
index ffd5450..bc667a7 100644
--- a/ECTrainer1/ECTrainer1Dlg.cpp
+++ b/ECTrainer1/ECTrainer1Dlg.cpp
@@ -338,9 +338,13 @@
TRACE(_T("TargetThreadProc start\n"));
Size targetW = Size(240, 180);
- Mat target = imread("manL1.png");
+ //Mat target = imread("manL1.png");
namedWindow("target", WINDOW_NORMAL);
+ Mat target;
+ cv::Ptr dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50);
+ aruco::drawMarker(dictionary, 1, 100, target, 1);
+
do {
Mat tdisp = target.clone();
diff --git a/ECTrainer1/ECTrainer1Dlg.h b/ECTrainer1/ECTrainer1Dlg.h
index d8bfc39..04b0389 100644
--- a/ECTrainer1/ECTrainer1Dlg.h
+++ b/ECTrainer1/ECTrainer1Dlg.h
@@ -9,7 +9,8 @@
#include "myOpenCV.h"
//#define ADDR "192.168.71.50"
-#define ADDR "192.168.23.158"
+//#define ADDR "192.168.23.158"
+#define ADDR "192.168.14.107"
const std::string KA_DATA_MSG = "{\"type\": \"live.data.unicast\", \"key\": \"some_GUID\", \"op\": \"start\"}";
@@ -33,11 +34,11 @@
HICON _hIcon;
bool _bRunning;
- CWinThread* _pCameraThread;
- CWinThread* _pImageThread;
- CWinThread* _pTargetThread;
- CWinThread* _pKeepAliveThread;
- CWinThread* _pDataThread;
+ CWinThread* _pCameraThread = NULL;
+ CWinThread* _pImageThread = NULL;
+ CWinThread* _pTargetThread = NULL;
+ CWinThread* _pKeepAliveThread = NULL;
+ CWinThread* _pDataThread = NULL;
SOCKET _socket;
struct sockaddr_in _socketAddr;
Point2f _gpC;
diff --git a/ECTrainer1/opencv411.props b/ECTrainer1/opencv411.props
deleted file mode 100644
index 45beb6f..0000000
--- a/ECTrainer1/opencv411.props
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
- D:\SDK\OpenCV4.1.1\include;$(IncludePath)
- D:\SDK\OpenCV4.1.1\x64\vc16\lib;$(LibraryPath)
-
-
- D:\SDK\OpenCV4.1.1\include;$(IncludePath)
- D:\SDK\OpenCV4.1.1\x86\vc16\lib\lib;$(LibraryPath)
-
-
-
-
diff --git a/ECTrainer1/opencv411gst.props b/ECTrainer1/opencv411gst.props
new file mode 100644
index 0000000..b242f7b
--- /dev/null
+++ b/ECTrainer1/opencv411gst.props
@@ -0,0 +1,15 @@
+
+
+
+
+
+ D:\SDK\OpenCV4.1.1_GST\include;$(IncludePath)
+ D:\SDK\OpenCV4.1.1_GST\x64\vc16\lib;$(LibraryPath)
+
+
+ D:\SDK\OpenCV4.1.1_GST\include;$(IncludePath)
+ D:\SDK\OpenCV4.1.1_GST\x86\vc16\lib\lib;$(LibraryPath)
+
+
+
+
diff --git a/PrismSoftware.sln b/PrismSoftware.sln
index e9e8b0f..aff4e75 100644
--- a/PrismSoftware.sln
+++ b/PrismSoftware.sln
@@ -7,6 +7,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ECTrainer1", "ECTrainer1\ECTrainer1.vcxproj", "{E2EC3843-4077-4DC8-96F7-37C1BA5094FD}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RESTtest", "RESTtest\RESTtest.vcxproj", "{9A1E4457-9AEC-4CDA-A108-4EB861715425}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -16,7 +18,6 @@
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BB038458-DFC5-4ACD-96CB-35512801136D}.Debug|x64.ActiveCfg = Debug|x64
- {BB038458-DFC5-4ACD-96CB-35512801136D}.Debug|x64.Build.0 = Debug|x64
{BB038458-DFC5-4ACD-96CB-35512801136D}.Debug|x86.ActiveCfg = Debug|Win32
{BB038458-DFC5-4ACD-96CB-35512801136D}.Debug|x86.Build.0 = Debug|Win32
{BB038458-DFC5-4ACD-96CB-35512801136D}.Release|x64.ActiveCfg = Release|x64
@@ -30,6 +31,14 @@
{E2EC3843-4077-4DC8-96F7-37C1BA5094FD}.Release|x64.Build.0 = Release|x64
{E2EC3843-4077-4DC8-96F7-37C1BA5094FD}.Release|x86.ActiveCfg = Release|Win32
{E2EC3843-4077-4DC8-96F7-37C1BA5094FD}.Release|x86.Build.0 = Release|Win32
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Debug|x64.ActiveCfg = Debug|x64
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Debug|x64.Build.0 = Debug|x64
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Debug|x86.ActiveCfg = Debug|Win32
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Debug|x86.Build.0 = Debug|Win32
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Release|x64.ActiveCfg = Release|x64
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Release|x64.Build.0 = Release|x64
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Release|x86.ActiveCfg = Release|Win32
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/RESTtest/RESTtest.cpp b/RESTtest/RESTtest.cpp
new file mode 100644
index 0000000..44827d9
--- /dev/null
+++ b/RESTtest/RESTtest.cpp
@@ -0,0 +1,157 @@
+// RESTtest.cpp : このファイルには 'main' 関数が含まれています。プログラム実行の開始と終了がそこで行われます。
+//
+
+#include
+#include
+#include
+#include
+
+using namespace web;
+using namespace web::http;
+using namespace web::http::client;
+
+pplx::task Get()
+{
+ return pplx::create_task([]
+ {
+ // proxyあり
+ // auto config = http_client_config();
+ // config.set_proxy(web_proxy(utility::conversions::to_string_t("http://127.0.0.1:8080")));
+ // http_client client(L"https://jsonplaceholder.typicode.com/posts/1", config);
+
+ http_client client(L"http://192.168.14.107/api/system/status");
+ return client.request(methods::GET);
+ }).then([](http_response response)
+ {
+ if (response.status_code() == status_codes::OK)
+ {
+ // レスポンスを文字列として取得後、標準出力する
+ // auto body = response.extract_string();
+ // std::wcout << body.get().c_str() << std::endl;
+
+ // レスポンスをJSONとして解析する
+ return response.extract_json();
+ }
+ }).then([](json::value json)
+ {
+ // タイトルだけ取得する
+ std::wcout << json[L"sys_name"].as_string() << std::endl;
+ });
+}
+
+pplx::task Post()
+{
+ return pplx::create_task([]
+ {
+ json::value postData;
+
+ auto sex = utility::conversions::to_string_t("man");
+ postData[L"user_info"][L"name"] = json::value::string(L"user001");
+ postData[L"user_info"][L"sex"] = json::value::string(sex);
+ postData[L"user_info"][L"age"] = json::value::number(20);
+
+ // proxyあり
+ // auto config = http_client_config();
+ // config.set_proxy(web_proxy(utility::conversions::to_string_t("http://127.0.0.1:8080")));
+ // http_client client(L"http://localhost/api", config);
+ http_client client(L"http://localhost/api");
+ return client.request(methods::POST, L"", postData.serialize(), L"application/json");
+ }).then([](http_response response)
+ {
+ if (response.status_code() == status_codes::OK)
+ {
+ //auto body = response.extract_string();
+ //std::wcout << body.get().c_str() << std::endl;
+ //std::cout << response.extract_json() << std::endl;
+ return response.extract_json();
+ }
+ }).then([](json::value json)
+ {
+ // リザルトコードを返す
+ return json[L"result"].as_integer();
+ });
+}
+
+http_response POST_request(const TCHAR* baseURL, json::value data = json::value::Null) {
+
+ http_client httpClient(baseURL);
+ http_response httpResponse = httpClient.request(methods::POST, L"",
+ data == json::value::Null ? _T("") : data.serialize(), L"application/json").get();
+ return httpResponse;
+}
+
+http_response GET_request(const TCHAR* baseURL) {
+ http_client httpClient(baseURL);
+ http_response httpResponse = httpClient.request(methods::GET, L"", L"", L"application/json").get();
+ return httpResponse;
+}
+
+std::wstring WaitForStatus(const TCHAR* baseURL, std::wstring key, std::vector values) {
+ int count = 0;
+ bool running = true;
+ int maxTries = 20;
+ json::value json;
+ std::wcout << baseURL << std::endl;
+ while (running) {
+ auto response = GET_request(baseURL);
+ json = response.extract_json().get();
+ std::wcout << _T("Status: ") << json[key].as_string() << std::endl;
+ if (count >= maxTries) running = false;
+ else {
+ for (int i = 0; i < values.size(); i++) {
+ if (json[key].as_string().compare(values[i]) == 0) {
+ running = false;
+ }
+ }
+ }
+ if (!running) break;
+ Sleep(1000);
+ count++;
+ }
+ return json[key].as_string();
+}
+
+int main()
+{
+ // コマンドプロンプトの文字コードをUTF-8に設定する
+ SetConsoleOutputCP(CP_UTF8);
+
+ try
+ {
+ json::value json = POST_request(_T("http://192.168.14.107/api/projects")).extract_json().get();
+ auto prId = json[_T("pr_id")].as_string();
+ std::wcout << "prId=" << prId << std::endl;
+
+ json::value postData;
+ postData[L"pa_project"] = json::value::string(prId);
+ json = POST_request(_T("http://192.168.14.107/api/participants"), postData).extract_json().get();
+ auto paId = json[_T("pa_id")].as_string();
+ std::wcout << "paId=" << paId << std::endl;
+
+ json::value postData2;
+ postData2[L"ca_project"] = json::value::string(prId);
+ postData2[L"ca_type"] = json::value::string(L"default");
+ postData2[L"ca_participant"] = json::value::string(paId);
+ json = POST_request(_T("http://192.168.14.107/api/calibrations"), postData2).extract_json().get();
+ auto caId = json[_T("ca_id")].as_string();
+ std::wcout << "caId=" << caId << std::endl;
+
+ std::wstring url = _T("http://192.168.14.107/api/calibrations/") + caId + _T("/start");
+ json = POST_request(url.c_str()).extract_json().get();
+
+ url = _T("http://192.168.14.107/api/calibrations/") + caId + _T("/status");
+ std::vector values;
+ values.push_back(_T("failed"));
+ values.push_back(_T("calibrated"));
+ std::wstring status = WaitForStatus(url.c_str(), _T("ca_state"), values);
+ if (status == _T("failed")) {
+ std::wcout << _T("Calibration failed.") << std::endl;
+ } else {
+ std::wcout << _T("Calibration successful.") << std::endl;
+ }
+ }
+ catch (const std::exception & e)
+ {
+ std::cout << "Error " << e.what() << std::endl;
+ }
+}
diff --git a/RESTtest/RESTtest.vcxproj b/RESTtest/RESTtest.vcxproj
new file mode 100644
index 0000000..de7222c
--- /dev/null
+++ b/RESTtest/RESTtest.vcxproj
@@ -0,0 +1,169 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {9A1E4457-9AEC-4CDA-A108-4EB861715425}
+ Win32Proj
+ RESTtest
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ このプロジェクトは、このコンピューター上にない NuGet パッケージを参照しています。それらのパッケージをダウンロードするには、[NuGet パッケージの復元] を使用します。詳細については、http://go.microsoft.com/fwlink/?LinkID=322105 を参照してください。見つからないファイルは {0} です。
+
+
+
+
\ No newline at end of file
diff --git a/RESTtest/RESTtest.vcxproj.filters b/RESTtest/RESTtest.vcxproj.filters
new file mode 100644
index 0000000..d00b3be
--- /dev/null
+++ b/RESTtest/RESTtest.vcxproj.filters
@@ -0,0 +1,25 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ ソース ファイル
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RESTtest/packages.config b/RESTtest/packages.config
new file mode 100644
index 0000000..5e043ca
--- /dev/null
+++ b/RESTtest/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/packages/cpprestsdk.v141.2.10.12.1/.signature.p7s b/packages/cpprestsdk.v141.2.10.12.1/.signature.p7s
new file mode 100644
index 0000000..932ade2
--- /dev/null
+++ b/packages/cpprestsdk.v141.2.10.12.1/.signature.p7s
Binary files differ
diff --git a/packages/cpprestsdk.v141.2.10.12.1/build/native/cpprestsdk.v141.targets b/packages/cpprestsdk.v141.2.10.12.1/build/native/cpprestsdk.v141.targets
new file mode 100644
index 0000000..e0b70a2
--- /dev/null
+++ b/packages/cpprestsdk.v141.2.10.12.1/build/native/cpprestsdk.v141.targets
@@ -0,0 +1,47 @@
+
+
+
+ true
+
+
+ true
+
+
+
+
+ $(MSBuildThisFileDirectory)include\;%(AdditionalIncludeDirectories)
+
+
+
+
+
+
+ $(MSBuildThisFileDirectory)x86\lib\cpprest141_2_10d.lib;%(AdditionalDependencies)
+ $(MSBuildThisFileDirectory)x86\lib\cpprest141_2_10.lib;%(AdditionalDependencies)
+
+ $(MSBuildThisFileDirectory)x64\lib\cpprest141_2_10d.lib;%(AdditionalDependencies)
+ $(MSBuildThisFileDirectory)x64\lib\cpprest141_2_10.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/astreambuf.h b/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/astreambuf.h
new file mode 100644
index 0000000..1dcb285
--- /dev/null
+++ b/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/astreambuf.h
@@ -0,0 +1,1180 @@
+/***
+ * Copyright (C) Microsoft. All rights reserved.
+ * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+ *
+ * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+ *
+ * Asynchronous I/O: stream buffer. This is an extension to the PPL concurrency features and therefore
+ * lives in the Concurrency namespace.
+ *
+ * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
+ *
+ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ ****/
+#pragma once
+
+#include "cpprest/asyncrt_utils.h"
+#include "cpprest/details/basic_types.h"
+#include "pplx/pplxtasks.h"
+#include
+#include
+#include
+#include
+#include
+
+#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) && !CPPREST_FORCE_PPLX
+namespace Concurrency // since namespace pplx = Concurrency
+#else
+namespace pplx
+#endif
+{
+namespace details
+{
+template
+pplx::task _do_while(F func)
+{
+ pplx::task first = func();
+ return first.then([=](bool guard) -> pplx::task {
+ if (guard)
+ return pplx::details::_do_while(func);
+ else
+ return first;
+ });
+}
+} // namespace details
+}
+
+namespace Concurrency
+{
+/// Library for asynchronous streams.
+namespace streams
+{
+///
+/// Extending the standard char_traits type with one that adds values and types
+/// that are unique to "C++ REST SDK" streams.
+///
+///
+/// The data type of the basic element of the stream.
+///
+template
+struct char_traits : std::char_traits<_CharType>
+{
+ ///
+ /// Some synchronous functions will return this value if the operation
+ /// requires an asynchronous call in a given situation.
+ ///
+ /// An int_type value which implies that an asynchronous call is required.
+ static typename std::char_traits<_CharType>::int_type requires_async()
+ {
+ return std::char_traits<_CharType>::eof() - 1;
+ }
+};
+#if !defined(_WIN32)
+template<>
+struct char_traits : private std::char_traits
+{
+public:
+ typedef unsigned char char_type;
+
+ using std::char_traits::eof;
+ using std::char_traits::int_type;
+ using std::char_traits::off_type;
+ using std::char_traits::pos_type;
+
+ static size_t length(const unsigned char* str)
+ {
+ return std::char_traits::length(reinterpret_cast(str));
+ }
+
+ static void assign(unsigned char& left, const unsigned char& right) { left = right; }
+ static unsigned char* assign(unsigned char* left, size_t n, unsigned char value)
+ {
+ return reinterpret_cast(
+ std::char_traits::assign(reinterpret_cast(left), n, static_cast(value)));
+ }
+
+ static unsigned char* copy(unsigned char* left, const unsigned char* right, size_t n)
+ {
+ return reinterpret_cast(
+ std::char_traits::copy(reinterpret_cast(left), reinterpret_cast(right), n));
+ }
+
+ static unsigned char* move(unsigned char* left, const unsigned char* right, size_t n)
+ {
+ return reinterpret_cast(
+ std::char_traits::move(reinterpret_cast(left), reinterpret_cast(right), n));
+ }
+
+ static int_type requires_async() { return eof() - 1; }
+};
+#endif
+
+namespace details
+{
+///
+/// Stream buffer base class.
+///
+template
+class basic_streambuf
+{
+public:
+ typedef _CharType char_type;
+ typedef ::concurrency::streams::char_traits<_CharType> traits;
+
+ typedef typename traits::int_type int_type;
+ typedef typename traits::pos_type pos_type;
+ typedef typename traits::off_type off_type;
+
+ ///
+ /// Virtual constructor for stream buffers.
+ ///
+ virtual ~basic_streambuf() {}
+
+ ///
+ /// can_read is used to determine whether a stream buffer will support read operations (get).
+ ///
+ virtual bool can_read() const = 0;
+
+ ///
+ /// can_write is used to determine whether a stream buffer will support write operations (put).
+ ///
+ virtual bool can_write() const = 0;
+
+ ///
+ /// can_seek is used to determine whether a stream buffer supports seeking.
+ ///
+ virtual bool can_seek() const = 0;
+
+ ///
+ /// has_size is used to determine whether a stream buffer supports size().
+ ///
+ virtual bool has_size() const = 0;
+
+ ///
+ /// is_eof is used to determine whether a read head has reached the end of the buffer.
+ ///
+ virtual bool is_eof() const = 0;
+
+ ///
+ /// Gets the stream buffer size, if one has been set.
+ ///
+ /// The direction of buffering (in or out)
+ /// The size of the internal buffer (for the given direction).
+ /// An implementation that does not support buffering will always return 0.
+ virtual size_t buffer_size(std::ios_base::openmode direction = std::ios_base::in) const = 0;
+
+ ///
+ /// Sets the stream buffer implementation to buffer or not buffer.
+ ///
+ /// The size to use for internal buffering, 0 if no buffering should be done.
+ /// The direction of buffering (in or out)
+ /// An implementation that does not support buffering will silently ignore calls to this function and it
+ /// will not have any effect on what is returned by subsequent calls to .
+ virtual void set_buffer_size(size_t size, std::ios_base::openmode direction = std::ios_base::in) = 0;
+
+ ///
+ /// For any input stream, in_avail returns the number of characters that are immediately available
+ /// to be consumed without blocking. May be used in conjunction with to read data without
+ /// incurring the overhead of using tasks.
+ ///
+ virtual size_t in_avail() const = 0;
+
+ ///
+ /// Checks if the stream buffer is open.
+ ///
+ /// No separation is made between open for reading and open for writing.
+ virtual bool is_open() const = 0;
+
+ ///
+ /// Closes the stream buffer, preventing further read or write operations.
+ ///
+ /// The I/O mode (in or out) to close for.
+ virtual pplx::task close(std::ios_base::openmode mode = (std::ios_base::in | std::ios_base::out)) = 0;
+
+ ///
+ /// Closes the stream buffer with an exception.
+ ///
+ /// The I/O mode (in or out) to close for.
+ /// Pointer to the exception.
+ virtual pplx::task close(std::ios_base::openmode mode, std::exception_ptr eptr) = 0;
+
+ ///
+ /// Writes a single character to the stream.
+ ///
+ /// The character to write
+ /// A task that holds the value of the character. This value is EOF if the write operation
+ /// fails.
+ virtual pplx::task putc(_CharType ch) = 0;
+
+ ///
+ /// Writes a number of characters to the stream.
+ ///
+ /// A pointer to the block of data to be written.
+ /// The number of characters to write.
+ /// A task that holds the number of characters actually written, either 'count' or 0.
+ virtual pplx::task putn(const _CharType* ptr, size_t count) = 0;
+
+ ///
+ /// Writes a number of characters to the stream. Note: callers must make sure the data to be written is valid until
+ /// the returned task completes.
+ ///
+ /// A pointer to the block of data to be written.
+ /// The number of characters to write.
+ /// A task that holds the number of characters actually written, either 'count' or 0.
+ virtual pplx::task putn_nocopy(const _CharType* ptr, size_t count) = 0;
+
+ ///
+ /// Reads a single character from the stream and advances the read position.
+ ///
+ /// A task that holds the value of the character. This value is EOF if the read fails.
+ virtual pplx::task bumpc() = 0;
+
+ ///
+ /// Reads a single character from the stream and advances the read position.
+ ///
+ /// The value of the character. -1 if the read fails. -2 if an asynchronous read is
+ /// requiredThis is a synchronous operation, but is guaranteed to never block.
+ virtual int_type sbumpc() = 0;
+
+ ///
+ /// Reads a single character from the stream without advancing the read position.
+ ///
+ /// A task that holds the value of the byte. This value is EOF if the read fails.
+ virtual pplx::task getc() = 0;
+
+ ///
+ /// Reads a single character from the stream without advancing the read position.
+ ///
+ /// The value of the character. EOF if the read fails. if an
+ /// asynchronous read is requiredThis is a synchronous operation, but is guaranteed to never
+ /// block.
+ virtual int_type sgetc() = 0;
+
+ ///
+ /// Advances the read position, then returns the next character without advancing again.
+ ///
+ /// A task that holds the value of the character. This value is EOF if the read fails.
+ virtual pplx::task nextc() = 0;
+
+ ///
+ /// Retreats the read position, then returns the current character without advancing.
+ ///
+ /// A task that holds the value of the character. This value is EOF if the read fails,
+ /// requires_async if an asynchronous read is required
+ virtual pplx::task ungetc() = 0;
+
+ ///
+ /// Reads up to a given number of characters from the stream.
+ ///
+ /// The address of the target memory area.
+ /// The maximum number of characters to read.
+ /// A task that holds the number of characters read. This value is O if the end of the stream is
+ /// reached.
+ virtual pplx::task getn(_Out_writes_(count) _CharType* ptr, _In_ size_t count) = 0;
+
+ ///
+ /// Copies up to a given number of characters from the stream, synchronously.
+ ///
+ /// The address of the target memory area.
+ /// The maximum number of characters to read.
+ /// The number of characters copied. O if the end of the stream is reached or an asynchronous read is
+ /// required.This is a synchronous operation, but is guaranteed to never block.
+ virtual size_t scopy(_Out_writes_(count) _CharType* ptr, _In_ size_t count) = 0;
+
+ ///
+ /// Gets the current read or write position in the stream.
+ ///
+ /// The I/O direction to seek (see remarks)
+ /// The current position. EOF if the operation fails.
+ /// Some streams may have separate write and read cursors.
+ /// For such streams, the direction parameter defines whether to move the read or the write
+ /// cursor.
+ virtual pos_type getpos(std::ios_base::openmode direction) const = 0;
+
+ ///
+ /// Gets the size of the stream, if known. Calls to has_size will determine whether
+ /// the result of size can be relied on.
+ ///
+ virtual utility::size64_t size() const = 0;
+
+ ///
+ /// Seeks to the given position.
+ ///
+ /// The offset from the beginning of the stream.
+ /// The I/O direction to seek (see remarks).
+ /// The position. EOF if the operation fails.
+ /// Some streams may have separate write and read cursors. For such streams, the direction parameter
+ /// defines whether to move the read or the write cursor.
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode direction) = 0;
+
+ ///
+ /// Seeks to a position given by a relative offset.
+ ///
+ /// The relative position to seek to
+ /// The starting point (beginning, end, current) for the seek.
+ /// The I/O direction to seek (see remarks)
+ /// The position. EOF if the operation fails.
+ /// Some streams may have separate write and read cursors.
+ /// For such streams, the mode parameter defines whether to move the read or the write cursor.
+ virtual pos_type seekoff(off_type offset, std::ios_base::seekdir way, std::ios_base::openmode mode) = 0;
+
+ ///
+ /// For output streams, flush any internally buffered data to the underlying medium.
+ ///
+ /// A task that returns true if the sync succeeds, false if not.
+ virtual pplx::task sync() = 0;
+
+ //
+ // Efficient read and write.
+ //
+ // The following routines are intended to be used for more efficient, copy-free, reading and
+ // writing of data from/to the stream. Rather than having the caller provide a buffer into which
+ // data is written or from which it is read, the stream buffer provides a pointer directly to the
+ // internal data blocks that it is using. Since not all stream buffers use internal data structures
+ // to copy data, the functions may not be supported by all. An application that wishes to use this
+ // functionality should therefore first try them and check for failure to support. If there is
+ // such failure, the application should fall back on the copying interfaces (putn / getn)
+ //
+
+ ///
+ /// Allocates a contiguous memory block and returns it.
+ ///
+ /// The number of characters to allocate.
+ /// A pointer to a block to write to, null if the stream buffer implementation does not support
+ /// alloc/commit.
+ virtual _CharType* alloc(_In_ size_t count) = 0;
+
+ ///
+ /// Submits a block already allocated by the stream buffer.
+ ///
+ /// The number of characters to be committed.
+ virtual void commit(_In_ size_t count) = 0;
+
+ ///
+ /// Gets a pointer to the next already allocated contiguous block of data.
+ ///
+ /// A reference to a pointer variable that will hold the address of the block on success.
+ /// The number of contiguous characters available at the address in 'ptr'.
+ /// true if the operation succeeded, false otherwise.
+ ///
+ /// A return of false does not necessarily indicate that a subsequent read operation would fail, only that
+ /// there is no block to return immediately or that the stream buffer does not support the operation.
+ /// The stream buffer may not de-allocate the block until is called.
+ /// If the end of the stream is reached, the function will return true, a null pointer, and a count of zero;
+ /// a subsequent read will not succeed.
+ ///
+ virtual bool acquire(_Out_ _CharType*& ptr, _Out_ size_t& count) = 0;
+
+ ///
+ /// Releases a block of data acquired using . This frees the stream buffer to
+ /// de-allocate the memory, if it so desires. Move the read position ahead by the count.
+ ///
+ /// A pointer to the block of data to be released.
+ /// The number of characters that were read.
+ virtual void release(_Out_writes_(count) _CharType* ptr, _In_ size_t count) = 0;
+
+ ///
+ /// Retrieves the stream buffer exception_ptr if it has been set.
+ ///
+ /// Pointer to the exception, if it has been set; otherwise, nullptr will be returned
+ virtual std::exception_ptr exception() const = 0;
+};
+
+template
+class streambuf_state_manager : public basic_streambuf<_CharType>,
+ public std::enable_shared_from_this>
+{
+public:
+ typedef typename details::basic_streambuf<_CharType>::traits traits;
+ typedef typename details::basic_streambuf<_CharType>::int_type int_type;
+ typedef typename details::basic_streambuf<_CharType>::pos_type pos_type;
+ typedef typename details::basic_streambuf<_CharType>::off_type off_type;
+
+ ///
+ /// can_read is used to determine whether a stream buffer will support read operations (get).
+ ///
+ virtual bool can_read() const { return m_stream_can_read; }
+
+ ///
+ /// can_write is used to determine whether a stream buffer will support write operations (put).
+ ///
+ virtual bool can_write() const { return m_stream_can_write; }
+
+ ///
+ /// Checks if the stream buffer is open.
+ ///
+ /// No separation is made between open for reading and open for writing.
+ virtual bool is_open() const { return can_read() || can_write(); }
+
+ ///
+ /// Closes the stream buffer, preventing further read or write operations.
+ ///
+ /// The I/O mode (in or out) to close for.
+ virtual pplx::task close(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
+ {
+ pplx::task closeOp = pplx::task_from_result();
+
+ if (mode & std::ios_base::in && can_read())
+ {
+ closeOp = _close_read();
+ }
+
+ // After the flush_internal task completed, "this" object may have been destroyed,
+ // accessing the members is invalid, use shared_from_this to avoid access violation exception.
+ auto this_ptr = std::static_pointer_cast(this->shared_from_this());
+
+ if (mode & std::ios_base::out && can_write())
+ {
+ if (closeOp.is_done())
+ closeOp = closeOp && _close_write().then([this_ptr] {}); // passing down exceptions from closeOp
+ else
+ closeOp = closeOp.then([this_ptr] { return this_ptr->_close_write().then([this_ptr] {}); });
+ }
+
+ return closeOp;
+ }
+
+ ///
+ /// Closes the stream buffer with an exception.
+ ///
+ /// The I/O mode (in or out) to close for.
+ /// Pointer to the exception.
+ virtual pplx::task close(std::ios_base::openmode mode, std::exception_ptr eptr)
+ {
+ if (m_currentException == nullptr) m_currentException = eptr;
+ return close(mode);
+ }
+
+ ///
+ /// is_eof is used to determine whether a read head has reached the end of the buffer.
+ ///
+ virtual bool is_eof() const { return m_stream_read_eof; }
+
+ ///
+ /// Writes a single character to the stream.
+ ///
+ /// The character to write
+ /// The value of the character. EOF if the write operation fails
+ virtual pplx::task putc(_CharType ch)
+ {
+ if (!can_write()) return create_exception_checked_value_task(traits::eof());
+
+ return create_exception_checked_task(_putc(ch), [](int_type) {
+ return false; // no EOF for write
+ });
+ }
+
+ ///
+ /// Writes a number of characters to the stream.
+ ///
+ /// A pointer to the block of data to be written.
+ /// The number of characters to write.
+ /// The number of characters actually written, either 'count' or 0.
+ CASABLANCA_DEPRECATED("This API in some cases performs a copy. It is deprecated and will be removed in a future "
+ "release. Use putn_nocopy instead.")
+ virtual pplx::task putn(const _CharType* ptr, size_t count)
+ {
+ if (!can_write()) return create_exception_checked_value_task(0);
+ if (count == 0) return pplx::task_from_result(0);
+
+ return create_exception_checked_task(_putn(ptr, count, true), [](size_t) {
+ return false; // no EOF for write
+ });
+ }
+
+ ///
+ /// Writes a number of characters to the stream. Note: callers must make sure the data to be written is valid until
+ /// the returned task completes.
+ ///
+ /// A pointer to the block of data to be written.
+ /// The number of characters to write.
+ /// A task that holds the number of characters actually written, either 'count' or 0.
+ virtual pplx::task putn_nocopy(const _CharType* ptr, size_t count)
+ {
+ if (!can_write()) return create_exception_checked_value_task(0);
+ if (count == 0) return pplx::task_from_result(0);
+
+ return create_exception_checked_task(_putn(ptr, count), [](size_t) {
+ return false; // no EOF for write
+ });
+ }
+
+ ///
+ /// Reads a single character from the stream and advances the read position.
+ ///
+ /// The value of the character. EOF if the read fails.
+ virtual pplx::task bumpc()
+ {
+ if (!can_read())
+ return create_exception_checked_value_task(streambuf_state_manager<_CharType>::traits::eof());
+
+ return create_exception_checked_task(
+ _bumpc(), [](int_type val) { return val == streambuf_state_manager<_CharType>::traits::eof(); });
+ }
+
+ ///
+ /// Reads a single character from the stream and advances the read position.
+ ///
+ /// The value of the character. -1 if the read fails. -2 if an asynchronous read is
+ /// requiredThis is a synchronous operation, but is guaranteed to never block.
+ virtual int_type sbumpc()
+ {
+ if (!(m_currentException == nullptr)) std::rethrow_exception(m_currentException);
+ if (!can_read()) return traits::eof();
+ return check_sync_read_eof(_sbumpc());
+ }
+
+ ///
+ /// Reads a single character from the stream without advancing the read position.
+ ///
+ /// The value of the byte. EOF if the read fails.
+ virtual pplx::task getc()
+ {
+ if (!can_read()) return create_exception_checked_value_task(traits::eof());
+
+ return create_exception_checked_task(
+ _getc(), [](int_type val) { return val == streambuf_state_manager<_CharType>::traits::eof(); });
+ }
+
+ ///
+ /// Reads a single character from the stream without advancing the read position.
+ ///
+ /// The value of the character. EOF if the read fails. if an
+ /// asynchronous read is requiredThis is a synchronous operation, but is guaranteed to never
+ /// block.
+ virtual int_type sgetc()
+ {
+ if (!(m_currentException == nullptr)) std::rethrow_exception(m_currentException);
+ if (!can_read()) return traits::eof();
+ return check_sync_read_eof(_sgetc());
+ }
+
+ ///
+ /// Advances the read position, then returns the next character without advancing again.
+ ///
+ /// The value of the character. EOF if the read fails.
+ virtual pplx::task nextc()
+ {
+ if (!can_read()) return create_exception_checked_value_task(traits::eof());
+
+ return create_exception_checked_task(
+ _nextc(), [](int_type val) { return val == streambuf_state_manager<_CharType>::traits::eof(); });
+ }
+
+ ///
+ /// Retreats the read position, then returns the current character without advancing.
+ ///
+ /// The value of the character. EOF if the read fails. if an
+ /// asynchronous read is required
+ virtual pplx::task ungetc()
+ {
+ if (!can_read()) return create_exception_checked_value_task(traits::eof());
+
+ return create_exception_checked_task(_ungetc(), [](int_type) { return false; });
+ }
+
+ ///
+ /// Reads up to a given number of characters from the stream.
+ ///
+ /// The address of the target memory area.
+ /// The maximum number of characters to read.
+ /// The number of characters read. O if the end of the stream is reached.
+ virtual pplx::task getn(_Out_writes_(count) _CharType* ptr, _In_ size_t count)
+ {
+ if (!can_read()) return create_exception_checked_value_task(0);
+ if (count == 0) return pplx::task_from_result(0);
+
+ return create_exception_checked_task(_getn(ptr, count), [](size_t val) { return val == 0; });
+ }
+
+ ///
+ /// Copies up to a given number of characters from the stream, synchronously.
+ ///
+ /// The address of the target memory area.
+ /// The maximum number of characters to read.
+ /// The number of characters copied. O if the end of the stream is reached or an asynchronous read is
+ /// required.This is a synchronous operation, but is guaranteed to never block.
+ virtual size_t scopy(_Out_writes_(count) _CharType* ptr, _In_ size_t count)
+ {
+ if (!(m_currentException == nullptr)) std::rethrow_exception(m_currentException);
+ if (!can_read()) return 0;
+
+ return _scopy(ptr, count);
+ }
+
+ ///
+ /// For output streams, flush any internally buffered data to the underlying medium.
+ ///
+ /// true if the flush succeeds, false if not
+ virtual pplx::task sync()
+ {
+ if (!can_write())
+ {
+ if (m_currentException == nullptr)
+ return pplx::task_from_result();
+ else
+ return pplx::task_from_exception(m_currentException);
+ }
+ return create_exception_checked_task(_sync(), [](bool) { return false; }).then([](bool) {});
+ }
+
+ ///
+ /// Retrieves the stream buffer exception_ptr if it has been set.
+ ///
+ /// Pointer to the exception, if it has been set; otherwise, nullptr will be returned.
+ virtual std::exception_ptr exception() const { return m_currentException; }
+
+ ///
+ /// Allocates a contiguous memory block and returns it.
+ ///
+ /// The number of characters to allocate.
+ /// A pointer to a block to write to, null if the stream buffer implementation does not support
+ /// alloc/commit.This is intended as an advanced API to be used only when it is important to
+ /// avoid extra copies.
+ _CharType* alloc(size_t count)
+ {
+ if (m_alloced)
+ throw std::logic_error(
+ "The buffer is already allocated, this maybe caused by overlap of stream read or write");
+
+ _CharType* alloc_result = _alloc(count);
+
+ if (alloc_result) m_alloced = true;
+
+ return alloc_result;
+ }
+
+ ///
+ /// Submits a block already allocated by the stream buffer.
+ ///
+ /// The number of characters to be committed.
+ /// This is intended as an advanced API to be used only when it is important to avoid extra
+ /// copies.
+ void commit(size_t count)
+ {
+ if (!m_alloced) throw std::logic_error("The buffer needs to allocate first");
+
+ _commit(count);
+ m_alloced = false;
+ }
+
+public:
+ virtual bool can_seek() const = 0;
+ virtual bool has_size() const = 0;
+ virtual utility::size64_t size() const { return 0; }
+ virtual size_t buffer_size(std::ios_base::openmode direction = std::ios_base::in) const = 0;
+ virtual void set_buffer_size(size_t size, std::ios_base::openmode direction = std::ios_base::in) = 0;
+ virtual size_t in_avail() const = 0;
+ virtual pos_type getpos(std::ios_base::openmode direction) const = 0;
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode direction) = 0;
+ virtual pos_type seekoff(off_type offset, std::ios_base::seekdir way, std::ios_base::openmode mode) = 0;
+ virtual bool acquire(_Out_writes_(count) _CharType*& ptr, _In_ size_t& count) = 0;
+ virtual void release(_Out_writes_(count) _CharType* ptr, _In_ size_t count) = 0;
+
+protected:
+ virtual pplx::task _putc(_CharType ch) = 0;
+
+ // This API is only needed for file streams and until we remove the deprecated stream buffer putn overload.
+ virtual pplx::task _putn(const _CharType* ptr, size_t count, bool)
+ {
+ // Default to no copy, only the file streams API overloads and performs a copy.
+ return _putn(ptr, count);
+ }
+ virtual pplx::task _putn(const _CharType* ptr, size_t count) = 0;
+
+ virtual pplx::task _bumpc() = 0;
+ virtual int_type _sbumpc() = 0;
+ virtual pplx::task _getc() = 0;
+ virtual int_type _sgetc() = 0;
+ virtual pplx::task _nextc() = 0;
+ virtual pplx::task _ungetc() = 0;
+ virtual pplx::task _getn(_Out_writes_(count) _CharType* ptr, _In_ size_t count) = 0;
+ virtual size_t _scopy(_Out_writes_(count) _CharType* ptr, _In_ size_t count) = 0;
+ virtual pplx::task _sync() = 0;
+ virtual _CharType* _alloc(size_t count) = 0;
+ virtual void _commit(size_t count) = 0;
+
+ ///
+ /// The real read head close operation, implementation should override it if there is any resource to be released.
+ ///
+ virtual pplx::task _close_read()
+ {
+ m_stream_can_read = false;
+ return pplx::task_from_result();
+ }
+
+ ///
+ /// The real write head close operation, implementation should override it if there is any resource to be released.
+ ///
+ virtual pplx::task _close_write()
+ {
+ m_stream_can_write = false;
+ return pplx::task_from_result();
+ }
+
+protected:
+ streambuf_state_manager(std::ios_base::openmode mode)
+ {
+ m_stream_can_read = (mode & std::ios_base::in) != 0;
+ m_stream_can_write = (mode & std::ios_base::out) != 0;
+ m_stream_read_eof = false;
+ m_alloced = false;
+ }
+
+ std::exception_ptr m_currentException;
+ // The in/out mode for the buffer
+ std::atomic m_stream_can_read;
+ std::atomic m_stream_can_write;
+ std::atomic m_stream_read_eof;
+ std::atomic m_alloced;
+
+private:
+ template
+ pplx::task<_CharType1> create_exception_checked_value_task(const _CharType1& val) const
+ {
+ if (this->exception() == nullptr)
+ return pplx::task_from_result<_CharType1>(static_cast<_CharType1>(val));
+ else
+ return pplx::task_from_exception<_CharType1>(this->exception());
+ }
+
+ // Set exception and eof states for async read
+ template
+ pplx::task<_CharType1> create_exception_checked_task(pplx::task<_CharType1> result,
+ std::function eof_test,
+ std::ios_base::openmode mode = std::ios_base::in |
+ std::ios_base::out)
+ {
+ auto thisPointer = this->shared_from_this();
+
+ auto func1 = [=](pplx::task<_CharType1> t1) -> pplx::task<_CharType1> {
+ try
+ {
+ thisPointer->m_stream_read_eof = eof_test(t1.get());
+ }
+ catch (...)
+ {
+ thisPointer->close(mode, std::current_exception()).get();
+ return pplx::task_from_exception<_CharType1>(thisPointer->exception(), pplx::task_options());
+ }
+ if (thisPointer->m_stream_read_eof && !(thisPointer->exception() == nullptr))
+ return pplx::task_from_exception<_CharType1>(thisPointer->exception(), pplx::task_options());
+ return t1;
+ };
+
+ if (result.is_done())
+ {
+ // If the data is already available, we should avoid scheduling a continuation, so we do it inline.
+ return func1(result);
+ }
+ else
+ {
+ return result.then(func1);
+ }
+ }
+
+ // Set eof states for sync read
+ int_type check_sync_read_eof(int_type ch)
+ {
+ m_stream_read_eof = ch == traits::eof();
+ return ch;
+ }
+};
+
+} // namespace details
+
+// Forward declarations
+template
+class basic_istream;
+template
+class basic_ostream;
+
+///
+/// Reference-counted stream buffer.
+///
+///
+/// The data type of the basic element of the streambuf.
+///
+///
+/// The data type of the basic element of the streambuf.
+///
+template
+class streambuf : public details::basic_streambuf<_CharType>
+{
+public:
+ typedef typename details::basic_streambuf<_CharType>::traits traits;
+ typedef typename details::basic_streambuf<_CharType>::int_type int_type;
+ typedef typename details::basic_streambuf<_CharType>::pos_type pos_type;
+ typedef typename details::basic_streambuf<_CharType>::off_type off_type;
+ typedef typename details::basic_streambuf<_CharType>::char_type char_type;
+
+ template
+ friend class streambuf;
+
+ ///
+ /// Constructor.
+ ///
+ /// A pointer to the concrete stream buffer implementation.
+ streambuf(_In_ const std::shared_ptr>& ptr) : m_buffer(ptr) {}
+
+ ///
+ /// Default constructor.
+ ///
+ streambuf() {}
+
+ ///
+ /// Converter Constructor.
+ ///
+ ///
+ /// The data type of the basic element of the source streambuf.
+ ///
+ /// The source buffer to be converted.
+ template
+ streambuf(const streambuf& other)
+ : m_buffer(std::static_pointer_cast>(
+ std::static_pointer_cast(other.m_buffer)))
+ {
+ static_assert(std::is_same::pos_type>::value &&
+ std::is_same::off_type>::value &&
+ std::is_integral<_CharType>::value && std::is_integral::value &&
+ std::is_integral::value &&
+ std::is_integral::int_type>::value &&
+ sizeof(_CharType) == sizeof(AlterCharType) &&
+ sizeof(int_type) == sizeof(typename details::basic_streambuf::int_type),
+ "incompatible stream character types");
+ }
+
+ ///
+ /// Constructs an input stream head for this stream buffer.
+ ///
+ /// basic_istream.
+ concurrency::streams::basic_istream<_CharType> create_istream() const
+ {
+ if (!can_read()) throw std::runtime_error("stream buffer not set up for input of data");
+ return concurrency::streams::basic_istream<_CharType>(*this);
+ }
+
+ ///
+ /// Constructs an output stream for this stream buffer.
+ ///
+ /// basic_ostream
+ concurrency::streams::basic_ostream<_CharType> create_ostream() const
+ {
+ if (!can_write()) throw std::runtime_error("stream buffer not set up for output of data");
+ return concurrency::streams::basic_ostream<_CharType>(*this);
+ }
+
+ ///
+ /// Checks if the stream buffer has been initialized or not.
+ ///
+ operator bool() const { return (bool)m_buffer; }
+
+ ///
+ /// Destructor
+ ///
+ virtual ~streambuf() {}
+
+ const std::shared_ptr>& get_base() const
+ {
+ if (!m_buffer)
+ {
+ throw std::invalid_argument("Invalid streambuf object");
+ }
+
+ return m_buffer;
+ }
+
+ ///
+ /// can_read is used to determine whether a stream buffer will support read operations (get).
+ ///
+ virtual bool can_read() const { return get_base()->can_read(); }
+
+ ///
+ /// can_write is used to determine whether a stream buffer will support write operations (put).
+ ///
+ virtual bool can_write() const { return get_base()->can_write(); }
+
+ ///
+ /// can_seek is used to determine whether a stream buffer supports seeking.
+ ///
+ /// True if seeking is supported, false otherwise.
+ virtual bool can_seek() const { return get_base()->can_seek(); }
+
+ ///
+ /// has_size is used to determine whether a stream buffer supports size().
+ ///
+ /// True if the size API is supported, false otherwise.
+ virtual bool has_size() const { return get_base()->has_size(); }
+
+ ///
+ /// Gets the total number of characters in the stream buffer, if known. Calls to has_size will determine
+ /// whether the result of size can be relied on.
+ ///
+ /// The total number of characters in the stream buffer.
+ virtual utility::size64_t size() const { return get_base()->size(); }
+
+ ///
+ /// Gets the stream buffer size, if one has been set.
+ ///
+ /// The direction of buffering (in or out)
+ /// The size of the internal buffer (for the given direction).
+ /// An implementation that does not support buffering will always return 0.
+ virtual size_t buffer_size(std::ios_base::openmode direction = std::ios_base::in) const
+ {
+ return get_base()->buffer_size(direction);
+ }
+
+ ///
+ /// Sets the stream buffer implementation to buffer or not buffer.
+ ///
+ /// The size to use for internal buffering, 0 if no buffering should be done.
+ /// The direction of buffering (in or out)
+ /// An implementation that does not support buffering will silently ignore calls to this function and it
+ /// will not have any effect on what is returned by subsequent calls to .
+ virtual void set_buffer_size(size_t size, std::ios_base::openmode direction = std::ios_base::in)
+ {
+ get_base()->set_buffer_size(size, direction);
+ }
+
+ ///
+ /// For any input stream, in_avail returns the number of characters that are immediately available
+ /// to be consumed without blocking. May be used in conjunction with to read data without
+ /// incurring the overhead of using tasks.
+ ///
+ /// Number of characters that are ready to read.
+ virtual size_t in_avail() const { return get_base()->in_avail(); }
+
+ ///
+ /// Checks if the stream buffer is open.
+ ///
+ /// No separation is made between open for reading and open for writing.
+ /// True if the stream buffer is open for reading or writing, false otherwise.
+ virtual bool is_open() const { return get_base()->is_open(); }
+
+ ///
+ /// is_eof is used to determine whether a read head has reached the end of the buffer.
+ ///
+ /// True if at the end of the buffer, false otherwise.
+ virtual bool is_eof() const { return get_base()->is_eof(); }
+
+ ///
+ /// Closes the stream buffer, preventing further read or write operations.
+ ///
+ /// The I/O mode (in or out) to close for.
+ virtual pplx::task close(std::ios_base::openmode mode = (std::ios_base::in | std::ios_base::out))
+ {
+ // We preserve the check here to workaround a Dev10 compiler crash
+ auto buffer = get_base();
+ return buffer ? buffer->close(mode) : pplx::task_from_result();
+ }
+
+ ///
+ /// Closes the stream buffer with an exception.
+ ///
+ /// The I/O mode (in or out) to close for.
+ /// Pointer to the exception.
+ virtual pplx::task close(std::ios_base::openmode mode, std::exception_ptr eptr)
+ {
+ // We preserve the check here to workaround a Dev10 compiler crash
+ auto buffer = get_base();
+ return buffer ? buffer->close(mode, eptr) : pplx::task_from_result();
+ }
+
+ ///
+ /// Writes a single character to the stream.
+ ///
+ /// The character to write
+ /// The value of the character. EOF if the write operation fails
+ virtual pplx::task putc(_CharType ch) { return get_base()->putc(ch); }
+
+ ///
+ /// Allocates a contiguous memory block and returns it.
+ ///
+ /// The number of characters to allocate.
+ /// A pointer to a block to write to, null if the stream buffer implementation does not support
+ /// alloc/commit.
+ virtual _CharType* alloc(size_t count) { return get_base()->alloc(count); }
+
+ ///
+ /// Submits a block already allocated by the stream buffer.
+ ///
+ /// The number of characters to be committed.
+ virtual void commit(size_t count) { get_base()->commit(count); }
+
+ ///
+ /// Gets a pointer to the next already allocated contiguous block of data.
+ ///
+ /// A reference to a pointer variable that will hold the address of the block on success.
+ /// The number of contiguous characters available at the address in 'ptr'.
+ /// true if the operation succeeded, false otherwise.
+ ///
+ /// A return of false does not necessarily indicate that a subsequent read operation would fail, only that
+ /// there is no block to return immediately or that the stream buffer does not support the operation.
+ /// The stream buffer may not de-allocate the block until is called.
+ /// If the end of the stream is reached, the function will return true, a null pointer, and a count of zero;
+ /// a subsequent read will not succeed.
+ ///
+ virtual bool acquire(_Out_ _CharType*& ptr, _Out_ size_t& count)
+ {
+ ptr = nullptr;
+ count = 0;
+ return get_base()->acquire(ptr, count);
+ }
+
+ ///
+ /// Releases a block of data acquired using . This frees the stream buffer to
+ /// de-allocate the memory, if it so desires. Move the read position ahead by the count.
+ ///
+ /// A pointer to the block of data to be released.
+ /// The number of characters that were read.
+ virtual void release(_Out_writes_(count) _CharType* ptr, _In_ size_t count) { get_base()->release(ptr, count); }
+
+ ///
+ /// Writes a number of characters to the stream.
+ ///
+ /// A pointer to the block of data to be written.
+ /// The number of characters to write.
+ /// The number of characters actually written, either 'count' or 0.
+ CASABLANCA_DEPRECATED("This API in some cases performs a copy. It is deprecated and will be removed in a future "
+ "release. Use putn_nocopy instead.")
+ virtual pplx::task putn(const _CharType* ptr, size_t count) { return get_base()->putn(ptr, count); }
+
+ ///
+ /// Writes a number of characters to the stream. Note: callers must make sure the data to be written is valid until
+ /// the returned task completes.
+ ///
+ /// A pointer to the block of data to be written.
+ /// The number of characters to write.
+ /// The number of characters actually written, either 'count' or 0.
+ virtual pplx::task putn_nocopy(const _CharType* ptr, size_t count)
+ {
+ return get_base()->putn_nocopy(ptr, count);
+ }
+
+ ///
+ /// Reads a single character from the stream and advances the read position.
+ ///
+ /// The value of the character. EOF if the read fails.
+ virtual pplx::task bumpc() { return get_base()->bumpc(); }
+
+ ///
+ /// Reads a single character from the stream and advances the read position.
+ ///
+ /// The value of the character. -1 if the read fails. -2 if an asynchronous read is
+ /// requiredThis is a synchronous operation, but is guaranteed to never block.
+ virtual typename details::basic_streambuf<_CharType>::int_type sbumpc() { return get_base()->sbumpc(); }
+
+ ///
+ /// Reads a single character from the stream without advancing the read position.
+ ///
+ /// The value of the byte. EOF if the read fails.
+ virtual pplx::task getc() { return get_base()->getc(); }
+
+ ///
+ /// Reads a single character from the stream without advancing the read position.
+ ///
+ /// The value of the character. EOF if the read fails. if an
+ /// asynchronous read is requiredThis is a synchronous operation, but is guaranteed to never
+ /// block.
+ virtual typename details::basic_streambuf<_CharType>::int_type sgetc() { return get_base()->sgetc(); }
+
+ ///
+ /// Advances the read position, then returns the next character without advancing again.
+ ///
+ /// The value of the character. EOF if the read fails.
+ pplx::task nextc() { return get_base()->nextc(); }
+
+ ///
+ /// Retreats the read position, then returns the current character without advancing.
+ ///
+ /// The value of the character. EOF if the read fails. if an
+ /// asynchronous read is required
+ pplx::task ungetc() { return get_base()->ungetc(); }
+
+ ///
+ /// Reads up to a given number of characters from the stream.
+ ///
+ /// The address of the target memory area.
+ /// The maximum number of characters to read.
+ /// The number of characters read. O if the end of the stream is reached.
+ virtual pplx::task getn(_Out_writes_(count) _CharType* ptr, _In_ size_t count)
+ {
+ return get_base()->getn(ptr, count);
+ }
+
+ ///
+ /// Copies up to a given number of characters from the stream, synchronously.
+ ///
+ /// The address of the target memory area.
+ /// The maximum number of characters to read.
+ /// The number of characters copied. O if the end of the stream is reached or an asynchronous read is
+ /// required.This is a synchronous operation, but is guaranteed to never block.
+ virtual size_t scopy(_Out_writes_(count) _CharType* ptr, _In_ size_t count)
+ {
+ return get_base()->scopy(ptr, count);
+ }
+
+ ///
+ /// Gets the current read or write position in the stream.
+ ///
+ /// The I/O direction to seek (see remarks)
+ /// The current position. EOF if the operation fails.
+ /// Some streams may have separate write and read cursors.
+ /// For such streams, the direction parameter defines whether to move the read or the write
+ /// cursor.
+ virtual typename details::basic_streambuf<_CharType>::pos_type getpos(std::ios_base::openmode direction) const
+ {
+ return get_base()->getpos(direction);
+ }
+
+ ///
+ /// Seeks to the given position.
+ ///
+ /// The offset from the beginning of the stream.
+ /// The I/O direction to seek (see remarks).
+ /// The position. EOF if the operation fails.
+ /// Some streams may have separate write and read cursors. For such streams, the direction parameter
+ /// defines whether to move the read or the write cursor.
+ virtual typename details::basic_streambuf<_CharType>::pos_type seekpos(
+ typename details::basic_streambuf<_CharType>::pos_type pos, std::ios_base::openmode direction)
+ {
+ return get_base()->seekpos(pos, direction);
+ }
+
+ ///
+ /// Seeks to a position given by a relative offset.
+ ///
+ /// The relative position to seek to
+ /// The starting point (beginning, end, current) for the seek.
+ /// The I/O direction to seek (see remarks)
+ /// The position. EOF if the operation fails.
+ /// Some streams may have separate write and read cursors.
+ /// For such streams, the mode parameter defines whether to move the read or the write cursor.
+ virtual typename details::basic_streambuf<_CharType>::pos_type seekoff(
+ typename details::basic_streambuf<_CharType>::off_type offset,
+ std::ios_base::seekdir way,
+ std::ios_base::openmode mode)
+ {
+ return get_base()->seekoff(offset, way, mode);
+ }
+
+ ///
+ /// For output streams, flush any internally buffered data to the underlying medium.
+ ///
+ /// true if the flush succeeds, false if not
+ virtual pplx::task sync() { return get_base()->sync(); }
+
+ ///
+ /// Retrieves the stream buffer exception_ptr if it has been set.
+ ///
+ /// Pointer to the exception, if it has been set; otherwise, nullptr will be returned
+ virtual std::exception_ptr exception() const { return get_base()->exception(); }
+
+private:
+ std::shared_ptr> m_buffer;
+};
+
+} // namespace streams
+} // namespace Concurrency
diff --git a/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/asyncrt_utils.h b/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/asyncrt_utils.h
new file mode 100644
index 0000000..a38702f
--- /dev/null
+++ b/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/asyncrt_utils.h
@@ -0,0 +1,697 @@
+/***
+ * Copyright (C) Microsoft. All rights reserved.
+ * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+ *
+ * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+ *
+ * Various common utilities.
+ *
+ * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
+ *
+ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ ****/
+
+#pragma once
+
+#include "cpprest/details/basic_types.h"
+#include "pplx/pplxtasks.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef _WIN32
+#include
+#if !defined(ANDROID) && !defined(__ANDROID__) && defined(HAVE_XLOCALE_H) // CodePlex 269
+/* Systems using glibc: xlocale.h has been removed from glibc 2.26
+ The above include of locale.h is sufficient
+ Further details: https://sourceware.org/git/?p=glibc.git;a=commit;h=f0be25b6336db7492e47d2e8e72eb8af53b5506d */
+#include
+#endif
+#endif
+
+/// Various utilities for string conversions and date and time manipulation.
+namespace utility
+{
+// Left over from VS2010 support, remains to avoid breaking.
+typedef std::chrono::seconds seconds;
+
+/// Functions for converting to/from std::chrono::seconds to xml string.
+namespace timespan
+{
+///
+/// Converts a timespan/interval in seconds to xml duration string as specified by
+/// http://www.w3.org/TR/xmlschema-2/#duration
+///
+_ASYNCRTIMP utility::string_t __cdecl seconds_to_xml_duration(utility::seconds numSecs);
+
+///
+/// Converts an xml duration to timespan/interval in seconds
+/// http://www.w3.org/TR/xmlschema-2/#duration
+///
+_ASYNCRTIMP utility::seconds __cdecl xml_duration_to_seconds(const utility::string_t& timespanString);
+} // namespace timespan
+
+/// Functions for Unicode string conversions.
+namespace conversions
+{
+///
+/// Converts a UTF-16 string to a UTF-8 string.
+///
+/// A two byte character UTF-16 string.
+/// A single byte character UTF-8 string.
+_ASYNCRTIMP std::string __cdecl utf16_to_utf8(const utf16string& w);
+
+///
+/// Converts a UTF-8 string to a UTF-16
+///
+/// A single byte character UTF-8 string.
+/// A two byte character UTF-16 string.
+_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(const std::string& s);
+
+///
+/// Converts a ASCII (us-ascii) string to a UTF-16 string.
+///
+/// A single byte character us-ascii string.
+/// A two byte character UTF-16 string.
+_ASYNCRTIMP utf16string __cdecl usascii_to_utf16(const std::string& s);
+
+///
+/// Converts a Latin1 (iso-8859-1) string to a UTF-16 string.
+///
+/// A single byte character UTF-8 string.
+/// A two byte character UTF-16 string.
+_ASYNCRTIMP utf16string __cdecl latin1_to_utf16(const std::string& s);
+
+///
+/// Converts a Latin1 (iso-8859-1) string to a UTF-8 string.
+///
+/// A single byte character UTF-8 string.
+/// A single byte character UTF-8 string.
+_ASYNCRTIMP utf8string __cdecl latin1_to_utf8(const std::string& s);
+
+///
+/// Converts to a platform dependent Unicode string type.
+///
+/// A single byte character UTF-8 string.
+/// A platform dependent string type.
+#ifdef _UTF16_STRINGS
+_ASYNCRTIMP utility::string_t __cdecl to_string_t(std::string&& s);
+#else
+inline utility::string_t&& to_string_t(std::string&& s) { return std::move(s); }
+#endif
+
+///
+/// Converts to a platform dependent Unicode string type.
+///
+/// A two byte character UTF-16 string.
+/// A platform dependent string type.
+#ifdef _UTF16_STRINGS
+inline utility::string_t&& to_string_t(utf16string&& s) { return std::move(s); }
+#else
+_ASYNCRTIMP utility::string_t __cdecl to_string_t(utf16string&& s);
+#endif
+///
+/// Converts to a platform dependent Unicode string type.
+///
+/// A single byte character UTF-8 string.
+/// A platform dependent string type.
+#ifdef _UTF16_STRINGS
+_ASYNCRTIMP utility::string_t __cdecl to_string_t(const std::string& s);
+#else
+inline const utility::string_t& to_string_t(const std::string& s) { return s; }
+#endif
+
+///
+/// Converts to a platform dependent Unicode string type.
+///
+/// A two byte character UTF-16 string.
+/// A platform dependent string type.
+#ifdef _UTF16_STRINGS
+inline const utility::string_t& to_string_t(const utf16string& s) { return s; }
+#else
+_ASYNCRTIMP utility::string_t __cdecl to_string_t(const utf16string& s);
+#endif
+
+///
+/// Converts to a UTF-16 from string.
+///
+/// A single byte character UTF-8 string.
+/// A two byte character UTF-16 string.
+_ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string& value);
+
+///
+/// Converts to a UTF-16 from string.
+///
+/// A two byte character UTF-16 string.
+/// A two byte character UTF-16 string.
+inline const utf16string& to_utf16string(const utf16string& value) { return value; }
+///
+/// Converts to a UTF-16 from string.
+///
+/// A two byte character UTF-16 string.
+/// A two byte character UTF-16 string.
+inline utf16string&& to_utf16string(utf16string&& value) { return std::move(value); }
+
+///
+/// Converts to a UTF-8 string.
+///
+/// A single byte character UTF-8 string.
+/// A single byte character UTF-8 string.
+inline std::string&& to_utf8string(std::string&& value) { return std::move(value); }
+
+///
+/// Converts to a UTF-8 string.
+///
+/// A single byte character UTF-8 string.
+/// A single byte character UTF-8 string.
+inline const std::string& to_utf8string(const std::string& value) { return value; }
+
+///
+/// Converts to a UTF-8 string.
+///
+/// A two byte character UTF-16 string.
+/// A single byte character UTF-8 string.
+_ASYNCRTIMP std::string __cdecl to_utf8string(const utf16string& value);
+
+///
+/// Encode the given byte array into a base64 string
+///
+_ASYNCRTIMP utility::string_t __cdecl to_base64(const std::vector& data);
+
+///
+/// Encode the given 8-byte integer into a base64 string
+///
+_ASYNCRTIMP utility::string_t __cdecl to_base64(uint64_t data);
+
+///
+/// Decode the given base64 string to a byte array
+///
+_ASYNCRTIMP std::vector __cdecl from_base64(const utility::string_t& str);
+
+template
+CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
+ "locale support is required.")
+utility::string_t print_string(const Source& val, const std::locale& loc = std::locale())
+{
+ utility::ostringstream_t oss;
+ oss.imbue(loc);
+ oss << val;
+ if (oss.bad())
+ {
+ throw std::bad_cast();
+ }
+ return oss.str();
+}
+
+CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
+ "locale support is required.")
+inline utility::string_t print_string(const utility::string_t& val) { return val; }
+
+namespace details
+{
+#if defined(__ANDROID__)
+template
+inline std::string to_string(const T t)
+{
+ std::ostringstream os;
+ os.imbue(std::locale::classic());
+ os << t;
+ return os.str();
+}
+#endif
+
+template
+inline utility::string_t to_string_t(const T t)
+{
+#ifdef _UTF16_STRINGS
+ using std::to_wstring;
+ return to_wstring(t);
+#else
+#if !defined(__ANDROID__)
+ using std::to_string;
+#endif
+ return to_string(t);
+#endif
+}
+
+template
+utility::string_t print_string(const Source& val)
+{
+ utility::ostringstream_t oss;
+ oss.imbue(std::locale::classic());
+ oss << val;
+ if (oss.bad())
+ {
+ throw std::bad_cast();
+ }
+ return oss.str();
+}
+
+inline const utility::string_t& print_string(const utility::string_t& val) { return val; }
+
+template
+utf8string print_utf8string(const Source& val)
+{
+ return conversions::to_utf8string(print_string(val));
+}
+inline const utf8string& print_utf8string(const utf8string& val) { return val; }
+
+template
+Target scan_string(const utility::string_t& str)
+{
+ Target t;
+ utility::istringstream_t iss(str);
+ iss.imbue(std::locale::classic());
+ iss >> t;
+ if (iss.bad())
+ {
+ throw std::bad_cast();
+ }
+ return t;
+}
+
+inline const utility::string_t& scan_string(const utility::string_t& str) { return str; }
+} // namespace details
+
+template
+CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
+ "locale support is required.")
+Target scan_string(const utility::string_t& str, const std::locale& loc = std::locale())
+{
+ Target t;
+ utility::istringstream_t iss(str);
+ iss.imbue(loc);
+ iss >> t;
+ if (iss.bad())
+ {
+ throw std::bad_cast();
+ }
+ return t;
+}
+
+CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
+ "locale support is required.")
+inline utility::string_t scan_string(const utility::string_t& str) { return str; }
+} // namespace conversions
+
+namespace details
+{
+///
+/// Cross platform RAII container for setting thread local locale.
+///
+class scoped_c_thread_locale
+{
+public:
+ _ASYNCRTIMP scoped_c_thread_locale();
+ _ASYNCRTIMP ~scoped_c_thread_locale();
+
+#if !defined(ANDROID) && !defined(__ANDROID__) // CodePlex 269
+#ifdef _WIN32
+ typedef _locale_t xplat_locale;
+#else
+ typedef locale_t xplat_locale;
+#endif
+
+ static _ASYNCRTIMP xplat_locale __cdecl c_locale();
+#endif
+private:
+#ifdef _WIN32
+ std::string m_prevLocale;
+ int m_prevThreadSetting;
+#elif !(defined(ANDROID) || defined(__ANDROID__))
+ locale_t m_prevLocale;
+#endif
+ scoped_c_thread_locale(const scoped_c_thread_locale&);
+ scoped_c_thread_locale& operator=(const scoped_c_thread_locale&);
+};
+
+///
+/// Our own implementation of alpha numeric instead of std::isalnum to avoid
+/// taking global lock for performance reasons.
+///
+inline bool __cdecl is_alnum(const unsigned char uch) CPPREST_NOEXCEPT
+{ // test if uch is an alnum character
+ // special casing char to avoid branches
+ // clang-format off
+ static CPPREST_CONSTEXPR bool is_alnum_table[UCHAR_MAX + 1] = {
+ /* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */
+ /* 0X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 1X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 2X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 3X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0-9 */
+ /* 4X */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A-Z */
+ /* 5X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ /* 6X */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a-z */
+ /* 7X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
+ /* non-ASCII values initialized to 0 */
+ };
+ // clang-format on
+ return (is_alnum_table[uch]);
+}
+
+///
+/// Our own implementation of alpha numeric instead of std::isalnum to avoid
+/// taking global lock for performance reasons.
+///
+inline bool __cdecl is_alnum(const char ch) CPPREST_NOEXCEPT { return (is_alnum(static_cast(ch))); }
+
+///
+/// Our own implementation of alpha numeric instead of std::isalnum to avoid
+/// taking global lock for performance reasons.
+///
+template
+inline bool __cdecl is_alnum(Elem ch) CPPREST_NOEXCEPT
+{
+ // assumes 'x' == L'x' for the ASCII range
+ typedef typename std::make_unsigned::type UElem;
+ const auto uch = static_cast(ch);
+ return (uch <= static_cast('z') && is_alnum(static_cast(uch)));
+}
+
+///
+/// Simplistic implementation of make_unique. A better implementation would be based on variadic templates
+/// and therefore not be compatible with Dev10.
+///
+template
+std::unique_ptr<_Type> make_unique()
+{
+ return std::unique_ptr<_Type>(new _Type());
+}
+
+template
+std::unique_ptr<_Type> make_unique(_Arg1&& arg1)
+{
+ return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1)));
+}
+
+template
+std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2)
+{
+ return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2)));
+}
+
+template
+std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3)
+{
+ return std::unique_ptr<_Type>(
+ new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2), std::forward<_Arg3>(arg3)));
+}
+
+template
+std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4)
+{
+ return std::unique_ptr<_Type>(new _Type(
+ std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2), std::forward<_Arg3>(arg3), std::forward<_Arg4>(arg4)));
+}
+
+template
+std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4, _Arg5&& arg5)
+{
+ return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1),
+ std::forward<_Arg2>(arg2),
+ std::forward<_Arg3>(arg3),
+ std::forward<_Arg4>(arg4),
+ std::forward<_Arg5>(arg5)));
+}
+
+template
+std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4, _Arg5&& arg5, _Arg6&& arg6)
+{
+ return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1),
+ std::forward<_Arg2>(arg2),
+ std::forward<_Arg3>(arg3),
+ std::forward<_Arg4>(arg4),
+ std::forward<_Arg5>(arg5),
+ std::forward<_Arg6>(arg6)));
+}
+
+///
+/// Cross platform utility function for performing case insensitive string equality comparison.
+///
+/// First string to compare.
+/// Second strong to compare.
+/// true if the strings are equivalent, false otherwise
+_ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& right) CPPREST_NOEXCEPT;
+
+///
+/// Cross platform utility function for performing case insensitive string equality comparison.
+///
+/// First string to compare.
+/// Second strong to compare.
+/// true if the strings are equivalent, false otherwise
+_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT;
+
+///
+/// Cross platform utility function for performing case insensitive string less-than comparison.
+///
+/// First string to compare.
+/// Second strong to compare.
+/// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise,
+/// false.
+_ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& right) CPPREST_NOEXCEPT;
+
+///
+/// Cross platform utility function for performing case insensitive string less-than comparison.
+///
+/// First string to compare.
+/// Second strong to compare.
+/// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise,
+/// false.
+_ASYNCRTIMP bool __cdecl str_iless(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT;
+
+///
+/// Convert a string to lowercase in place.
+///
+/// The string to convert to lowercase.
+_ASYNCRTIMP void __cdecl inplace_tolower(std::string& target) CPPREST_NOEXCEPT;
+
+///
+/// Convert a string to lowercase in place.
+///
+/// The string to convert to lowercase.
+_ASYNCRTIMP void __cdecl inplace_tolower(std::wstring& target) CPPREST_NOEXCEPT;
+
+#ifdef _WIN32
+
+///
+/// Category error type for Windows OS errors.
+///
+class windows_category_impl : public std::error_category
+{
+public:
+ virtual const char* name() const CPPREST_NOEXCEPT { return "windows"; }
+
+ virtual std::string message(int errorCode) const CPPREST_NOEXCEPT;
+
+ virtual std::error_condition default_error_condition(int errorCode) const CPPREST_NOEXCEPT;
+};
+
+///
+/// Gets the one global instance of the windows error category.
+///
+/// An error category instance.
+_ASYNCRTIMP const std::error_category& __cdecl windows_category();
+
+#else
+
+///
+/// Gets the one global instance of the linux error category.
+///
+/// An error category instance.
+_ASYNCRTIMP const std::error_category& __cdecl linux_category();
+
+#endif
+
+///
+/// Gets the one global instance of the current platform's error category.
+///
+_ASYNCRTIMP const std::error_category& __cdecl platform_category();
+
+///
+/// Creates an instance of std::system_error from a OS error code.
+///
+inline std::system_error __cdecl create_system_error(unsigned long errorCode)
+{
+ std::error_code code((int)errorCode, platform_category());
+ return std::system_error(code, code.message());
+}
+
+///
+/// Creates a std::error_code from a OS error code.
+///
+inline std::error_code __cdecl create_error_code(unsigned long errorCode)
+{
+ return std::error_code((int)errorCode, platform_category());
+}
+
+///
+/// Creates the corresponding error message from a OS error code.
+///
+inline utility::string_t __cdecl create_error_message(unsigned long errorCode)
+{
+ return utility::conversions::to_string_t(create_error_code(errorCode).message());
+}
+
+} // namespace details
+
+class datetime
+{
+public:
+ typedef uint64_t interval_type;
+
+ ///
+ /// Defines the supported date and time string formats.
+ ///
+ enum date_format
+ {
+ RFC_1123,
+ ISO_8601
+ };
+
+ ///
+ /// Returns the current UTC time.
+ ///
+ static _ASYNCRTIMP datetime __cdecl utc_now();
+
+ ///
+ /// An invalid UTC timestamp value.
+ ///
+ enum : interval_type
+ {
+ utc_timestamp_invalid = static_cast(-1)
+ };
+
+ ///
+ /// Returns seconds since Unix/POSIX time epoch at 01-01-1970 00:00:00.
+ /// If time is before epoch, utc_timestamp_invalid is returned.
+ ///
+ static interval_type utc_timestamp()
+ {
+ const auto seconds = utc_now().to_interval() / _secondTicks;
+ if (seconds >= 11644473600LL)
+ {
+ return seconds - 11644473600LL;
+ }
+ else
+ {
+ return utc_timestamp_invalid;
+ }
+ }
+
+ datetime() : m_interval(0) {}
+
+ ///
+ /// Creates datetime from a string representing time in UTC in RFC 1123 format.
+ ///
+ /// Returns a datetime of zero if not successful.
+ static _ASYNCRTIMP datetime __cdecl from_string(const utility::string_t& timestring, date_format format = RFC_1123);
+
+ ///
+ /// Returns a string representation of the datetime.
+ ///
+ _ASYNCRTIMP utility::string_t to_string(date_format format = RFC_1123) const;
+
+ ///
+ /// Returns the integral time value.
+ ///
+ interval_type to_interval() const { return m_interval; }
+
+ datetime operator-(interval_type value) const { return datetime(m_interval - value); }
+
+ datetime operator+(interval_type value) const { return datetime(m_interval + value); }
+
+ bool operator==(datetime dt) const { return m_interval == dt.m_interval; }
+
+ bool operator!=(const datetime& dt) const { return !(*this == dt); }
+
+ static interval_type from_milliseconds(unsigned int milliseconds) { return milliseconds * _msTicks; }
+
+ static interval_type from_seconds(unsigned int seconds) { return seconds * _secondTicks; }
+
+ static interval_type from_minutes(unsigned int minutes) { return minutes * _minuteTicks; }
+
+ static interval_type from_hours(unsigned int hours) { return hours * _hourTicks; }
+
+ static interval_type from_days(unsigned int days) { return days * _dayTicks; }
+
+ bool is_initialized() const { return m_interval != 0; }
+
+private:
+ friend int operator-(datetime t1, datetime t2);
+
+ static const interval_type _msTicks = static_cast(10000);
+ static const interval_type _secondTicks = 1000 * _msTicks;
+ static const interval_type _minuteTicks = 60 * _secondTicks;
+ static const interval_type _hourTicks = 60 * 60 * _secondTicks;
+ static const interval_type _dayTicks = 24 * 60 * 60 * _secondTicks;
+
+ // Private constructor. Use static methods to create an instance.
+ datetime(interval_type interval) : m_interval(interval) {}
+
+ // Storing as hundreds of nanoseconds 10e-7, i.e. 1 here equals 100ns.
+ interval_type m_interval;
+};
+
+inline int operator-(datetime t1, datetime t2)
+{
+ auto diff = (t1.m_interval - t2.m_interval);
+
+ // Round it down to seconds
+ diff /= 10 * 1000 * 1000;
+
+ return static_cast(diff);
+}
+
+///
+/// Nonce string generator class.
+///
+class nonce_generator
+{
+public:
+ ///
+ /// Define default nonce length.
+ ///
+ enum
+ {
+ default_length = 32
+ };
+
+ ///
+ /// Nonce generator constructor.
+ ///
+ /// Length of the generated nonce string.
+ nonce_generator(int length = default_length)
+ : m_random(static_cast(utility::datetime::utc_timestamp())), m_length(length)
+ {
+ }
+
+ ///
+ /// Generate a nonce string containing random alphanumeric characters (A-Za-z0-9).
+ /// Length of the generated string is set by length().
+ ///
+ /// The generated nonce string.
+ _ASYNCRTIMP utility::string_t generate();
+
+ ///
+ /// Get length of generated nonce string.
+ ///
+ /// Nonce string length.
+ int length() const { return m_length; }
+
+ ///
+ /// Set length of the generated nonce string.
+ ///
+ /// Lenght of nonce string.
+ void set_length(int length) { m_length = length; }
+
+private:
+ std::mt19937 m_random;
+ int m_length;
+};
+
+} // namespace utility
diff --git a/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/base_uri.h b/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/base_uri.h
new file mode 100644
index 0000000..7c69431
--- /dev/null
+++ b/packages/cpprestsdk.v141.2.10.12.1/build/native/include/cpprest/base_uri.h
@@ -0,0 +1,391 @@
+/***
+ * Copyright (C) Microsoft. All rights reserved.
+ * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+ *
+ * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+ *
+ * Protocol independent support for URIs.
+ *
+ * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
+ *
+ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ ****/
+
+#pragma once
+
+#include "cpprest/asyncrt_utils.h"
+#include "cpprest/details/basic_types.h"
+#include