~vcs-imports/simias/trunk

« back to all changes in this revision

Viewing changes to simias/tools/gsoap/gsoap-linux-2.7/samples/dime/dimeclient.cpp

  • Committer: kalidasbala
  • Date: 2007-08-25 12:48:51 UTC
  • Revision ID: vcs-imports@canonical.com-20070825124851-vlfvzun3732ld196
Latest gsoap code update

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      dimeclient.cpp
 
2
 
 
3
        Example streaming DIME client for DIME server (dimeserver.cpp).
 
4
        Supports three methods:
 
5
 
 
6
        putData stores multiple data sets on the server and returns
 
7
                named references to each data set
 
8
        getData retrieves data sets given named references.
 
9
        getImage is an example file-based image retrieval method
 
10
 
 
11
        Change the endpoint in dime.h to your needs.
 
12
 
 
13
        Copyright (C) 2000-2003 Robert A. van Engelen, Genivia, Inc.
 
14
        All Rights Reserved.
 
15
 
 
16
        Usage (server):
 
17
 
 
18
        Start dimeserver on your host at port 8085 (see dimeserver.cpp):
 
19
 
 
20
        dimeserver 8085 &
 
21
 
 
22
        Usage (client):
 
23
 
 
24
        dimeclient [-p] [-g] [-i] name ...
 
25
 
 
26
        dimeclient
 
27
                Without args retrieves image.jpg
 
28
        dimeclient name
 
29
                Retrieves image stored under name
 
30
        dimeclient -p name1 name2 ...
 
31
                Stores files name1, name2, etc. The storage keys are printed.
 
32
                The keys provide access to the data on the server.
 
33
        dimeclient -g name1 name2 ...
 
34
                Retrieves files stored under keys name1, name2, etc.
 
35
                The keys must correspond to the keys returned when storing
 
36
                files. Files are stored locally under the key name.
 
37
 
 
38
        Unix/Linux: add a sigpipe handler to avoid broken pipes.
 
39
*/
 
40
 
 
41
#include "soapH.h"
 
42
#include "dime.nsmap"
 
43
#include <assert.h>
 
44
 
 
45
// use the default endpoint set in dime.h for demo:
 
46
const char *endpoint = NULL;
 
47
// use the localhost for -p and -g (put and get):
 
48
const char *localhost = "http://localhost:8085";
 
49
 
 
50
////////////////////////////////////////////////////////////////////////////////
 
51
//
 
52
//      Forward decls
 
53
//
 
54
////////////////////////////////////////////////////////////////////////////////
 
55
 
 
56
static void putData(struct soap*, int, char**);
 
57
static void getData(struct soap*, int, char**);
 
58
static void getImage(struct soap*, char*);
 
59
static void saveData(ns__Data&, const char*);
 
60
 
 
61
////////////////////////////////////////////////////////////////////////////////
 
62
//
 
63
//      Streaming DIME attachment content handlers
 
64
//
 
65
////////////////////////////////////////////////////////////////////////////////
 
66
 
 
67
static void *dime_read_open(struct soap*, void*, const char*, const char*, const char*);
 
68
static void dime_read_close(struct soap*, void*);
 
69
static size_t dime_read(struct soap*, void*, char*, size_t);
 
70
static void *dime_write_open(struct soap*, const char*, const char*, const char*);
 
71
static void dime_write_close(struct soap*, void*);
 
72
static int dime_write(struct soap*, void*, const char*, size_t);
 
73
 
 
74
////////////////////////////////////////////////////////////////////////////////
 
75
//
 
76
//      Main
 
77
//
 
78
////////////////////////////////////////////////////////////////////////////////
 
79
 
 
80
int main(int argc, char **argv)
 
