How to save poco uploaded file - c++

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.

Related

Program crashes trying to create ofstream or fopen

I don't have enough reputation points to comment to ask if they solved the problem originally stated here. I have the same problem of the program crashing in construction of an ofstream.
It is not multi-threaded access, but it can be called in quick succession. I believe it crashes on the 2nd time. I use scope to ensure the stream object is destroyed.
Why would this happen?
I tried std::fopen too. It also results in a crash.
Here is the code using the ofstream:
static bool writeConfigFile (const char * filename, const Config & cfg)
{
logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_INFO, "Write config file (%s stream)", filename);
ofstream os(filename); // FIXME: Crashes here creating ofstream 2nd time
if (os.good())
{
// Uses stream insertion operator to output attributes to stream
// in human readable form (about 2kb)
outputConfig(cfg, os);
if (!os.good())
{
logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_NOTICE, "Failed to write configuration file (%s)", filename);
return false;
}
logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_INFO, "Configuration written to file (%s)", filename);
return true;
}
logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_NOTICE, "Cannot write configuration file (%s)", filename);
return false;
}
/**
* Called when configuration settings have been read/received and validated
* #return true if successfully set, and written to file
*/
bool Config::set (SysConfigSource source, const struct SCADA_dsconfig * p)
{
Lock lock(mtxSet); // This is locking a mutex on construction of the lock. Release it on destruction.
// Setup the non-current one to switch to
Config * pCfg = pConfig.other();
unsigned i, f, n = 0;
// set attributes in pCfg based on the config received
// and some constants ...
pCfg->setWritten(writeConfigFile("test.conf", *pCfg));
if (!pCfg->isWritten())
{
// Don't set system config status here. Existing one still in use.
logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_NOTICE, "Config file not written. Retain prior config.");
return false;
}
pConfig.swap(); // switch-in the new config
setSystemConfigSource(source);
toSyslog(pCfg);
notifyConfigChange();
return true;
}
Maybe post a segment of your source code in order to get an idea of where it went wrong.
Here is a very basic segment of code of how I would use fstream.. hope you will find it helpful.
#include <iostream>
#include <fstream>
#include <string>
int main() {
while (1) {
std::string testString;
std::ofstream outFile;
outFile.open("Test", std::ios_base::app); // Appends to file, does not delete existing code
std::cout << "Enter a string: ";
std::cin >> testString;
outFile << testString << std::endl;
outFile.close();
}
}
It turned out to be a device driver bus master issue. Add "ahci nobmstr" when launching devb-ahci.
Derived via http://www.qnx.com/developers/docs/qnxcar2/index.jsp?topic=%2Fcom.qnx.doc.neutrino.user_guide%2Ftopic%2Fhardware_Troubleshooting_devb-eide.html

Writing to .ini file - SimpleIni SetValue not doing anything, despite appearing to succeed

