54 static inline bool is_host_big_endian()
56 #ifdef COMPUTE_ENDIAN_AT_RUNTIME
59 char *c =
reinterpret_cast<char*
>(&i);
64 #ifdef WORDS_BIGENDIAN
78 uint32_t part0 =
static_cast<uint32_t
>(value );
79 uint32_t part1 =
static_cast<uint32_t
>(value >> 28);
80 uint32_t part2 =
static_cast<uint32_t
>(value >> 56);
93 if (part0 < (1 << 14)) {
94 if (part0 < (1 << 7)) {
100 if (part0 < (1 << 21)) {
101 size = 3;
goto size3;
103 size = 4;
goto size4;
107 if (part1 < (1 << 14)) {
108 if (part1 < (1 << 7)) {
109 size = 5;
goto size5;
111 size = 6;
goto size6;
114 if (part1 < (1 << 21)) {
115 size = 7;
goto size7;
117 size = 8;
goto size8;
122 if (part2 < (1 << 7)) {
123 size = 9;
goto size9;
125 size = 10;
goto size10;
131 size10: target[9] =
static_cast<uint8_t
>((part2 >> 7) | 0x80);
132 size9 : target[8] =
static_cast<uint8_t
>((part2 ) | 0x80);
133 size8 : target[7] =
static_cast<uint8_t
>((part1 >> 21) | 0x80);
134 size7 : target[6] =
static_cast<uint8_t
>((part1 >> 14) | 0x80);
135 size6 : target[5] =
static_cast<uint8_t
>((part1 >> 7) | 0x80);
136 size5 : target[4] =
static_cast<uint8_t
>((part1 ) | 0x80);
137 size4 : target[3] =
static_cast<uint8_t
>((part0 >> 21) | 0x80);
138 size3 : target[2] =
static_cast<uint8_t
>((part0 >> 14) | 0x80);
139 size2 : target[1] =
static_cast<uint8_t
>((part0 >> 7) | 0x80);
140 size1 : target[0] =
static_cast<uint8_t
>((part0 ) | 0x80);
142 target[size-1] &= 0x7F;
143 return target + size;
153 DAP4StreamMarshaller::DAP4StreamMarshaller(ostream &out,
bool write_data) :
154 d_out(out), d_ctx(0), d_write_data(write_data), d_checksum_ctx_valid(false)
162 throw InternalErr(__FILE__, __LINE__,
"Could not create DAP4StreamMarshaller");
163 xdrmem_create(&d_scalar_sink, d_ieee754_buf,
sizeof(
dods_float64), XDR_ENCODE);
167 out.exceptions(ostream::failbit | ostream::badbit);
169 d_ctx = EVP_MD_CTX_create();
177 xdr_destroy (&d_scalar_sink);
179 EVP_MD_CTX_destroy(d_ctx);
191 return (is_host_big_endian()) ?
"big":
"little";
200 if (EVP_DigestInit_ex(d_ctx, EVP_md5(), 0) == 0)
201 throw Error(
"Failed to initialize checksum object.");
203 d_checksum_ctx_valid =
true;
209 void DAP4StreamMarshaller::m_compute_checksum()
211 if (d_checksum_ctx_valid) {
214 d_checksum_ctx_valid =
false;
221 int status = EVP_DigestFinal_ex(d_ctx, &d_md[0], &md_len);
223 throw Error(
"Error computing the checksum (checksum computation).");
234 if (d_checksum_ctx_valid) {
235 m_compute_checksum();
239 oss.setf(ios::hex, ios::basefield);
241 oss << setfill(
'0') << setw(2) << (
unsigned int) d_md[i];
249 if (d_checksum_ctx_valid) {
250 m_compute_checksum();
253 d_out.write(reinterpret_cast<char*>(&d_md[0]),
c_md5_length);
258 if (!d_checksum_ctx_valid)
259 throw InternalErr(__FILE__, __LINE__,
"Invalid checksum context (checksum update).");
261 if (EVP_DigestUpdate(d_ctx, data, len) == 0) {
262 d_checksum_ctx_valid =
false;
263 throw Error(
"Error computing the checksum (checksum update).");
272 DBG( std::cerr <<
"put_byte: " << val << std::endl );
274 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_byte));
283 DBG( std::cerr <<
"put_int8: " << val << std::endl );
285 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int8));
294 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int16));
302 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int32));
310 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_int64));
318 if (std::numeric_limits<float>::is_iec559 ) {
319 DBG2(cerr <<
"Native rep is ieee754." << endl);
320 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_float32));
323 if (!xdr_setpos(&d_scalar_sink, 0))
324 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float32 variable");
326 if (!xdr_float(&d_scalar_sink, &val))
327 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float32 variable");
330 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float32 variable");
333 static bool twiddle_bytes = !is_host_big_endian();
349 if (std::numeric_limits<double>::is_iec559)
350 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_float64));
352 if (!xdr_setpos(&d_scalar_sink, 0))
353 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 variable");
355 if (!xdr_double(&d_scalar_sink, &val))
356 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 variable");
359 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 variable");
362 static bool twiddle_bytes = !is_host_big_endian();
378 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_uint16));
386 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_uint32));
394 d_out.write(reinterpret_cast<char*>(&val),
sizeof(
dods_uint64));
404 d_out.write(val.data(), val.length());
419 d_out.write(val, len);
426 DBG2(cerr <<
"val: " << val << endl);
428 vector<uint8_t> target(
sizeof(
dods_uint64) + 1, 0);
430 d_out.write(reinterpret_cast<char*>(&target[0]), to_send - &target[0]);
432 DBG2(cerr <<
"varint: " << hex << *(uint64_t*)&target[0] << dec << endl);
440 d_out.write(val, num);
463 void DAP4StreamMarshaller::m_serialize_reals(
char *val,
unsigned int num,
int width,
Type type)
468 vector<char> buf(size);
470 xdrmem_create(&xdr, &buf[0], size, XDR_ENCODE);
473 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 array");
475 if (xdr_getpos(&xdr) != size)
476 throw InternalErr(__FILE__, __LINE__,
"Error serializing a Float64 array");
479 static bool twiddle_bytes = !is_host_big_endian();
497 d_out.write(&buf[0], size);
511 if (type ==
dods_float32_c && !std::numeric_limits<float>::is_iec559) {
513 m_serialize_reals(val, num, 4, type);
515 else if (type ==
dods_float64_c && !std::numeric_limits<double>::is_iec559) {
516 m_serialize_reals(val, num, 8, type);
519 d_out.write(val, num * width);
543 strm <<
DapIndent::LMarg <<
"DAP4StreamMarshaller::dump - (" << (
void *)
this <<
")" << endl;