VAPOR3 3.9.4
udunits2.h
Go to the documentation of this file.
1/*
2 * Copyright 2008, 2009 University Corporation for Atmospheric Research
3 *
4 * This file is part of the UDUNITS-2 package. See the file LICENSE
5 * in the top-level source-directory of the package for copying and
6 * redistribution conditions.
7 */
8#ifndef UT_UNITS2_H_INCLUDED
9#define UT_UNITS2_H_INCLUDED
10#include "vapor/common.h"
11#include <stdarg.h>
12#include <stddef.h>
13
14#include "converter.h"
15
16typedef struct ut_system ut_system;
17typedef union ut_unit ut_unit;
18
19typedef enum {
20 UT_SUCCESS = 0, /* Success */
21 UT_BAD_ARG, /* An argument violates the function's contract */
22 UT_EXISTS, /* Unit, prefix, or identifier already exists */
23 UT_NO_UNIT, /* No such unit exists */
24 UT_OS, /* Operating-system error. See "errno". */
25 UT_NOT_SAME_SYSTEM, /* The units belong to different unit-systems */
26 UT_MEANINGLESS, /* The operation on the unit(s) is meaningless */
27 UT_NO_SECOND, /* The unit-system doesn't have a unit named "second" */
28 UT_VISIT_ERROR, /* An error occurred while visiting a unit */
29 UT_CANT_FORMAT, /* A unit can't be formatted in the desired manner */
30 UT_SYNTAX, /* string unit representation contains syntax error */
31 UT_UNKNOWN, /* string unit representation contains unknown word */
32 UT_OPEN_ARG, /* Can't open argument-specified unit database */
33 UT_OPEN_ENV, /* Can't open environment-specified unit database */
34 UT_OPEN_DEFAULT, /* Can't open installed, default, unit database */
35 UT_PARSE /* Error parsing unit specification */
37
39
40#define UT_NAMES 4
41#define UT_DEFINITION 8
42
43/*
44 * Data-structure for a visitor to a unit:
45 */
46typedef struct {
47 /*
48 * Visits a basic-unit. A basic-unit is a base unit like "meter" or a non-
49 * dimensional but named unit like "radian".
50 *
51 * Arguments:
52 * unit Pointer to the basic-unit.
53 * arg Client pointer passed to ut_accept_visitor().
54 * Returns:
55 * UT_SUCCESS Success.
56 * else Failure.
57 */
58 ut_status (*visit_basic)(const ut_unit *unit, void *arg);
59
60 /*
61 * Visits a product-unit. A product-unit is a product of zero or more
62 * basic-units, each raised to a non-zero power.
63 *
64 * Arguments:
65 * unit Pointer to the product-unit.
66 * count The number of basic-units in the product. May be zero.
67 * basicUnits Pointer to an array of basic-units in the product.
68 * powers Pointer to an array of powers to which the respective
69 * basic-units are raised.
70 * arg Client pointer passed to ut_accept_visitor().
71 * Returns:
72 * UT_SUCCESS Success.
73 * else Failure.
74 */
75 ut_status (*visit_product)(const ut_unit *unit, int count, const ut_unit *const *basicUnits, const int *powers, void *arg);
76
77 /*
78 * Visits a Galilean-unit. A Galilean-unit has an underlying unit and a
79 * non-unity scale factor or a non-zero offset.
80 *
81 * Arguments:
82 * unit Pointer to the Galilean-unit.
83 * scale The scale factor (e.g., 1000 for a kilometer when the
84 * underlying unit is a meter).
85 * underlyingUnit Pointer to the underlying unit.
86 * offset Pointer to the underlying unit.
87 * arg Client pointer passed to ut_accept_visitor().
88 * Returns:
89 * UT_SUCCESS Success.
90 * else Failure.
91 */
92 ut_status (*visit_galilean)(const ut_unit *unit, double scale, const ut_unit *underlyingUnit, double offset, void *arg);
93
94 /*
95 * Visits a timestamp-unit. A timestamp-unit has an underlying unit of time
96 * and an encoded time-origin.
97 *
98 * Arguments:
99 * unit Pointer to the timestamp-unit.
100 * timeUnit Pointer to the underlying unit of time.
101 * origin Encoded origin of the timestamp-unit.
102 * arg Client pointer passed to ut_accept_visitor().
103 * Returns:
104 * UT_SUCCESS Success.
105 * else Failure.
106 */
107 ut_status (*visit_timestamp)(const ut_unit *unit, const ut_unit *timeUnit, double origin, void *arg);
108
109 /*
110 * Visits a logarithmic-unit. A logarithmic-unit has a logarithmic base and
111 * a unit that specifies the reference level.
112 *
113 * Arguments:
114 * unit Pointer to the logarithmic-unit.
115 * base The logarithmic base (e.g., 2, M_E, 10).
116 * reference Pointer to the unit that specifies the reference level.
117 * arg Client pointer passed to ut_accept_visitor().
118 * Returns:
119 * UT_SUCCESS Success.
120 * else Failure.
121 */
122 ut_status (*visit_logarithmic)(const ut_unit *unit, double base, const ut_unit *reference, void *arg);
123} ut_visitor;
124
125typedef int (*ut_error_message_handler)(const char *fmt, va_list args);
126
127#ifdef __cplusplus
128extern "C" {
129#endif
130
131/******************************************************************************
132 * Unit System:
133 ******************************************************************************/
134
135/*
136 * Returns the unit-system corresponding to an XML file. This is the usual way
137 * that a client will obtain a unit-system.
138 *
139 * Arguments:
140 * path The pathname of the XML file or NULL. If NULL, then the
141 * pathname specified by the environment variable UDUNITS2_XML_PATH
142 * is used if set; otherwise, the compile-time pathname of the
143 * installed, default, unit database is used.
144 * Returns:
145 * NULL Failure. "ut_get_status()" will be
146 * UT_OPEN_ARG "path" is non-NULL but file couldn't be
147 * opened. See "errno" for reason.
148 * UT_OPEN_ENV "path" is NULL and environment variable
149 * UDUNITS2_XML_PATH is set but file
150 * couldn't be opened. See "errno" for
151 * reason.
152 * UT_OPEN_DEFAULT "path" is NULL, environment variable
153 * UDUNITS2_XML_PATH is unset, and the
154 * installed, default, unit database
155 * couldn't be opened. See "errno" for
156 * reason.
157 * UT_PARSE Couldn't parse unit database.
158 * UT_OS Operating-system error. See "errno".
159 * else Pointer to the unit-system defined by "path".
160 */
161UDUNITS2_API ut_system *ut_read_xml(const char *path);
162
163/*
164 * Returns a new unit-system. On success, the unit-system will only contain
165 * the dimensionless unit one. See "ut_get_dimensionless_unit_one()".
166 *
167 * Returns:
168 * NULL Failure. "ut_get_status()" will be:
169 * UT_OS Operating-system error. See "errno".
170 * else Pointer to a new unit system.
171 */
172UDUNITS2_API ut_system *ut_new_system(void);
173
174/*
175 * Frees a unit-system. All unit-to-identifier and identifier-to-unit mappings
176 * will be removed.
177 *
178 * Arguments:
179 * system Pointer to the unit-system to be freed. Use of "system"
180 * upon return results in undefined behavior.
181 */
182UDUNITS2_API void ut_free_system(ut_system *system);
183
184/*
185 * Returns the unit-system to which a unit belongs.
186 *
187 * Arguments:
188 * unit Pointer to the unit in question.
189 * Returns:
190 * NULL Failure. "ut_get_status()" will be
191 * UT_BAD_ARG "unit" is NULL.
192 * else Pointer to the unit-system to which "unit" belongs.
193 */
194UDUNITS2_API ut_system *ut_get_system(const ut_unit *const unit);
195
196/*
197 * Returns the dimensionless-unit one of a unit-system.
198 *
199 * Arguments:
200 * system Pointer to the unit-system for which the dimensionless-unit one
201 * will be returned.
202 * Returns:
203 * NULL Failure. "ut_get_status()" will be:
204 * UT_BAD_ARG "system" is NULL.
205 * else Pointer to the dimensionless-unit one associated with "system".
206 * While not necessary, the pointer may be passed to ut_free()
207 * when the unit is no longer needed by the client.
208 */
209UDUNITS2_API ut_unit *ut_get_dimensionless_unit_one(const ut_system *const system);
210
211/*
212 * Returns the unit with a given name from a unit-system. Name comparisons
213 * are case-insensitive.
214 *
215 * Arguments:
216 * system Pointer to the unit-system.
217 * name Pointer to the name of the unit to be returned.
218 * Returns:
219 * NULL Failure. "ut_get_status()" will be
220 * UT_SUCCESS "name" doesn't map to a unit of
221 * "system".
222 * UT_BAD_ARG "system" or "name" is NULL.
223 * else Pointer to the unit of the unit-system with the given name.
224 * The pointer should be passed to ut_free() when the unit is
225 * no longer needed.
226 */
227UDUNITS2_API ut_unit *ut_get_unit_by_name(const ut_system *const system, const char *const name);
228
229/*
230 * Returns the unit with a given symbol from a unit-system. Symbol
231 * comparisons are case-sensitive.
232 *
233 * Arguments:
234 * system Pointer to the unit-system.
235 * symbol Pointer to the symbol associated with the unit to be
236 * returned.
237 * Returns:
238 * NULL Failure. "ut_get_status()" will be
239 * UT_SUCCESS "symbol" doesn't map to a unit of
240 * "system".
241 * UT_BAD_ARG "system" or "symbol" is NULL.
242 * else Pointer to the unit in the unit-system with the given symbol.
243 * The pointer should be passed to ut_free() when the unit is no
244 * longer needed.
245 */
246UDUNITS2_API ut_unit *ut_get_unit_by_symbol(const ut_system *const system, const char *const symbol);
247
248/*
249 * Sets the "second" unit of a unit-system. This function must be called before
250 * the first call to "ut_offset_by_time()". ut_read_xml() calls this function if the
251 * resulting unit-system contains a unit named "second".
252 *
253 * Arguments:
254 * second Pointer to the "second" unit.
255 * Returns:
256 * UT_BAD_ARG "second" is NULL.
257 * UT_EXISTS The second unit of the unit-system to which "second"
258 * belongs is set to a different unit.
259 * UT_SUCCESS Success.
260 */
261UDUNITS2_API ut_status ut_set_second(const ut_unit *const second);
262
263/******************************************************************************
264 * Defining Unit Prefixes:
265 ******************************************************************************/
266
267/*
268 * Adds a name-prefix to a unit-system. A name-prefix is something like "mega"
269 * or "milli". Comparisons between name-prefixes are case-insensitive.
270 *
271 * Arguments:
272 * system Pointer to the unit-system.
273 * name Pointer to the name-prefix (e.g., "mega"). May be freed
274 * upon return.
275 * value The value of the prefix (e.g., 1e6).
276 * Returns:
277 * UT_SUCCESS Success.
278 * UT_BAD_ARG "system" or "name" is NULL, or "value" is 0.
279 * UT_EXISTS "name" already maps to a different value.
280 * UT_OS Operating-system failure. See "errno".
281 */
282UDUNITS2_API ut_status ut_add_name_prefix(ut_system *const system, const char *const name, const double value);
283
284/*
285 * Adds a symbol-prefix to a unit-system. A symbol-prefix is something like
286 * "M" or "y". Comparisons between symbol-prefixes are case-sensitive.
287 *
288 * Arguments:
289 * system Pointer to the unit-system.
290 * symbol Pointer to the symbol-prefix (e.g., "M"). May be freed
291 * upon return.
292 * value The value of the prefix (e.g., 1e6).
293 * Returns:
294 * UT_SUCCESS Success.
295 * UT_BADSYSTEM "system" or "symbol" is NULL.
296 * UT_BAD_ARG "value" is 0.
297 * UT_EXISTS "symbol" already maps to a different value.
298 * UT_OS Operating-system failure. See "errno".
299 */
300UDUNITS2_API ut_status ut_add_symbol_prefix(ut_system *const system, const char *const symbol, const double value);
301
302/******************************************************************************
303 * Defining and Deleting Units:
304 ******************************************************************************/
305
306/*
307 * Adds a base-unit to a unit-system. Clients that use ut_read_xml() should not
308 * normally need to call this function.
309 *
310 * Arguments:
311 * system Pointer to the unit-system to which to add the new base-unit.
312 * Returns:
313 * NULL Failure. "ut_get_status()" will be
314 * UT_BAD_ARG "system" or "name" is NULL.
315 * UT_OS Operating-system error. See "errno".
316 * else Pointer to the new base-unit. The pointer should be passed to
317 * ut_free() when the unit is no longer needed by the client (the
318 * unit will remain in the unit-system).
319 */
320UDUNITS2_API ut_unit *ut_new_base_unit(ut_system *const system);
321
322/*
323 * Adds a dimensionless-unit to a unit-system. In the SI system of units, the
324 * derived-unit radian is a dimensionless-unit. Clients that use ut_read_xml()
325 * should not normally need to call this function.
326 *
327 * Arguments:
328 * system Pointer to the unit-system to which to add the new
329 * dimensionless-unit.
330 * Returns:
331 * NULL Failure. "ut_get_status()" will be
332 * UT_BAD_ARG "system" is NULL.
333 * UT_OS Operating-system error. See "errno".
334 * else Pointer to the new dimensionless-unit. The pointer should be
335 * passed to ut_free() when the unit is no longer needed by the
336 * client (the unit will remain in the unit-system).
337 */
338UDUNITS2_API ut_unit *ut_new_dimensionless_unit(ut_system *const system);
339
340/*
341 * Returns a clone of a unit.
342 *
343 * Arguments:
344 * unit Pointer to the unit to be cloned.
345 * Returns:
346 * NULL Failure. ut_get_status() will be
347 * UT_OS Operating-system failure. See "errno".
348 * UT_BAD_ARG "unit" is NULL.
349 * else Pointer to the clone of "unit". The pointer should be
350 * passed to ut_free() when the unit is no longer needed by the
351 * client.
352 */
353UDUNITS2_API ut_unit *ut_clone(const ut_unit *unit);
354
355/*
356 * Frees resources associated with a unit. This function should be invoked on
357 * all units that are no longer needed by the client. Use of the unit upon
358 * return from this function will result in undefined behavior.
359 *
360 * Arguments:
361 * unit Pointer to the unit to have its resources freed or NULL.
362 */
363UDUNITS2_API void ut_free(ut_unit *const unit);
364
365/******************************************************************************
366 * Mapping between Units and Names:
367 ******************************************************************************/
368
369/*
370 * Returns the name in a given encoding to which a unit maps.
371 *
372 * Arguments:
373 * unit Pointer to the unit whose name should be returned.
374 * encoding The desired encoding of the name.
375 * Returns:
376 * NULL Failure. "ut_get_status()" will be
377 * UT_BAD_ARG "unit" is NULL.
378 * UT_SUCCESS "unit" doesn't map to a name in
379 * in the given encoding.
380 * else Pointer to the name in the given encoding to which
381 * "unit" maps.
382 */
383UDUNITS2_API const char *ut_get_name(const ut_unit *const unit, const ut_encoding encoding);
384
385/*
386 * Adds a mapping from a name to a unit.
387 *
388 * Arguments:
389 * name Pointer to the name to be mapped to "unit". May be
390 * freed upon return.
391 * encoding The character encoding of "name".
392 * unit Pointer to the unit to be mapped-to by "name". May be
393 * freed upon return.
394 * Returns:
395 * UT_BAD_ARG "name" or "unit" is NULL.
396 * UT_OS Operating-system error. See "errno".
397 * UT_EXISTS "name" already maps to a different unit.
398 * UT_SUCCESS Success.
399 */
400ut_status ut_map_name_to_unit(const char *const name, const ut_encoding encoding, const ut_unit *const unit);
401
402/*
403 * Removes a mapping from a name to a unit. After this function,
404 * ut_get_unit_by_name(system,name) will no longer return a unit.
405 *
406 * Arguments:
407 * system The unit-system to which the unit belongs.
408 * name The name of the unit.
409 * encoding The character encoding of "name".
410 * Returns:
411 * UT_SUCCESS Success.
412 * UT_BAD_ARG "system" or "name" is NULL.
413 */
414UDUNITS2_API ut_status ut_unmap_name_to_unit(ut_system *system, const char *const name, const ut_encoding encoding);
415
416/*
417 * Adds a mapping from a unit to a name.
418 *
419 * Arguments:
420 * unit Pointer to the unit to be mapped to "name". May be
421 * freed upon return.
422 * name Pointer to the name to be mapped-to by "unit". May be
423 * freed upon return.
424 * encoding The encoding of "name".
425 * Returns:
426 * UT_SUCCESS Success.
427 * UT_BAD_ARG "unit" or "name" is NULL, or "name" is not in the
428 * specified encoding.
429 * UT_OS Operating-system error. See "errno".
430 * UT_EXISTS "unit" already maps to a name.
431 */
432UDUNITS2_API ut_status ut_map_unit_to_name(const ut_unit *const unit, const char *const name, ut_encoding encoding);
433
434/*
435 * Removes a mapping from a unit to a name.
436 *
437 * Arguments:
438 * unit Pointer to the unit. May be freed upon return.
439 * encoding The encoding to be removed. No other encodings will be
440 * removed.
441 * Returns:
442 * UT_BAD_ARG "unit" is NULL.
443 * UT_SUCCESS Success.
444 */
445UDUNITS2_API ut_status ut_unmap_unit_to_name(const ut_unit *const unit, ut_encoding encoding);
446
447/******************************************************************************
448 * Mapping between Units and Symbols:
449 ******************************************************************************/
450
451/*
452 * Returns the symbol in a given encoding to which a unit maps.
453 *
454 * Arguments:
455 * unit Pointer to the unit whose symbol should be returned.
456 * encoding The desired encoding of the symbol.
457 * Returns:
458 * NULL Failure. "ut_get_status()" will be
459 * UT_BAD_ARG "unit" is NULL.
460 * UT_SUCCESS "unit" doesn't map to a symbol
461 * in the given encoding.
462 * else Pointer to the symbol in the given encoding to which
463 * "unit" maps.
464 */
465UDUNITS2_API const char *ut_get_symbol(const ut_unit *const unit, const ut_encoding encoding);
466
467/*
468 * Adds a mapping from a symbol to a unit.
469 *
470 * Arguments:
471 * symbol Pointer to the symbol to be mapped to "unit". May be
472 * freed upon return.
473 * ut_encoding The character encoding of "symbol".
474 * unit Pointer to the unit to be mapped-to by "symbol". May
475 * be freed upon return.
476 * Returns:
477 * UT_BAD_ARG "symbol" or "unit" is NULL.
478 * UT_OS Operating-system error. See "errno".
479 * UT_EXISTS "symbol" already maps to a different unit.
480 * UT_SUCCESS Success.
481 */
482UDUNITS2_API ut_status ut_map_symbol_to_unit(const char *const symbol, const ut_encoding encoding, const ut_unit *const unit);
483
484/*
485 * Removes a mapping from a symbol to a unit. After this function,
486 * ut_get_unit_by_symbol(system,symbol) will no longer return a unit.
487 *
488 * Arguments:
489 * system The unit-system to which the unit belongs.
490 * symbol The symbol of the unit.
491 * encoding The character encoding of "symbol".
492 * Returns:
493 * UT_SUCCESS Success.
494 * UT_BAD_ARG "system" or "symbol" is NULL.
495 */
496UDUNITS2_API ut_status ut_unmap_symbol_to_unit(ut_system *system, const char *const symbol, const ut_encoding encoding);
497
498/*
499 * Adds a mapping from a unit to a symbol.
500 *
501 * Arguments:
502 * unit Pointer to the unit to be mapped to "symbol". May be
503 * freed upon return.
504 * symbol Pointer to the symbol to be mapped-to by "unit". May
505 * be freed upon return.
506 * encoding The encoding of "symbol".
507 * Returns:
508 * UT_SUCCESS Success.
509 * UT_BAD_ARG "unit" or "symbol" is NULL.
510 * UT_OS Operating-system error. See "errno".
511 * UT_EXISTS "unit" already maps to a symbol.
512 */
513UDUNITS2_API ut_status ut_map_unit_to_symbol(const ut_unit *unit, const char *const symbol, ut_encoding encoding);
514
515/*
516 * Removes a mapping from a unit to a symbol.
517 *
518 * Arguments:
519 * unit Pointer to the unit to be unmapped to a symbol. May be
520 * freed upon return.
521 * encoding The encoding to be removed. The mappings for "unit" in
522 * other encodings will not be removed.
523 * Returns:
524 * UT_SUCCESS Success.
525 * UT_BAD_ARG "unit" is NULL.
526 */
527UDUNITS2_API ut_status ut_unmap_unit_to_symbol(const ut_unit *const unit, ut_encoding encoding);
528
529/******************************************************************************
530 * Getting Information about a Unit:
531 ******************************************************************************/
532
533/*
534 * Indicates if a given unit is dimensionless or not. Note that logarithmic
535 * units are dimensionless by definition.
536 *
537 * Arguments:
538 * unit Pointer to the unit in question.
539 * Returns:
540 * 0 "unit" is dimensionfull or an error occurred. "ut_get_status()"
541 * will be
542 * UT_BAD_ARG "unit" is NULL.
543 * UT_SUCCESS "unit" is dimensionfull.
544 * else "unit" is dimensionless.
545 */
546UDUNITS2_API int ut_is_dimensionless(const ut_unit *const unit);
547
548/*
549 * Indicates if two units belong to the same unit-system.
550 *
551 * Arguments:
552 * unit1 Pointer to a unit.
553 * unit2 Pointer to another unit.
554 * Returns:
555 * 0 Failure or the units belong to different unit-systems.
556 * "ut_get_status()" will be
557 * UT_BAD_ARG "unit1" or "unit2" is NULL.
558 * UT_SUCCESS The units belong to different
559 * unit-systems.
560 * else The units belong to the same unit-system.
561 */
562UDUNITS2_API int ut_same_system(const ut_unit *const unit1, const ut_unit *const unit2);
563
564/*
565 * Compares two units. Returns a value less than, equal to, or greater than
566 * zero as the first unit is considered less than, equal to, or greater than
567 * the second unit, respectively. Units from different unit-systems never
568 * compare equal.
569 *
570 * Arguments:
571 * unit1 Pointer to a unit or NULL.
572 * unit2 Pointer to another unit or NULL.
573 * Returns:
574 * <0 The first unit is less than the second unit.
575 * 0 The first and second units are equal or both units are NULL.
576 * >0 The first unit is greater than the second unit.
577 */
578UDUNITS2_API int ut_compare(const ut_unit *const unit1, const ut_unit *const unit2);
579
580/*
581 * Indicates if numeric values in one unit are convertible to numeric values in
582 * another unit via "ut_get_converter()". In making this determination,
583 * dimensionless units are ignored.
584 *
585 * Arguments:
586 * unit1 Pointer to a unit.
587 * unit2 Pointer to another unit.
588 * Returns:
589 * 0 Failure. "ut_get_status()" will be
590 * UT_BAD_ARG "unit1" or "unit2" is NULL.
591 * UT_NOT_SAME_SYSTEM "unit1" and "unit2" belong to
592 * different unit-sytems.
593 * UT_SUCCESS Conversion between the units is
594 * not possible (e.g., "unit1" is
595 * "meter" and "unit2" is
596 * "kilogram").
597 * else Numeric values can be converted between the units.
598 */
599UDUNITS2_API int ut_are_convertible(const ut_unit *const unit1, const ut_unit *const unit2);
600
601/*
602 * Returns a converter of numeric values in one unit to numeric values in
603 * another unit. The returned converter should be passed to cv_free() when it is
604 * no longer needed by the client.
605 *
606 * NOTE: Leap seconds are not taken into account when converting between
607 * timestamp units.
608 *
609 * Arguments:
610 * from Pointer to the unit from which to convert values.
611 * to Pointer to the unit to which to convert values.
612 * Returns:
613 * NULL Failure. "ut_get_status()" will be:
614 * UT_BAD_ARG "from" or "to" is NULL.
615 * UT_NOT_SAME_SYSTEM "from" and "to" belong to
616 * different unit-systems.
617 * UT_MEANINGLESS Conversion between the units is
618 * not possible. See
619 * "ut_are_convertible()".
620 * else Pointer to the appropriate converter. The pointer
621 * should be passed to cv_free() when no longer needed by
622 * the client.
623 */
624UDUNITS2_API cv_converter *ut_get_converter(ut_unit *const from, ut_unit *const to);
625
626/******************************************************************************
627 * Arithmetic Unit Manipulation:
628 ******************************************************************************/
629
630/*
631 * Returns a unit equivalent to another unit scaled by a numeric factor,
632 * e.g.,
633 * const ut_unit* meter = ...
634 * const ut_unit* kilometer = ut_scale(1000, meter);
635 *
636 * Arguments:
637 * factor The numeric scale factor.
638 * unit Pointer to the unit to be scaled.
639 * Returns:
640 * NULL Failure. "ut_get_status()" will be
641 * UT_BAD_ARG "factor" is 0 or "unit" is NULL.
642 * UT_OS Operating-system error. See
643 * "errno".
644 * else Pointer to the resulting unit. The pointer should be
645 * passed to ut_free() when the unit is no longer needed by
646 * the client.
647 */
648UDUNITS2_API ut_unit *ut_scale(const double factor, const ut_unit *const unit);
649
650/*
651 * Returns a unit equivalent to another unit offset by a numeric amount,
652 * e.g.,
653 * const ut_unit* kelvin = ...
654 * const ut_unit* celsius = ut_offset(kelvin, 273.15);
655 *
656 * Arguments:
657 * unit Pointer to the unit to be offset.
658 * offset The numeric offset.
659 * Returns:
660 * NULL Failure. "ut_get_status()" will be
661 * UT_BAD_ARG "unit" is NULL.
662 * UT_OS Operating-system error. See
663 * "errno".
664 * else Pointer to the resulting unit. The pointer should be
665 * passed to ut_free() when the unit is no longer needed by
666 * the client.
667 */
668UDUNITS2_API ut_unit *ut_offset(const ut_unit *const unit, const double offset);
669
670/*
671 * Returns a unit equivalent to another unit relative to a particular time.
672 * e.g.,
673 * const ut_unit* second = ...
674 * const ut_unit* secondsSinceTheEpoch =
675 * ut_offset_by_time(second, ut_encode_time(1970, 1, 1, 0, 0, 0.0));
676 *
677 * Arguments:
678 * unit Pointer to the time-unit to be made relative to a time-origin.
679 * origin The origin as returned by ut_encode_time().
680 * Returns:
681 * NULL Failure. "ut_get_status()" will be
682 * UT_BAD_ARG "unit" is NULL.
683 * UT_OS Operating-system error. See "errno".
684 * UT_MEANINGLESS Creation of a timestamp unit based on
685 * "unit" is not meaningful.
686 * UT_NO_SECOND The associated unit-system doesn't
687 * contain a "second" unit. See
688 * ut_set_second().
689 * else Pointer to the resulting unit. The pointer should be passed
690 * to ut_free() when the unit is no longer needed by the client.
691 */
692UDUNITS2_API ut_unit *ut_offset_by_time(const ut_unit *const unit, const double origin);
693
694/*
695 * Returns the result of multiplying one unit by another unit.
696 *
697 * Arguments:
698 * unit1 Pointer to a unit.
699 * unit2 Pointer to another unit.
700 * Returns:
701 * NULL Failure. "ut_get_status()" will be:
702 * UT_BAD_ARG "unit1" or "unit2" is NULL.
703 * UT_NOT_SAME_SYSTEM "unit1" and "unit2" belong to
704 * different unit-systems.
705 * UT_OS Operating-system error. See "errno".
706 * else Pointer to the resulting unit. The pointer should be passed
707 * to ut_free() when the unit is no longer needed by the client.
708 */
709UDUNITS2_API ut_unit *ut_multiply(const ut_unit *const unit1, const ut_unit *const unit2);
710
711/*
712 * Returns the inverse (i.e., reciprocal) of a unit. This convenience function
713 * is equal to "ut_raise(unit, -1)".
714 *
715 * Arguments:
716 * unit Pointer to the unit.
717 * Returns:
718 * NULL Failure. "ut_get_status()" will be:
719 * UT_BAD_ARG "unit" is NULL.
720 * UT_OS Operating-system error. See "errno".
721 * else Pointer to the resulting unit. The pointer should be passed to
722 * ut_free() when the unit is no longer needed by the client.
723 */
724UDUNITS2_API ut_unit *ut_invert(const ut_unit *const unit);
725
726/*
727 * Returns the result of dividing one unit by another unit. This convenience
728 * function is equivalent to the following sequence:
729 * {
730 * ut_unit* inverse = ut_invert(denom);
731 * ut_multiply(numer, inverse);
732 * ut_free(inverse);
733 * }
734 *
735 * Arguments:
736 * numer Pointer to the numerator (top, dividend) unit.
737 * denom Pointer to the denominator (bottom, divisor) unit.
738 * Returns:
739 * NULL Failure. "ut_get_status()" will be:
740 * UT_BAD_ARG "numer" or "denom" is NULL.
741 * UT_NOT_SAME_SYSTEM "unit1" and "unit2" belong to
742 * different unit-systems.
743 * UT_OS Operating-system error. See "errno".
744 * else Pointer to the resulting unit. The pointer should be passed to
745 * ut_free() when the unit is no longer needed by the client.
746 */
747UDUNITS2_API ut_unit *ut_divide(const ut_unit *const numer, const ut_unit *const denom);
748
749/*
750 * Returns the result of raising a unit to a power.
751 *
752 * Arguments:
753 * unit Pointer to the unit.
754 * power The power by which to raise "unit". Must be greater than or
755 * equal to -255 and less than or equal to 255.
756 * Returns:
757 * NULL Failure. "ut_get_status()" will be:
758 * UT_BAD_ARG "unit" is NULL or "power" is invalid.
759 * UT_OS Operating-system error. See "errno".
760 * else Pointer to the resulting unit. The pointer should be passed to
761 * ut_free() when the unit is no longer needed by the client.
762 */
763UDUNITS2_API ut_unit *ut_raise(const ut_unit *const unit, const int power);
764
765/*
766 * Returns the result of taking the root of a unit.
767 *
768 * Arguments:
769 * unit Pointer to the unit.
770 * root The root to take of "unit". Must be greater than or
771 * equal to 1 and less than or equal to 255.
772 * Returns:
773 * NULL Failure. "ut_get_status()" will be:
774 * UT_BAD_ARG "unit" is NULL, or "root" is invalid.
775 * In particular, all powers of base units
776 * in "unit" must be integral multiples of
777 * "root".
778 * UT_OS Operating-system error. See "errno".
779 * else Pointer to the resulting unit. The pointer should be passed to
780 * ut_free() when the unit is no longer needed by the client.
781 */
782UDUNITS2_API ut_unit *ut_root(const ut_unit *const unit, const int root);
783
784/*
785 * Returns the logarithmic unit corresponding to a logarithmic base and a
786 * reference level. For example, the following creates a decibel unit with a
787 * one milliwatt reference level:
788 *
789 * const ut_unit* watt = ...;
790 * const ut_unit* milliWatt = ut_scale(0.001, watt);
791 *
792 * if (milliWatt != NULL) {
793 * const ut_unit* bel_1_mW = ut_log(10.0, milliWatt);
794 *
795 * if (bel_1_mW != NULL) {
796 * const ut_unit* decibel_1_mW = ut_scale(0.1, bel_1_mW);
797 *
798 * if (decibel_1_mW != NULL) {
799 * ...
800 * ut_free(decibel_1_mW);
801 * } // "decibel_1_mW" allocated
802 *
803 * ut_free(bel_1_mW);
804 * } // "bel_1_mW" allocated
805 *
806 * ut_free(milliWatt);
807 * } // "milliWatt" allocated
808 *
809 * Arguments:
810 * base The logarithmic base (e.g., 2, M_E, 10). Must be
811 * greater than one. "M_E" is defined in <math.h>.
812 * reference Pointer to the reference value as a unit.
813 * Returns:
814 * NULL Failure. "ut_get_status()" will be:
815 * UT_BAD_ARG "base" is invalid or "reference"
816 * is NULL.
817 * UT_OS Operating-system error. See
818 * "errno".
819 * else Pointer to the resulting unit. The pointer should be
820 * passed to ut_free() when the unit is no longer needed by
821 * the client.
822 */
823UDUNITS2_API ut_unit *ut_log(const double base, const ut_unit *const reference);
824
825/******************************************************************************
826 * Parsing and Formatting Units:
827 ******************************************************************************/
828
829/*
830 * Returns the binary representation of a unit corresponding to a string
831 * representation.
832 *
833 * Arguments:
834 * system Pointer to the unit-system in which the parsing will
835 * occur.
836 * string The string to be parsed (e.g., "millimeters"). There
837 * should be no leading or trailing whitespace in the
838 * string. See ut_trim().
839 * encoding The encoding of "string".
840 * Returns:
841 * NULL Failure. "ut_get_status()" will be one of
842 * UT_BAD_ARG "system" or "string" is NULL.
843 * UT_SYNTAX "string" contained a syntax
844 * error.
845 * UT_UNKNOWN "string" contained an unknown
846 * identifier.
847 * UT_OS Operating-system failure. See
848 * "errno".
849 * else Pointer to the unit corresponding to "string".
850 */
851UDUNITS2_API ut_unit *ut_parse(const ut_system *const system, const char *const string, const ut_encoding encoding);
852
853/*
854 * Removes leading and trailing whitespace from a string.
855 *
856 * Arguments:
857 * string NUL-terminated string. Will be modified if it contains
858 * whitespace..
859 * encoding The character-encoding of "string".
860 * Returns:
861 * "string", with all leading and trailing whitespace removed.
862 */
863UDUNITS2_API char *ut_trim(char *const string, const ut_encoding encoding);
864
865/*
866 * Formats a unit.
867 *
868 * Arguments:
869 * unit Pointer to the unit to be formatted.
870 * buf Pointer to the buffer into which to format "unit".
871 * size Size of the buffer in bytes.
872 * opts Formatting options: bitwise-OR of zero or more of the
873 * following:
874 * UT_NAMES Use unit names instead of
875 * symbols
876 * UT_DEFINITION The formatted string should be
877 * the definition of "unit" in
878 * terms of basic-units instead of
879 * stopping any expansion at the
880 * highest level possible.
881 * UT_ASCII The string should be formatted
882 * using the ASCII character set
883 * (default).
884 * UT_LATIN1 The string should be formatted
885 * using the ISO Latin-1 (alias
886 * ISO-8859-1) character set.
887 * UT_UTF8 The string should be formatted
888 * using the UTF-8 character set.
889 * UT_LATIN1 and UT_UTF8 are mutually exclusive: they may
890 * not both be specified.
891 * Returns:
892 * -1 Failure: "ut_get_status()" will be
893 * UT_BAD_ARG "unit" or "buf" is NULL, or both
894 * UT_LATIN1 and UT_UTF8 specified.
895 * UT_CANT_FORMAT "unit" can't be formatted in
896 * the desired manner.
897 * else Success. Number of characters printed in "buf". If
898 * the number is equal to the size of the buffer, then the
899 * buffer is too small to have a terminating NUL character.
900 */
901UDUNITS2_API int ut_format(const ut_unit *const unit, char *buf, size_t size, unsigned opts);
902
903/*
904 * Accepts a visitor to a unit.
905 *
906 * Arguments:
907 * unit Pointer to the unit to accept the visitor.
908 * visitor Pointer to the visitor of "unit".
909 * arg An arbitrary pointer that will be passed to "visitor".
910 * Returns:
911 * UT_BAD_ARG "unit" or "visitor" is NULL.
912 * UT_VISIT_ERROR A error occurred in "visitor" while visiting "unit".
913 * UT_SUCCESS Success.
914 */
915UDUNITS2_API ut_status ut_accept_visitor(const ut_unit *const unit, const ut_visitor *const visitor, void *const arg);
916
917/******************************************************************************
918 * Time Handling:
919 ******************************************************************************/
920
921/*
922 * Encodes a date as a double-precision value.
923 *
924 * Arguments:
925 * year The year.
926 * month The month.
927 * day The day (1 = the first of the month).
928 * Returns:
929 * The date encoded as a scalar value.
930 */
931UDUNITS2_API double ut_encode_date(int year, int month, int day);
932
933/*
934 * Encodes a time as a double-precision value.
935 *
936 * Arguments:
937 * hours The number of hours (0 = midnight).
938 * minutes The number of minutes.
939 * seconds The number of seconds.
940 * Returns:
941 * The clock-time encoded as a scalar value.
942 */
943UDUNITS2_API double ut_encode_clock(int hours, int minutes, double seconds);
944
945/*
946 * Encodes a time as a double-precision value. The convenience function is
947 * equivalent to "ut_encode_date(year,month,day) +
948 * ut_encode_clock(hour,minute,second)"
949 *
950 * Arguments:
951 * year The year.
952 * month The month.
953 * day The day.
954 * hour The hour.
955 * minute The minute.
956 * second The second.
957 * Returns:
958 * The time encoded as a scalar value.
959 */
960UDUNITS2_API double ut_encode_time(const int year, const int month, const int day, const int hour, const int minute, const double second);
961
962/*
963 * Decodes a time from a double-precision value.
964 *
965 * Arguments:
966 * value The value to be decoded.
967 * year Pointer to the variable to be set to the year.
968 * month Pointer to the variable to be set to the month.
969 * day Pointer to the variable to be set to the day.
970 * hour Pointer to the variable to be set to the hour.
971 * minute Pointer to the variable to be set to the minute.
972 * second Pointer to the variable to be set to the second.
973 * resolution Pointer to the variable to be set to the resolution
974 * of the decoded time in seconds.
975 */
976UDUNITS2_API void ut_decode_time(double value, int *year, int *month, int *day, int *hour, int *minute, double *second, double *resolution);
977
978/******************************************************************************
979 * Error Handling:
980 ******************************************************************************/
981
982/*
983 * Returns the status of the last operation by the units module. This function
984 * will not change the status.
985 */
986UDUNITS2_API ut_status ut_get_status(void);
987
988/*
989 * Sets the status of the units module. This function would not normally be
990 * called by the user unless they were doing their own parsing or formatting.
991 *
992 * Arguments:
993 * status The status of the units module.
994 */
995UDUNITS2_API void ut_set_status(ut_status status);
996
997/*
998 * Handles an error-message.
999 *
1000 * Arguments:
1001 * fmt The format for the error-message.
1002 * ... The arguments for "fmt".
1003 * Returns:
1004 * <0 An output error was encountered.
1005 * else The number of bytes of "fmt" and "arg" written excluding any
1006 * terminating NUL.
1007 */
1008UDUNITS2_API int ut_handle_error_message(const char *const fmt, ...);
1009
1010/*
1011 * Returns the previously-installed error-message handler and optionally
1012 * installs a new handler. The initial handler is "ut_write_to_stderr()".
1013 *
1014 * Arguments:
1015 * handler NULL or pointer to the error-message handler. If NULL,
1016 * then the handler is not changed. The
1017 * currently-installed handler can be obtained this way.
1018 * Returns:
1019 * Pointer to the previously-installed error-message handler.
1020 */
1022
1023/*
1024 * Writes an error-message to the standard-error stream when received and
1025 * appends a newline. This is the initial error-message handler.
1026 *
1027 * Arguments:
1028 * fmt The format for the error-message.
1029 * args The arguments of "fmt".
1030 * Returns:
1031 * <0 A output error was encountered. See "errno".
1032 * else The number of bytes of "fmt" and "arg" written excluding any
1033 * terminating NUL.
1034 */
1035UDUNITS2_API int ut_write_to_stderr(const char *const fmt, va_list args);
1036
1037/*
1038 * Does nothing with an error-message.
1039 *
1040 * Arguments:
1041 * fmt The format for the error-message.
1042 * args The arguments of "fmt".
1043 * Returns:
1044 * 0 Always.
1045 */
1046UDUNITS2_API int ut_ignore(const char *const fmt, va_list args);
1047
1048#ifdef __cplusplus
1049}
1050#endif
1051
1052#endif
union cv_converter cv_converter
Definition: converter.h:22
UDUNITS2_API ut_unit * ut_new_dimensionless_unit(ut_system *const system)
UDUNITS2_API const char * ut_get_name(const ut_unit *const unit, const ut_encoding encoding)
ut_status ut_map_name_to_unit(const char *const name, const ut_encoding encoding, const ut_unit *const unit)
UDUNITS2_API void ut_decode_time(double value, int *year, int *month, int *day, int *hour, int *minute, double *second, double *resolution)
UDUNITS2_API ut_status ut_add_symbol_prefix(ut_system *const system, const char *const symbol, const double value)
UDUNITS2_API int ut_are_convertible(const ut_unit *const unit1, const ut_unit *const unit2)
UDUNITS2_API ut_status ut_map_unit_to_symbol(const ut_unit *unit, const char *const symbol, ut_encoding encoding)
UDUNITS2_API ut_status ut_get_status(void)
UDUNITS2_API ut_status ut_unmap_unit_to_symbol(const ut_unit *const unit, ut_encoding encoding)
UDUNITS2_API ut_unit * ut_get_unit_by_name(const ut_system *const system, const char *const name)
UDUNITS2_API ut_unit * ut_get_unit_by_symbol(const ut_system *const system, const char *const symbol)
ut_status
Definition: udunits2.h:19
@ UT_MEANINGLESS
Definition: udunits2.h:26
@ UT_VISIT_ERROR
Definition: udunits2.h:28
@ UT_NO_SECOND
Definition: udunits2.h:27
@ UT_NO_UNIT
Definition: udunits2.h:23
@ UT_CANT_FORMAT
Definition: udunits2.h:29
@ UT_UNKNOWN
Definition: udunits2.h:31
@ UT_NOT_SAME_SYSTEM
Definition: udunits2.h:25
@ UT_OPEN_ARG
Definition: udunits2.h:32
@ UT_SUCCESS
Definition: udunits2.h:20
@ UT_PARSE
Definition: udunits2.h:35
@ UT_EXISTS
Definition: udunits2.h:22
@ UT_OPEN_ENV
Definition: udunits2.h:33
@ UT_OPEN_DEFAULT
Definition: udunits2.h:34
@ UT_SYNTAX
Definition: udunits2.h:30
@ UT_BAD_ARG
Definition: udunits2.h:21
@ UT_OS
Definition: udunits2.h:24
UDUNITS2_API double ut_encode_time(const int year, const int month, const int day, const int hour, const int minute, const double second)
UDUNITS2_API ut_unit * ut_raise(const ut_unit *const unit, const int power)
union ut_unit ut_unit
Definition: udunits2.h:17
UDUNITS2_API int ut_is_dimensionless(const ut_unit *const unit)
UDUNITS2_API ut_unit * ut_offset(const ut_unit *const unit, const double offset)
UDUNITS2_API double ut_encode_clock(int hours, int minutes, double seconds)
UDUNITS2_API ut_system * ut_new_system(void)
UDUNITS2_API ut_system * ut_get_system(const ut_unit *const unit)
UDUNITS2_API ut_unit * ut_scale(const double factor, const ut_unit *const unit)
UDUNITS2_API ut_status ut_unmap_name_to_unit(ut_system *system, const char *const name, const ut_encoding encoding)
UDUNITS2_API ut_unit * ut_parse(const ut_system *const system, const char *const string, const ut_encoding encoding)
UDUNITS2_API ut_status ut_unmap_unit_to_name(const ut_unit *const unit, ut_encoding encoding)
UDUNITS2_API ut_status ut_accept_visitor(const ut_unit *const unit, const ut_visitor *const visitor, void *const arg)
UDUNITS2_API char * ut_trim(char *const string, const ut_encoding encoding)
UDUNITS2_API int ut_handle_error_message(const char *const fmt,...)
UDUNITS2_API int ut_same_system(const ut_unit *const unit1, const ut_unit *const unit2)
UDUNITS2_API ut_unit * ut_new_base_unit(ut_system *const system)
int(* ut_error_message_handler)(const char *fmt, va_list args)
Definition: udunits2.h:125
UDUNITS2_API void ut_set_status(ut_status status)
UDUNITS2_API double ut_encode_date(int year, int month, int day)
UDUNITS2_API ut_unit * ut_invert(const ut_unit *const unit)
UDUNITS2_API int ut_compare(const ut_unit *const unit1, const ut_unit *const unit2)
struct ut_system ut_system
Definition: udunits2.h:16
UDUNITS2_API ut_system * ut_read_xml(const char *path)
UDUNITS2_API ut_unit * ut_divide(const ut_unit *const numer, const ut_unit *const denom)
UDUNITS2_API ut_status ut_unmap_symbol_to_unit(ut_system *system, const char *const symbol, const ut_encoding encoding)
UDUNITS2_API void ut_free(ut_unit *const unit)
UDUNITS2_API cv_converter * ut_get_converter(ut_unit *const from, ut_unit *const to)
UDUNITS2_API void ut_free_system(ut_system *system)
UDUNITS2_API ut_status ut_map_symbol_to_unit(const char *const symbol, const ut_encoding encoding, const ut_unit *const unit)
UDUNITS2_API int ut_ignore(const char *const fmt, va_list args)
UDUNITS2_API ut_unit * ut_multiply(const ut_unit *const unit1, const ut_unit *const unit2)
ut_encoding
Definition: udunits2.h:38
@ UT_LATIN1
Definition: udunits2.h:38
@ UT_ISO_8859_1
Definition: udunits2.h:38
@ UT_ASCII
Definition: udunits2.h:38
@ UT_UTF8
Definition: udunits2.h:38
UDUNITS2_API int ut_format(const ut_unit *const unit, char *buf, size_t size, unsigned opts)
UDUNITS2_API ut_status ut_add_name_prefix(ut_system *const system, const char *const name, const double value)
UDUNITS2_API ut_status ut_set_second(const ut_unit *const second)
UDUNITS2_API const char * ut_get_symbol(const ut_unit *const unit, const ut_encoding encoding)
UDUNITS2_API ut_unit * ut_offset_by_time(const ut_unit *const unit, const double origin)
UDUNITS2_API ut_error_message_handler ut_set_error_message_handler(ut_error_message_handler handler)
UDUNITS2_API ut_unit * ut_root(const ut_unit *const unit, const int root)
UDUNITS2_API ut_unit * ut_log(const double base, const ut_unit *const reference)
UDUNITS2_API int ut_write_to_stderr(const char *const fmt, va_list args)
UDUNITS2_API ut_unit * ut_get_dimensionless_unit_one(const ut_system *const system)
UDUNITS2_API ut_unit * ut_clone(const ut_unit *unit)
UDUNITS2_API ut_status ut_map_unit_to_name(const ut_unit *const unit, const char *const name, ut_encoding encoding)