http_client of cpprestsdk/casablanca - c++

I have api https://api.gm-system.net/api/authenticate/searchStaffs/searchText which return a list staff.
And here is my code to access this api using cpprestsdk with c++.
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.html")).then([=](ostream outFile)
{
*fileStream = outFile;
// Create http_client to send the request.
http_client client(U("https://api.gm-system.net/api/authenticate/searchStaffs/michael"));
return client.request(methods::GET);
})
// Handle response headers arriving.
.then([=](http_response response)
{
......
}
This one if fine. But with that i just manually input the "michael" searchText.
How can I make it that it will accept any searchText something like this.
void MyTest(std::string searchText)
{
..... code here
// Create http_client to send the request.
http_client client(U("https://api.gm-system.net/api/authenticate/searchStaffs/" + searchText));
return client.request(methods::GET);
..... code here
}
I already tried this it won't work. Some problem with 'U' macro.
From https://github.com/Microsoft/cpprestsdk/wiki/FAQ the discription of U macro is says:
The 'U' macro can be used to create a string literal of the platform type. If you are using a library causing conflicts with the 'U' macro, for example Boost.Iostreams it can be turned off by defining the macro '_TURN_OFF_PLATFORM_STRING' before including the C++ REST SDK header files.
If I point my cursor to U, the error says:
no operator "+" matches these operands operand types are; const wchar_t[57] + const std::string
I hope some can help me. Thanks.

Since
The C++ REST SDK uses a different string type dependent on the
platform being targeted. For example for the Windows platforms
utility::string_t is std::wstring using UTF-16, on Linux std::string
using UTF-8.
you should use the utility::string_t class whenever it is required and don't mix it with std::string or const char * (and use the U macro when in need of a literal).
In other words, your function should accept an utility::string_t as its searchText argument (instead of std::string):
void MyTest(utility::string_t searchText)
{
http_client client(U("https://api.gm-system.net/api/authenticate/searchStaffs/") + searchText);
// etc ...
}
use it like this:
int main()
{
utility::string_t searchText = U("Michael");
MyTest(searchText);
return 0;
}
If the function has to be called from a platform specific context, the corresponding std type can be used as the passed in argument type (i.e. use std::wstring on Windows):
std::wstring searchText = L"Michael";
MyTest(searchText);

Related

How do I convert a std::string to System.String in C++ with Il2CppInspector?

I am using Il2CppInspector to generate scaffolding for a Unity game. I am able to convert System.String (app::String in Il2CppInspector) to std::string using the functions provided below.
How would I reverse this process; how do I convert a std::string to System.String?
helpers.cpp
// Helper function to convert Il2CppString to std::string
std::string il2cppi_to_string(Il2CppString* str) {
std::u16string u16(reinterpret_cast<const char16_t*>(str->chars));
return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(u16);
}
// Helper function to convert System.String to std::string
std::string il2cppi_to_string(app::String* str) {
return il2cppi_to_string(reinterpret_cast<Il2CppString*>(str));
}
In short, I am looking for a function that takes in a std::string and returns an app::String
// Helper function to convert std::string to System.String
app::String string_to_il2cppi(std::string str) {
// Conversion code here
}
The accepted answer is actually wrong, there is no size parameter and copying stops at the first null byte (0x00) according to the MSDN documentation.
The following code fixes these problems and works correctly:
app::String* string_to_il2cppi(const std::string& string)
{
const auto encoding = (*app::Encoding__TypeInfo)->static_fields->utf8Encoding;
const auto managed_string = app::String_CreateStringFromEncoding((uint8_t*)&string.at(0), string.size(), encoding, nullptr);
return managed_string;
}
A quote from djkaty:
To create a string, you cannot use System.String‘s constructors –
these are redirected to icalls that throw exceptions. Instead, you
should use the internal Mono function String.CreateString. This
function has many overloads accepting various types of pointer and
array; an easy one to use accepts a uint16_t* to a Unicode string and
can be called as follows [...]
Export Il2CppInspector with all namespaces, which will give you access to Marshal_PtrToStringAnsi.
app::String* string_to_il2cppi(std::string str) {
return app::Marshal_PtrToStringAnsi((void*)&str, NULL);
}
Limitation: do not attempt to convert a string with null terminators inside of them example:
std::string test = "Hello\0world";
Use BullyWiiPlaza's solution if this is an issue for you.

how read a stream into a Concurrency::streams::streambuf<uint8_t> buffer; in C++

I'm working with cpprestsdk in a project as a server. I need to read the Body of a put request.
the documentation uses message.body().read_to_end(buffer);
I tried this without success.
void MyProject::handle_post(http_request message)
{
Concurrency::streams::streambuf<uint8_t> buffer;
buffer.alloc(10); // Crashes Here
message.body().read_to_end(buffer);
...
What am I doing wrong? How can I allocate and read data from that buffer?
Faced the same issue, I opted for not using read_to_end because every solution I found throw an exception. Turns out it's not the easiest way to extract the body.
To extract the data from the http_message body ( regardless of MIME type ) i am using the following
const auto data = message.content_ready().get().extract_vector().get();
const utility::string_t body = { data.begin(), data.end() };
The other option which I can offer up if you need an std::string in all cases is
const auto body = response.content_ready().get().extract_utf8string(true).get();
which is also very convenient way to access the data.
You can use this to read the body to a file:
auto fileStream = concurrency::streams::fstream::open_ostream(utility::conversions::to_string_t(filepath), std::ios::out | std::ios::binary).get();
// Get body from request
auto bodyStream = request.body();
// Write input from request body directly to output filestream
bodyStream.read_to_end(fileStream.streambuf()).wait();
fileStream.close().wait();

How to print utility::string_t type value? [duplicate]

I am using the casablanca C++ Rest library to make HTTP requests.
The problem is that this gives a utility::string_t string as output and I can't quite find any way to convert this to a classic std::string. Any ideas?
client.request(methods::GET).then([](http_response response)
{
if(response.status_code() == status_codes::OK)
{
string_t s = response.extract_string().get();
}
});
Depending on what platform you are compiling for, the utility::string_t type will be typedef'd to either std::wstring (on Windows) or std::string (on Linux/OSX).
To get a classic utf-8 std::string regardless of platform, take a look at utility::conversions::to_utf8string.
reference documentation
If you see the documentation for C++ REST SDK from github, you'll find a typedef
C++ Rest SDK - utility Namespace Reference
typedef std::string string_t;
So no need to convert it. Both are same types.
On Windows Phone 8.1 there is this define:
typedef std::wstring string_t;
I used this:
string_t toStringT = U("sample");
std::string fromStringT(toStringT.begin(), toStringT.end());
or:
std::string fromStringT(conversions::to_utf8string(toStringT));

C++ nlohmann/json how to use runtime provided json_pointers to read json values

I am using the json parser Json for Modern C++ (https://github.com/nlohmann/json). I know that I can get the value of a JSON value with a JSON_Pointer:
auto v1 = j["/a/b/c"_json_pointer];
But how would I go about getting the value if the JSON Pointer is defined at runtime (passed into my function)?
std:string s1 = "/a/b/c";
auto v1 = j[s1]; // doesn't work
You can't append "json_pointer" to either the std::string assignment or to the s1 variable. Is there a function that will convert a std::string to a json_pointer? The caller knows nothing about json and can't have access to the "json.hpp" header. I've also tried
std::string s1 = "/a/b/c";
json_pointer p1(s1);
but "json_pointer" class is undefined. Other than this issue this is a great library that does everything else I need. TIA.
Look at the source code:
inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t)
{
return nlohmann::json::json_pointer(s);
}
If json_pointer is undefined, then you aren't using the right namespaces. Try
using nlohmann::json::json_pointer;
std::string s1 = "/a/b/c";
json_pointer p1(s1);

no suitable user-defined conversion from utility::string_t to std::string

I am using the casablanca C++ Rest library to make HTTP requests.
The problem is that this gives a utility::string_t string as output and I can't quite find any way to convert this to a classic std::string. Any ideas?
client.request(methods::GET).then([](http_response response)
{
if(response.status_code() == status_codes::OK)
{
string_t s = response.extract_string().get();
}
});
Depending on what platform you are compiling for, the utility::string_t type will be typedef'd to either std::wstring (on Windows) or std::string (on Linux/OSX).
To get a classic utf-8 std::string regardless of platform, take a look at utility::conversions::to_utf8string.
reference documentation
If you see the documentation for C++ REST SDK from github, you'll find a typedef
C++ Rest SDK - utility Namespace Reference
typedef std::string string_t;
So no need to convert it. Both are same types.
On Windows Phone 8.1 there is this define:
typedef std::wstring string_t;
I used this:
string_t toStringT = U("sample");
std::string fromStringT(toStringT.begin(), toStringT.end());
or:
std::string fromStringT(conversions::to_utf8string(toStringT));