18 #include "eckit/filesystem/TmpFile.h"
19 #include "eckit/io/Buffer.h"
20 #include "eckit/testing/Test.h"
24 using namespace eckit::testing;
28 #define CHECK_RETURN(x) EXPECT((x) == ODC_SUCCESS)
54 CASE(
"Encode data in standard tabular form") {
60 double data[nrows][ncols];
64 for (
int row = 0; row < nrows; ++row) {
65 for (
int col = 0; col < 4; ++col) {
66 data[row][col] = (1000 * row) + (3 * col);
70 ::strncpy(
reinterpret_cast<char*
>(&data[row][4]),
"abcdefghijkl", 2*
sizeof(
double));
71 for (
int col = 6; col < ncols; ++col) {
72 data[row][col] = (1000 * row) + (3 * col);
80 std::unique_ptr<odc_encoder_t> enc_deleter(enc);
82 bool columnMajor =
false;
90 int elementSize = 2 *
sizeof(double);
100 eckit::Buffer encoded(1024 * 1024);
109 std::unique_ptr<odc_reader_t> reader_deleter(reader);
114 std::unique_ptr<odc_frame_t> frame_deleter(frame);
120 EXPECT(column_count == ncols-1);
124 EXPECT(row_count == nrows);
126 const char* column_names[] = {
"col1",
"col2",
"col3",
"col4",
"col5",
"col6",
"col7"};
128 const char* bitfield_names[] = {
"bits1",
"bits2",
"bits3"};
129 int bitfield_sizes[] = {2, 3, 1};
130 int bitfield_offsets[] = {0, 2, 5};
132 for (
int col = 0; col < 7; ++col) {
140 EXPECT(::strcmp(
name, column_names[col]) == 0);
141 EXPECT(
type == column_types[col]);
142 EXPECT(elementSize == (col == 4 ? 2 : 1) *
int(
sizeof(
double)));
143 EXPECT(bitfieldCount == (col == 6 ? 3 : 0));
146 for (
int bf = 0; bf < 3; ++bf) {
152 EXPECT(::strcmp(bf_name, bitfield_names[bf]) == 0);
153 EXPECT(bfSize == bitfield_sizes[bf]);
154 EXPECT(bfOffset == bitfield_offsets[bf]);
164 std::unique_ptr<odc_decoder_t> decoder_deleter(decoder);
170 EXPECT(rows_decoded == nrows);
176 bool decodeColumnMajor;
178 EXPECT(!decodeColumnMajor);
179 EXPECT(p !=
nullptr);
180 EXPECT(pdata !=
nullptr);
182 EXPECT(row_stride == 8*
sizeof(
double));
184 double vals1[] = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000};
185 double vals2[] = {3, 1003, 2003, 3003, 4003, 5003, 6003, 7003, 8003, 9003, 10003, 11003, 12003, 13003, 14003};
186 double vals3[] = {6, 1006, 2006, 3006, 4006, 5006, 6006, 7006, 8006, 9006, 10006, 11006, 12006, 13006, 14006};
187 double vals4[] = {9, 1009, 2009, 3009, 4009, 5009, 6009, 7009, 8009, 9009, 10009, 11009, 12009, 13009, 14009};
188 double vals6[] = {18, 1018, 2018, 3018, 4018, 5018, 6018, 7018, 8018, 9018, 10018, 11018, 12018, 13018, 14018};
189 double vals7[] = {21, 1021, 2021, 3021, 4021, 5021, 6021, 7021, 8021, 9021, 10021, 11021, 12021, 13021, 14021};
191 const double (*row_data)[8] =
reinterpret_cast<const double (*)[8]
>(pdata);
193 for (
size_t row = 0; row < nrows; ++row) {
194 EXPECT(vals1[row] == row_data[row][0]);
195 EXPECT(
vals2[row] == row_data[row][1]);
196 EXPECT(vals3[row] == row_data[row][2]);
197 EXPECT(vals4[row] == row_data[row][3]);
198 EXPECT(::strncmp(
"abcdefghijkl",
reinterpret_cast<const char*
>(&row_data[row][4]), 2*
sizeof(
double)) == 0);
199 EXPECT(vals6[row] == row_data[row][6]);
200 EXPECT(vals7[row] == row_data[row][7]);
207 CASE(
"Encode from columnar data") {
211 const int nrows = 10;
216 long icol[nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0};
217 long bcol[nrows] = {1101, 2202, 3303, 4404, 5505, 6606, 7707, 8808, 9909, 0};
218 char scol[nrows][3 *
sizeof(double)] = {0};
219 double dcol[nrows] = {1131, 2232, 3333, 4434, 5535, 6636, 7737, 8838, 9939, 0};
220 double rcol[nrows] = {1141, 2242, 3343, 4444, 5545, 6646, 7747, 8848, 9949, 0};
221 for (
size_t i = 0;
i < nrows; ++
i) {
222 ::strncpy(&scol[
i][0],
"abcdefghhgfedcbazzzz", 3*
sizeof(
double));
229 std::unique_ptr<odc_encoder_t> enc_deleter(enc);
238 int elementSizeCol2 = 3 *
sizeof(double);
247 eckit::Buffer encoded(1024 * 1024);
256 std::unique_ptr<odc_reader_t> reader_deleter(reader);
261 std::unique_ptr<odc_frame_t> frame_deleter(frame);
267 EXPECT(column_count == ncols);
271 EXPECT(row_count == nrows);
278 std::unique_ptr<odc_decoder_t> decoder_deleter(decoder);
284 EXPECT(rows_decoded == nrows);
288 bool decodeColumnMajor;
290 EXPECT(!decodeColumnMajor);
291 EXPECT(pdata !=
nullptr);
292 EXPECT(row_stride == 7*
sizeof(
double));
294 const double (*row_data)[7] =
reinterpret_cast<const double (*)[7]
>(pdata);
296 for (
size_t row = 0; row < nrows; ++row) {
297 EXPECT(
reinterpret_cast<const long&
>(row_data[row][0]) == icol[row]);
298 EXPECT(
reinterpret_cast<const long&
>(row_data[row][1]) == bcol[row]);
299 EXPECT(::strncmp(
"abcdefghhgfedcbazzzz",
reinterpret_cast<const char*
>(&row_data[row][2]), 3*
sizeof(
double)) == 0);
300 EXPECT(row_data[row][5] == dcol[row]);
301 EXPECT(row_data[row][6] == rcol[row]);
309 CASE(
"Encode data with custom stride") {
318 long icol[2*nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0};
319 long bcol[2*nrows] = {1101, 2202, 3303, 4404, 5505, 6606, 7707, 8808, 9909, 0};
320 char scol[2*nrows][3 *
sizeof(double)] = {0};
321 double dcol[2*nrows] = {1131, 2232, 3333, 4434, 5535, 6636, 7737, 8838, 9939, 0};
322 double rcol[2*nrows] = {1141, 2242, 3343, 4444, 5545, 6646, 7747, 8848, 9949, 0};
323 for (
size_t i = 0;
i < 2*nrows; ++
i) {
324 ::strncpy(&scol[
i][0],
"abcdefghhgfedcbazzzz", 3*
sizeof(
double));
331 std::unique_ptr<odc_encoder_t> enc_deleter(enc);
348 eckit::Buffer encoded(1024 * 1024);
357 std::unique_ptr<odc_reader_t> reader_deleter(reader);
362 std::unique_ptr<odc_frame_t> frame_deleter(frame);
368 EXPECT(column_count == ncols);
372 EXPECT(row_count == nrows);
379 std::unique_ptr<odc_decoder_t> decoder_deleter(decoder);
385 EXPECT(rows_decoded == nrows);
389 bool decodeColumnMajor;
391 EXPECT(!decodeColumnMajor);
392 EXPECT(pdata !=
nullptr);
393 EXPECT(row_stride == 7*
sizeof(
double));
395 const double (*row_data)[7] =
reinterpret_cast<const double (*)[7]
>(pdata);
397 for (
size_t row = 0; row < nrows; ++row) {
398 EXPECT(
reinterpret_cast<const long&
>(row_data[row][0]) == icol[2*row]);
399 EXPECT(
reinterpret_cast<const long&
>(row_data[row][1]) == bcol[2*row]);
400 EXPECT(::strncmp(
"abcdefghhgfedcbazzzz",
reinterpret_cast<const char*
>(&row_data[row][2]), 3*
sizeof(
double)) == 0);
401 EXPECT(row_data[row][5] == dcol[2*row]);
402 EXPECT(row_data[row][6] == rcol[2*row]);
410 CASE(
"Encode with more rows that fit inside a table") {
414 const int nrows = 10;
419 long icol[nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0};
420 long bcol[nrows] = {1101, 2202, 3303, 4404, 5505, 6606, 7707, 8808, 9909, 0};
421 char scol[nrows][3 *
sizeof(double)] = {0};
422 double dcol[nrows] = {1131, 2232, 3333, 4434, 5535, 6636, 7737, 8838, 9939, 0};
423 double rcol[nrows] = {1141, 2242, 3343, 4444, 5545, 6646, 7747, 8848, 9949, 0};
424 for (
size_t i = 0;
i < nrows; ++
i) {
425 ::strncpy(&scol[
i][0],
"abcdefghhgfedcbazzzz", 3*
sizeof(
double));
432 std::unique_ptr<odc_encoder_t> enc_deleter(enc);
454 eckit::Buffer encoded(1024 * 1024);
463 std::unique_ptr<odc_reader_t> reader_deleter(reader);
468 std::unique_ptr<odc_frame_t> frame_deleter(frame);
472 for (
int frame_idx = 0; frame_idx < 2; ++frame_idx) {
475 int row_offset = (frame_idx * maxPerFrame);
479 EXPECT(column_count == ncols);
483 EXPECT(row_count == (frame_idx ? nrows-maxPerFrame : maxPerFrame));
490 std::unique_ptr<odc_decoder_t> decoder_deleter(decoder);
496 EXPECT(rows_decoded == row_count);
500 bool decodeColumnMajor;
502 EXPECT(!decodeColumnMajor);
503 EXPECT(pdata !=
nullptr);
504 EXPECT(row_stride == 7*
sizeof(
double));
506 const double (*row_data)[7] =
reinterpret_cast<const double (*)[7]
>(pdata);
508 for (
int row = 0; row < row_count; ++row) {
509 EXPECT(
reinterpret_cast<const long&
>(row_data[row][0]) == icol[row+row_offset]);
510 EXPECT(
reinterpret_cast<const long&
>(row_data[row][1]) == bcol[row+row_offset]);
511 EXPECT(::strncmp(
"abcdefghhgfedcbazzzz",
reinterpret_cast<const char*
>(&row_data[row][2]), 3*
sizeof(
double)) == 0);
512 EXPECT(row_data[row][5] == dcol[row+row_offset]);
513 EXPECT(row_data[row][6] == rcol[row+row_offset]);
522 CASE(
"Encode to a file descriptor") {
528 const int nrows = 10;
529 long icol[nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0};
535 std::unique_ptr<odc_encoder_t> enc_deleter(enc);
544 int fd = ::open(tf.asString().c_str(), O_CREAT|O_WRONLY, 0666);
554 EXPECT(sz == tf.size());
562 std::unique_ptr<odc_reader_t> reader_deleter(reader);
567 std::unique_ptr<odc_frame_t> frame_deleter(frame);
573 EXPECT(column_count == 1);
577 EXPECT(row_count == nrows);
584 std::unique_ptr<odc_decoder_t> decoder_deleter(decoder);
590 EXPECT(rows_decoded == nrows);
594 EXPECT(::memcmp(icol, pdata,
sizeof(icol)) == 0);
607 typedef long (*
write_fn)(
void* handle,
const void* buffer,
long length);
610 ASSERT(length + handle->
pos <= handle->
size);
611 ::memcpy(handle->
data + handle->
pos, buffer, length);
612 handle->
pos += length;
616 CASE(
"Encode to a custom output stream") {
622 const int nrows = 10;
623 long icol[nrows] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 0};
629 std::unique_ptr<odc_encoder_t> enc_deleter(enc);
637 eckit::Buffer encoded(1024 * 1024);
643 EXPECT(
size_t(sz) == handle.
pos);
650 std::unique_ptr<odc_reader_t> reader_deleter(reader);
655 std::unique_ptr<odc_frame_t> frame_deleter(frame);
661 EXPECT(column_count == 1);
665 EXPECT(row_count == nrows);
672 std::unique_ptr<odc_decoder_t> decoder_deleter(decoder);
678 EXPECT(rows_decoded == nrows);
682 EXPECT(::memcmp(icol, pdata,
sizeof(icol)) == 0);
689 int main(
int argc,
char* argv[]) {
690 return run_tests(argc, argv);
int odc_encoder_add_column(odc_encoder_t *encoder, const char *name, int type)
int odc_free_encoder(const odc_encoder_t *encoder)
int odc_decoder_defaults_from_frame(odc_decoder_t *decoder, const odc_frame_t *frame)
int odc_frame_column_count(const odc_frame_t *frame, int *count)
int odc_encode_to_stream(odc_encoder_t *encoder, void *handle, odc_stream_write_t write_fn, long *bytes_encoded)
int odc_encoder_set_row_count(odc_encoder_t *encoder, long nrows)
int odc_free_frame(const odc_frame_t *frame)
int odc_next_frame(odc_frame_t *frame)
int odc_decode(odc_decoder_t *decoder, const odc_frame_t *frame, long *rows_decoded)
int odc_encoder_set_data_array(odc_encoder_t *encoder, const void *data, long width, long height, int columnMajorWidth)
int odc_encoder_column_add_bitfield(odc_encoder_t *encoder, int col, const char *name, int nbits)
int odc_open_buffer(odc_reader_t **reader, const void *data, long length)
int odc_frame_column_attributes(const odc_frame_t *frame, int col, const char **name, int *type, int *element_size, int *bitfield_count)
int odc_encode_to_file_descriptor(odc_encoder_t *encoder, int fd, long *bytes_encoded)
int odc_integer_behaviour(int integerBehaviour)
int odc_decoder_data_array(const odc_decoder_t *decoder, const void **data, long *width, long *height, bool *columnMajor)
int odc_new_encoder(odc_encoder_t **encoder)
int odc_open_path(odc_reader_t **reader, const char *filename)
int odc_new_decoder(odc_decoder_t **decoder)
int odc_decoder_column_data_array(const odc_decoder_t *decoder, int col, int *element_size, int *stride, const void **data)
int odc_encoder_column_set_data_array(odc_encoder_t *encoder, int col, int element_size, int stride, const void *data)
int odc_frame_bitfield_attributes(const odc_frame_t *frame, int col, int field, const char **name, int *offset, int *size)
int odc_frame_row_count(const odc_frame_t *frame, long *count)
int odc_new_frame(odc_frame_t **frame, odc_reader_t *reader)
int odc_close(const odc_reader_t *reader)
int odc_encoder_set_rows_per_frame(odc_encoder_t *encoder, long rows_per_frame)
int odc_encode_to_buffer(odc_encoder_t *encoder, void *buffer, long length, long *bytes_encoded)
int odc_free_decoder(const odc_decoder_t *decoder)
int main(int argc, char *argv[])
long custom_buffer_write(custom_buffer_t *handle, const void *buffer, long length)
long(* write_fn)(void *handle, const void *buffer, long length)
CASE("Encode data in standard tabular form")
const int ODC_INTEGERS_AS_LONGS
const int ODC_INTEGERS_AS_DOUBLES