11 #include "eckit/testing/Test.h"
12 #include "eckit/system/SystemInfo.h"
13 #include "eckit/io/DataHandle.h"
14 #include "eckit/eckit_ecbuild_config.h"
29 using namespace eckit::testing;
52 const std::string& codec_name,
53 bool bigEndian=
false) {
55 data.insert(data.begin(), 4, 0);
56 data[bigEndian ? 3 : 0] =
static_cast<unsigned char>(codec_name.size());
58 data.insert(data.begin() + 4, codec_name.begin(), codec_name.end());
60 return 4 + codec_name.length();
63 CASE(
"Constant values are constant") {
68 const char* source_data[] = {
72 "\xb7\xe6\x87\xb4\x80\x65\xd2\x41",
73 "\x00\x00\x00\x00\x00\x00\x00\x00",
74 "\x00\x00\x00\x00\x00\x00\x00\x00",
80 for (
int i = 0;
i < 2;
i++) {
82 bool bigEndianSource = (
i == 1);
84 std::vector<unsigned char> data;
86 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
87 size_t len = (j == 0) ? 4 : 8;
88 data.insert(data.end(), source_data[j], source_data[j] + len);
90 std::reverse(data.end()-len, data.end());
98 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
100 std::unique_ptr<Codec>
c;
101 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
108 EXPECT(ds.
position() == eckit::Offset(28));
109 EXPECT(
c->dataSizeDoubles() == 1);
113 EXPECT(tmp == 1234567890.1234567);
115 EXPECT(tmp == 1234567890.1234567);
117 EXPECT(tmp == 1234567890.1234567);
119 EXPECT(tmp == 1234567890.1234567);
122 EXPECT(ds.
position() == eckit::Offset(28));
131 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
133 std::unique_ptr<Codec>
c;
134 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
140 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
141 EXPECT(
c->dataSizeDoubles() == 1);
145 EXPECT(tmp == 1234567890.1234567);
146 EXPECT(tmp == 1234567890.1234567);
147 EXPECT(tmp == 1234567890.1234567);
148 EXPECT(tmp == 1234567890.1234567);
150 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
155 CASE(
"Constant integer values are constant") {
158 TestIntegerDecoding resetter;
163 const char* source_data[] = {
167 "\x00\x00\x80\xb4\x80\x65\xd2\x41",
168 "\x00\x00\x00\x00\x00\x00\x00\x00",
169 "\x00\x00\x00\x00\x00\x00\x00\x00",
175 for (
int i = 0;
i < 2;
i++) {
177 bool bigEndianSource = (
i == 1);
179 std::vector<unsigned char> data;
181 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
182 size_t len = (j == 0) ? 4 : 8;
183 data.insert(data.end(), source_data[j], source_data[j] + len);
185 std::reverse(data.end()-len, data.end());
193 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
195 std::unique_ptr<Codec>
c;
196 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
203 EXPECT(ds.
position() == eckit::Offset(28));
204 EXPECT(
c->dataSizeDoubles() == 1);
207 double& tmpd(
reinterpret_cast<double&
>(tmpi));
209 EXPECT(tmpi == 1234567890);
211 EXPECT(tmpi == 1234567890);
213 EXPECT(tmpi == 1234567890);
215 EXPECT(tmpi == 1234567890);
218 EXPECT(ds.
position() == eckit::Offset(28));
227 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
229 std::unique_ptr<Codec>
c;
230 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
236 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
237 EXPECT(
c->dataSizeDoubles() == 1);
240 double& tmp(
reinterpret_cast<double&
>(tmpi));
242 EXPECT(tmpi == 1234567890);
243 EXPECT(tmpi == 1234567890);
244 EXPECT(tmpi == 1234567890);
245 EXPECT(tmpi == 1234567890);
247 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
253 CASE(
"constant strings are constant") {
261 const char* source_data[] = {
266 "\x00\x00\x00\x00\x00\x00\x00\x00",
267 "\x00\x00\x00\x00\x00\x00\x00\x00",
272 for (
int i = 0;
i < 2;
i++) {
274 bool bigEndianSource = (
i == 1);
276 std::vector<unsigned char> data;
278 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
279 size_t len = (j == 0) ? 4 : 8;
280 data.insert(data.end(), source_data[j], source_data[j] + len);
283 if (bigEndianSource && j != 1)
284 std::reverse(data.end()-len, data.end());
292 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
294 std::unique_ptr<Codec>
c;
295 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
302 EXPECT(ds.
position() == eckit::Offset(28));
303 EXPECT(
c->dataSizeDoubles() == 1);
307 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
309 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
311 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
313 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
316 EXPECT(ds.
position() == eckit::Offset(28));
325 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
327 std::unique_ptr<Codec>
c;
328 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
334 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
335 EXPECT(
c->dataSizeDoubles() == 1);
339 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
341 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
343 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
345 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"hi-there");
347 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
352 CASE(
"Constant integer or missing value behaves a bit oddly") {
362 const char* source_data[] = {
368 "\xad\x69\xfe\x58\x34\x6f\xcd\x41",
369 "\xad\x69\xfe\x58\x34\x6f\xcd\x41",
370 "\x00\x00\xc0\xff\xff\xff\xdf\x41"
375 for (
int i = 0;
i < 2;
i++) {
377 bool bigEndianSource = (
i == 1);
379 std::vector<unsigned char> data;
381 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
382 size_t len = (j == 0) ? 4 : 8;
383 data.insert(data.end(), source_data[j], source_data[j] + len);
385 std::reverse(data.end()-len, data.end());
391 data.push_back(0xff);
392 for (
size_t n = 0; n < 255; n++) {
393 data.push_back(
static_cast<unsigned char>(n));
395 data.push_back(0xff);
402 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
404 std::unique_ptr<Codec>
c;
405 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
411 c->setDataStream(ds);
413 EXPECT(ds.
position() == eckit::Offset(28));
414 EXPECT(
c->dataSizeDoubles() == 1);
416 double baseValue = 987654321.9876;
420 EXPECT(baseValue == decoded);
423 for (
size_t n = 0; n < 255; n++) {
424 double b = baseValue + n;
426 EXPECT(b == decoded);
431 EXPECT(ds.
position() == eckit::Offset(28 + 258));
440 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
442 std::unique_ptr<Codec>
c;
443 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
448 c->setDataStream(ds);
450 EXPECT(ds.
position() == eckit::Offset(hdrSize+28));
451 EXPECT(
c->dataSizeDoubles() == 1);
453 double baseValue = 987654321.9876;
456 EXPECT(baseValue == decoded);
459 for (
size_t i = 0;
i < 255;
i++) {
460 double b = baseValue +
i;
462 EXPECT(b == decoded);
467 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + 258));
473 CASE(
"real constant or missing value is not quite constant") {
482 const char* source_data[] = {
486 "\x41\xcd\x6f\x34\x58\xfe\x69\xad",
487 "\x41\xcd\x6f\x34\x58\xfe\x69\xad",
488 "\xc1\xdf\xff\xff\xff\xc0\x00\x00"
493 for (
int i = 0;
i < 2;
i++) {
495 bool bigEndianSource = (
i == 1);
497 std::vector<unsigned char> data;
499 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
500 size_t len = (j == 0) ? 4 : 8;
501 data.insert(data.end(), source_data[j], source_data[j] + len);
502 if (!bigEndianSource)
503 std::reverse(data.end()-len, data.end());
509 data.push_back(0xff);
510 for (
size_t i = 0;
i < 255;
i++) {
511 data.push_back(
static_cast<unsigned char>(
i));
513 data.push_back(0xff);
520 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
522 std::unique_ptr<Codec>
c;
523 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
529 c->setDataStream(ds);
531 EXPECT(ds.
position() == eckit::Offset(28));
532 EXPECT(
c->dataSizeDoubles() == 1);
534 double baseValue = 987654321.9876;
538 EXPECT(baseValue == decoded);
541 for (
size_t i = 0;
i < 255;
i++) {
542 double b = baseValue +
i;
544 EXPECT(b == decoded);
549 EXPECT(ds.
position() == eckit::Offset(28 + 258));
558 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
560 std::unique_ptr<Codec>
c;
561 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
566 c->setDataStream(ds);
568 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
569 EXPECT(
c->dataSizeDoubles() == 1);
571 double baseValue = 987654321.9876;
574 EXPECT(baseValue == decoded);
577 for (
size_t i = 0;
i < 255;
i++) {
578 double b = baseValue +
i;
580 EXPECT(b == decoded);
585 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + 258));
591 CASE(
"Character strings are 8-byte sequences coerced into being treated as doubles") {
597 const char* source_data[] = {
601 "\x00\x00\x00\x00\x00\x00\x00\x00",
602 "\x00\x00\x00\x00\x00\x00\x00\x00",
603 "\x00\x00\x00\x00\x00\x00\x00\x00",
609 "\0\xff\0\xff\0\xff\0\xff",
611 "\xff\xff\xff\xff\xff\xff\xff\xff",
616 for (
int i = 0;
i < 2;
i++) {
618 bool bigEndianSource = (
i == 1);
620 std::vector<unsigned char> data;
622 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
623 size_t len = (j == 0 || j == 4) ? 4 : 8;
624 data.insert(data.end(), source_data[j], source_data[j] + len);
627 if (bigEndianSource && j < 5)
628 std::reverse(data.end()-len, data.end());
636 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
638 std::unique_ptr<Codec>
c;
639 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
645 c->setDataStream(ds);
647 EXPECT(ds.
position() == eckit::Offset(32));
648 EXPECT(
c->dataSizeDoubles() == 1);
652 EXPECT(::memcmp(&
val, source_data[5], 8) == 0);
654 EXPECT(::memcmp(&
val, source_data[6], 8) == 0);
656 EXPECT(::memcmp(&
val, source_data[7], 8) == 0);
658 EXPECT(::memcmp(&
val, source_data[8], 8) == 0);
660 EXPECT(::memcmp(&
val, source_data[9], 8) == 0);
662 EXPECT(ds.
position() == eckit::Offset(32 + (8 * 5)));
671 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
673 std::unique_ptr<Codec>
c;
674 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
679 c->setDataStream(ds);
681 EXPECT(ds.
position() == eckit::Offset(hdrSize + 32));
682 EXPECT(
c->dataSizeDoubles() == 1);
686 EXPECT(::memcmp(&
val, source_data[5], 8) == 0);
688 EXPECT(::memcmp(&
val, source_data[6], 8) == 0);
690 EXPECT(::memcmp(&
val, source_data[7], 8) == 0);
692 EXPECT(::memcmp(&
val, source_data[8], 8) == 0);
694 EXPECT(::memcmp(&
val, source_data[9], 8) == 0);
696 EXPECT(ds.
position() == eckit::Offset(hdrSize + 32 + (8 * 5)));
702 CASE(
"long floating point values can include the missing data value") {
704 const char* source_data[] = {
708 "\x00\x00\x00\x00\x00\x00\x00\x00",
709 "\x00\x00\x00\x00\x00\x00\x00\x00",
710 "\x00\x00\x00\x00\x00\x00\x00\x00",
713 "\x00\x00\x00\x00\x00\x00\x00\x00",
714 "\x53\xa4\x0c\x54\x34\x6f\x9d\x41",
715 "\x9b\xe6\x57\xb7\x80\x65\x02\xc2",
716 "\x00\x00\x00\x00\x00\x00\xf0\x7f",
717 "\x00\x00\x00\x00\x00\x00\xf0\xff",
718 "\x7f\xf7\xff\xff\xff\xff\xff\xff",
719 "\x7f\xff\xff\xff\xff\xff\xff\xff",
720 "\x00\x00\xc0\xff\xff\xff\xdf\xc1"
725 for (
int i = 0;
i < 2;
i++) {
727 bool bigEndianSource = (
i == 1);
729 std::vector<unsigned char> data;
731 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
732 size_t len = (j == 0) ? 4 : 8;
733 data.insert(data.end(), source_data[j], source_data[j] + len);
735 std::reverse(data.end()-len, data.end());
743 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
745 std::unique_ptr<Codec>
c;
746 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
752 c->setDataStream(ds);
754 EXPECT(ds.
position() == eckit::Offset(28));
755 EXPECT(
c->dataSizeDoubles() == 1);
761 EXPECT(
val == 123456789.0123456);
763 EXPECT(
val == -9876543210.9876);
765 EXPECT(std::isinf(
val));
768 EXPECT(std::isinf(
val));
771 EXPECT(std::isnan(
val));
773 EXPECT(std::isnan(
val));
775 EXPECT(
val == -2147483647);
777 EXPECT(ds.
position() == eckit::Offset(28 + (8 * 8)));
786 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
788 std::unique_ptr<Codec>
c;
789 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
794 c->setDataStream(ds);
796 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
797 EXPECT(
c->dataSizeDoubles() == 1);
803 EXPECT(
val == 123456789.0123456);
805 EXPECT(
val == -9876543210.9876);
807 EXPECT(std::isinf(
val));
810 EXPECT(std::isinf(
val));
813 EXPECT(std::isnan(
val));
815 EXPECT(std::isnan(
val));
817 EXPECT(
val == -2147483647);
819 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + (8 * 8)));
825 CASE(
"short floating point values can include the missing data value") {
829 const char* source_data[] = {
833 "\x00\x00\x00\x00\x00\x00\x00\x00",
834 "\x00\x00\x00\x00\x00\x00\x00\x00",
835 "\x04\x4f\xab\xa0\xe4\x4e\x91\x26",
850 for (
int i = 0;
i < 4;
i++) {
852 bool bigEndianSource = (
i % 2 == 0);
853 bool secondCodec = (
i > 1);
855 std::vector<unsigned char> data;
857 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
858 size_t len = (j == 0 || j > 3) ? 4 : 8;
859 data.insert(data.end(), source_data[j], source_data[j] + len);
861 std::reverse(data.end()-len, data.end());
869 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
871 std::unique_ptr<Codec>
c;
872 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
886 c->setDataStream(ds);
888 EXPECT(ds.
position() == eckit::Offset(28));
889 EXPECT(
c->dataSizeDoubles() == 1);
896 EXPECT(
val ==
float(654321.123));
900 EXPECT(
val ==
float(1.17549435082229e-38));
902 EXPECT(
val == 6.54565456545599971850917315786e-123);
905 EXPECT(
val == 6.54565456545599971850917315786e-123);
907 EXPECT(
val ==
float(-3.40282346638529e+38));
910 EXPECT(std::isinf(
val));
913 EXPECT(std::isinf(
val));
916 EXPECT(std::isnan(
val));
918 EXPECT(std::isnan(
val));
920 EXPECT(ds.
position() == eckit::Offset(28 + (8 * 4)));
929 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
931 std::unique_ptr<Codec>
c;
932 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
937 c->setDataStream(ds);
939 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
940 EXPECT(
c->dataSizeDoubles() == 1);
946 EXPECT(
val ==
float(654321.123));
950 EXPECT(
val ==
float(1.17549435082229e-38));
952 EXPECT(
val == 6.54565456545599971850917315786e-123);
955 EXPECT(
val == 6.54565456545599971850917315786e-123);
957 EXPECT(
val ==
float(-3.40282346638529e+38));
960 EXPECT(std::isinf(
val));
963 EXPECT(std::isinf(
val));
966 EXPECT(std::isnan(
val));
968 EXPECT(std::isnan(
val));
970 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + (8 * 4)));
975 CASE(
"32bit integers can be decoded direct to integers") {
978 TestIntegerDecoding resetter;
982 const char* source_data[] = {
986 "\x00\x00\x00\x00\x00\x00\x00\x00",
987 "\x00\x00\x00\x00\x00\x00\x00\x00",
988 "\x00\x00\x00\x00\x00\x00\x00\x00",
1000 for (
int i = 0;
i < 2;
i++) {
1002 bool bigEndianSource = (
i == 1);
1004 std::vector<unsigned char> data;
1006 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1007 size_t len = (j == 0 || j > 3) ? 4 : 8;
1008 data.insert(data.end(), source_data[j], source_data[j] + len);
1009 if (bigEndianSource)
1010 std::reverse(data.end()-len, data.end());
1018 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1020 std::unique_ptr<Codec>
c;
1021 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1027 c->setDataStream(ds);
1029 EXPECT(ds.
position() == eckit::Offset(28));
1030 EXPECT(
c->dataSizeDoubles() == 1);
1033 int64_t& intVal =
reinterpret_cast<int64_t&
>(
val);
1035 EXPECT(intVal == 0);
1037 EXPECT(intVal == -1);
1039 EXPECT(intVal == 2147483647);
1041 EXPECT(intVal == -2147483648);
1043 EXPECT(intVal == -6543210);
1045 EXPECT(ds.
position() == eckit::Offset(28 + (5 * 4)));
1054 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1056 std::unique_ptr<Codec>
c;
1057 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1062 c->setDataStream(ds);
1064 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
1065 EXPECT(
c->dataSizeDoubles() == 1);
1068 int64_t& intVal =
reinterpret_cast<int64_t&
>(
val);
1070 EXPECT(intVal == 0);
1072 EXPECT(intVal == -1);
1074 EXPECT(intVal == 2147483647);
1076 EXPECT(intVal == -2147483648);
1078 EXPECT(intVal == -6543210);
1080 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + (5 * 4)));
1090 const char* source_data[] = {
1094 "\x00\x00\x00\x00\x00\x00\x00\x00",
1095 "\x00\x00\x00\x00\x00\x00\x00\x00",
1096 "\x00\x00\x00\x00\x00\x00\x00\x00",
1108 for (
int i = 0;
i < 2;
i++) {
1110 bool bigEndianSource = (
i == 1);
1112 std::vector<unsigned char> data;
1114 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1115 size_t len = (j == 0 || j > 3) ? 4 : 8;
1116 data.insert(data.end(), source_data[j], source_data[j] + len);
1117 if (bigEndianSource)
1118 std::reverse(data.end()-len, data.end());
1126 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1128 std::unique_ptr<Codec>
c;
1129 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1135 c->setDataStream(ds);
1137 EXPECT(ds.
position() == eckit::Offset(28));
1138 EXPECT(
c->dataSizeDoubles() == 1);
1146 EXPECT(
val == 2147483647);
1148 EXPECT(
val == -2147483648);
1150 EXPECT(
val == -6543210);
1152 EXPECT(ds.
position() == eckit::Offset(28 + (5 * 4)));
1161 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1163 std::unique_ptr<Codec>
c;
1164 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1169 c->setDataStream(ds);
1171 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
1172 EXPECT(
c->dataSizeDoubles() == 1);
1180 EXPECT(
val == 2147483647);
1182 EXPECT(
val == -2147483648);
1184 EXPECT(
val == -6543210);
1186 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + (5 * 4)));
1192 CASE(
"16bit integers are stored with an offset. This need not (strictly) be integral!!") {
1198 const char* source_data[] = {
1202 "\xcd\xcc\xcc\xcc\xcc\xdc\x5e\xc0",
1203 "\x00\x00\x00\x00\x00\x00\x00\x00",
1204 "\x04\x4f\xab\xa0\xe4\x4e\x91\x26",
1216 for (
int i = 0;
i < 4;
i++) {
1218 bool bigEndianSource = (
i % 2 == 0);
1220 bool withMissing = (
i > 1);
1222 std::vector<unsigned char> data;
1224 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1225 size_t len = (j == 0) ? 4 : (j > 3) ? 2 : 8;
1226 data.insert(data.end(), source_data[j], source_data[j] + len);
1227 if (bigEndianSource)
1228 std::reverse(data.end()-len, data.end());
1236 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1238 std::unique_ptr<Codec>
c;
1239 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1253 c->setDataStream(ds);
1255 EXPECT(ds.
position() == eckit::Offset(28));
1256 EXPECT(
c->dataSizeDoubles() == 1);
1260 EXPECT(
val == (
double(-123.45) + 0));
1263 EXPECT(
val == 6.54565456545599971850917315786e-123);
1265 EXPECT(
val == (
double(-123.45) + 65535));
1268 EXPECT(
val == (
double(-123.45) + 32767));
1270 EXPECT(
val == (
double(-123.45) + 32768));
1272 EXPECT(
val == (
double(-123.45) + 12345));
1274 EXPECT(ds.
position() == eckit::Offset(28 + (5 * 2)));
1283 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1285 std::unique_ptr<Codec>
c;
1286 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1291 c->setDataStream(ds);
1293 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
1294 EXPECT(
c->dataSizeDoubles() == 1);
1298 EXPECT(
val == (
double(-123.45) + 0));
1301 EXPECT(
val == 6.54565456545599971850917315786e-123);
1303 EXPECT(
val == (
double(-123.45) + 65535));
1306 EXPECT(
val == (
double(-123.45) + 32767));
1308 EXPECT(
val == (
double(-123.45) + 32768));
1310 EXPECT(
val == (
double(-123.45) + 12345));
1312 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + (5 * 2)));
1318 CASE(
"16bit integers are stored with an offset and can be decoded to integers") {
1321 TestIntegerDecoding resetter;
1327 const char* source_data[] = {
1331 "\x00\x00\x00\x00\x00\xc0\x5e\xc0",
1332 "\x00\x00\x00\x00\x00\x00\x00\x00",
1333 "\x04\x4f\xab\xa0\xe4\x4e\x91\x26",
1345 for (
int i = 0;
i < 4;
i++) {
1347 bool bigEndianSource = (
i % 2 == 0);
1349 bool withMissing = (
i > 1);
1351 std::vector<unsigned char> data;
1353 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1354 size_t len = (j == 0) ? 4 : (j > 3) ? 2 : 8;
1355 data.insert(data.end(), source_data[j], source_data[j] + len);
1356 if (bigEndianSource)
1357 std::reverse(data.end()-len, data.end());
1365 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1367 std::unique_ptr<Codec>
c;
1368 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1382 c->setDataStream(ds);
1384 EXPECT(ds.
position() == eckit::Offset(28));
1385 EXPECT(
c->dataSizeDoubles() == 1);
1388 int64_t& intVal(
reinterpret_cast<int64_t&
>(
val));
1390 EXPECT(intVal == -123 + 0);
1396 EXPECT(intVal == -123 + 65535);
1399 EXPECT(intVal == -123 + 32767);
1401 EXPECT(intVal == -123 + 32768);
1403 EXPECT(intVal == -123 + 12345);
1405 EXPECT(ds.
position() == eckit::Offset(28 + (5 * 2)));
1414 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1416 std::unique_ptr<Codec>
c;
1417 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1422 c->setDataStream(ds);
1424 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
1425 EXPECT(
c->dataSizeDoubles() == 1);
1428 int64_t& intVal(
reinterpret_cast<int64_t&
>(
val));
1430 EXPECT(intVal == -123 + 0);
1435 EXPECT(intVal == -123 + 65535);
1438 EXPECT(intVal == -123 + 32767);
1440 EXPECT(intVal == -123 + 32768);
1442 EXPECT(intVal == -123 + 12345);
1444 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + (5 * 2)));
1450 CASE(
"8bit integers are stored with an offset. This need not (strictly) be integral!!") {
1456 const char* source_data[] = {
1460 "\x00\x00\x00\x00\x80\x88\xb3\xc0",
1461 "\x00\x00\x00\x00\x00\x00\x00\x00",
1462 "\x04\x4f\xab\xa0\xe4\x4e\x91\x26",
1467 for (
int i = 0;
i < 4;
i++) {
1469 bool bigEndianSource = (
i % 2 == 0);
1471 bool withMissing = (
i > 1);
1473 std::vector<unsigned char> data;
1475 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1476 size_t len = (j == 0) ? 4 : 8;
1477 data.insert(data.end(), source_data[j], source_data[j] + len);
1478 if (bigEndianSource)
1479 std::reverse(data.end()-len, data.end());
1484 for (
int n = 0; n < 256; n++) {
1485 data.push_back(
static_cast<unsigned char>(n));
1493 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1495 std::unique_ptr<Codec>
c;
1496 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1510 c->setDataStream(ds);
1512 EXPECT(ds.
position() == eckit::Offset(28));
1513 EXPECT(
c->dataSizeDoubles() == 1);
1516 for (
int n = 0; n < 255; n++) {
1518 EXPECT(
val == (
double(-5000.5) + n));
1522 EXPECT(
val == (withMissing ? 6.54565456545599971850917315786e-123 : (-5000.5 + 255)));
1524 EXPECT(ds.
position() == eckit::Offset(28 + 256));
1533 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1535 std::unique_ptr<Codec>
c;
1536 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1541 c->setDataStream(ds);
1543 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
1544 EXPECT(
c->dataSizeDoubles() == 1);
1547 for (
int n = 0; n < 255; n++) {
1549 EXPECT(
val == (
double(-5000.5) + n));
1553 EXPECT(
val == (withMissing ? 6.54565456545599971850917315786e-123 : (-5000.5 + 255)));
1555 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + 256));
1561 CASE(
"8bit integers are stored with an offset and can be decoded to integers") {
1564 TestIntegerDecoding resetter;
1570 const char* source_data[] = {
1574 "\x00\x00\x00\x00\x00\x88\xb3\xc0",
1575 "\x00\x00\x00\x00\x00\x00\x00\x00",
1576 "\x04\x4f\xab\xa0\xe4\x4e\x91\x26",
1581 for (
int i = 0;
i < 4;
i++) {
1583 bool bigEndianSource = (
i % 2 == 0);
1585 bool withMissing = (
i > 1);
1587 std::vector<unsigned char> data;
1589 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1590 size_t len = (j == 0) ? 4 : 8;
1591 data.insert(data.end(), source_data[j], source_data[j] + len);
1592 if (bigEndianSource)
1593 std::reverse(data.end()-len, data.end());
1598 for (
int n = 0; n < 256; n++) {
1599 data.push_back(
static_cast<unsigned char>(n));
1607 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1609 std::unique_ptr<Codec>
c;
1610 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1624 c->setDataStream(ds);
1626 EXPECT(ds.
position() == eckit::Offset(28));
1627 EXPECT(
c->dataSizeDoubles() == 1);
1630 int64_t& intVal =
reinterpret_cast<int64_t&
>(
val);
1631 for (
int n = 0; n < 255; n++) {
1633 EXPECT(intVal == (-5000 + n));
1640 EXPECT(ds.
position() == eckit::Offset(28 + 256));
1649 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1651 std::unique_ptr<Codec>
c;
1652 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1657 c->setDataStream(ds);
1659 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28));
1660 EXPECT(
c->dataSizeDoubles() == 1);
1663 int64_t& intVal =
reinterpret_cast<int64_t&
>(
val);
1664 for (
int n = 0; n < 255; n++) {
1666 EXPECT(intVal == (-5000 + n));
1673 EXPECT(ds.
position() == eckit::Offset(hdrSize + 28 + 256));
1678 CASE(
"Character strings can be stored in a flat list, and indexed") {
1682 const char* source_data[] = {
1686 "\x00\x00\x00\x00\x00\x00\x00\x00",
1687 "\x00\x00\x00\x00\x00\x00\x00\x00",
1688 "\x00\x00\x00\x00\x00\x00\x00\x00",
1696 "\x02\x00\x00\x00",
"ab",
"\x00\x00\x00\x00",
"\x03\x00\x00\x00",
1697 "\x06\x00\x00\x00",
"ghijkl",
"\x00\x00\x00\x00",
"\x04\x00\x00\x00",
1698 "\x08\x00\x00\x00",
"mnopqrst",
"\x00\x00\x00\x00",
"\x05\x00\x00\x00",
1699 "\x08\x00\x00\x00",
"uvwxyzab",
"\x00\x00\x00\x00",
"\x01\x00\x00\x00",
1700 "\x08\x00\x00\x00",
"ghijklmn",
"\x00\x00\x00\x00",
"\x00\x00\x00\x00",
1701 "\x08\x00\x00\x00",
"opqrstuv",
"\x00\x00\x00\x00",
"\x02\x00\x00\x00"
1706 for (
int i = 0;
i < 4;
i++) {
1708 bool bigEndianSource = (
i % 2 == 0);
1710 bool bits16 = (
i > 1);
1712 std::vector<unsigned char> data;
1714 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1716 (j < 5) ? ((j == 0 || j == 4) ? 4 : 8)
1717 : ((j+2) % 4 == 0 ? ::strlen(source_data[j]) : 4);
1718 data.insert(data.end(), source_data[j], source_data[j] + len);
1721 if (bigEndianSource && !((j > 5) && ((j+2) % 4 == 0)))
1722 std::reverse(data.end()-len, data.end());
1727 for (
int n = 5; n >= 0; n--) {
1728 if (bits16 && bigEndianSource)
1730 data.push_back(
static_cast<unsigned char>(n));
1731 if (bits16 && !bigEndianSource)
1740 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1742 std::unique_ptr<Codec>
c;
1743 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1757 c->setDataStream(ds);
1759 EXPECT(ds.
position() == eckit::Offset(144));
1760 EXPECT(
c->dataSizeDoubles() == 1);
1764 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"mnopqrst");
1766 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 6) ==
"ghijkl");
1768 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 2) ==
"ab");
1770 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"opqrstuv");
1772 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"uvwxyzab");
1774 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"ghijklmn");
1776 EXPECT(ds.
position() == eckit::Offset(144 + (6 * (bits16 ? 2 : 1))));
1785 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1787 std::unique_ptr<Codec>
c;
1788 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1793 c->setDataStream(ds);
1795 EXPECT(ds.
position() == eckit::Offset(hdrSize + 144));
1796 EXPECT(
c->dataSizeDoubles() == 1);
1800 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"mnopqrst");
1802 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 6) ==
"ghijkl");
1804 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 2) ==
"ab");
1806 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"opqrstuv");
1808 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"uvwxyzab");
1810 EXPECT(std::string(
reinterpret_cast<const char*
>(&
val), 8) ==
"ghijklmn");
1812 EXPECT(ds.
position() == eckit::Offset(hdrSize + 144 + (6 * (bits16 ? 2 : 1))));
1818 CASE(
"Character strings can be stored in a flat list, and indexed, and be longer than 8 bytes") {
1822 const char* source_data[] = {
1826 "\x00\x00\x00\x00\x00\x00\x00\x00",
1827 "\x00\x00\x00\x00\x00\x00\x00\x00",
1828 "\x00\x00\x00\x00\x00\x00\x00\x00",
1836 "\x02\x00\x00\x00",
"ab",
"\x00\x00\x00\x00",
"\x03\x00\x00\x00",
1837 "\x06\x00\x00\x00",
"ghijkl",
"\x00\x00\x00\x00",
"\x04\x00\x00\x00",
1838 "\x08\x00\x00\x00",
"mnopqrst",
"\x00\x00\x00\x00",
"\x05\x00\x00\x00",
1839 "\x0c\x00\x00\x00",
"uvwxyzabcdef",
"\x00\x00\x00\x00",
"\x01\x00\x00\x00",
1840 "\x10\x00\x00\x00",
"ghijklmnopqrstuv",
"\x00\x00\x00\x00",
"\x00\x00\x00\x00",
1841 "\x08\x00\x00\x00",
"opqrstuv",
"\x00\x00\x00\x00",
"\x02\x00\x00\x00"
1846 for (
int i = 0;
i < 4;
i++) {
1848 bool bigEndianSource = (
i % 2 == 0);
1850 bool bits16 = (
i > 1);
1852 std::vector<unsigned char> data;
1854 for (
size_t j = 0; j <
sizeof(source_data) /
sizeof(
const char*); j++) {
1856 (j < 5) ? ((j == 0 || j == 4) ? 4 : 8)
1857 : ((j+2) % 4 == 0 ? ::strlen(source_data[j]) : 4);
1858 data.insert(data.end(), source_data[j], source_data[j] + len);
1861 if (bigEndianSource && !((j > 5) && ((j+2) % 4 == 0)))
1862 std::reverse(data.end()-len, data.end());
1867 for (
int n = 5; n >= 0; n--) {
1868 if (bits16 && bigEndianSource)
1870 data.push_back(
static_cast<unsigned char>(n));
1871 if (bits16 && !bigEndianSource)
1880 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1882 std::unique_ptr<Codec>
c;
1883 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1897 c->setDataStream(ds);
1899 EXPECT(ds.
position() == eckit::Offset(156));
1902 EXPECT(
c->dataSizeDoubles() == 2);
1905 const char* val_c =
reinterpret_cast<const char*
>(
val);
1907 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"mnopqrst");
1909 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"ghijkl");
1911 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"ab");
1913 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"opqrstuv");
1915 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"uvwxyzabcdef");
1917 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"ghijklmnopqrstuv");
1919 EXPECT(ds.
position() == eckit::Offset(156 + (6 * (bits16 ? 2 : 1))));
1928 GeneralDataStream ds(bigEndianSource != eckit::system::SystemInfo::isBigEndian(), &data[0], data.size());
1930 std::unique_ptr<Codec>
c;
1931 if (bigEndianSource == eckit::system::SystemInfo::isBigEndian()) {
1936 c->setDataStream(ds);
1938 EXPECT(ds.
position() == eckit::Offset(hdrSize + 156));
1941 EXPECT(
c->dataSizeDoubles() == 2);
1944 const char* val_c =
reinterpret_cast<const char*
>(
val);
1946 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"mnopqrst");
1948 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"ghijkl");
1950 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"ab");
1952 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"opqrstuv");
1954 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"uvwxyzabcdef");
1956 EXPECT(std::string(val_c, ::strnlen(val_c, 16)) ==
"ghijklmnopqrstuv");
1958 EXPECT(ds.
position() == eckit::Offset(hdrSize + 156 + (6 * (bits16 ? 2 : 1))));
1967 return run_tests(argc, argv);
static double integerMDI()
static void treatIntegersAsDoubles(bool flag)
DataStream< SameByteOrder > & same()
eckit::Offset position() const
DataStream< OtherByteOrder > & other()
int main(int argc, char *argv[])
size_t prepend_codec_selection_header(std::vector< unsigned char > &data, const std::string &codec_name, bool bigEndian=false)
CASE("Constant values are constant")