Page 1 of 1

xmlhttp60 : get_ResponseStream()

Posted: 28 Feb 2019 8:00
by Tonton Luc
Hi,

How to write the PDF file's contain using get_ResponseStream() [or get_responseText()] ?
I've tried this following VP 7.3 code without success because my htmlSource PDF file contain a lot of "???" :

Code: Select all

        XML = xmlhttp60::new(),         XMLR = XML:get_IXMLHTTPRequest_import(),         XMLR:predicate_open("GET","ftp://my_IP_server/my_folder/My_PDF_file.pdf",comDomains::boolean(false),comDomains::string("my_user_name"),comDomains::string("my_password")),         XMLR:send(comDomains::null) , !,         Status = XMLR:get_Status(),         stdio::writef("Status= %\n",Status),                 StatusText = XMLR:get_StatusText(),         stdio::writef("StatusText= %\n",StatusText),                                           ReadyState = XMLR:get_readyState(),         stdio::writef("ReadyState= %\n",ReadyState),                 ResponseStream = XMLR:get_ResponseStream(),         stdio::writef("ResponseStream= %\n",ResponseStream),         if ResponseStream = comDomains::iUnknown(Val) then             OS = outputStream_file::create("htmlSource.pdf"),             OS:write(Val),             OS:close()         end if,                 Html = XMLR:get_responseText(),         file::writeCodedString("htmlSource2.pdf",Html,ansi()),         !.

Re: xmlhttp60 : get_ResponseStream()

Posted: 28 Feb 2019 11:29
by Thomas Linder Puls
It is a problem that a pdf file is binary. So you have to obtain the raw bytes and write them unchanged to the file.

The following works in Vip9 (and probably also in vip8, but it will look different in Vip7.3 and maybe there is not support for it all):

Code: Select all

        XML = xmlhttp60::new(),         XML:open_predicate("GET", @"file:///C:/...../test.pdf", comDomains::boolean(false), comDomains::null,             comDomains::null),         XML:send(comDomains::null),         Status = XML:status,         stdio::writef("Status= %\n", Status),         StatusText = XML:statusText,         stdio::writef("StatusText= %\n", StatusText),         ReadyState = XML:readyState,         stdio::writef("ReadyState= %\n", ReadyState),         ResponseBody = XML:responseBody,         stdio::writef("ResponseBody= %\n", ResponseBody),         if comDomains::safeArray(SA) = ResponseBody then             SA8 = safeArrayUnsigned8::newCopy(SA),             [comDomains::boundary(L, 0)] == SA8:getBoundaries(),             Data = SA8:accessData(),             F = outputStream_file::create(@"..\test2.pdf", stream::binary),             F:writeBytes(Data, convert(byteCount, L)),             F:close(),             SA8:unaccessData(),             SA8:release()         end if.

Re: xmlhttp60 : get_ResponseStream()

Posted: 28 Feb 2019 21:57
by Tonton Luc
Hi,

Your previous code works fine with VP 7.3 + this :
F:writeBytes(Data, convert(byteCount, L)+1),
Many thanks for your help.

Re: xmlhttp60 : get_ResponseStream()

Posted: 1 Mar 2019 8:58
by Thomas Linder Puls
Excellent.

I did notice that the length was one smaller in the boundary, than in the safeArray descriptor. But since it worked I assumed that someone had considered this at a different time. But I will check/review if we do something wrong with the boundaries.

Re: xmlhttp60 : get_ResponseStream()

Posted: 1 Mar 2019 9:22
by Thomas Linder Puls
After checking it turned out adding 1 is correct (its a classic bug).

In Vip7.5 and Vip8 the correct place to add 1 is here (in the file safeArray.pro):

Code: Select all

class predicates     getBoundaries : (comDomains::nativeSafeArray) -> comDomains::boundary*. clauses     getBoundaries(NativeSafeArray) = Boundaries :-         Dims = safeArray_api::safeArrayGetDim(NativeSafeArray),         Boundaries =             [ comDomains::boundary(Elements, L) ||                 Dim = std::fromTo(1, Dims),                 L = safeArray_api::safeArrayGetLBound(NativeSafeArray, Dim),                 U = safeArray_api::safeArrayGetUBound(NativeSafeArray, Dim),                 Elements = convert(unsigned, U - L + 1)  % <==== add 1 here             ].
Fortunately, it is very seldom that you need safeArrays. I only think I have ever seen it used like here where we don't really want an array of bytes, but just a binary (or string rather than a array of chars).

Re: xmlhttp60 : get_ResponseStream()

Posted: 5 Mar 2019 13:22
by Tonton Luc
Hi,

And do you think it's possible to upload some files using xmlhttp60 ?
I've tried without success :

Code: Select all

        XML = xmlhttp60::new(),         XMLR = XML:get_IXMLHTTPRequest_import(),         XMLR:predicate_open("PUT","ftp://???",comDomains::boolean(false),comDomains::string("my_user_name"),comDomains::string("my_password")),         XMLR:send(???) , !,         Status = XMLR:get_Status(),         stdio::writef("Status= %\n",Status),         ...

Re: xmlhttp60 : get_ResponseStream()

Posted: 5 Mar 2019 15:23
by Thomas Linder Puls
Unfortunately, I don't know.