HTTP Post Response parsing in C++ - c++

I am writing puzzle bot, http server which upon hitting , renders a default page with text area to write code similar to http://codepad.org/. When I type in following program.
#include <stdio.h>
int main( int argc, char **argv) {
return 0;
}
I get following response from HTTP POST.
code : %23include+%3Cstdio.h%3E%0D%0Aint+main%28+int+argc%2C+char+**argv%29+%7B%0D%0A++++return+0%3B%0D%0A%7D
lang : C
How Do I parse the information from the key code. I need to write this program in a temporary file and then compile/run.

You need to decode the data, first. You could use this reference .
All spaces are replaces with the sign +, and all numbers after % are special - 2 digit hex encoded numbers - URL encoded special symbols (like +, ,, }, etc.).
For example, you code will be translated to :
#include <stdio.h>\r\nint main( int argc, char **argv) {\r\n return 0;\r\n}
Where \r\n are CRLF, So, from this, you'll finally get:
#include <stdio.h>
int main( int argc, char **argv) {
return 0;
}
which is exactly your code. Then you could write it to your temp file and try to compile it.
Some things, that come to my mind for better application like this:
make it multithreading - you'll be able to handle more than one such request at the same time
add some queues for the received data - don't lose the data that comes, while your program is processing the current request (kinda queue)
of course, synchronize the threads and be careful with that
I think you're going to need IPC (Inter-Process Communication) - to communicate with your compiler's process and extract the errors, it gives you (unless you have some special API, provided for your compiler)
Of course, these are just some advice, that come to my mind. That would be great exercise for any developer - IPC + multithreading + network programming + http! Great :)
Good luck

Related

Read line on stdin on Windows 10 IoT (Raspberry Pi 2)

I'm new to developing apps on Windows 10 IoT, so I made little test application just to test how to read input from stdin on a console app on a Raspberry Pi 2 running Windows 10.
Now I know that this is not the average use case, but my original app has the purpose to only serve as a demo.
My little code in C++ (for reasons I'm restricted to C++) so far is very simple:
#include "pch.h"
int main(int argc, char **argv) {
char buffer[1024];
std::cin.getline(buffer, 1024);
printf("%s \n", buffer);
}
The problem I face is, that the line
std::cin.getline(buffer, 1024);
seems to be omitted. All the program does is printing an empty line. So there isn't even time to type anything to stdin.
Maybe it's worth mentioning that I'm testing this via a powershell remote session so maybe this has anything to do with it.
My questions are now:
Is it even possible to read a line from stdin? (I guess so)
Am I doing it wright? (Certainly not)
What is the correct/clean way to do so? Where is my error?

Parsing a textfile (with HTML in it) with C++

I've been able to get some raw data in the form of a html webpage, which I have in turn put into an ordinary text file. I'm currently trying to use a C++ program to parse this file, but for some reason it's giving me weird output in that it's putting #s, symbols, and ^Ms in between every single letter. I'm unsure as to whether this is because I'm trying to parse an HTML file or if it's because my code is wrong, but I've tried my code on smaller HTML files and it works fine. The file I want it to work on is just 145kB
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char** argv)
{
ifstream inFile;
inFile.open(argv[1]);
string str;
while(getline(inFile, str))
{
cout << str << endl;
}
}
If anyone could give me a clue as to why this isn't working, I'd be very grateful.
HTML files may come in virtually any encoding. OP needs to open the file, according the encoding that it has, that is typically supplied by the web browser he got it from as part of the page serve. Note that each individual page served up by the same site, may have different encodings. The "#" are probably actually printed as "^#", which is what many output routines will print if you give them null characters. He may have a UTF-16 file, and is reading it assuming it is ASCII 8 bit.
He also needs to understand that "newline" conventions vary between machines; his "^M" probably means he is running on a Unix machine (which thinks "^J" is a line break, and he got his file from a Windows box, which thinks "^M^J" is a line break. Welcome to the real world.
Next, OP will find that parsing HTML is actually hard because it is complex, has lots of crazy character conventions (above and beyond encoding), and often is often simply illegal because the browsers allow it, and not every checks that their HTML is clean.
Try if this works for you.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char** argv)
{
wifstream inFile;
inFile.open(argv[1]);
wstring str;
while(getline(inFile, str))
{
wcout << str << endl;
}
}

