55 static inline bool is_host_big_endian()
57 #ifdef COMPUTE_ENDIAN_AT_RUNTIME
60 char *c =
reinterpret_cast<char*
>(&i);
65 #ifdef WORDS_BIGENDIAN
79 uint32_t part0 =
static_cast<uint32_t
>(value );
80 uint32_t part1 =
static_cast<uint32_t
>(value >> 28);
81 uint32_t part2 =
static_cast<uint32_t
>(value >> 56);
94 if (part0 < (1 << 14)) {
95 if (part0 < (1 << 7)) {
101 if (part0 < (1 << 21)) {
102 size = 3;
goto size3;
104 size = 4;
goto size4;
108 if (part1 < (1 << 14)) {
109 if (part1 < (1 << 7)) {
110 size = 5;
goto size5;
112 size = 6;
goto size6;
115 if (part1 < (1 << 21)) {
116 size = 7;
goto size7;
118 size = 8;
goto size8;
123 if (part2 < (1 << 7)) {
124 size = 9;
goto size9;
126 size = 10;
goto size10;
132 size10: target[9] =
static_cast<uint8_t
>((part2 >> 7) | 0x80);
133 size9 : target[8] =
static_cast<uint8_t
>((part2 ) | 0x80);
134 size8 : target[7] =
static_cast<uint8_t
>((part1 >> 21) | 0x80);
135 size7 : target[6] =
static_cast<uint8_t
>((part1 >> 14) | 0x80);
136 size6 : target[5] =
static_cast<uint8_t
>((part1 >> 7) | 0x80);
137 size5 : target[4] =
static_cast<uint8_t
>((part1 ) | 0x80);
138 size4 : target[3] =
static_cast<uint8_t
>((part0 >> 21) | 0x80);
139 size3 : target[2] =
static_cast<uint8_t
>((part0 >> 14) | 0x80);
140 size2 : target[1] =
static_cast<uint8_t
>((part0 >> 7) | 0x80);
141 size1 : target[0] =
static_cast<uint8_t
>((part0 ) | 0x80);
143 target[size-1] &= 0x7F;
144 return target + size;
154 DAP4StreamMarshaller::DAP4StreamMarshaller(ostream &out,
bool write_data) :
155 d_out(out), d_ctx(0), d_write_data(write_data), d_checksum_ctx_valid(false)
163 throw InternalErr(__FILE__, __LINE__,
"Could not create DAP4StreamMarshaller");
164 xdrmem_create(&d_scalar_sink, d_ieee754_buf,
sizeof(
dods_float64), XDR_ENCODE);
168 out.exceptions(ostream::failbit | ostream::badbit);
170 d_ctx = EVP_MD_CTX_create();
178 xdr_destroy (&d_scalar_sink);
180 EVP_MD_CTX_destroy(d_ctx);
192 return (is_host_big_endian()) ?
"big":
"little";
201 if (EVP_DigestInit_ex(d_ctx, EVP_md5(), 0) == 0)
202 throw Error(
"Failed to initialize checksum object.");
204 d_checksum_ctx_valid =
true;
210 void DAP4StreamMarshaller::m_compute_checksum()
212 if (d_checksum_ctx_valid) {
215 d_checksum_ctx_valid =
false;
222 int status = EVP_DigestFinal_ex(d_ctx, &d_md[0], &md_len);
224 throw Error(
"Error computing the checksum (checksum computation).");
235 if (d_checksum_ctx_valid) {
236 m_compute_checksum();
240 oss.setf(ios::hex, ios::basefield);
242 oss << setfill(
'0') << setw(2) << (
unsigned int) d_md[i];
250 if (d_checksum_ctx_valid) {
251 m_compute_checksum();
254 d_out.write(reinterpret_cast<char*>(&d_md[0]),
c_md5_length);
259 if (!d_checksum_ctx_valid)
260 throw InternalErr(__FILE__, __LINE__,
"Invalid checksum context (checksum update).");
262 if (EVP_DigestUpdate(d_ctx, data, len) == 0) {
263 d_checksum_ctx_valid =
false;
264 throw Error(
"Error computing the checksum (checksum update).");
273 DBG( std::cerr <<
"put_byte: " << val << std::endl );
275 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_byte));
284 DBG( std::cerr <<
"put_int8: " << val << std::endl );
286 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int8));
295 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int16));
303 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int32));
311 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int64));
319 if (std::numeric_limits<float>::is_iec559 ) {
320 DBG2(cerr <<
"Native rep is ieee754." << endl);
321 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_float32));
324 if (!xdr_setpos(&d_scalar_sink, 0))
325 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float32 variable");
327 if (!xdr_float(&d_scalar_sink, &val))
328 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float32 variable");
331 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float32 variable");
334 static bool twiddle_bytes = !is_host_big_endian();
350 if (std::numeric_limits<double>::is_iec559)
351 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_float64));
353 if (!xdr_setpos(&d_scalar_sink, 0))
354 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 variable");
356 if (!xdr_double(&d_scalar_sink, &val))
357 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 variable");
360 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 variable");
363 static bool twiddle_bytes = !is_host_big_endian();
379 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_uint16));
387 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_uint32));
395 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_uint64));
405 d_out.write(val.data(), val.length());
420 d_out.write(val, len);
427 DBG2(cerr <<
"val: " << val << endl);
429 vector<uint8_t> target(
sizeof(
dods_uint64) + 1, 0);
431 d_out.write(reinterpret_cast<char*>(&target[0]), to_send - &target[0]);
433 DBG2(cerr <<
"varint: " << hex << *(uint64_t*)&target[0] << dec << endl);
441 d_out.write(val, num);
464 void DAP4StreamMarshaller::m_serialize_reals(
char *val,
unsigned int num,
int width,
Type type)
469 vector<char> buf(size);
471 xdrmem_create(&xdr, &buf[0], size, XDR_ENCODE);
474 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 array");
476 if (xdr_getpos(&xdr) != size)
477 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 array");
480 static bool twiddle_bytes = !is_host_big_endian();
498 d_out.write(&buf[0], size);
512 if (type ==
dods_float32_c && !std::numeric_limits<float>::is_iec559) {
514 m_serialize_reals(val, num, 4, type);
516 else if (type ==
dods_float64_c && !std::numeric_limits<double>::is_iec559) {
517 m_serialize_reals(val, num, 8, type);
520 d_out.write(val, num * width);
544 strm <<
DapIndent::LMarg <<
"DAP4StreamMarshaller::dump - (" << (
void *)
this <<
")" << endl;
virtual void put_uint16(dods_uint16 val)
static const unsigned int c_md5_length
virtual void put_varying_vector(char *val, unsigned int num)
virtual void put_float64(dods_float64 val)
virtual void put_float32(dods_float32 val)
virtual void put_vector(char *val, unsigned int num)
virtual void dump(ostream &strm) const
dump the contents of this object to the specified ostream
virtual void put_opaque(char *val, unsigned int len)
Type
Identifies the data type.
virtual string get_endian() const
A class for software fault reporting.
uint8_t * WriteVarint64ToArrayInline(uint64_t value, uint8_t *target)
virtual void put_int32(dods_int32 val)
virtual void checksum_update(const void *data, unsigned long len)
virtual void put_int16(dods_int16 val)
virtual void put_int8(dods_int8 val)
virtual void put_byte(dods_byte val)
virtual void put_url(const string &val)
virtual void put_uint64(dods_uint64 val)
static ostream & LMarg(ostream &strm)
virtual ~DAP4StreamMarshaller()
virtual void put_uint32(dods_uint32 val)
virtual void put_str(const string &val)
virtual void reset_checksum()
virtual void put_int64(dods_int64 val)
static xdrproc_t xdr_coder(const Type &t)
Returns a function used to encode elements of an array.
A class for error processing.
virtual void put_length_prefix(dods_uint64 val)
virtual string get_checksum()