81
{ struct soap soap;
 
82
  // use HTTP 1.1 chunking
 
83
  // HTTP chunking allows streaming of DIME content without requiring DIME attachment size to be set
 
84
  // DIME attachments can be streamed without chunking ONLY if the attachment size is set
 
85
  soap_init1(&soap, SOAP_IO_CHUNK);
 
86
  // set DIME callbacks
 
87
  soap.fdimereadopen = dime_read_open;
 
88
  soap.fdimereadclose = dime_read_close;
 
89
  soap.fdimeread = dime_read;
 
90
  soap.fdimewriteopen = dime_write_open;
 
91
  soap.fdimewriteclose = dime_write_close;
 
92
  soap.fdimewrite = dime_write;
 
93
  // connect timeout value (not supported by Linux)
 
94
  soap.connect_timeout = 10;
 
95
  // IO timeouts
 
96
  soap.send_timeout = 30;
 
97
  soap.recv_timeout = 30;
 
98
  // Unix/Linux SIGPIPE, this is OS dependent:
 
99
  // soap.accept_flags = SO_NOSIGPIPE;  // some systems like this
 
100
  // soap.socket_flags = MSG_NOSIGNAL;  // others need this
 
101
  // signal(SIGPIPE, sigpipe_handle);   // or a sigpipe handler (portable)
 
102
  if (argc < 3)
 
103
  { char *name;
 
104
    if (argc < 2)
 
105
      name = "image.jpg";
 
106
    else
 
107
      name = argv[1];
 
108
    getImage(&soap, name);
 
109
  }
 
110
  else
 
111
  { switch (argv[1][1])
 
112
    { case 'p':
 
113
        endpoint = localhost;
 
114
        putData(&soap, argc, argv);
 
115
        break;
 
116
      case 'g':
 
117
        endpoint = localhost;
 
118
        getData(&soap, argc, argv);
 
119
        break;
 
120
      default:
 
121
        fprintf(stderr, "Usage: [-p] [-g] name ...\n");
 
122
        exit(0);
 
123
    }
 
124
  }
 
125
  soap_destroy(&soap);
 
126
  soap_end(&soap);
 
127
  soap_done(&soap);
 
128
  return SOAP_OK;
 
129
}
 
130
 
 
131
////////////////////////////////////////////////////////////////////////////////
 
132
//
 
133
//      Helper functions
 
134
//
 
135
////////////////////////////////////////////////////////////////////////////////
 
136
 
 
137
static void putData(struct soap *soap, int argc, char **argv)
 
138
{ arrayOfData data;
 
139
  arrayOfName names;
 
140
  data.resize(argc - 2);
 
141
  for (int i = 2; i < argc; i++)
 
142
  { data[i - 2].__ptr = (unsigned char*)argv[i];
 
143
    // MUST set id or type to enable DIME
 
144
    // zero size indicates streaming DIME (this requires HTTP chunking)
 
145
    data[i - 2].type = "";
 
146
  }
 
147
  if (soap_call_ns__putData(soap, endpoint, NULL, &data, &names))
 
148
    soap_print_fault(soap, stderr);
 
149
  else
 
150
  { printf("Data stored with keys:\n");
 
151
    for (int j = 0; j < names.size(); j++)
 
152
      printf("\t%s\n", names[j]);
 
153
    printf("Use these keys to retrieve the data\n");
 
154
  }
 
155
}
 
156
 
 
157
static void getData(struct soap *soap, int argc, char **argv)
 
158
{ arrayOfData data;
 
159
  arrayOfName names;
 
160
  names.resize(argc - 2);
 
161
  for (int i = 2; i < argc; i++)
 
162
    names[i - 2] = argv[i];
 
163
  soap->user = (void*)names.__ptr;
 
164
  if (soap_call_ns__getData(soap, endpoint, NULL, &names, &data))
 
165
    soap_print_fault(soap, stderr);
 
166
  else
 
167
  { for (int j = 0; j < data.size(); j++)
 
168
      if (!data[j].id)
 
169
        saveData(data[j], argv[j + 2]);
 
170
    printf("Data retrieved\n");
 
171
  }
 
172
}
 
173
 
 
174
static void getImage(struct soap *soap, char *name)
 
