Unable to write json data to file in c++ - c++

I have a json data which I want to write to a json file in c++. I am using nlohmann json and below is the code:
using nlohmann::json;
std::ofstream output_file("C:\\Program Files (x86)\\output.json");
json outJson;
std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::string created(30, '\0');
std::strftime(&created[0], created.size(), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
outJson["Created"] = created;
outJson["DataId"] = "T-452";
outJson["Type"] = "UserData";
output_file << outJson;
But nothing is getting saved in output.json.

Explicit serialisation and calling close() before exiting should do the trick here.
output_file << outJson.dump(4);
output_file.close();

Related

Initialize Magick++ from stream buffer in C++

I can't seem to find an example of the proper syntax/method for initializing an ImageMagick Magick++ object from an iostream stream_buffer in C++.
I'm trying to use the result from an aws sdk getObject which seems to return a stream buffer to push into ImageMagick to create thumbnails via lambda on demand.
example of the relevant code from the aws-sdk-cpp I'm using to retrieve the object:
auto get_object_outcome = s3_client.GetObject(object_request);
if (get_object_outcome.IsSuccess())
{
// Get an Aws::IOStream reference to the retrieved file
auto &retrieved_file = get_object_outcome.GetResultWithOwnership().GetBody();
// read the object's contents and write to a file
std::ofstream output_file(file_name, std::ios::binary);
output_file << retrieved_file.rdbuf();
return true;
}
else
{
auto error = get_object_outcome.GetError();
std::cout << "ERROR: " << error.GetExceptionName() << ": "
<< error.GetMessage() << std::endl;
return false;
}
Any help is appreciated - new to c++ so I'm not yet versed in converting more advanced data formats such as streams/blobs/buffers.
I try taking your retrieved_file, copy it into a std::vector, create an magick blob, create an image from the blob:
// create an empty buffer
std::vector<char> buffer;
// file your buffer with the retrieved file
std::copy(istream_iterator(retrieved_file), istream_iterator(), std::back_inserter(buffer));
// create a Magick++ blob with your data
Blob my_blob(buffer.data(), buffer.size());
// create a Magick++ image from your blob
Image image_from_blob(my_blob);

How to transfer a C++ object to a web service using POCO library

I have an image processing application that uses Qt and openCV.
for each frame, I should send the captured cv::Mat image object to the server to process it and get the results.
I should use the REST architecture for its low playload.
What is the tool that I should use to send cv::Mat to the server.
I am using POCO for portability.
I seek for the lightest solution to do that, I need a minimum speed of 10 frames processed by the server in a second.
I mean, is there a method to pass the C++ Object to the server without an explicit serialization?
EDIT
With the POCO library, you can take a look in this answer: HttpRequest PUT content in poco library. He is sending a file on a ifstream.
In this answer you can check how to convert a cv::Mat into a istream: OpenCV cv::Mat to std::ifstream for base64 encoding.
And finally, Thanks to polymorphism, the istream is implicity converted to a ifstream.
You can use the C++ Rest SDK. A code example of the PUT command.
Source of code
Library Github where you can find the full documentation.
#include <http_client.h>
#include <filestream.h>
#include <iostream>
#include <sstream>
using namespace web::http;
using namespace web::http::client;
// Upload a file to an HTTP server.
pplx::task<void> UploadFileToHttpServerAsync()
{
using concurrency::streams::file_stream;
using concurrency::streams::basic_istream;
// To run this example, you must have a file named myfile.txt in the current folder.
// Alternatively, you can use the following code to create a stream from a text string.
// std::string s("abcdefg");
// auto ss = concurrency::streams::stringstream::open_istream(s);
// Open stream to file.
return file_stream<unsigned char>::open_istream(L"myfile.txt").then([](pplx::task<basic_istream<unsigned char>> previousTask)
{
try
{
auto fileStream = previousTask.get();
// Make HTTP request with the file stream as the body.
http_client client(L"http://www.fourthcoffee.com");
return client.request(methods::PUT, L"myfile", fileStream).then([fileStream](pplx::task<http_response> previousTask)
{
fileStream.close();
std::wostringstream ss;
try
{
auto response = previousTask.get();
ss << L"Server returned returned status code " << response.status_code() << L"." << std::endl;
}
catch (const http_exception& e)
{
ss << e.what() << std::endl;
}
std::wcout << ss.str();
});
}
catch (const std::system_error& e)
{
std::wostringstream ss;
ss << e.what() << std::endl;
std::wcout << ss.str();
// Return an empty task.
return pplx::task_from_result();
}
});
/* Sample output:
The request must be resent
*/
}

How to save poco uploaded file

I want to upload file using poco library.
Now I have the uploaded file in the istream variable but I don't know how I can save it to a file?
Here is my code where i can get the length of the file.
void handlePart(const MessageHeader &header, std::istream &stream) {
_type = header.get("Content-Type", "(unspecified)");
if (header.has("Content-Disposition")) {
std::string disp;
NameValueCollection params;
MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
_name = params.get("name", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
}
CountingInputStream istr(stream);
NullOutputStream ostr;
StreamCopier::copyStream(istr, ostr);
_length = istr.chars();
}
Also now it's 1 file uploaded in the form if there be more than 1 file how it will be managed in istream?
Now there is 2 days I'm searching and testing different ways but I couldn't find any way, please help to resolve this problem.
Thank you in advanced.
Depend on #Abhinav question on this post:
We can write save code like this:
if (fileName.length() != 0){
std::ofstream fout( fileName, std::ios::binary);
fileList.push_back(fileName);
fout << stream.rdbuf() ;
fout.close();
}
But unfortunately it's working for one file if there is more than one this code can't catch correctly.

How to create a dynamic filename for an SD card on Arduino

I'd like to log my data on my Arduino one file at a time. I'd like the filename to be a combination of the number of milliseconds that have passed + some ID. For example, GPS data would be millis()+"GPS".
I tried the following code, but it doesn't like the fact that I am using a String. I could use a char array, but the length would always be dynamic. Is there a way to do this with at string somehow?
static void writeToSD()
{
String logEntry = " GPS: ";
logEntry += GPSString;
String filename = String(millis());
filename += "GPS";
Serial.println(logEntry);
Serial.println(filename);
File dataFile = SD.open(filename, FILE_WRITE);
// If the file is available, write to it:
if (dataFile) {
dataFile.println(logEntry);
dataFile.close();
Serial.println("Closed");
}
// If the file isn't open, pop up an error:
else {
Serial.println("error opening file");
}
}
You could try the following
char fileNameCharArray[filename.length()];
filename.toCharArray(fileNameCharArray, filename.length())
File dataFile = SD.open(fileNameCharArray, FILE_WRITE);
sprintf (filename, "%ld-GPS", millis());
Note that the use of String on Arduino is discouraged because of the well documented memory leak/fragmentation problems.

boost: Uncompress http response using gzip failed

I'm trying to uncompress http body response using boost gzip filters. I'm using the standard code example provided everywhere:
std::string source = "c:\\install\\data.gz";
std::string destination = "c:\\install\\data.txt";
using namespace std;
using namespace boost::iostreams;
ifstream file(source, ios_base::in | ios_base::binary);
filtering_streambuf<input> in;
in.push(gzip_decompressor());
in.push(file);
ofstream unzipped(destination, std::ios::out | std::ios::binary);
boost::iostreams::copy(in, unzipped);
In this scenario, I saved content of the page into source file before. The problem is that this code doesn't work with some sites using gzip-encoding (for example, http://mail.ru - the biggest russian portal). Other sites, for example, http://bing.com is uncompressed perfectly.
I wrote small code to test saved data using GZipStream. It work fine even with mail.ru:
String source = #"c:\install\data.gz";
String destination = #"c:\install\data.txt";
using (FileStream inFile = new FileStream(source, FileMode.Open))
{
using (FileStream outFile = File.Create(destination))
{
using (GZipStream Decompress = new GZipStream(inFile, CompressionMode.Decompress))
{
Decompress.CopyTo(outFile);
}
}
}
Can anybody explain what's wrong with me, mail.ru or gzip?