So I've been trying to read and write from my windows service's .ini file. I am storing the ini file temporarily at 'C:\test\CppWindowsService.ini'. The program reads the ini just fine, but has trouble setting the value in the ini file. It appears to update the value, but in reality does not do anything. I am using brofield's SimpleIni available at github, something I've seen numerous people online using for their ini parsing needs. You can find it here.
Things I've tried/checked thus far:
Security Settings: the Administrators, Domain Admins, System and I all have read/write access. This section of code is being ran as my Domain Admin.
Any help is greatly appreciated, and thanks in advance!
bool readini()
{
// Load .ini file and retrieve ClientGuid **
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile("C:\\test\\CppWindowsService.ini");
const char * pVal = ini.GetValue("GUID", "Clientguid", NULL);
std::cout << "pVal:" << pVal << std::endl;
std::string test(pVal); // Had to convert pVal to string for unknow reason:
if (test == "noguid") // const char * "noguid" != const char[7] "noguid" ???
{ // Aren't these the exact same thing?... Compiler wasn't
// generate guid ** // throwing the error, but the if statement wouldn't pass
GUID initguid; // the condition until I did this.
HRESULT hCreateGuid = CoCreateGuid(&initguid);
// generate bstr from guid **
wchar_t* bstrGuid;
StringFromCLSID(initguid, &bstrGuid);
std::wcout << bstrGuid << std::endl;
// transform bstr to str **
std::stringstream ss;
ss << bstrGuid;
std::string guid = ss.str();
// set .ini clientguid with generated guid **
SI_Error rc = ini.SetValue("GUID", "Clientguid", guid.c_str());
if (rc < 0)
{
return false;
}
printf("key: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
::CoTaskMemFree(bstrGuid);
}
}
The output from the three various cout/wcout/print statements:
pval: noguid
{D002CD3F-6434-47E9-8246-06884FDE1FEA}
key: updated
Ini format:
[GUID]
Clientguid = noguid
I've only included the SimpleIni.h file, as the others look like they aren't really useful for me. This seems to be ok, and as far as I can tell, it isn't the issue... but please let me know if I'm wrong!
You need to save the INI file using the command:
ini.SaveFile("C:\\test\\CppWindowsService.ini");

Serialize PNG and Send to Rest Client

iam sending images in the png format to my rest clients.
But when i download the file on the client side and try to open it, i will get errors.
I believe the Headers of the file are missing, but how can i add them to the serverresponse?
On the details of my picture i can see, that the size and so on is missing.
ifstream Stream;
Stream.open(FullFileName,std::ios::binary);
string Content, Line;
if (Stream)
{
while (getline(Stream,Line)){
Content += Line;
}
}
Stream.close();
Request::request->set_body(Content);
After searching around found a post post on this side.
And the Sequenze i create from that.
ifstream *Stream = new ifstream(FullFileName, std::ios::in | std::ios::binary);
std::ostringstream *oss = new ostringstream();
*oss << Stream->rdbuf();
string *Content = new string(oss->str());
Stream->close();
Request::request->set_body(*Content);

Qt: QuaZip to extract file and show its progress in QProgressDialog

How could I use QuaZip to extract a .zip file and show its extraction progress in a QProgressDialog?
I've tried an example from this question1 (and also this question2) without success. Because I need to unzip .zip files (not .gz files) and that code shows % of progress but not unzip the files.
And even that, I don't know how to show that % in a QProgressDialog.
I've been able to extract .zip file using:
JlCompress::extractDir("C:/test/test.zip", "C:/test/");
However, that is not enought for my goal, because I need to show that extraction progress in a QProgressDialog in real time...
This is my code:
QString fileName = "C:/test/firefox-29.0.1.gz"; //I need to unzip .zip files
qDebug() << "Opened";
progressUnzip->setWindowTitle(tr("Unzip Manager"));
progressUnzip->setLabelText(tr("Unzipping %1. \nThis can take a long time to complete").arg(fileName));
progressUnzip->setAttribute(Qt::WA_DeleteOnClose);
QFile file(fileName);
file.open(QFile::ReadOnly);
QuaGzipFile gzip;
gzip.open(file.handle(), QuaGzipFile::ReadOnly);
progressUnzip->show();
while(true) {
QByteArray buf = gzip.read(1000);
//process buf
if (buf.isEmpty()) { break; }
QFile temp_file_object;
temp_file_object.open(file.handle(), QFile::ReadOnly);
double progress = 100.0 * temp_file_object.pos() / file.size();
updateUnzipProgress(temp_file_object.pos(), file.size());
qDebug() << qRound(progress) << "%";
}
unzipFinished();
qDebug() << "Finish";
Where:
void MainWindow::updateUnzipProgress(qint64 bytesRead, qint64 totalBytes)
{
qDebug() << bytesRead << "/" << totalBytes;
qint64 th = 1;
if (totalBytes >= 100000000)
{
th = 1000;
}
progressUnzip->setMaximum(totalBytes/th);
progressUnzip->setValue(bytesRead/th);
}
// When unzip finished or canceled, this will be called
void MainWindow::unzipFinished()
{
qDebug() << "Unzip finished.";
progressUnzip->hide();
}
In this code, QProgressDialog doesn't show any progress bar and at the end the file is not unzipped.
Any idea?
Thanks for your help,
I'm not going to write the whole code for you, but I can give you some hints to help you solve the problem.
QuaZIP library does not provide any Qt signals about the extraction progress, and that means that you should implement it yourself.
First, take a look at JlCompress::extractDir function implementation to see how it works. The source code can be found here. The function creates a QuaZip object which describes the zip archive you want to extract. Then it iterates over the files in the archive. On every iteration it creates a QuaZipFile object which describes a compressed file in the archive and then writes (=extracts) its data to a new file.
This is the copy function:
static bool copyData(QIODevice &inFile, QIODevice &outFile)
{
while (!inFile.atEnd()) {
char buf[4096];
qint64 readLen = inFile.read(buf, 4096);
if (readLen <= 0)
return false;
if (outFile.write(buf, readLen) != readLen)
return false;
}
return true;
}
inFile is the compressed (QuaZipFile) file and outFile is a new file where the compressed data is extracted to.
Now you should understand the underlying logic.
To add signals about extraction progress, you can can copy the JlCompress::extractDir source code to some wrapper class and make some changes.
While iterating over the files in the archive, you can get information about them using QuaZipFile::getFileInfo. That information contains uncompressed file size. Now go back to the copyData function. You know how many bytes you have written and you know the expected file size. That means you can calculate the single file extraction progress. Also you can get total files count and their uncompressed sizes using QuaZip::getFileInfoList64. That will let you calculate the whole extraction progress too.

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.