[Cppcms-users] SOLVED - Re: HTTP response and binary stream (libharu)
Brought to you by:
artyom-beilis
|
From: augustin <aug...@ov...> - 2015-09-22 04:19:24
|
On Saturday, September 19, 2015 03:22:16 AM Artyom Beilis wrote:
> Several points:
> (a) You misunderstand meaning of "raw" output - "raw" means you are sending
> CGI output including headers etc on your own and CppCMS does not interfere
> with it. There only very-very specific cases you may actually need this -
> bottom line you don't need it.
Ok.
I had been struggling with my problem for a few days before I asked, and I was
trying to eliminate all possible sources of corruption. I had come to the
conclusion that this probably was not it.
Thanks for confirming it.
> (b) std::ostream is just a character or more
> correctly octet stream, std::string is a container that keeps bytes/"C
> chars"/octets in it in string friendly way. You can put any binary data to
> it.
> Now in your case the problem is there
app()->response().out() << buf << std::flush;
> or
cppcms_buf << buf
>
> Why? std::ostream assumes that buf is NUL terminated string so it would
> stop on NUL, and this what corrupts the stream.You need to use
> std::ostream::write, i.e. out().write(buf,siz)
> That's it
>
> Artyom Beilis
Thank you Artyom!
You clearly saw the source of the problem. Joerg also gave me a hint earlier
which pointed me in the right direction.
I had searched online and found other newbies like me who made the same wrong
assumption about the << operator, which, I understand now, should not be used
for binary streams.
After reading your mail, I still struggled for a while with type casting.
I had compile errors such as:
error: invalid conversion from 'HPDF_BYTE*' to 'const char*'
or:
error: invalid static_cast from type 'HPDF_BYTE [4096]' to type 'const char*'
Finally, I was forced to use a reinterpret_cast, but apparently it cannot be
avoided:
// #include <hpdf.h>
typedef unsigned char HPDF_BYTE;
// my_pdf.cpp:
// Create PDF.
HPDF_Doc pdf = HPDF_New(pdf::error_handler, NULL);
....
.... // Add content to pdf.
....
HPDF_SaveToStream (pdf);
for (;;) {
HPDF_BYTE buf[4096];
HPDF_UINT32 siz = 4096;
HPDF_ReadFromStream (pdf, buf, &siz);
// cppcms::http::response:
app()->response().out().write(reinterpret_cast<const char*>(buf), siz);
if (siz == 0)
break;
}
app()->response().out() << std::flush;
HPDF_Free(pdf);
I am not sure if the << std::flush at the end is necessary, but it doesn't
seem to hurt.
Artyom, would you like me to create a simple tutorial on using cppcms +
libharu on the cppcms wiki?
Do you think it may be useful to other people?
I can do it if you wish.
On Saturday, September 19, 2015 03:26:34 AM Artyom Beilis wrote:
> As BTW is shown in this
> example:
http://libharu.sourceforge.net/how_to_use.html#Save_a_document_to_file_
Yes, I had already seen that page.
Actually, the project has moved to github, so I was following the
corresponding page there:
https://github.com/libharu/libharu/wiki/Usage-examples
My main problem is lack of experience (I don't code full time) and I am still
baffled by some intricacies of the language and the standard libraries.
I often fail to see the relevance of what I am reading to my problem.
Once I have solved a problem, it is often frustrating to see that I had
actually come across the solution days earlier but failed to understand it!
Believe me, I don't take free online help for granted. I always ask as a last
resort, when I feel really stuck after having spent a few days trying to fully
understand the problem and researching online.
As always, I am grateful for you help, and I am in awe of your mastery of the
language! :)
Blessings,
augustin.
|