[email protected] wrote:
> Mr Monnerat:
> Many thanks to you for your ongoing work in porting curllib to the
as400.
You're welcome. I would also say it would not have been feasible without
the help of the libcurl developer's community. Oh, by the way, the
product is called libcurl (http://curl.haxx.se/libcurl/) ;-)
> Following your "readme" instructions I successfully compiled the
library, and am able to do a curl_easy_perform to request data via http
from a website within an RPGLE Program using h bnddir('CURL/CURL'),
d/copy curl/h,curl.inc
Fine !
> The data appears to be sent to standard out.
This is the normal default behavior.
> I would like to pull the data into the variable which I can use in the
RPG program.
> If you have RPG LE examples of doing this I would appreciate it.
There are no RPG examples available, but plenty of C example programs on
the curl web site:
http://curl.haxx.se/libcurl/c/example.html. I have made an RPG example
specially for you. Please find it in attachment.
> I have tried use easy_recv:
> curl_easy_setopt_ccsid($ch : CURLOPT_CONNECT_ONLY:'1');
> curl_easy_recv($chP:%addr($info):%size($info):$bytes);
> But no data appears to be returned. I added a 3 second sleep before
just it case the data wasn't there yet.
1) If you use curl_easy_setopt_ccsid(), you should specify that CCSID !
2) Option CURLOPT_CONNECT_ONLY requires a long parameter. You should
then use curl_easy_setopt_long($ch: CURLOPT_CONNECT_ONLY: 1);
3) The regular way of passing data to libcurl is via callbacks. This is
illustrated in the attached example program and in
http://curl.haxx.se/libcurl/c/getinmemory.html that you've already found
! I've never used curl_easy_recv() and I don't think it's very much used
in general.
> I have looked at: /docs/examples/getinmemory.c I could create a c
program that could call with RPG to return the information, but am not
sure if the ASCII to EBCDIC conversion would be done.
As you know, OS400 is stuck in the EBCDIC ghetto ! The *_ccsid()
wrappers do the conversion job for procedure parameters and return
values, but not for callbacks. You then have to convert the data
encoding yourself, in the target code of your choice. The attached
example shows a conversion to job's CCSID from ISO-8859-1 (although this
conversion is outside of libcurl's scope). You may inspire your own RPG
code from this example, but I can't take data conversion into account in
my wrappers since nowadays, many data are in UTF-8 and thus prevent me
to make any assumption about the remote encoding. In addition, there are
a lot of UTF-8 characters that cannnot be converted to some EBCDIC code.
Please, subscribe to the curl-library mailing list
(http://cool.haxx.se/mailman/listinfo/curl-library) and post your
libcurl questions there instead of sending them directly to me: I read
this list and would see your posts there, but in addition, there will be
plenty of libcurl gurus that can help you better than I would never be
able to do, and this may help other user's through the list archive. I
don't know if there are some other RPGists there, but this is the main
place for libcurl programming and functionality. Since it may help
others, I cc this answer to this list.
Have a good fun with libcurl !
Regards,
h dftactgrp(*no) actgrp(*new)
h copyright('Copyright (c) 2009 by Patrick Monnerat and DATASPHERE S.A.')
h option(*noshowcpy)
h bnddir('CURL/CURL')
*
d/copy curl/h,curl.inc
*
**************************************************************************
* Prototypes
**************************************************************************
*
* Write data callback for libcurl.
*
d @remotewrite pr 10i 0
d buf 65535 options(*varsize)
d size 10u 0 value
d nmemb 10u 0 value
d userdata * value
*
* Convert CCSID.
*
d @convertA2A pr 65535 varying
d ccsid_to 10u 0 value
d ccsid_from 10u 0 value
d data 65535 const varying
*
* CCSID conversion system APIs.
*
d iconv_t ds qualified based(#####dummyptr#####)
d return_value 10i 0
d cd 10i 0 dim(12)
*
d iconv_open pr extproc('iconv_open')
d likeds(iconv_t)
d tocode * value options(*string)
Destination CCSID
d fromcode * value options(*string)
Source CCSID
*
d iconv pr 10i 0 extproc('iconv')
d cd value likeds(iconv_t)
d inbuf *
d inbytesleft 10u 0
d outbuf *
d outbytesleft 10u 0
*
d iconv_close pr 10i 0 extproc('iconv_close')
d cd value likeds(iconv_t)
*
**************************************************************************
* Global storage
**************************************************************************
*
d buffer s 65535 varying
Remote data buffer
d res s like(CURLcode)
Libcurl return code
d hcurl s *
Curl easy handle
d dsplybuf s 34
Display buffer
*
**************************************************************************
* Main program
**************************************************************************
*
/free
// Start libcurl.
B01 if curl_global_init(CURL_GLOBAL_ALL) <> CURLE_OK;
dsply 'curl_global_init() failed';
X01 else;
hcurl = curl_easy_init();
B02 if hcurl = *null;
dsply 'curl_easy_init() failed';
X02 else;
curl_easy_setopt_ccsid(hcurl: CURLOPT_URL:
'http://curl.haxx.se/': 0);
curl_easy_setopt_function(hcurl: CURLOPT_WRITEFUNCTION:
%paddr(@remotewrite));
curl_easy_setopt_long(hcurl: CURLOPT_VERBOSE: 1);
// For debug.
curl_easy_setopt_object(hcurl: CURLOPT_WRITEDATA:
%addr(buffer));
buffer = '';
res = curl_easy_perform(hcurl);
B03 if res <> CURLE_OK;
dsply 'curl_easy_perform() failed';
dsplybuf = %str(curl_easy_strerror_ccsid(res:
0));
dsply dsplybuf;
X03 else;
// Convert data to EBCDIC and display
// first 32 characters.
dsplybuf = @convertA2A(0: 819: buffer);
dsply dsplybuf;
E03 endif;
curl_easy_cleanup(hcurl);
E02 endif;
curl_global_cleanup();
E01 endif;
*inlr = *on;
/end-free
/space 3
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* Write data callback for libcurl.
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*
____ p @remotewrite b
*
d @remotewrite pi 10i 0
d buf 65535 options(*varsize)
d size 10u 0 value
d nmemb 10u 0 value
d userdata * value
*
d buffer s 65535 varying based(userdata)
*
**************************************************************************
* Local storage
**************************************************************************
*
d i s 10i 0
*
**************************************************************************
* Procedure code
**************************************************************************
*
/free
nmemb = nmemb * size; // Compute true data size.
i = %size(buffer) - %len(buffer);
B01 if nmemb > i;
nmemb = i;
E01 endif;
B01 if nmemb > 0;
buffer = buffer + %subst(buf: 1: nmemb);
E01 endif;
return %div(nmemb: size);
/end-free
____ p @remotewrite e
/space 3
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* Convert CCSID.
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*
____ p @convertA2A b
*
d @convertA2A pi 65535 varying
d ccsid_to 10u 0 value
d ccsid_from 10u 0 value
d data 65535 const varying
*
**************************************************************************
* Local storage
**************************************************************************
*
d cd ds likeds(iconv_t)
Conversion descriptr
d buffer s 65535
Destination buffer
d inbuf s *
Input pointer
d inbytesleft s 10u 0
Input byte counter
d outbuf s *
Output pointer
d outbytesleft s 10u 0
Output byte counter
*
**************************************************************************
* Procedure code
**************************************************************************
*
/free
cd = iconv_open('IBMCCSID' + %trim(%editw(ccsid_to: ' 0 ')) +
X'00000000000000000000000000000000000000': 'IBMCCSID' +
%trim(%editw(ccsid_from: ' 0 ')) + '0000000' +
X'000000000000000000000000');
B01 if cd.return_value = -1;
return '';
E01 endif;
buffer = data;
inbuf = %addr(buffer);
outbuf = %addr(buffer);
inbytesleft = %len(data);
outbytesleft = %size(buffer);
iconv(cd: inbuf: inbytesleft: outbuf: outbytesleft);
iconv_close(cd);
return %subst(buffer: 1: %size(buffer) - outbytesleft);
/end-free
____ p @convertA2A e
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html