49 #include "XDRStreamMarshaller.h" 50 #ifdef USE_POSIX_THREADS 51 #include "MarshallerThread.h" 58 #include "DapIndent.h" 68 char *XDRStreamMarshaller::d_buf = 0;
69 static const int XDR_DAP_BUFF_SIZE=256;
80 XDRStreamMarshaller::XDRStreamMarshaller(ostream &out) :
81 d_out(out), d_partial_put_byte_count(0), tm(0)
83 if (!d_buf) d_buf = (
char *) malloc(XDR_DAP_BUFF_SIZE);
84 if (!d_buf)
throw Error(internal_error,
"Failed to allocate memory for data serialization.");
86 xdrmem_create(&d_sink, d_buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE);
88 #ifdef USE_POSIX_THREADS 93 XDRStreamMarshaller::~XDRStreamMarshaller()
97 #ifdef USE_POSIX_THREADS 100 xdr_destroy(&d_sink);
103 void XDRStreamMarshaller::put_byte(dods_byte val)
105 if (!xdr_setpos(&d_sink, 0))
106 throw Error(
"Network I/O Error. Could not send byte data - unable to set stream position.");
108 if (!xdr_char(&d_sink, (
char *) &val))
110 "Network I/O Error. Could not send byte data.");
112 unsigned int bytes_written = xdr_getpos(&d_sink);
115 "Network I/O Error. Could not send byte data - unable to get stream position.");
117 #ifdef USE_POSIX_THREADS 118 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
121 d_out.write(d_buf, bytes_written);
124 void XDRStreamMarshaller::put_int16(dods_int16 val)
126 if (!xdr_setpos(&d_sink, 0))
128 "Network I/O Error. Could not send int 16 data - unable to set stream position.");
130 if (!XDR_INT16(&d_sink, &val))
132 "Network I/O Error. Could not send int 16 data.");
134 unsigned int bytes_written = xdr_getpos(&d_sink);
137 "Network I/O Error. Could not send int 16 data - unable to get stream position.");
139 #ifdef USE_POSIX_THREADS 140 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
143 d_out.write(d_buf, bytes_written);
146 void XDRStreamMarshaller::put_int32(dods_int32 val)
148 if (!xdr_setpos(&d_sink, 0))
150 "Network I/O Error. Could not send int 32 data - unable to set stream position.");
152 if (!XDR_INT32(&d_sink, &val))
154 "Network I/O Error. Culd not read int 32 data.");
156 unsigned int bytes_written = xdr_getpos(&d_sink);
159 "Network I/O Error. Could not send int 32 data - unable to get stream position.");
161 #ifdef USE_POSIX_THREADS 162 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
165 d_out.write(d_buf, bytes_written);
168 void XDRStreamMarshaller::put_float32(dods_float32 val)
170 if (!xdr_setpos(&d_sink, 0))
172 "Network I/O Error. Could not send float 32 data - unable to set stream position.");
174 if (!xdr_float(&d_sink, &val))
176 "Network I/O Error. Could not send float 32 data.");
178 unsigned int bytes_written = xdr_getpos(&d_sink);
181 "Network I/O Error. Could not send float 32 data - unable to get stream position.");
183 #ifdef USE_POSIX_THREADS 184 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
187 d_out.write(d_buf, bytes_written);
190 void XDRStreamMarshaller::put_float64(dods_float64 val)
192 if (!xdr_setpos(&d_sink, 0))
194 "Network I/O Error. Could not send float 64 data - unable to set stream position.");
196 if (!xdr_double(&d_sink, &val))
198 "Network I/O Error. Could not send float 64 data.");
200 unsigned int bytes_written = xdr_getpos(&d_sink);
203 "Network I/O Error. Could not send float 64 data - unable to get stream position.");
205 #ifdef USE_POSIX_THREADS 206 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
209 d_out.write(d_buf, bytes_written);
212 void XDRStreamMarshaller::put_uint16(dods_uint16 val)
214 if (!xdr_setpos(&d_sink, 0))
216 "Network I/O Error. Could not send uint 16 data - unable to set stream position.");
218 if (!XDR_UINT16(&d_sink, &val))
220 "Network I/O Error. Could not send uint 16 data.");
222 unsigned int bytes_written = xdr_getpos(&d_sink);
225 "Network I/O Error. Could not send uint 16 data - unable to get stream position.");
227 #ifdef USE_POSIX_THREADS 228 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
231 d_out.write(d_buf, bytes_written);
234 void XDRStreamMarshaller::put_uint32(dods_uint32 val)
236 if (!xdr_setpos(&d_sink, 0))
238 "Network I/O Error. Could not send uint 32 data - unable to set stream position.");
240 if (!XDR_UINT32(&d_sink, &val))
242 "Network I/O Error. Could not send uint 32 data.");
244 unsigned int bytes_written = xdr_getpos(&d_sink);
247 "Network I/O Error. Could not send uint 32 data - unable to get stream position.");
249 #ifdef USE_POSIX_THREADS 250 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
253 d_out.write(d_buf, bytes_written);
256 void XDRStreamMarshaller::put_str(
const string &val)
258 int size = val.length() + 8;
261 vector<char> str_buf(size);
264 xdrmem_create(&str_sink, &str_buf[0], size, XDR_ENCODE);
266 if (!xdr_setpos(&str_sink, 0))
268 "Network I/O Error. Could not send string data - unable to set stream position.");
270 const char *out_tmp = val.c_str();
271 if (!xdr_string(&str_sink, (
char **) &out_tmp, size))
273 "Network I/O Error. Could not send string data.");
275 unsigned int bytes_written = xdr_getpos(&str_sink);
278 "Network I/O Error. Could not send string data - unable to get stream position.");
280 #ifdef USE_POSIX_THREADS 281 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
284 d_out.write(&str_buf[0], bytes_written);
286 xdr_destroy(&str_sink);
289 xdr_destroy(&str_sink);
294 void XDRStreamMarshaller::put_url(
const string &val)
299 void XDRStreamMarshaller::put_opaque(
char *val,
unsigned int len)
301 if (len > XDR_DAP_BUFF_SIZE)
302 throw Error(
"Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
304 if (!xdr_setpos(&d_sink, 0))
306 "Network I/O Error. Could not send opaque data - unable to set stream position.");
308 if (!xdr_opaque(&d_sink, val, len))
310 "Network I/O Error. Could not send opaque data.");
312 unsigned int bytes_written = xdr_getpos(&d_sink);
315 "Network I/O Error. Could not send opaque data - unable to get stream position.");
317 #ifdef USE_POSIX_THREADS 318 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
321 d_out.write(d_buf, bytes_written);
324 void XDRStreamMarshaller::put_int(
int val)
326 if (!xdr_setpos(&d_sink, 0))
328 "Network I/O Error. Could not send int data - unable to set stream position.");
330 if (!xdr_int(&d_sink, &val))
332 "Network I/O Error(1). Could not send int data.");
334 unsigned int bytes_written = xdr_getpos(&d_sink);
337 "Network I/O Error. Could not send int data - unable to get stream position.");
339 #ifdef USE_POSIX_THREADS 340 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
343 d_out.write(d_buf, bytes_written);
346 void XDRStreamMarshaller::put_vector(
char *val,
int num,
int width,
Vector &vec)
348 put_vector(val, num, width, vec.
var()->
type());
364 d_partial_put_byte_count = 0;
375 #ifdef USE_POSIX_THREADS 376 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
383 unsigned int mod_4 = d_partial_put_byte_count & 0x03;
384 unsigned int pad = (mod_4 == 0) ? 0: 4 - mod_4;
387 vector<char> padding(4, 0);
389 d_out.write(&padding[0], pad);
390 if (d_out.fail())
throw Error(
"Network I/O Error. Could not send vector data padding");
395 void XDRStreamMarshaller::put_vector(
char *val,
int num,
Vector &)
397 if (!val)
throw InternalErr(__FILE__, __LINE__,
"Could not send byte vector data. Buffer pointer is not set.");
403 const unsigned int add_to = 8;
406 char *byte_buf =
new char[num + add_to];
409 xdrmem_create(&byte_sink, byte_buf, num + add_to, XDR_ENCODE);
410 if (!xdr_setpos(&byte_sink, 0))
411 throw Error(
"Network I/O Error. Could not send byte vector data - unable to set stream position.");
413 if (!xdr_bytes(&byte_sink, (
char **) &val, (
unsigned int *) &num, num + add_to))
414 throw Error(
"Network I/O Error(2). Could not send byte vector data - unable to encode data.");
416 unsigned int bytes_written = xdr_getpos(&byte_sink);
418 throw Error(
"Network I/O Error. Could not send byte vector data - unable to get stream position.");
420 #ifdef USE_POSIX_THREADS 421 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
422 tm->increment_child_thread_count();
424 xdr_destroy(&byte_sink);
426 d_out.write(byte_buf, bytes_written);
427 xdr_destroy(&byte_sink);
433 DBG(cerr <<
"Caught an exception in put_vector_thread" << endl);
434 xdr_destroy(&byte_sink);
451 void XDRStreamMarshaller::put_vector(
char *val,
unsigned int num,
int width,
Type type)
453 assert(val || num == 0);
461 int use_width = width;
462 if (use_width < 4) use_width = 4;
466 int size = (num * use_width) + 4;
470 char *vec_buf =
new char[size];
473 xdrmem_create(&vec_sink, vec_buf, size, XDR_ENCODE);
476 if (!xdr_setpos(&vec_sink, 0))
477 throw Error(
"Network I/O Error. Could not send vector data - unable to set stream position.");
480 if (!xdr_array(&vec_sink, (
char **) &val, (
unsigned int *) &num, size, width,
XDRUtils::xdr_coder(type)))
481 throw Error(
"Network I/O Error(2). Could not send vector data - unable to encode.");
484 unsigned int bytes_written = xdr_getpos(&vec_sink);
486 throw Error(
"Network I/O Error. Could not send vector data - unable to get stream position.");
488 #ifdef USE_POSIX_THREADS 489 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
490 tm->increment_child_thread_count();
492 xdr_destroy(&vec_sink);
494 d_out.write(vec_buf, bytes_written);
495 xdr_destroy(&vec_sink);
500 xdr_destroy(&vec_sink);
522 const unsigned int add_to = 8;
523 unsigned int bufsiz = num + add_to;
525 char *byte_buf =
new char[bufsiz];
528 xdrmem_create(&byte_sink, byte_buf, bufsiz, XDR_ENCODE);
529 if (!xdr_setpos(&byte_sink, 0))
530 throw Error(
"Network I/O Error. Could not send byte vector data - unable to set stream position.");
532 if (!xdr_bytes(&byte_sink, (
char **) &val, (
unsigned int *) &num, bufsiz))
533 throw Error(
"Network I/O Error(2). Could not send byte vector data - unable to encode data.");
535 #ifdef USE_POSIX_THREADS 536 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
537 tm->increment_child_thread_count();
540 d_partial_put_byte_count += num;
543 xdr_destroy(&byte_sink);
548 d_out.write(byte_buf + 4, num);
551 throw Error (
"Network I/O Error. Could not send initial part of byte vector data");
554 d_partial_put_byte_count += num;
556 xdr_destroy(&byte_sink);
561 xdr_destroy(&byte_sink);
567 int use_width = (width < 4) ? 4 : width;
571 int size = (num * use_width) + 4;
575 char *vec_buf =
new char[size];
578 xdrmem_create(&vec_sink, vec_buf, size, XDR_ENCODE);
581 if (!xdr_setpos(&vec_sink, 0))
582 throw Error(
"Network I/O Error. Could not send vector data - unable to set stream position.");
585 if (!xdr_array(&vec_sink, (
char **) &val, (
unsigned int *) &num, size, width,
XDRUtils::xdr_coder(type)))
586 throw Error(
"Network I/O Error(2). Could not send vector data -unable to encode data.");
588 #ifdef USE_POSIX_THREADS 589 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
590 tm->increment_child_thread_count();
593 d_partial_put_byte_count += (size - 4);
595 xdr_destroy(&vec_sink);
599 d_out.write(vec_buf + 4, size - 4);
602 throw Error (
"Network I/O Error. Could not send part of vector data");
605 d_partial_put_byte_count += (size - 4);
607 xdr_destroy(&vec_sink);
612 xdr_destroy(&vec_sink);
621 strm << DapIndent::LMarg <<
"XDRStreamMarshaller::dump - (" << (
void *)
this <<
")" << endl;
static void * write_thread(void *arg)
Holds a one-dimensional collection of DAP2 data types.
virtual void put_vector_part(char *val, unsigned int num, int width, Type type)
void start_thread(void *(*thread)(void *arg), std::ostream &out, char *byte_buf, unsigned int bytes_written)
virtual void put_vector_start(int num)
Type
Identifies the data type.
top level DAP object to house generic methods
A class for software fault reporting.
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
virtual Type type() const
Returns the type of the class instance.
virtual void put_vector_end()
static void * write_thread_part(void *arg)
static xdrproc_t xdr_coder(const Type &t)
Returns a function used to encode elements of an array.
A class for error processing.