| /* dimeclient.cpp |
| |
| Example DIME client for simple image server. This DIME client |
| demonstrates the new gSOAP DIME streaming feature. |
| |
| Copyright (C) 2000-2002 Robert A. van Engelen. All Rights Reserved. |
| |
| Run from command line. The first optional argument is the image file |
| name. The second optional argument is the service endpoint URL. The |
| third optional argument is the file name to save the image file to. |
| */ |
| |
| #include "soapH.h" |
| #include "dime.nsmap" |
| #include <sys/stat.h> // use fstat() for streaming DIME |
| |
| // streaming DIME callbacks |
| static void *dime_write_open(struct soap*, const char*, const char*, const char*); |
| static void dime_write_close(struct soap*, void*); |
| static int dime_write(struct soap*, void*, const char*, size_t); |
| |
| static void *dime_read_open(struct soap*, void*, const char*, const char*, const char*); |
| static void dime_read_close(struct soap*, void*); |
| static size_t dime_read(struct soap*, void*, char*, size_t); |
| |
| |
| static int getImage(const char *name, const char *url, const char *outputfile) { |
| struct soap soap; |
| xsd__base64Binary image; |
| soap_init(&soap); |
| soap.user = (void*)outputfile; |
| soap.fdimewriteopen = dime_write_open; |
| soap.fdimewriteclose = dime_write_close; |
| soap.fdimewrite = dime_write; |
| soap.connect_timeout = 10; |
| int nRet = soap_call_ns__getImage(&soap, url, "", (char *)name, image); |
| if (nRet != SOAP_OK) { |
| soap_print_fault(&soap, stderr); |
| } else { |
| printf("got an image, I suppose\n"); |
| } |
| soap_destroy(&soap); |
| soap_end(&soap); |
| return nRet; |
| } |
| static int putImage(const char *name, const char *url, const char *inputfile) { |
| FILE *fd = fopen(inputfile, "rb"); |
| if (NULL == fd) { |
| printf("failed to open %s\n", inputfile); |
| return 3; |
| } |
| struct stat sb; |
| if (0 != fstat(fileno(fd), &sb) || sb.st_size <= 0) { |
| printf("cannot find the length of file %s\n", inputfile); |
| return 4; |
| |
| } |
| struct soap soap; |
| soap_init(&soap); |
| xsd__base64Binary *pimage = soap_new_xsd__base64Binary(&soap, -1); |
| soap.user = (void *)inputfile; |
| soap.fdimereadopen = dime_read_open; |
| soap.fdimereadclose = dime_read_close; |
| soap.fdimeread = dime_read; |
| pimage->__ptr = (unsigned char*)fd; |
| pimage->__size = sb.st_size; // must set size |
| pimage->type = "image/jpeg"; |
| pimage->options = soap_dime_option(&soap, 0, "My sent picture"); |
| soap.connect_timeout = 10; |
| |
| int nStatus = 0; |
| int nRet = soap_call_ns__putImage(&soap, url, "", (char *)name, pimage, nStatus); |
| if (nRet != SOAP_OK) { |
| soap_print_fault(&soap, stderr); |
| } else { |
| printf("sent an image, I suppose"); |
| } |
| soap_destroy(&soap); |
| soap_end(&soap); |
| return nRet; |
| } |
| int main(const int argc, const char *const *const argv) { |
| if (4 != argc) { |
| printf("usage: %s imagename outputfilename\n", argv[0]); |
| return 1; |
| } |
| int nRet = 0; |
| nRet = getImage(argv[1], argv[2], argv[3]); |
| if (0 == nRet) { |
| nRet = putImage(argv[1], argv[2], argv[3]); |
| } |
| return nRet; |
| } |
| |
| static void *dime_write_open(struct soap *soap, const char *id, const char *type, const char *options) |
| { FILE *handle = NULL; |
| // we can return NULL without setting soap->error if we don't want to use the streaming callback for this DIME attachment |
| handle = fopen((char*)soap->user, "wb"); |
| if (handle) |
| printf("Streaming image id=%s type=%s into file %s\n", id, type, (char*)soap->user); |
| else |
| { soap->error = SOAP_EOF; // could not open file for writing |
| soap->errnum = errno; // get reason |
| } |
| return (void*)handle; |
| } |
| |
| static void dime_write_close(struct soap *soap, void *handle) |
| { fclose((FILE*)handle); |
| } |
| |
| static int dime_write(struct soap *soap, void *handle, const char *buf, size_t len) |
| { size_t nwritten; |
| while (len) |
| { nwritten = fwrite(buf, 1, len, (FILE*)handle); |
| if (!nwritten) |
| { soap->errnum = errno; // get reason |
| return SOAP_EOF; |
| } |
| len -= nwritten; |
| buf += nwritten; |
| } |
| return SOAP_OK; |
| } |
| |
| //// reading routines for putImage: |
| /** save a file sent by the client to our server */ |
| static void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options) { |
| // we should return NULL without setting soap->error if we don't want to use the streaming callback for this DIME attachment. The handle contains the non-NULL __ptr field value which should have been set in the application. |
| // the value of the handle can be changed and will be passed on to the fdimeread and fdimereadclose callbacks. The value will not affect the __ptr field. |
| return handle; |
| } |
| |
| static void dime_read_close(struct soap *soap, void *handle) { |
| fclose((FILE*)handle); |
| } |
| static size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len) { |
| return fread(buf, 1, len, (FILE*)handle); |
| } |
| |