summaryrefslogtreecommitdiff
path: root/taler-kotlin-android/src/main/java/net/taler/common
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2023-01-03 11:22:42 -0300
committerTorsten Grote <t@grobox.de>2023-01-03 11:22:42 -0300
commit9bb3505277b8132c3fd0be52d9bbbc6078723ff2 (patch)
tree60688f65d464ee02834c4ae1d89b715f4e8f5640 /taler-kotlin-android/src/main/java/net/taler/common
parent3cf3abb25adf040ad8e4e30d0fc8f311b2b1f4ee (diff)
downloadtaler-android-9bb3505277b8132c3fd0be52d9bbbc6078723ff2.tar.gz
taler-android-9bb3505277b8132c3fd0be52d9bbbc6078723ff2.tar.bz2
taler-android-9bb3505277b8132c3fd0be52d9bbbc6078723ff2.zip
[wallet] Don't allow entering invalid amounts
#0007350
Diffstat (limited to 'taler-kotlin-android/src/main/java/net/taler/common')
-rw-r--r--taler-kotlin-android/src/main/java/net/taler/common/Amount.kt44
1 files changed, 34 insertions, 10 deletions
diff --git a/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt b/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
index 4a6e4b3..750a1de 100644
--- a/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
+++ b/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
@@ -25,8 +25,11 @@ import kotlin.math.floor
import kotlin.math.pow
import kotlin.math.roundToInt
-public class AmountParserException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
-public class AmountOverflowException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
+public class AmountParserException(msg: String? = null, cause: Throwable? = null) :
+ Exception(msg, cause)
+
+public class AmountOverflowException(msg: String? = null, cause: Throwable? = null) :
+ Exception(msg, cause)
@Serializable(with = KotlinXAmountSerializer::class)
public data class Amount(
@@ -50,7 +53,7 @@ public data class Amount(
* of the base currency value. For example, a fraction
* of 50_000_000 would correspond to 50 cents.
*/
- val fraction: Int
+ val fraction: Int,
) : Comparable<Amount> {
public companion object {
@@ -63,8 +66,8 @@ public data class Amount(
public const val MAX_FRACTION: Int = 99_999_999
public fun fromDouble(currency: String, value: Double): Amount {
- val intPart = Math.floor(value).toLong()
- val fraPart = Math.floor((value - intPart) * FRACTIONAL_BASE).toInt()
+ val intPart = floor(value).toLong()
+ val fraPart = floor((value - intPart) * FRACTIONAL_BASE).toInt()
return Amount(currency, intPart, fraPart)
}
@@ -87,14 +90,34 @@ public data class Amount(
val fractionStr = valueSplit[1]
if (fractionStr.length > MAX_FRACTION_LENGTH)
throw AmountParserException("Fraction $fractionStr too long")
- val fraction = "0.$fractionStr".toDoubleOrNull()
- ?.times(FRACTIONAL_BASE)
- ?.roundToInt()
- checkFraction(fraction)
+ checkFraction(fractionStr.getFraction())
} else 0
return Amount(checkCurrency(currency), value, fraction)
}
+ public fun isValidAmountStr(str: String): Boolean {
+ val split = str.split(".")
+ try {
+ checkValue(split[0].toLongOrNull())
+ } catch (e: AmountParserException) {
+ return false
+ }
+ // also check fraction, if it exists
+ if (split.size > 1) {
+ val fractionStr = split[1]
+ if (fractionStr.length > MAX_FRACTION_LENGTH) return false
+ val fraction = fractionStr.getFraction() ?: return false
+ return fraction <= MAX_FRACTION
+ }
+ return true
+ }
+
+ private fun String.getFraction(): Int? {
+ return "0.$this".toDoubleOrNull()
+ ?.times(FRACTIONAL_BASE)
+ ?.roundToInt()
+ }
+
public fun min(currency: String): Amount = Amount(currency, 0, 1)
public fun max(currency: String): Amount = Amount(currency, MAX_VALUE, MAX_FRACTION)
@@ -132,7 +155,8 @@ public data class Amount(
public operator fun plus(other: Amount): Amount {
check(currency == other.currency) { "Can only subtract from same currency" }
- val resultValue = value + other.value + floor((fraction + other.fraction).toDouble() / FRACTIONAL_BASE).toLong()
+ val resultValue =
+ value + other.value + floor((fraction + other.fraction).toDouble() / FRACTIONAL_BASE).toLong()
if (resultValue > MAX_VALUE)
throw AmountOverflowException()
val resultFraction = (fraction + other.fraction) % FRACTIONAL_BASE