175
{ ns__Data image;
 
176
  arrayOfName temp;
 
177
  temp.resize(1);
 
178
  temp[0] = name;
 
179
  soap->user = (void*)temp.__ptr;
 
180
  if (soap_call_ns__getImage(soap, endpoint, NULL, name, image))
 
181
    soap_print_fault(soap, stderr);
 
182
  else if (image.id)
 
183
  { if (image.__size)
 
184
      printf("Got image %s size=%d type=%s through streaming DIME\n", name, image.__size, image.type?image.type:"");
 
185
    else
 
186
      printf("Got image %s type=%s through chunked streaming DIME\n", name, image.type?image.type:"");
 
187
  }
 
188
  else
 
189
  { printf("Got image %s\n", name);
 
190
    saveData(image, name);
 
191
  }
 
192
}
 
193
 
 
194
static void saveData(ns__Data& data, const char *name)
 
195
{ char *buf = (char*)data.__ptr;
 
196
  int len = data.__size;
 
197
  FILE *fd = fopen(name, "wb");
 
198
  if (!fd)
 
199
  { fprintf(stderr, "Cannot save file %s\n", name);
 
200
    return;
 
201
  }
 
202
  while (len)
 
203
  { size_t nwritten = fwrite(buf, 1, len, fd);
 
204
    if (!nwritten)
 
205
    { fprintf(stderr, "Cannot write to %s\n", name);
 
206
      return;
 
207
    }
 
208
    len -= nwritten;
 
209
    buf += nwritten;
 
210
  }
 
211
  printf("Saved file %s\n", name);
 
212
}
 
213
 
 
214
////////////////////////////////////////////////////////////////////////////////
 
215
//
 
216
//      Streaming DIME attachment content handlers
 
217
//
 
218
////////////////////////////////////////////////////////////////////////////////
 
219
 
 
220
static void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options)
 
221
{ FILE *fd;
 
222
  // 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.
 
223
  // return value of this function will be passed on to the fdimeread and fdimereadclose callbacks. The return value will not affect the __ptr field.
 
224
  fd = fopen((char*)handle, "rb");
 
225
  return (void*)fd;
 
226
}
 
227
 
 
228
static void dime_read_close(struct soap *soap, void *handle)
 
229
{ fclose((FILE*)handle);
 
230
}
 
231
 
 
232
static size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len)
 
233
{ return fread(buf, 1, len, (FILE*)handle);
 
234
}
 
235
 
 
236
static void *dime_write_open(struct soap *soap, const char *id, const char *type, const char *options)
 
237
{ // we can return NULL without setting soap->error if we don't want to use the streaming callback for this DIME attachment
 
238
  FILE *handle = NULL;
 
239
  char *name;
 
240
  // get file name from options (not '\0' terminated)
 
241
  if (options)
 
242
  { size_t len = ((unsigned char)options[2] << 8) | ((unsigned char)options[3]); // option string length
 
243
    name = (char*)soap_malloc(soap, len + 1);
 
244
    strncpy(name, options + 4, len);
 
245
    name[len] = '\0';
 
246
    handle = fopen(name, "wb");
 
247
    if (!handle)
 
248
    { soap->error = SOAP_EOF; // could not open file for writing
 
249
      soap->errnum = errno; // get reason
 
250
      return NULL;
 
251
    }
 
252
  }
 
253
  else 
 
254
    soap->error = soap_receiver_fault(soap, "Cannot save to file, because no file name was present in attachment", NULL);
 
255
  return (void*)handle;
 
256
}
 
257
 
 
258
static void dime_write_close(struct soap *soap, void *handle)
 
259
{ fclose((FILE*)handle);
 
260
}
 
261
 
 
262
static int dime_write(struct soap *soap, void *handle, const char *buf, size_t len)
 
263
{ while (len)
 
264
  { size_t nwritten = fwrite(buf, 1, len, (FILE*)handle);
 
265
    if (!nwritten)
 
266
    { soap->errnum = errno; // get reason
 
267
      return SOAP_EOF;
 
268
    }
 
269
    len -= nwritten;
 
270
    buf += nwritten;
 
271
  }
 
272
  return SOAP_OK;
 
273
}
 
