11 #include "eckit/io/Buffer.h"
12 #include "eckit/io/MemoryHandle.h"
13 #include "eckit/testing/Test.h"
14 #include "eckit/exception/Exceptions.h"
15 #include "eckit/eckit_config.h"
21 using namespace eckit::testing;
23 #if __cplusplus <= 199711L
27 const float float_lowest = std::numeric_limits<float>::lowest();
28 const double double_lowest = std::numeric_limits<double>::lowest();
33 CASE(
"Columns are initialised correctly for writing") {
35 eckit::Buffer buf(4096);
36 eckit::MemoryHandle dh(buf);
43 writer->setNumberOfColumns(10);
50 writer->columns()[2]->dataSizeDoubles(3);
74 EXPECT(
writer->columns()[0]->name() ==
"int");
75 EXPECT(
writer->columns()[1]->name() ==
"real");
76 EXPECT(
writer->columns()[2]->name() ==
"str");
77 EXPECT(
writer->columns()[3]->name() ==
"bitf");
78 EXPECT(
writer->columns()[4]->name() ==
"dbl");
79 EXPECT(
writer->columns()[5]->name() ==
"int2");
80 EXPECT(
writer->columns()[6]->name() ==
"real2");
81 EXPECT(
writer->columns()[7]->name() ==
"str2");
82 EXPECT(
writer->columns()[8]->name() ==
"bitf2");
83 EXPECT(
writer->columns()[9]->name() ==
"dbl2");
87 EXPECT(
writer->columns()[0]->coder().name() ==
"int32");
88 EXPECT(
writer->columns()[1]->coder().name() ==
"long_real");
89 EXPECT(
writer->columns()[2]->coder().name() ==
"chars");
90 EXPECT(
writer->columns()[3]->coder().name() ==
"int32");
91 EXPECT(
writer->columns()[4]->coder().name() ==
"long_real");
92 EXPECT(
writer->columns()[5]->coder().name() ==
"int32");
93 EXPECT(
writer->columns()[6]->coder().name() ==
"long_real");
94 EXPECT(
writer->columns()[7]->coder().name() ==
"chars");
95 EXPECT(
writer->columns()[8]->coder().name() ==
"int32");
96 EXPECT(
writer->columns()[9]->coder().name() ==
"long_real");
100 EXPECT(
writer->columns()[0]->coder().dataSizeDoubles() == 1);
101 EXPECT(
writer->columns()[1]->coder().dataSizeDoubles() == 1);
102 EXPECT(
writer->columns()[2]->coder().dataSizeDoubles() == 3);
103 EXPECT(
writer->columns()[3]->coder().dataSizeDoubles() == 1);
104 EXPECT(
writer->columns()[4]->coder().dataSizeDoubles() == 1);
105 EXPECT(
writer->columns()[5]->coder().dataSizeDoubles() == 1);
106 EXPECT(
writer->columns()[6]->coder().dataSizeDoubles() == 1);
107 EXPECT(
writer->columns()[7]->coder().dataSizeDoubles() == 1);
108 EXPECT(
writer->columns()[8]->coder().dataSizeDoubles() == 1);
109 EXPECT(
writer->columns()[9]->coder().dataSizeDoubles() == 1);
112 CASE(
"If out-of range columns are created, exceptions are thrown") {
114 eckit::Buffer buf(4096);
115 eckit::MemoryHandle dh(buf);
120 writer->setNumberOfColumns(10);
128 CASE(
"If columns are created with invalid types, exceptions are thrown") {
130 eckit::Buffer buf(4096);
131 eckit::MemoryHandle dh(buf);
138 writer->setNumberOfColumns(10);
147 CASE(
"Columns names must be unique") {
151 eckit::Buffer buf(4096);
152 eckit::MemoryHandle dh(buf);
159 writer->setNumberOfColumns(10);
175 CASE(
"Data is encoded and read back correctly") {
177 const int32_t i1 = 987654321;
178 const int32_t i2 = -1;
179 const int32_t i3 = std::numeric_limits<int32_t>::min();
180 const int32_t i4 = std::numeric_limits<int32_t>::max();
181 const int32_t i5 = 0;
182 const int32_t i6 = -654321;
184 const float f1 = std::numeric_limits<float>::min();
185 const float f2 = std::numeric_limits<float>::max();
186 const float f3 = 0.0;
188 const float f5 =
static_cast<float>(654321.123);
189 const float f6 =
static_cast<float>(-123456.789e-21);
191 const char*
const s1 =
"a-string-longstrvvvvlong";
192 const char*
const s2 =
"string-2";
193 const char*
const s3 =
"string-3-LLong";
194 const char*
const s4 =
"string-4";
195 const char*
const s5 =
"string-5-LLong";
196 const char*
const s6 =
"string-6";
198 const int32_t b1 =
static_cast<int32_t
>((uint32_t)std::numeric_limits<uint32_t>::min());
199 const int32_t b2 =
static_cast<int32_t
>((uint32_t)std::numeric_limits<uint32_t>::max());
200 const int32_t b3 =
static_cast<int32_t
>((uint32_t)0);
201 const int32_t b4 =
static_cast<int32_t
>((uint32_t)0xff00ff00);
202 const int32_t b5 =
static_cast<int32_t
>((uint32_t)0x00ff00ff);
203 const int32_t b6 =
static_cast<int32_t
>((uint32_t)0xfedcba98);
205 const double d1 = std::numeric_limits<double>::min();
206 const double d2 = std::numeric_limits<double>::max();
208 const double d4 = 0.0;
209 const double d5 = -123456789.0123;
210 const double d6 = 987654321.987e-56;
214 eckit::Buffer buf(4096);
215 eckit::MemoryHandle dhWrite(buf);
223 writer->setNumberOfColumns(10);
227 writer->columns()[2]->dataSizeDoubles(3);
239 EXPECT(
writer->dataOffset(0) == 0);
240 EXPECT(
writer->dataOffset(1) == 1);
241 EXPECT(
writer->dataOffset(2) == 2);
242 EXPECT(
writer->dataOffset(3) == 5);
243 EXPECT(
writer->dataOffset(4) == 6);
244 EXPECT(
writer->dataOffset(5) == 7);
245 EXPECT(
writer->dataOffset(6) == 8);
246 EXPECT(
writer->dataOffset(7) == 9);
247 EXPECT(
writer->dataOffset(8) == 10);
248 EXPECT(
writer->dataOffset(9) == 11);
253 (*writer)[1] =
static_cast<double>(
f1);
254 ::strncpy(
reinterpret_cast<char*
>(&(*
writer)[2]), s1, 24);
258 (*writer)[6] =
static_cast<double>(f2);
259 (*writer)[7] = *
reinterpret_cast<const double*
>(s2);
266 ::strncpy(
reinterpret_cast<char*
>(&
writer->data()[
writer->dataOffset(2)]), s3, 24);
270 writer->data()[
writer->dataOffset(6)] =
static_cast<double>(f4);
271 writer->data()[
writer->dataOffset(7)] = *
reinterpret_cast<const double*
>(s4);
277 writer->data(1) =
static_cast<double>(f5);
278 ::strncpy(
reinterpret_cast<char*
>(&
writer->data(2)), s5, 24);
282 writer->data(6) =
static_cast<double>(f6);
283 writer->data(7) = *
reinterpret_cast<const double*
>(s6);
292 eckit::MemoryHandle dh(buf.data(),
static_cast<size_t>(dhWrite.position()));
297 EXPECT(reader->
columns().size() ==
size_t(10));
299 EXPECT(reader->
columns()[0]->dataSizeDoubles() == 1);
300 EXPECT(reader->
columns()[1]->dataSizeDoubles() == 1);
301 EXPECT(reader->
columns()[2]->dataSizeDoubles() == 3);
302 EXPECT(reader->
columns()[3]->dataSizeDoubles() == 1);
303 EXPECT(reader->
columns()[4]->dataSizeDoubles() == 1);
304 EXPECT(reader->
columns()[5]->dataSizeDoubles() == 1);
305 EXPECT(reader->
columns()[6]->dataSizeDoubles() == 1);
306 EXPECT(reader->
columns()[7]->dataSizeDoubles() == 1);
307 EXPECT(reader->
columns()[8]->dataSizeDoubles() == 1);
308 EXPECT(reader->
columns()[9]->dataSizeDoubles() == 1);
310 EXPECT((*reader)[0] == i1);
311 EXPECT((*reader)[1] ==
static_cast<double>(
f1));
312 EXPECT(::strncmp(
reinterpret_cast<const char*
>(&(*reader)[2]), s1, 24) == 0);
313 EXPECT((*reader)[3] == b1);
314 EXPECT((*reader)[4] ==
d1);
315 EXPECT((*reader)[5] == i2);
316 EXPECT((*reader)[6] ==
static_cast<double>(f2));
317 EXPECT((*reader)[7] == *
reinterpret_cast<const double*
>(s2));
318 EXPECT((*reader)[8] == b2);
319 EXPECT((*reader)[9] == d2);
324 EXPECT(::strncmp(
reinterpret_cast<const char*
>(&reader->
data()[reader->
dataOffset(2)]),s3, 24) == 0);
328 EXPECT(reader->
data()[reader->
dataOffset(6)] ==
static_cast<double>(f4));
329 EXPECT(reader->
data()[reader->
dataOffset(7)] == *
reinterpret_cast<const double*
>(s4));
334 EXPECT(reader->
data(0) == i5);
335 EXPECT(reader->
data(1) ==
static_cast<double>(f5));
336 EXPECT(::strncmp(
reinterpret_cast<const char*
>(&reader->
data(2)), s5, 24) == 0);
337 EXPECT(reader->
data(3) == b5);
338 EXPECT(reader->
data(4) == d5);
339 EXPECT(reader->
data(5) == i6);
340 EXPECT(reader->
data(6) ==
static_cast<double>(f6));
341 EXPECT(reader->
data(7) == *
reinterpret_cast<const double*
>(s6));
342 EXPECT(reader->
data(8) == b6);
343 EXPECT(reader->
data(9) == d6);
350 CASE(
"We cannot encode short_real with both possible internal missing values") {
352 const float f1 = std::numeric_limits<float>::min();
355 eckit::Buffer buf(4096);
358 eckit::MemoryHandle dh(buf);
364 writer->setNumberOfColumns(1);
376 }, eckit::AssertionFailed);
382 CASE(
"We ASSERT on cases where we try and use an incompletely configured writer") {
384 eckit::Buffer buf(4096);
388 eckit::MemoryHandle dh(buf);
394 writer->setNumberOfColumns(2);
398 EXPECT_THROWS_AS(
writer->writeHeader(), eckit::AssertionFailed);
401 EXPECT_THROWS_AS((*
writer)[0] = 1234.56, eckit::AssertionFailed);
404 EXPECT_THROWS_AS(++
writer, eckit::AssertionFailed);
407 CASE(
"Data is automatically written after a configurable number of rows") {
411 CASE(
"Pathological data for integral codecs is correctly encoded") {
418 eckit::Buffer buf(4096);
420 for (
int i = 0;
i < 4;
i++) {
422 bool withMissing = (
i % 2 == 1);
423 bool bits16 = (
i > 1);
430 int32_t i2 = 12345 + (bits16 ? 0xffff : 0xff);
433 eckit::MemoryHandle dh(buf);
439 writer->setNumberOfColumns(1);
458 EXPECT(
writer->columns()[0]->hasMissing() == withMissing);
464 eckit::MemoryHandle dh(buf);
470 EXPECT(reader->
columns().size() ==
size_t(1));
472 EXPECT(reader->
columns()[0]->hasMissing() == withMissing);
476 if (withMissing && bits16) {
477 EXPECT(reader->
columns()[0]->coder().name() ==
"int32");
478 }
else if (withMissing) {
479 EXPECT(reader->
columns()[0]->coder().name() ==
"int16_missing");
481 EXPECT(reader->
columns()[0]->coder().name() ==
"int16");
483 EXPECT(reader->
columns()[0]->coder().name() ==
"int8");
486 EXPECT((*reader)[0] == i1);
489 EXPECT((*reader)[0] == i2);
502 int main(
int argc,
char* argv[]) {
503 return run_tests(argc, argv);
static double integerMDI()
const core::MetaData & columns() const
size_t dataOffset(size_t i) const
int main(int argc, char *argv[])
const double double_lowest
CASE("Columns are initialised correctly for writing")