47 #include "XDRStreamMarshaller.h" 48 #ifdef USE_POSIX_THREADS 49 #include "MarshallerThread.h" 65 char *XDRStreamMarshaller::d_buf = 0;
66 static const int XDR_DAP_BUFF_SIZE=256;
77 XDRStreamMarshaller::XDRStreamMarshaller(ostream &out) :
78 d_out(out), d_partial_put_byte_count(0), tm(0)
80 if (!d_buf) d_buf = (
char *) malloc(XDR_DAP_BUFF_SIZE);
81 if (!d_buf)
throw Error(internal_error,
"Failed to allocate memory for data serialization.");
83 xdrmem_create(&d_sink, d_buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE);
85 #ifdef USE_POSIX_THREADS 90 XDRStreamMarshaller::~XDRStreamMarshaller()
97 void XDRStreamMarshaller::put_byte(dods_byte val)
99 if (!xdr_setpos(&d_sink, 0))
100 throw Error(
"Network I/O Error. Could not send byte data - unable to set stream position.");
102 if (!xdr_char(&d_sink, (
char *) &val))
104 "Network I/O Error. Could not send byte data.");
106 unsigned int bytes_written = xdr_getpos(&d_sink);
109 "Network I/O Error. Could not send byte data - unable to get stream position.");
111 #ifdef USE_POSIX_THREADS 112 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
115 d_out.write(d_buf, bytes_written);
118 void XDRStreamMarshaller::put_int16(dods_int16 val)
120 if (!xdr_setpos(&d_sink, 0))
122 "Network I/O Error. Could not send int 16 data - unable to set stream position.");
124 if (!XDR_INT16(&d_sink, &val))
126 "Network I/O Error. Could not send int 16 data.");
128 unsigned int bytes_written = xdr_getpos(&d_sink);
131 "Network I/O Error. Could not send int 16 data - unable to get stream position.");
133 #ifdef USE_POSIX_THREADS 134 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
137 d_out.write(d_buf, bytes_written);
140 void XDRStreamMarshaller::put_int32(dods_int32 val)
142 if (!xdr_setpos(&d_sink, 0))
144 "Network I/O Error. Could not send int 32 data - unable to set stream position.");
146 if (!XDR_INT32(&d_sink, &val))
148 "Network I/O Error. Culd not read int 32 data.");
150 unsigned int bytes_written = xdr_getpos(&d_sink);
153 "Network I/O Error. Could not send int 32 data - unable to get stream position.");
155 #ifdef USE_POSIX_THREADS 156 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
159 d_out.write(d_buf, bytes_written);
162 void XDRStreamMarshaller::put_float32(dods_float32 val)
164 if (!xdr_setpos(&d_sink, 0))
166 "Network I/O Error. Could not send float 32 data - unable to set stream position.");
168 if (!xdr_float(&d_sink, &val))
170 "Network I/O Error. Could not send float 32 data.");
172 unsigned int bytes_written = xdr_getpos(&d_sink);
175 "Network I/O Error. Could not send float 32 data - unable to get stream position.");
177 #ifdef USE_POSIX_THREADS 178 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
181 d_out.write(d_buf, bytes_written);
184 void XDRStreamMarshaller::put_float64(dods_float64 val)
186 if (!xdr_setpos(&d_sink, 0))
188 "Network I/O Error. Could not send float 64 data - unable to set stream position.");
190 if (!xdr_double(&d_sink, &val))
192 "Network I/O Error. Could not send float 64 data.");
194 unsigned int bytes_written = xdr_getpos(&d_sink);
197 "Network I/O Error. Could not send float 64 data - unable to get stream position.");
199 #ifdef USE_POSIX_THREADS 200 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
203 d_out.write(d_buf, bytes_written);
206 void XDRStreamMarshaller::put_uint16(dods_uint16 val)
208 if (!xdr_setpos(&d_sink, 0))
210 "Network I/O Error. Could not send uint 16 data - unable to set stream position.");
212 if (!XDR_UINT16(&d_sink, &val))
214 "Network I/O Error. Could not send uint 16 data.");
216 unsigned int bytes_written = xdr_getpos(&d_sink);
219 "Network I/O Error. Could not send uint 16 data - unable to get stream position.");
221 #ifdef USE_POSIX_THREADS 222 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
225 d_out.write(d_buf, bytes_written);
228 void XDRStreamMarshaller::put_uint32(dods_uint32 val)
230 if (!xdr_setpos(&d_sink, 0))
232 "Network I/O Error. Could not send uint 32 data - unable to set stream position.");
234 if (!XDR_UINT32(&d_sink, &val))
236 "Network I/O Error. Could not send uint 32 data.");
238 unsigned int bytes_written = xdr_getpos(&d_sink);
241 "Network I/O Error. Could not send uint 32 data - unable to get stream position.");
243 #ifdef USE_POSIX_THREADS 244 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
247 d_out.write(d_buf, bytes_written);
250 void XDRStreamMarshaller::put_str(
const string &val)
252 int size = val.length() + 8;
255 vector<char> str_buf(size);
258 xdrmem_create(&str_sink, &str_buf[0], size, XDR_ENCODE);
260 if (!xdr_setpos(&str_sink, 0))
262 "Network I/O Error. Could not send string data - unable to set stream position.");
264 const char *out_tmp = val.c_str();
265 if (!xdr_string(&str_sink, (
char **) &out_tmp, size))
267 "Network I/O Error. Could not send string data.");
269 unsigned int bytes_written = xdr_getpos(&str_sink);
272 "Network I/O Error. Could not send string data - unable to get stream position.");
274 #ifdef USE_POSIX_THREADS 275 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
278 d_out.write(&str_buf[0], bytes_written);
280 xdr_destroy(&str_sink);
283 xdr_destroy(&str_sink);
288 void XDRStreamMarshaller::put_url(
const string &val)
293 void XDRStreamMarshaller::put_opaque(
char *val,
unsigned int len)
295 if (len > XDR_DAP_BUFF_SIZE)
296 throw Error(
"Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
298 if (!xdr_setpos(&d_sink, 0))
300 "Network I/O Error. Could not send opaque data - unable to set stream position.");
302 if (!xdr_opaque(&d_sink, val, len))
304 "Network I/O Error. Could not send opaque data.");
306 unsigned int bytes_written = xdr_getpos(&d_sink);
309 "Network I/O Error. Could not send opaque data - unable to get stream position.");
311 #ifdef USE_POSIX_THREADS 312 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
315 d_out.write(d_buf, bytes_written);
318 void XDRStreamMarshaller::put_int(
int val)
320 if (!xdr_setpos(&d_sink, 0))
322 "Network I/O Error. Could not send int data - unable to set stream position.");
324 if (!xdr_int(&d_sink, &val))
326 "Network I/O Error(1). Could not send int data.");
328 unsigned int bytes_written = xdr_getpos(&d_sink);
331 "Network I/O Error. Could not send int data - unable to get stream position.");
333 #ifdef USE_POSIX_THREADS 334 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
337 d_out.write(d_buf, bytes_written);
340 void XDRStreamMarshaller::put_vector(
char *val,
int num,
int width,
Vector &vec)
342 put_vector(val, num, width, vec.
var()->
type());
358 d_partial_put_byte_count = 0;
369 #ifdef USE_POSIX_THREADS 370 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
377 unsigned int mod_4 = d_partial_put_byte_count & 0x03;
378 unsigned int pad = (mod_4 == 0) ? 0: 4 - mod_4;
381 vector<char> padding(4, 0);
383 d_out.write(&padding[0], pad);
384 if (d_out.fail())
throw Error(
"Network I/O Error. Could not send vector data padding");
389 void XDRStreamMarshaller::put_vector(
char *val,
int num,
Vector &)
391 if (!val)
throw InternalErr(__FILE__, __LINE__,
"Could not send byte vector data. Buffer pointer is not set.");
397 const unsigned int add_to = 8;
400 char *byte_buf =
new char[num + add_to];
403 xdrmem_create(&byte_sink, byte_buf, num + add_to, XDR_ENCODE);
404 if (!xdr_setpos(&byte_sink, 0))
405 throw Error(
"Network I/O Error. Could not send byte vector data - unable to set stream position.");
407 if (!xdr_bytes(&byte_sink, (
char **) &val, (
unsigned int *) &num, num + add_to))
408 throw Error(
"Network I/O Error(2). Could not send byte vector data - unable to encode data.");
410 unsigned int bytes_written = xdr_getpos(&byte_sink);
412 throw Error(
"Network I/O Error. Could not send byte vector data - unable to get stream position.");
414 #ifdef USE_POSIX_THREADS 415 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
416 tm->increment_child_thread_count();
418 xdr_destroy(&byte_sink);
420 d_out.write(byte_buf, bytes_written);
421 xdr_destroy(&byte_sink);
427 DBG(cerr <<
"Caught an exception in put_vector_thread" << endl);
428 xdr_destroy(&byte_sink);
445 void XDRStreamMarshaller::put_vector(
char *val,
unsigned int num,
int width,
Type type)
447 assert(val || num == 0);
455 int use_width = width;
456 if (use_width < 4) use_width = 4;
460 int size = (num * use_width) + 4;
464 char *vec_buf =
new char[size];
467 xdrmem_create(&vec_sink, vec_buf, size, XDR_ENCODE);
470 if (!xdr_setpos(&vec_sink, 0))
471 throw Error(
"Network I/O Error. Could not send vector data - unable to set stream position.");
474 if (!xdr_array(&vec_sink, (
char **) &val, (
unsigned int *) &num, size, width,
XDRUtils::xdr_coder(type)))
475 throw Error(
"Network I/O Error(2). Could not send vector data - unable to encode.");
478 unsigned int bytes_written = xdr_getpos(&vec_sink);
480 throw Error(
"Network I/O Error. Could not send vector data - unable to get stream position.");
482 #ifdef USE_POSIX_THREADS 483 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
484 tm->increment_child_thread_count();
486 xdr_destroy(&vec_sink);
488 d_out.write(vec_buf, bytes_written);
489 xdr_destroy(&vec_sink);
494 xdr_destroy(&vec_sink);
516 const unsigned int add_to = 8;
517 unsigned int bufsiz = num + add_to;
519 char *byte_buf =
new char[bufsiz];
522 xdrmem_create(&byte_sink, byte_buf, bufsiz, XDR_ENCODE);
523 if (!xdr_setpos(&byte_sink, 0))
524 throw Error(
"Network I/O Error. Could not send byte vector data - unable to set stream position.");
526 if (!xdr_bytes(&byte_sink, (
char **) &val, (
unsigned int *) &num, bufsiz))
527 throw Error(
"Network I/O Error(2). Could not send byte vector data - unable to encode data.");
529 #ifdef USE_POSIX_THREADS 530 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
531 tm->increment_child_thread_count();
534 d_partial_put_byte_count += num;
537 xdr_destroy(&byte_sink);
542 d_out.write(byte_buf + 4, num);
545 throw Error (
"Network I/O Error. Could not send initial part of byte vector data");
548 d_partial_put_byte_count += num;
550 xdr_destroy(&byte_sink);
555 xdr_destroy(&byte_sink);
561 int use_width = (width < 4) ? 4 : width;
565 int size = (num * use_width) + 4;
569 char *vec_buf =
new char[size];
572 xdrmem_create(&vec_sink, vec_buf, size, XDR_ENCODE);
575 if (!xdr_setpos(&vec_sink, 0))
576 throw Error(
"Network I/O Error. Could not send vector data - unable to set stream position.");
579 if (!xdr_array(&vec_sink, (
char **) &val, (
unsigned int *) &num, size, width,
XDRUtils::xdr_coder(type)))
580 throw Error(
"Network I/O Error(2). Could not send vector data -unable to encode data.");
582 #ifdef USE_POSIX_THREADS 583 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
584 tm->increment_child_thread_count();
587 d_partial_put_byte_count += (size - 4);
589 xdr_destroy(&vec_sink);
593 d_out.write(vec_buf + 4, size - 4);
596 throw Error (
"Network I/O Error. Could not send part of vector data");
599 d_partial_put_byte_count += (size - 4);
601 xdr_destroy(&vec_sink);
606 xdr_destroy(&vec_sink);
615 strm << DapIndent::LMarg <<
"XDRStreamMarshaller::dump - (" << (
void *)
this <<
")" << endl;
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
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.
virtual Type type() const
Returns the type of the class instance.
A class for software fault reporting.
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
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.