Extra Characters Reading from Serial Port Using libserial on Linux

I have a very basic device with which I am trying to interact via a serial connection on Linux. I am on the steep part of the learning curve here, still, so please be gentle!
Anyhow, I am able to control the device via Hyperterminal in Windows, or via cu, screen, or minicom in Linux. I am connected via a built-in serial port on a PC at 19200, 8N1. The interface for the device is very simple:
Type "H", and the device echoes back "H".
Type "V", and the device echoes back a string containing its software version, "ADD111C".
Type "S", and the device returns "0", "1", or "?", depending on its printer status.
Type "Q", and it returns a five-line response with details on the last transaction processed.
Each response is followed by a new-line, perhaps a CR, too, I am not certain.
There's more, but that's a good start. When I connect to the device using screen, it works fine:
root#dc5000:~# screen /dev/ttyS0 19200,cs8,-ixon,-ixoff
V
ADD111C
Once I had that working manually, I tried to write a simple program using C++ and libserial to interact with the device. It looks like this:
#include <SerialStream.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
using namespace LibSerial;
int main(){
char next_char[100];
int i;
SerialStream my_serial_stream;
my_serial_stream.Open("/dev/ttyS0") ;
my_serial_stream.SetBaudRate( SerialStreamBuf::BAUD_19200 ) ;
my_serial_stream.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ;
my_serial_stream.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ;
my_serial_stream.SetParity( SerialStreamBuf::PARITY_NONE ) ;
my_serial_stream.SetNumOfStopBits(1) ;
my_serial_stream.SetVTime(1);
my_serial_stream.SetVMin(100);
cout<<"Sending Command:\n";
my_serial_stream << "V";
my_serial_stream.read(next_char,100);
cout<<"Result: "<<next_char<<"\n";
my_serial_stream.Close();
return 0;
}
This is successfully able to send the "V" to the serial port, but when I read it back, I get a number of non-printing characters back after the valid data:
root#dc5000:~# g++ -o serialtest serialtest.cpp -lserial
root#dc5000:~# ./serialtest
Sending Command:
Result:
V
ADD111C
��se�Xw��AN��ƿ,�
root#dc5000:~#
What am I missing to only grab the response to my query? I'm guessing that I need to flush a buffer on the port or something, but I have reached the end of my limited knowledge here.
Ideally I would like to just get the "ADD111C", but I don't want to paint myself into a corner by grabbing a specific length of data (in case it changes in the future), and the garbage at the end of the read does not always seem to be the same length, or the same data.
Many thanks for taking a look,
Tom
Zack & keshlam: Thank you for the help. Zack's suggestion to write a NULL to the end of the string resolved the problem, but I actually stumbled across a simpler method while working with another string (trying to grab a substring of the output).
Rather than define the C string like this:
char next_char[100];
I did it like this:
char next_char[100] = "";
It seems that assigning a value to the char before reading from the serial port properly null terminated it. I can now remove the memset command from my code and it now works fine:
root#dc5000:~# ./serialtest
Sending Command:
Result:
V
ADD111C
Thanks for the help!

Flushing a boost::iostreams::zlib_compressor. How to obtain a "sync flush"?

