49#ifdef USE_POSIX_THREADS
67char *XDRStreamMarshaller::d_buf = 0;
68static const int XDR_DAP_BUFF_SIZE = 256;
78XDRStreamMarshaller::XDRStreamMarshaller(ostream &out) : d_out(out), d_partial_put_byte_count(0), tm(0) {
80 d_buf = (
char *)malloc(XDR_DAP_BUFF_SIZE);
84 xdrmem_create(&d_sink, d_buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE);
86#ifdef USE_POSIX_THREADS
94#ifdef USE_POSIX_THREADS
101 if (!xdr_setpos(&d_sink, 0))
102 throw Error(
"Network I/O Error. Could not send byte data - unable to set stream position.");
104 if (!xdr_char(&d_sink, (
char *)&val))
105 throw Error(
"Network I/O Error. Could not send byte data.");
107 unsigned int bytes_written = xdr_getpos(&d_sink);
109 throw Error(
"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);
119 if (!xdr_setpos(&d_sink, 0))
120 throw Error(
"Network I/O Error. Could not send int 16 data - unable to set stream position.");
123 throw Error(
"Network I/O Error. Could not send int 16 data.");
125 unsigned int bytes_written = xdr_getpos(&d_sink);
127 throw Error(
"Network I/O Error. Could not send int 16 data - unable to get stream position.");
129#ifdef USE_POSIX_THREADS
130 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
133 d_out.write(d_buf, bytes_written);
137 if (!xdr_setpos(&d_sink, 0))
138 throw Error(
"Network I/O Error. Could not send int 32 data - unable to set stream position.");
141 throw Error(
"Network I/O Error. Culd not read int 32 data.");
143 unsigned int bytes_written = xdr_getpos(&d_sink);
145 throw Error(
"Network I/O Error. Could not send int 32 data - unable to get stream position.");
147#ifdef USE_POSIX_THREADS
148 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
151 d_out.write(d_buf, bytes_written);
155 if (!xdr_setpos(&d_sink, 0))
156 throw Error(
"Network I/O Error. Could not send float 32 data - unable to set stream position.");
158 if (!xdr_float(&d_sink, &val))
159 throw Error(
"Network I/O Error. Could not send float 32 data.");
161 unsigned int bytes_written = xdr_getpos(&d_sink);
163 throw Error(
"Network I/O Error. Could not send float 32 data - unable to get stream position.");
165#ifdef USE_POSIX_THREADS
166 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
169 d_out.write(d_buf, bytes_written);
173 if (!xdr_setpos(&d_sink, 0))
174 throw Error(
"Network I/O Error. Could not send float 64 data - unable to set stream position.");
176 if (!xdr_double(&d_sink, &val))
177 throw Error(
"Network I/O Error. Could not send float 64 data.");
179 unsigned int bytes_written = xdr_getpos(&d_sink);
181 throw Error(
"Network I/O Error. Could not send float 64 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);
191 if (!xdr_setpos(&d_sink, 0))
192 throw Error(
"Network I/O Error. Could not send uint 16 data - unable to set stream position.");
195 throw Error(
"Network I/O Error. Could not send uint 16 data.");
197 unsigned int bytes_written = xdr_getpos(&d_sink);
199 throw Error(
"Network I/O Error. Could not send uint 16 data - unable to get stream position.");
201#ifdef USE_POSIX_THREADS
202 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
205 d_out.write(d_buf, bytes_written);
209 if (!xdr_setpos(&d_sink, 0))
210 throw Error(
"Network I/O Error. Could not send uint 32 data - unable to set stream position.");
213 throw Error(
"Network I/O Error. Could not send uint 32 data.");
215 unsigned int bytes_written = xdr_getpos(&d_sink);
217 throw Error(
"Network I/O Error. Could not send uint 32 data - unable to get stream position.");
219#ifdef USE_POSIX_THREADS
220 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
223 d_out.write(d_buf, bytes_written);
227 int size = val.length() + 8;
230 vector<char> str_buf(size);
233 xdrmem_create(&str_sink, str_buf.data(), size, XDR_ENCODE);
235 if (!xdr_setpos(&str_sink, 0))
236 throw Error(
"Network I/O Error. Could not send string data - unable to set stream position.");
238 const char *out_tmp = val.c_str();
239 if (!xdr_string(&str_sink, (
char **)&out_tmp, size))
240 throw Error(
"Network I/O Error. Could not send string data.");
242 unsigned int bytes_written = xdr_getpos(&str_sink);
244 throw Error(
"Network I/O Error. Could not send string data - unable to get stream position.");
246#ifdef USE_POSIX_THREADS
247 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
250 d_out.write(str_buf.data(), bytes_written);
252 xdr_destroy(&str_sink);
254 xdr_destroy(&str_sink);
262 if (len > XDR_DAP_BUFF_SIZE)
263 throw Error(
"Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
265 if (!xdr_setpos(&d_sink, 0))
266 throw Error(
"Network I/O Error. Could not send opaque data - unable to set stream position.");
268 if (!xdr_opaque(&d_sink, val, len))
269 throw Error(
"Network I/O Error. Could not send opaque data.");
271 unsigned int bytes_written = xdr_getpos(&d_sink);
273 throw Error(
"Network I/O Error. Could not send opaque data - unable to get stream position.");
275#ifdef USE_POSIX_THREADS
276 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
279 d_out.write(d_buf, bytes_written);
283 if (!xdr_setpos(&d_sink, 0))
284 throw Error(
"Network I/O Error. Could not send int data - unable to set stream position.");
286 if (!xdr_int(&d_sink, &val))
287 throw Error(
"Network I/O Error(1). Could not send int data.");
289 unsigned int bytes_written = xdr_getpos(&d_sink);
291 throw Error(
"Network I/O Error. Could not send int data - unable to get stream position.");
293#ifdef USE_POSIX_THREADS
294 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
297 d_out.write(d_buf, bytes_written);
300void XDRStreamMarshaller::put_vector(
char *val,
int num,
int width,
Vector &vec) {
301 put_vector(val, num, width, vec.
var()->
type());
315 d_partial_put_byte_count = 0;
325#ifdef USE_POSIX_THREADS
326 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
333 unsigned int mod_4 = d_partial_put_byte_count & 0x03;
334 unsigned int pad = (mod_4 == 0) ? 0 : 4 - mod_4;
337 vector<char> padding(4, 0);
339 d_out.write(padding.data(), pad);
341 throw Error(
"Network I/O Error. Could not send vector data padding");
346void XDRStreamMarshaller::put_vector(
char *val,
int num,
Vector &) {
348 throw InternalErr(__FILE__, __LINE__,
"Could not send byte vector data. Buffer pointer is not set.");
354 const unsigned int add_to = 8;
357 char *byte_buf =
new char[num + add_to];
360 xdrmem_create(&byte_sink, byte_buf, num + add_to, XDR_ENCODE);
361 if (!xdr_setpos(&byte_sink, 0))
362 throw Error(
"Network I/O Error. Could not send byte vector data - unable to set stream position.");
364 if (!xdr_bytes(&byte_sink, (
char **)&val, (
unsigned int *)&num, num + add_to))
365 throw Error(
"Network I/O Error(2). Could not send byte vector data - unable to encode data.");
367 unsigned int bytes_written = xdr_getpos(&byte_sink);
369 throw Error(
"Network I/O Error. Could not send byte vector data - unable to get stream position.");
371#ifdef USE_POSIX_THREADS
372 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
373 tm->increment_child_thread_count();
375 xdr_destroy(&byte_sink);
377 d_out.write(byte_buf, bytes_written);
378 xdr_destroy(&byte_sink);
383 DBG(cerr <<
"Caught an exception in put_vector_thread" << endl);
384 xdr_destroy(&byte_sink);
401void XDRStreamMarshaller::put_vector(
char *val,
unsigned int num,
int width,
Type type) {
402 assert(val || num == 0);
410 int use_width = width;
416 int size = (num * use_width) + 4;
420 char *vec_buf =
new char[size];
423 xdrmem_create(&vec_sink, vec_buf, size, XDR_ENCODE);
426 if (!xdr_setpos(&vec_sink, 0))
427 throw Error(
"Network I/O Error. Could not send vector data - unable to set stream position.");
430 if (!xdr_array(&vec_sink, (
char **)&val, (
unsigned int *)&num, size, width,
XDRUtils::xdr_coder(type)))
431 throw Error(
"Network I/O Error(2). Could not send vector data - unable to encode.");
434 unsigned int bytes_written = xdr_getpos(&vec_sink);
436 throw Error(
"Network I/O Error. Could not send vector data - unable to get stream position.");
438#ifdef USE_POSIX_THREADS
442 xdr_destroy(&vec_sink);
444 d_out.write(vec_buf, bytes_written);
445 xdr_destroy(&vec_sink);
449 xdr_destroy(&vec_sink);
470 const unsigned int add_to = 8;
471 unsigned int bufsiz = num + add_to;
473 char *byte_buf =
new char[bufsiz];
476 xdrmem_create(&byte_sink, byte_buf, bufsiz, XDR_ENCODE);
477 if (!xdr_setpos(&byte_sink, 0))
478 throw Error(
"Network I/O Error. Could not send byte vector data - unable to set stream position.");
480 if (!xdr_bytes(&byte_sink, (
char **)&val, (
unsigned int *)&num, bufsiz))
481 throw Error(
"Network I/O Error(2). Could not send byte vector data - unable to encode data.");
483#ifdef USE_POSIX_THREADS
484 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
485 tm->increment_child_thread_count();
488 d_partial_put_byte_count += num;
491 xdr_destroy(&byte_sink);
496 d_out.write(byte_buf + 4, num);
499 throw Error(
"Network I/O Error. Could not send initial part of byte vector data");
502 d_partial_put_byte_count += num;
504 xdr_destroy(&byte_sink);
508 xdr_destroy(&byte_sink);
513 int use_width = (width < 4) ? 4 : width;
517 int size = (num * use_width) + 4;
521 char *vec_buf =
new char[size];
524 xdrmem_create(&vec_sink, vec_buf, size, XDR_ENCODE);
527 if (!xdr_setpos(&vec_sink, 0))
528 throw Error(
"Network I/O Error. Could not send vector data - unable to set stream position.");
531 if (!xdr_array(&vec_sink, (
char **)&val, (
unsigned int *)&num, size, width,
XDRUtils::xdr_coder(type)))
532 throw Error(
"Network I/O Error(2). Could not send vector data -unable to encode data.");
534#ifdef USE_POSIX_THREADS
535 Locker lock(tm->get_mutex(), tm->get_cond(), tm->get_child_thread_count());
536 tm->increment_child_thread_count();
539 d_partial_put_byte_count += (size - 4);
541 xdr_destroy(&vec_sink);
545 d_out.write(vec_buf + 4, size - 4);
548 throw Error(
"Network I/O Error. Could not send part of vector data");
551 d_partial_put_byte_count += (size - 4);
553 xdr_destroy(&vec_sink);
557 xdr_destroy(&vec_sink);
565 strm <<
DapIndent::LMarg <<
"XDRStreamMarshaller::dump - (" << (
void *)
this <<
")" << endl;
#define internal_error
Internal server error (500)
virtual Type type() const
Returns the type of the class instance.
static ostream & LMarg(ostream &strm)
A class for error processing.
A class for software fault reporting.
static void * write_thread(void *arg)
void increment_child_thread_count()
int & get_child_thread_count()
void start_thread(void *(*thread)(void *arg), std::ostream &out, char *byte_buf, std::streamsize bytes_written)
pthread_mutex_t & get_mutex()
static void * write_thread_part(void *arg)
pthread_cond_t & get_cond()
Holds a one-dimensional collection of DAP2 data types.
BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=nullptr) override
virtual ~XDRStreamMarshaller()
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
virtual void put_float64(dods_float64 val)
virtual void put_str(const string &val)
virtual void put_vector_end()
virtual void put_int16(dods_int16 val)
virtual void put_url(const string &val)
virtual void put_float32(dods_float32 val)
virtual void put_uint16(dods_uint16 val)
virtual void put_int(int val)
virtual void put_opaque(char *val, unsigned int len)
virtual void put_int32(dods_int32 val)
virtual void put_vector_start(int num)
virtual void put_uint32(dods_uint32 val)
virtual void put_byte(dods_byte val)
virtual void put_vector_part(char *val, unsigned int num, int width, Type type)
static xdrproc_t xdr_coder(const Type &t)
Returns a function used to encode elements of an array.
top level DAP object to house generic methods
Type
Identifies the data type.