IODA Bundle
odc/src/odc/api/ODC.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2019- ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 
12 /** @author Simon Smart */
13 /** @date January 2019 */
14 
15 #ifndef odc_api_odc_H
16 #define odc_api_odc_H
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /*--------------------------------------------------------------------------------------------------------------------*/
23 
24 #include <stdbool.h>
25 
26 /**
27  * Initialise API
28  * @note This is only required if being used from a context where eckit::Main() is not otherwise initialised
29  */
30 
31 ///@{
32 
33 const int ODC_INTEGERS_AS_DOUBLES = 1; // this is the default
34 const int ODC_INTEGERS_AS_LONGS = 2;
35 
36 int odc_initialise_api();
37 int odc_integer_behaviour(int integerBehaviour);
38 
39 ///@}
40 
41 
42 /** Version accessors */
43 
44 ///@{
45 
46 /** Human readable release version e.g. 1.2.3 */
47 int odc_version(const char** version);
48 /** Version under VCS system, typically a git sha1. Not useful for computing software dependencies. */
49 int odc_vcs_version(const char** version);
50 
51 ///@}
52 
53 
54 /** Error handling */
55 
56 ///@{
57 
63 };
64 
65 const char* odc_error_string(int err);
66 
67 // int odc_abort_on_failure(bool abort); ///< @todo to remove
68 
69 typedef void (*odc_failure_handler_t)(void* context, int error_code);
70 
71 /** Set a function to be called on error in addition to returning an error code.
72  * The handler can can access odc_error_string()
73  * The handler can also access std::current_exception() if needed (and even rethrow if required).
74  */
75 int odc_set_failure_handler(odc_failure_handler_t handler, void* context);
76 
77 ///@}
78 
79 
80 /** Values and Types */
81 
82 ///@{
83 
87  ODC_REAL = 2,
90  ODC_DOUBLE = 5
91 };
92 
93 /** Get the number of column types. */
95 
96 /** Get the name of the column type identified by the integer */
97 int odc_column_type_name(int type, const char** type_name);
98 
99 /// @todo In the top CMakelists.txt assert that in this system C long is 64 bit
100 /// @todo In the top CMakelists.txt assert that in this system C double is 64 bit
101 
102 
103 /** Set the value that identifies a missing integer (64 bit long) when encoding and decoding via this interface.
104  This differs from the marker used to identify missing values in the encoded ODB message,
105  which depends on the codec used. */
106 int odc_set_missing_integer(long missing_integer);
107 
108 /** Set the value that identifies a missing double (64 bit double) when encoding and decoding via this interface.
109  This differs from the marker used to identify missing values in the encoded ODB message,
110  which depends on the codec used. */
111 int odc_set_missing_double(double missing_double);
112 
113 /** The value that identifies a missing integer (64 bit long) when encoding and decoding via this interface. */
115 /** The value that identifies a missing double (64 bit double) when encoding and decoding via this interface. */
117 
118 ///@}
119 
120 
121 /** Basic Read API */
122 
123 ///@{
124 
125 struct odc_reader_t;
126 typedef struct odc_reader_t odc_reader_t;
127 /** Creates a reader and opens the speficied file. */
128 int odc_open_path(odc_reader_t** reader, const char* filename);
129 
130 /** Creates a reader from an already open file descriptor.
131  * It will duplicate the file descriptor so the calling code is safe to close the file descriptor.
132  */
133 int odc_open_file_descriptor(odc_reader_t** reader, int fd);
134 
135 /** Creates a reader from a memory buffer. */
136 int odc_open_buffer(odc_reader_t** reader, const void* data, long length);
137 
138 typedef long (*odc_stream_read_t)(void* context, void* buffer, long length);
139 
140 /** Creates a reader associated to a stream handler. */
141 int odc_open_stream(odc_reader_t** reader, void* context, odc_stream_read_t stream_proc);
142 
143 /** Closes and destroys the reader.
144  * Must be called for every reader created.
145  */
146 int odc_close(const odc_reader_t* reader);
147 
148 ///@}
149 
150 
151 /** Frame handling */
152 
153 ///@{
154 
155 struct odc_frame_t;
156 typedef struct odc_frame_t odc_frame_t;
157 
158 /** Creates a frame object, with client responsible to free it. */
159 int odc_new_frame(odc_frame_t** frame, odc_reader_t* reader);
160 
161 /** Frees the frame object. */
162 int odc_free_frame(const odc_frame_t* frame);
163 
164 /** Advance to the next frame.
165  * Must be called to access the first frame.
166  * Once iteration is complete (no more valid frames), it returns ODC_ITERATION_COMPLETE
167  */
168 int odc_next_frame(odc_frame_t* frame);
169 
170 /** Advance to the next logical frame.
171  ODB2 files contain multiple encoded frames.
172  This function merges multiple sequential frames that have the same structure.
173 */
174 int odc_next_frame_aggregated(odc_frame_t* frame, long maximum_rows);
175 
176 /** Copies a frame to another newly allocated frame. */
177 int odc_copy_frame(odc_frame_t* source_frame, odc_frame_t** copy);
178 
179 /** The number of rows in the frame. */
180 int odc_frame_row_count(const odc_frame_t* frame, long* count);
181 
182 /** The number of columns in the frame. */
183 int odc_frame_column_count(const odc_frame_t* frame, int* count);
184 
185 /** The properties of a columns in the frame.
186  NULL pointers will be understood as a parameter that is not required to be filled in.
187  @param frame the frame
188  @param col the column number (0-based)
189  @param name return the name of the column
190  @param type return the type of the column
191  @param element_size return the element size in bytes (guaranteed to be a multiple of 8)
192  @param bitfield_count return the number of entries associated with the bitfield column (0 if type is not ODC_BITFIELD)
193  */
194 int odc_frame_column_attributes(const odc_frame_t* frame, int col, const char** name, int* type, int* element_size, int* bitfield_count);
195 
196 /** The properties of an entry in a bitfield column.
197  NULL pointers will be understood as a parameter that is not required to be filled in.
198  @param frame the frame
199  @param col the column number (0-based)
200  @param entry the entry number in the bitfield (0-based)
201  @param name return the name of the column
202  @param offset return which bit at which the entry in the bitfield begins
203  @param size return the entry size in bits
204  */
205 int odc_frame_bitfield_attributes(const odc_frame_t* frame, int col, int entry, const char** name, int* offset, int* size);
206 
207 ///@}
208 
209 
210 
211 /**
212  * Decoding data
213  */
214 
215 ///@{
216 
217 struct odc_decoder_t;
218 typedef struct odc_decoder_t odc_decoder_t;
219 
220 /* A decode target may allocate its own buffer to decode into, or use one that is
221  * externally supplied */
222 
223 /** Creates a decoder for decoding ODB2 format */
224 int odc_new_decoder(odc_decoder_t** decoder);
225 
226 /** Deallocates the decoder */
227 int odc_free_decoder(const odc_decoder_t* decoder);
228 
229 /** Configures a decoder to decode all the data contained in the frame.
230  * This is the most typical way to decode data, and is equivalent to adding all columns to the decoder.
231  */
232 int odc_decoder_defaults_from_frame(odc_decoder_t* decoder, const odc_frame_t* frame);
233 
234 /** Instruct the decoder to output in column major form */
236 
237 /** If the decoder is to allocate its buffer internally, specify the number of rows to allocate
238  if this is to be different from the number of rows in the frame decoded.
239  This is only really useful if we are re-using a decoder. */
240 int odc_decoder_set_row_count(odc_decoder_t* decoder, long nrows);
241 
242 /** Get the number of rows the decoder is configured to decode data into */
243 int odc_decoder_row_count(const odc_decoder_t* decoder, long* nrows);
244 
245 /**
246  * Define the output data array into which the data may be decoded.
247  * This is a shortcut to calling odc_decoder_column_set_data_array for every column.
248  */
249 int odc_decoder_set_data_array(odc_decoder_t* decoder, void* data, long width, long height, bool columnMajor);
250 
251 /** Gets the output data array into which the data may be decoded */
252 int odc_decoder_data_array(const odc_decoder_t* decoder, const void** data, long* width, long* height, bool* columnMajor);
253 
254 /**
255  * Adds a column to the set for decoding.
256  * This is an alternative to odc_decoder_defaults_from_frame
257  */
258 int odc_decoder_add_column(odc_decoder_t* decoder, const char* name);
259 
260 /** The number of columns the decoder is configured to decode */
261 int odc_decoder_column_count(const odc_decoder_t* decoder, int* count);
262 
263 /**
264  * Set the decoded data size for a column in bytes.
265  */
266 int odc_decoder_column_set_data_size(odc_decoder_t* decoder, int col, int element_size);
267 
268 /**
269  * Sets a specific data array into which the data associated with the column can be decoded
270  * This is an alternative to the odc_decoder_set_data_array.
271  */
272 int odc_decoder_column_set_data_array(odc_decoder_t* decoder, int col, int element_size, int stride, void* data);
273 
274 /**
275  * Gets the buffer and data layout into which the data has been decoded.
276  * Only valid after calling odc_decode
277  */
278 int odc_decoder_column_data_array(const odc_decoder_t* decoder, int col, int* element_size, int* stride, const void** data);
279 
280 /**
281  * Decode the data described by the frame into the data array(s) configured in the decoder.
282  * If no data array has been set above, an array to decode into will be allocated. This can be
283  * obtained by using the odc_decoder_data_array function.
284  */
285 int odc_decode(odc_decoder_t* decoder, const odc_frame_t* frame, long* rows_decoded);
286 
287 /**
288  * Decode the data described by the frame into the data array(s) configured in the decoder.
289  * If the frame is logical aggregated over multiple frames in the message,
290  * then parallelise the decoding over multiple threads.
291  */
292 int odc_decode_threaded(odc_decoder_t* decoder, const odc_frame_t* frame, long* rows_decoded, int nthreads);
293 
294 ///@}
295 
296 
297 
298 /**
299  * Encoding data
300  */
301 
302 ///@{
303 
304 struct odc_encoder_t;
305 typedef struct odc_encoder_t odc_encoder_t;
306 
307 /** Creates an encoder for encoding into ODB2 format */
308 int odc_new_encoder(odc_encoder_t** encoder);
309 
310 /** Deallocates the encoder */
311 int odc_free_encoder(const odc_encoder_t* encoder);
312 
313 /** Add a property (key-value) to the encoder to encode into the ODB2 file */
314 int odc_encoder_add_property(odc_encoder_t* encoder, const char* key, const char* value);
315 
316 /** Declare the number of rows you are going to encode */
317 int odc_encoder_set_row_count(odc_encoder_t* encoder, long nrows);
318 
319 /** Overrides the default number of rows which will be grouped together into frames */
320 int odc_encoder_set_rows_per_frame(odc_encoder_t* encoder, long rows_per_frame);
321 
322 /** Associate a 2D data array to an encoder and describe its shape.
323  * Note this does not yet encode the data and the data isn't copied.
324  * The client code is responsible for keeping the data in memory until encoded.
325  * There can be only one associated data array at a time per encoder,
326  * but an encoder can be used to encode a sequence of data arrays with interleaved calls to odc_encode_to_* functions.
327  * @param encoder the encoder
328  * @param data the memory buffer
329  * @param width the width of the 2D array in bytes. NOTE it is in BYTES.
330  * @param height the height of the 2D array in rows, being greater or equal than the row count.
331  * @param columnMajorWidth if zero then 2D array is interpreted as row-major, otherwise its the size in bytes of the
332  * column entries, typically 8 bytes.
333  */
334 int odc_encoder_set_data_array(odc_encoder_t* encoder, const void* data, long width, long height, int columnMajorWidth);
335 
336 /// @todo implment the int columnMajorWidth in the above function
337 
338 /** Describes a new column in the encoder */
339 int odc_encoder_add_column(odc_encoder_t* encoder, const char* name, int type);
340 
341 /**
342  * Set the source data size for a given column in bytes
343  * @param encoder the encoder
344  * @param col the column (zero indexed)
345  * @param element_size the element size in bytes (must be a multiple of 8) [a value of 0 uses default]
346  */
347 int odc_encoder_column_set_data_size(odc_encoder_t* encoder, int col, int element_size);
348 
349 /** Associates a custom data layout and data array with the column.
350  * This function is used as an alternative to odc_encoder_set_data_array
351  * @param encoder the encoder
352  * @param col the column (zero indexed)
353  * @param element_size the element size in bytes (must be a multiple of 8) [a value of 0 uses default]
354  * @param stride the separation in memory between consecutive elements in bytes [0 uses default, i.e. contiguous]
355  * @param data a pointer to the first element
356  */
357 int odc_encoder_column_set_data_array(odc_encoder_t* encoder, int col, int element_size, int stride, const void* data);
358 
359 /** Adds a bitfield to a column */
360 int odc_encoder_column_add_bitfield(odc_encoder_t* encoder, int col, const char* name, int nbits);
361 
362 
363 typedef long (*odc_stream_write_t)(void* context, const void* buffer, long length);
364 
365 /** Encodes ODB2 in a stream handler */
366 int odc_encode_to_stream(odc_encoder_t* encoder, void* context, odc_stream_write_t write_fn, long* bytes_encoded);
367 
368 /** Encodes ODB2 into an already open file descriptor */
369 int odc_encode_to_file_descriptor(odc_encoder_t* encoder, int fd, long* bytes_encoded);
370 
371 /** Encodes ODB2 into a pre-allocated memory buffer.
372  Returns an error if an insufficiently large buffer is supplied */
373 int odc_encode_to_buffer(odc_encoder_t* encoder, void* buffer, long length, long* bytes_encoded);
374 
375 ///@}
376 
377 /*--------------------------------------------------------------------------------------------------------------------*/
378 
379 #ifdef __cplusplus
380 } /* extern "C" */
381 #endif
382 
383 #endif /* odc_api_odc_H */
static void count(void *counter, const double *data, size_t n)
Definition: UnitTests.cc:531
long(* write_fn)(void *handle, const void *buffer, long length)
Definition: encode.cc:607
IODA_DL void copy(const ObjectSelection &from, ObjectSelection &to, const ScaleMapping &scale_map)
Generic data copying function.
Definition: Copying.cpp:63
int odc_encoder_add_column(odc_encoder_t *encoder, const char *name, int type)
Definition: api/odc.cc:778
int odc_free_encoder(const odc_encoder_t *encoder)
Definition: api/odc.cc:728
int odc_decoder_set_data_array(odc_decoder_t *decoder, void *data, long width, long height, bool columnMajor)
Definition: api/odc.cc:494
int odc_open_stream(odc_reader_t **reader, void *context, odc_stream_read_t stream_proc)
Definition: api/odc.cc:309
int odc_column_type_name(int type, const char **type_name)
Definition: api/odc.cc:169
int odc_set_missing_integer(long missing_integer)
Definition: api/odc.cc:257
int odc_initialise_api()
Definition: api/odc.cc:203
int odc_decoder_defaults_from_frame(odc_decoder_t *decoder, const odc_frame_t *frame)
Definition: api/odc.cc:453
int odc_frame_column_count(const odc_frame_t *frame, int *count)
Definition: api/odc.cc:396
int odc_encoder_add_property(odc_encoder_t *encoder, const char *key, const char *value)
Definition: api/odc.cc:734
int odc_encoder_column_set_data_size(odc_encoder_t *encoder, int col, int element_size)
Definition: api/odc.cc:786
int odc_decoder_column_set_data_size(odc_decoder_t *decoder, int col, int element_size)
Definition: api/odc.cc:544
const char * odc_error_string(int err)
Definition: api/odc.cc:93
int odc_encoder_set_row_count(odc_encoder_t *encoder, long nrows)
Definition: api/odc.cc:741
int odc_open_file_descriptor(odc_reader_t **reader, int fd)
Definition: api/odc.cc:292
int odc_column_type_count(int *count)
Definition: api/odc.cc:163
long(* odc_stream_read_t)(void *context, void *buffer, long length)
int odc_decoder_column_count(const odc_decoder_t *decoder, int *count)
Definition: api/odc.cc:536
int odc_set_failure_handler(odc_failure_handler_t handler, void *context)
Definition: api/odc.cc:235
int odc_missing_integer(long *missing_value)
Definition: api/odc.cc:243
int odc_frame_bitfield_attributes(const odc_frame_t *frame, int col, int entry, const char **name, int *offset, int *size)
Definition: api/odc.cc:423
const int ODC_INTEGERS_AS_LONGS
int odc_free_frame(const odc_frame_t *frame)
Definition: api/odc.cc:352
int odc_next_frame(odc_frame_t *frame)
Definition: api/odc.cc:359
int odc_decode(odc_decoder_t *decoder, const odc_frame_t *frame, long *rows_decoded)
Definition: api/odc.cc:714
int odc_encoder_set_data_array(odc_encoder_t *encoder, const void *data, long width, long height, int columnMajorWidth)
Definition: api/odc.cc:755
OdcErrorValues
@ ODC_ERROR_GENERAL_EXCEPTION
@ ODC_ITERATION_COMPLETE
@ ODC_SUCCESS
@ ODC_ERROR_UNKNOWN_EXCEPTION
int odc_encoder_column_add_bitfield(odc_encoder_t *encoder, int col, const char *name, int nbits)
Definition: api/odc.cc:807
int odc_decode_threaded(odc_decoder_t *decoder, const odc_frame_t *frame, long *rows_decoded, int nthreads)
Definition: api/odc.cc:643
int odc_open_buffer(odc_reader_t **reader, const void *data, long length)
Definition: api/odc.cc:302
long(* odc_stream_write_t)(void *context, const void *buffer, long length)
int odc_set_missing_double(double missing_double)
Definition: api/odc.cc:263
int odc_version(const char **version)
Definition: api/odc.cc:269
int odc_decoder_row_count(const odc_decoder_t *decoder, long *nrows)
Definition: api/odc.cc:486
int odc_frame_column_attributes(const odc_frame_t *frame, int col, const char **name, int *type, int *element_size, int *bitfield_count)
Definition: api/odc.cc:404
const int ODC_INTEGERS_AS_DOUBLES
int odc_missing_double(double *missing_value)
Definition: api/odc.cc:250
int odc_decoder_add_column(odc_decoder_t *decoder, const char *name)
Definition: api/odc.cc:527
void(* odc_failure_handler_t)(void *context, int error_code)
int odc_encode_to_file_descriptor(odc_encoder_t *encoder, int fd, long *bytes_encoded)
Definition: api/odc.cc:982
int odc_copy_frame(odc_frame_t *source_frame, odc_frame_t **copy)
Definition: api/odc.cc:381
int odc_integer_behaviour(int integerBehaviour)
Definition: api/odc.cc:226
int odc_decoder_data_array(const odc_decoder_t *decoder, const void **data, long *width, long *height, bool *columnMajor)
Definition: api/odc.cc:508
int odc_new_encoder(odc_encoder_t **encoder)
Definition: api/odc.cc:722
int odc_open_path(odc_reader_t **reader, const char *filename)
Definition: api/odc.cc:285
int odc_decoder_set_column_major(odc_decoder_t *decoder, bool columnMajor)
Definition: api/odc.cc:472
int odc_new_decoder(odc_decoder_t **decoder)
Definition: api/odc.cc:441
int odc_decoder_column_set_data_array(odc_decoder_t *decoder, int col, int element_size, int stride, void *data)
Definition: api/odc.cc:554
int odc_decoder_column_data_array(const odc_decoder_t *decoder, int col, int *element_size, int *stride, const void **data)
Definition: api/odc.cc:566
int odc_encoder_column_set_data_array(odc_encoder_t *encoder, int col, int element_size, int stride, const void *data)
Definition: api/odc.cc:795
int odc_frame_row_count(const odc_frame_t *frame, long *count)
Definition: api/odc.cc:388
int odc_new_frame(odc_frame_t **frame, odc_reader_t *reader)
Definition: api/odc.cc:345
int odc_close(const odc_reader_t *reader)
Definition: api/odc.cc:332
int odc_vcs_version(const char **version)
Definition: api/odc.cc:275
OdcColumnType
@ ODC_INTEGER
@ ODC_IGNORE
@ ODC_REAL
@ ODC_BITFIELD
@ ODC_STRING
@ ODC_DOUBLE
int odc_encode_to_stream(odc_encoder_t *encoder, void *context, odc_stream_write_t write_fn, long *bytes_encoded)
Definition: api/odc.cc:949
int odc_encoder_set_rows_per_frame(odc_encoder_t *encoder, long rows_per_frame)
Definition: api/odc.cc:748
int odc_encode_to_buffer(odc_encoder_t *encoder, void *buffer, long length, long *bytes_encoded)
Definition: api/odc.cc:992
int odc_next_frame_aggregated(odc_frame_t *frame, long maximum_rows)
Definition: api/odc.cc:370
int odc_decoder_set_row_count(odc_decoder_t *decoder, long nrows)
Definition: api/odc.cc:479
int odc_free_decoder(const odc_decoder_t *decoder)
Definition: api/odc.cc:447
size_t nrows
Definition: api/odc.cc:51
bool columnMajor
Definition: api/odc.cc:58
size_t nrows
Definition: api/odc.cc:75
int columnMajorWidth
Definition: api/odc.cc:73