Is there some magic required to obtain a "zlib sync flush" when using boost::iostreams::zlib_compressor ? Just invoking flush on the filter, or strict_sync on a filtering_ostream containing it doesn't see to do the job (ie I want the compressor to flush enough that the decompressor can recover all the bytes consumed by the compressor so far, without closing the stream).
Looking at the header, there seem to be some "flush codes" defined (notably a sync_flush) but it's unclear to me how they should be used (bearing in mind my compressor is just added into a filtering_ostream).
It turns out there is a fundamental problem that the symmetric_filter that
zlib_compressor inherits from isn't itself flushable (which seems rather
an oversight).
Possibly adding such support to symmetric_filter would be as simple as adding the flushable_tag and exposing the existing private flush methods, but for now I can live with it.
This C++ zlib wrapper library, of which I'm the author, supports flush functionality and is arguably simpler to use:
https://github.com/rudi-cilibrasi/zlibcomplete
It is as easy as this:
#include <iostream>
#include <zlc/zlibcomplete.hpp>
using namespace zlibcomplete;
using namespace std;
int main(int argc, char **argv)
{
const int CHUNK = 16384;
char inbuf[CHUNK];
int readBytes;
ZLibCompressor compressor(9, auto_flush);
for (;;) {
cin.read(inbuf, CHUNK);
readBytes = cin.gcount();
if (readBytes == 0) {
break;
}
string input(inbuf, readBytes);
cout << compressor.compress(input);
}
cout << compressor.finish();
return 0;
}
The main difference from boost is that instead of using a template class filter you simply pass in a string and write out the compressed string that results as many times as you want. Each string will be flushed (in auto_flush mode) so it can be used in interactive network protocols. At the end just call finish to get the last bit of compressed data and a termination block. While the boost example is shorter, it requires using two other template classes that are not as well-known as std::string, namely filtering_streambuf and the less-standard boost::iostreams:copy. The boost interface to zlib is incomplete in that it does not support Z_SYNC_FLUSH. This means it is not appropriate for online streaming applications such as in TCP interactive protocols. I love boost and use it as my main C++ support library in all of my C++ projects but in this particular case it was not usable in my application due to the missing flush functionality.

C++ Console Progress Indicator

What would be an easy way of implementing a console-based progress indicator for a task that's being executed, but I can't anticipate how much time it would take?
I used to do this back when I coded in Clipper, and it was only a matter of iterating through the chars '/', '-', '\', '|' and positioning them in the same place.
Any way / links / libs for doing that (or something similar) in C++?
The target for this is *nix environments.
Edits:
changed the title to be more coherent and generic;
added target environment.
A very simple way to do it is to print out a string followed by a '\r' character. That is carriage return by itself and on most consoles, it returns the cursor to the beginning of the line without moving down. That allows you to overwrite the current line.
If you are writing to stdout or cout or clog remember to fflush or std::flush the stream to make it output the line immediately. If you are writing to stderr or cerr then the stream is unbuffered and all output is immediate (and inefficient).
A more complicated way to do it is to get into using a screen drawing library like curses. The Windows consoles have some other ways of setting them for direct screen writing but I don't know what they are.
You could try something like:
void
spinner(int spin_seconds) {
static char const spin_chars[] = "/-\\|";
unsigned long i, num_iterations = (spin_seconds * 10);
for (i=0; i<num_iterations; ++i) {
putchar(spin_chars[i % sizeof(spin_chars)]);
fflush(stdout);
usleep(100000);
putchar('\b');
}
}
Of course, this is non-standard because of the sub-second usleep() and I'm not sure if there is any guarantee that \b erases a character or not, but it works on most platforms. You can also try \r instead if \b doesn't do the trick. Otherwise, try to find a version of curses.
Edit (curses sample)
This should get you started:
#include <curses.h>
#include <unistd.h>
void spinner(int spin_seconds) {
static char const spin_chars[] = "/-\\|";
unsigned long i, num_iterations = (spin_seconds * 10);
for (i=0; i<num_iterations; ++i) {
mvaddch(0, 0, spin_chars[i & 3]);
refresh();
usleep(100000);
}
}
int main() {
initscr(); /* initializes curses */
spinner(10); /* spin for 10 seconds */
endwin(); /* cleanup curses */
return 0;
}
Make sure to link with either -lcurses or -lncurses. That should work on any UNIX alike out there.
Boost has a progress library which can help some of these things
Wow, clipper, perhaps you are talking about the #row,col things built in to the language? (Rhetorical question only...)
You can do simple progress bars with printf: you can leave out the trailing newline. You can obviously begin or end the string with \b in order to overprint characters. It's easy to do the traditional -\|/ kind that way.
I recall that the Eclipse UI guidelines recommended progress indicators regardless of how much you were able to tell about the actual progress. I think theory was that anything is better than nothing and to just do the best you can.
The only trick that you are likely to need is potentially to defeat line buffering. Be sure to fflush(stdout) after each output operation. (Or ostream::flush())