2015-01-28 20:53:21 +01:00
|
|
|
/*
|
|
|
|
This file is part of TALER
|
2016-01-19 14:39:00 +01:00
|
|
|
Copyright (C) 2014, 2015 GNUnet e.V.
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
TALER is free software; you can redistribute it and/or modify it under the
|
|
|
|
terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
|
|
|
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
2016-07-07 17:55:25 +02:00
|
|
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @file include/taler_amount_lib.h
|
|
|
|
* @brief amount-representation utility functions
|
|
|
|
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
|
|
|
*/
|
|
|
|
#ifndef TALER_AMOUNT_LIB_H
|
|
|
|
#define TALER_AMOUNT_LIB_H
|
|
|
|
|
2015-06-09 13:55:05 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#if 0 /* keep Emacsens' auto-indent happy */
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
/**
|
2015-03-28 15:53:53 +01:00
|
|
|
* @brief Number of characters (plus 1 for 0-termination) we use to
|
2015-04-08 22:28:52 +02:00
|
|
|
* represent currency names (i.e. EUR, USD, etc.). We use 8+4 for
|
|
|
|
* alignment in the `struct TALER_Amount`. The amount is typically an
|
|
|
|
* ISO 4217 currency code when an alpha-numeric 3-digit code is used.
|
|
|
|
* For regional currencies, the first character should be a "*" followed
|
|
|
|
* by a region-specific name (i.e. "*BRETAGNEFR").
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
2015-04-08 22:28:52 +02:00
|
|
|
#define TALER_CURRENCY_LEN 12
|
2015-01-28 20:53:21 +01:00
|
|
|
|
2015-05-06 11:47:12 +02:00
|
|
|
/**
|
|
|
|
* Taler currency length as a string.
|
|
|
|
*/
|
|
|
|
#define TALER_CURRENCY_LEN_STR "12"
|
|
|
|
|
2015-03-18 18:55:41 +01:00
|
|
|
/**
|
2015-03-28 15:53:53 +01:00
|
|
|
* @brief The "fraction" value in a `struct TALER_Amount` represents which
|
2015-03-18 18:55:41 +01:00
|
|
|
* fraction of the "main" value?
|
|
|
|
*
|
|
|
|
* Note that we need sub-cent precision here as transaction fees might
|
|
|
|
* be that low, and as we want to support microdonations.
|
|
|
|
*/
|
2016-11-18 14:58:16 +01:00
|
|
|
#define TALER_AMOUNT_FRAC_BASE 100000000
|
2015-03-18 18:55:41 +01:00
|
|
|
|
|
|
|
/**
|
2015-03-28 15:53:53 +01:00
|
|
|
* @brief How many digits behind the comma are required to represent the
|
2015-03-18 18:55:41 +01:00
|
|
|
* fractional value in human readable decimal format? Must match
|
|
|
|
* lg(#TALER_AMOUNT_FRAC_BASE).
|
|
|
|
*/
|
2016-11-18 14:58:16 +01:00
|
|
|
#define TALER_AMOUNT_FRAC_LEN 8
|
2015-03-18 18:55:41 +01:00
|
|
|
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_BEGIN
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-03-28 15:53:53 +01:00
|
|
|
* @brief Amount, encoded for network transmission.
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
|
|
|
struct TALER_AmountNBO
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Value in the main currency, in NBO.
|
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
uint64_t value GNUNET_PACKED;
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Additinal fractional value, in NBO.
|
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
uint32_t fraction GNUNET_PACKED;
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Type of the currency being represented.
|
|
|
|
*/
|
|
|
|
char currency[TALER_CURRENCY_LEN];
|
|
|
|
};
|
|
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_END
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-03-28 15:53:53 +01:00
|
|
|
* @brief Representation of monetary value in a given currency.
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
|
|
|
struct TALER_Amount
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Value (numerator of fraction)
|
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
uint64_t value;
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fraction (denominator of fraction)
|
|
|
|
*/
|
|
|
|
uint32_t fraction;
|
|
|
|
|
|
|
|
/**
|
2015-03-18 18:55:41 +01:00
|
|
|
* Currency string, left adjusted and padded with zeros. All zeros
|
|
|
|
* for "invalid" values.
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
|
|
|
char currency[TALER_CURRENCY_LEN];
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-04-13 17:20:46 +02:00
|
|
|
* Parse denomination description, in the format "T:V.F".
|
2015-01-28 20:53:21 +01:00
|
|
|
*
|
|
|
|
* @param str denomination description
|
|
|
|
* @param denom denomination to write the result to
|
|
|
|
* @return #GNUNET_OK if the string is a valid denomination specification,
|
|
|
|
* #GNUNET_SYSERR if it is invalid.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_string_to_amount (const char *str,
|
|
|
|
struct TALER_Amount *denom);
|
|
|
|
|
|
|
|
|
2016-04-04 16:47:11 +02:00
|
|
|
/**
|
|
|
|
* Parse denomination description, in the format "T:V.F".
|
|
|
|
*
|
|
|
|
* @param str denomination description
|
|
|
|
* @param denom denomination to write the result to, in NBO
|
|
|
|
* @return #GNUNET_OK if the string is a valid denomination specification,
|
|
|
|
* #GNUNET_SYSERR if it is invalid.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_string_to_amount_nbo (const char *str,
|
|
|
|
struct TALER_AmountNBO *denom);
|
|
|
|
|
|
|
|
|
2015-03-18 18:55:41 +01:00
|
|
|
/**
|
|
|
|
* Get the value of "zero" in a particular currency.
|
|
|
|
*
|
|
|
|
* @param cur currency description
|
|
|
|
* @param denom denomination to write the result to
|
|
|
|
* @return #GNUNET_OK if @a cur is a valid currency specification,
|
|
|
|
* #GNUNET_SYSERR if it is invalid.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_amount_get_zero (const char *cur,
|
|
|
|
struct TALER_Amount *denom);
|
|
|
|
|
|
|
|
|
2017-03-15 12:01:06 +01:00
|
|
|
/**
|
|
|
|
* Test if the given amount is valid.
|
|
|
|
*
|
|
|
|
* @param amount amount to check
|
|
|
|
* @return #GNUNET_OK if @a amount is valid
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_amount_is_valid (const struct TALER_Amount *amount);
|
|
|
|
|
|
|
|
|
2015-01-28 20:53:21 +01:00
|
|
|
/**
|
|
|
|
* Convert amount from host to network representation.
|
|
|
|
*
|
2015-03-18 18:55:41 +01:00
|
|
|
* @param res where to store amount in network representation
|
2015-01-28 20:53:21 +01:00
|
|
|
* @param d amount in host representation
|
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
void
|
|
|
|
TALER_amount_hton (struct TALER_AmountNBO *res,
|
|
|
|
const struct TALER_Amount *d);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert amount from network to host representation.
|
|
|
|
*
|
2015-03-18 18:55:41 +01:00
|
|
|
* @param res where to store amount in host representation
|
2015-03-28 15:42:07 +01:00
|
|
|
* @param dn amount in network representation
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
void
|
|
|
|
TALER_amount_ntoh (struct TALER_Amount *res,
|
|
|
|
const struct TALER_AmountNBO *dn);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-03-18 18:55:41 +01:00
|
|
|
* Compare the value/fraction of two amounts. Does not compare the currency.
|
|
|
|
* Comparing amounts of different currencies will cause the program to abort().
|
|
|
|
* If unsure, check with #TALER_amount_cmp_currency() first to be sure that
|
|
|
|
* the currencies of the two amounts are identical.
|
2015-01-28 20:53:21 +01:00
|
|
|
*
|
|
|
|
* @param a1 first amount
|
|
|
|
* @param a2 second amount
|
|
|
|
* @return result of the comparison
|
2015-07-05 13:18:49 +02:00
|
|
|
* -1 if `a1 < a2`
|
|
|
|
* 1 if `a1 > a2`
|
|
|
|
* 0 if `a1 == a2`.
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
|
|
|
int
|
2015-03-18 18:55:41 +01:00
|
|
|
TALER_amount_cmp (const struct TALER_Amount *a1,
|
|
|
|
const struct TALER_Amount *a2);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if @a a1 and @a a2 are the same currency.
|
|
|
|
*
|
|
|
|
* @param a1 amount to test
|
|
|
|
* @param a2 amount to test
|
|
|
|
* @return #GNUNET_YES if @a a1 and @a a2 are the same currency
|
|
|
|
* #GNUNET_NO if the currencies are different
|
|
|
|
* #GNUNET_SYSERR if either amount is invalid
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_amount_cmp_currency (const struct TALER_Amount *a1,
|
|
|
|
const struct TALER_Amount *a2);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
|
2015-06-03 15:41:09 +02:00
|
|
|
/**
|
|
|
|
* Test if @a a1 and @a a2 are the same currency, NBO variant.
|
|
|
|
*
|
|
|
|
* @param a1 amount to test
|
|
|
|
* @param a2 amount to test
|
|
|
|
* @return #GNUNET_YES if @a a1 and @a a2 are the same currency
|
|
|
|
* #GNUNET_NO if the currencies are different
|
|
|
|
* #GNUNET_SYSERR if either amount is invalid
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_amount_cmp_currency_nbo (const struct TALER_AmountNBO *a1,
|
|
|
|
const struct TALER_AmountNBO *a2);
|
|
|
|
|
|
|
|
|
2015-01-28 20:53:21 +01:00
|
|
|
/**
|
|
|
|
* Perform saturating subtraction of amounts.
|
|
|
|
*
|
2015-03-18 18:55:41 +01:00
|
|
|
* @param diff where to store (@a a1 - @a a2), or invalid if @a a2 > @a a1
|
2015-01-28 20:53:21 +01:00
|
|
|
* @param a1 amount to subtract from
|
|
|
|
* @param a2 amount to subtract
|
2015-03-18 18:55:41 +01:00
|
|
|
* @return #GNUNET_OK if the subtraction worked,
|
|
|
|
* #GNUNET_NO if @a a1 = @a a2
|
|
|
|
* #GNUNET_SYSERR if @a a2 > @a a1 or currencies are incompatible;
|
|
|
|
* @a diff is set to invalid
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
int
|
|
|
|
TALER_amount_subtract (struct TALER_Amount *diff,
|
|
|
|
const struct TALER_Amount *a1,
|
|
|
|
const struct TALER_Amount *a2);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-03-18 18:55:41 +01:00
|
|
|
* Perform addition of amounts.
|
2015-01-28 20:53:21 +01:00
|
|
|
*
|
2015-03-18 18:55:41 +01:00
|
|
|
* @param sum where to store @a a1 + @a a2, set to "invalid" on overflow
|
2015-01-28 20:53:21 +01:00
|
|
|
* @param a1 first amount to add
|
|
|
|
* @param a2 second amount to add
|
2015-03-18 18:55:41 +01:00
|
|
|
* @return #GNUNET_OK if the addition worked,
|
|
|
|
* #GNUNET_SYSERR on overflow
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
int
|
|
|
|
TALER_amount_add (struct TALER_Amount *sum,
|
|
|
|
const struct TALER_Amount *a1,
|
|
|
|
const struct TALER_Amount *a2);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
|
2017-03-06 16:35:30 +01:00
|
|
|
/**
|
|
|
|
* Divide an amount by a float. Note that this function
|
|
|
|
* may introduce a rounding error!
|
|
|
|
*
|
|
|
|
* @param result where to store @a dividend / @a divisor
|
|
|
|
* @param dividend amount to divide
|
|
|
|
* @param divisor by what to divide, must be positive
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
TALER_amount_divide (struct TALER_Amount *result,
|
|
|
|
const struct TALER_Amount *dividend,
|
|
|
|
uint32_t divisor);
|
|
|
|
|
|
|
|
|
2015-01-28 20:53:21 +01:00
|
|
|
/**
|
|
|
|
* Normalize the given amount.
|
|
|
|
*
|
2015-03-18 18:55:41 +01:00
|
|
|
* @param amount amount to normalize
|
|
|
|
* @return #GNUNET_OK if normalization worked
|
|
|
|
* #GNUNET_NO if value was already normalized
|
|
|
|
* #GNUNET_SYSERR if value was invalid or could not be normalized
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
2015-03-18 18:55:41 +01:00
|
|
|
int
|
|
|
|
TALER_amount_normalize (struct TALER_Amount *amount);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert amount to string.
|
|
|
|
*
|
|
|
|
* @param amount amount to convert to string
|
2015-03-18 18:55:41 +01:00
|
|
|
* @return freshly allocated string representation,
|
|
|
|
* NULL if the @a amount was invalid
|
2015-01-28 20:53:21 +01:00
|
|
|
*/
|
|
|
|
char *
|
2015-03-18 18:55:41 +01:00
|
|
|
TALER_amount_to_string (const struct TALER_Amount *amount);
|
2015-01-28 20:53:21 +01:00
|
|
|
|
2017-03-20 02:29:33 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert amount to string.
|
|
|
|
*
|
|
|
|
* @param amount amount to convert to string
|
|
|
|
* @return statically allocated buffer with string representation,
|
|
|
|
* NULL if the @a amount was invalid
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
TALER_amount2s (const struct TALER_Amount *amount);
|
|
|
|
|
|
|
|
|
2020-01-13 18:16:01 +01:00
|
|
|
/**
|
2020-01-15 15:17:02 +01:00
|
|
|
* Round the amount to something that can be transferred on the wire.
|
2020-01-17 18:59:15 +01:00
|
|
|
* The rounding mode is specified via the smallest transferable unit,
|
|
|
|
* which must only have a fractional part.
|
2020-01-13 18:16:01 +01:00
|
|
|
*
|
|
|
|
* @param[in,out] amount amount to round down
|
2020-01-17 18:59:15 +01:00
|
|
|
* @param[in] round_unit unit that should be rounded down to,
|
|
|
|
* the value part of this amount must be zero
|
2020-01-13 18:16:01 +01:00
|
|
|
* @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
|
|
|
|
* #GNUNET_SYSERR if the amount or currency was invalid
|
|
|
|
*/
|
|
|
|
int
|
2020-01-15 15:17:02 +01:00
|
|
|
TALER_amount_round_down (struct TALER_Amount *amount,
|
2020-01-17 18:59:15 +01:00
|
|
|
const struct TALER_Amount *round_unit);
|
2020-01-13 18:16:01 +01:00
|
|
|
|
|
|
|
|
2015-06-09 13:55:05 +02:00
|
|
|
#if 0 /* keep Emacsens' auto-indent happy */
|
|
|
|
{
|
|
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-01-28 20:53:21 +01:00
|
|
|
|
|
|
|
#endif
|