Here’s a code snippet from CppRestSDK How to POST multipart data
std::stringstream bodyContent;
std::ostringstream imgContent;
bodyContent << ... << imgContent.str();
imgContent is the binary file content in which there’s inevitably a ‘\0’.
I checked std::ostringstream::str() first,
std::ostringstream oss;
oss << "abc\0""123";
std::string s = oss.str();
cout << s.length();//3
Yes, the string would be sliced by ‘\0’. So I guessed the file eventually uploaded would be sliced by the ‘\0’. And I also checked the file, there are a lot of ‘\0’s.
But unexpectedly, the uploaded file was intact. I got into deep confustion.
Below is the code to copy file content into the stream.
std::ifstream inputFile;
inputFile.open(imagePath, std::ios::binary | std::ios::in);
std::ostringstream imgContent;
std::copy(std::istreambuf_iterator<char>(inputFile),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(imgContent));
>Solution :
oss << "abc\0""123";
There will be slicing up to the \0 here, because the overload of operator<< for std::ostream which will be chosen here expects a const char* pointer to a null-terminated character string and will interpret it as such. There is no overload of operator<< for std::ostream taking a reference to a const char array. If there was, the function would be able to tell the full size of the literal and print it including the embedded null character.
bodyContent << ... << imgContent.str();
Here however str() returns a std::string which store an explicit size and can hold null characters as part of its contents. There is an overload of operator<< for std::ostream which expects a std::string and will write its full contents, not interpreting the string contents as a null-terminated string.
A string literal can be forced into a std::string even if null characters are embedded e.g. with the help of the user-defined literal operator operator""s which produces a std::string:
using namespace std::string_literals;
oss << "abc\0123"s;