274
 
 
275
////////////////////////////////////////////////////////////////////////////////
 
276
//
 
277
//      ns__Data class
 
278
//
 
279
////////////////////////////////////////////////////////////////////////////////
 
280
 
 
281
ns__Data::ns__Data()
 
282
{ __ptr = NULL;
 
283
  __size = 0;
 
284
  id = NULL;
 
285
  type = NULL;
 
286
  options = NULL;
 
287
  soap = NULL;
 
288
}
 
289
 
 
290
////////////////////////////////////////////////////////////////////////////////
 
291
//
 
292
//      arrayOfData class
 
293
//
 
294
////////////////////////////////////////////////////////////////////////////////
 
295
 
 
296
arrayOfData::arrayOfData()
 
297
{ __ptr = NULL;
 
298
  __size = 0;
 
299
  soap = NULL;
 
300
}
 
301
 
 
302
arrayOfData::arrayOfData(struct soap *soap, int n)
 
303
{ __ptr = NULL;
 
304
  __size = 0;
 
305
  this->soap = soap;
 
306
  resize(n);
 
307
}
 
308
 
 
309
arrayOfData::~arrayOfData()
 
310
{ resize(0);
 
311
}
 
312
 
 
313
int arrayOfData::size()
 
314
{ return __size;
 
315
}
 
316
 
 
317
void arrayOfData::resize(int n)
 
318
{ if (__ptr)
 
319
  { if (soap) // if created by soap environment
 
320
      soap_delete(soap, __ptr); // then delete
 
321
    else
 
322
      delete[] __ptr;
 
323
  }
 
324
  __size = n;
 
325
  if (n <= 0)
 
326
    __ptr = NULL;
 
327
  else if (soap)
 
328
    __ptr = soap_new_ns__Data(soap, n);
 
329
  else
 
330
    __ptr = new ns__Data[n];
 
331
}
 
332
 
 
333
ns__Data& arrayOfData::operator[](int i) const
 
334
{ assert(__ptr && i >= 0 && i < __size);
 
335
  return __ptr[i];
 
336
}
 
337
 
 
338
////////////////////////////////////////////////////////////////////////////////
 
339
//
 
340
//      arrayOfName class
 
341
//
 
342
////////////////////////////////////////////////////////////////////////////////
 
343
 
 
344
arrayOfName::arrayOfName()
 
345
{ __ptr = NULL;
 
346
  __size = 0;
 
347
  soap = NULL;
 
348
}
 
349
 
 
350
arrayOfName::arrayOfName(struct soap *soap, int n)
 
351
{ __ptr = NULL;
 
352
  __size = 0;
 
353
  this->soap = soap;
 
354
  resize(n);
 
355
}
 
356
 
 
357
arrayOfName::~arrayOfName()
 
358
{ resize(0);
 
359
}
 
360
 
 
361
int arrayOfName::size()
 
362
{ return __size;
 
363
}
 
364
 
 
365
void arrayOfName::resize(int n)
 
366
{ if (__ptr)
 
367
  { if (soap) // if created by soap environment
 
368
      soap_delete(soap, __ptr); // then delete
 
369
    else
 
370
      free(__ptr);
 
371
  }
 
372
  __size = n;
 
373
  if (n <= 0)
 
374
    __ptr = NULL;
 
375
  else
 
376
  { if (soap)
 
377
      __ptr = (char**)soap_malloc(soap, sizeof(char*) * n);
 
378
    else
 
379
      __ptr = (char**)malloc(sizeof(char*) * n);
 
380
    memset(__ptr, 0, n);
 
381
  }
 
382
}
 
383
 
 
384
char*& arrayOfName::operator[](int i) const
 
385
{ assert(__ptr && i >= 0 && i < __size);
 
386
  return __ptr[i];
 
387
}
 
388