summaryrefslogtreecommitdiff
path: root/platform/android/src/text/format_number.cpp
blob: 3a41175ecc13916b326fadbc14aec47ed79640fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <mbgl/style/expression/collator.hpp>
#include <mbgl/text/language_tag.hpp>
#include <mbgl/util/platform.hpp>

#include <jni/jni.hpp>

#include "../attach_env.hpp"
#include "format_number_jni.hpp"

namespace mbgl {
namespace android {

void NumberFormat::registerNative(jni::JNIEnv& env) {
    jni::Class<NumberFormat>::Singleton(env);
}

jni::Local<jni::Object<NumberFormat>> NumberFormat::getInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
    static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
    static auto method = javaClass.GetStaticMethod<jni::Object<NumberFormat> (jni::Object<Locale>)>(env, "getInstance");
    return javaClass.Call(env, method, locale);
}

jni::Local<jni::Object<NumberFormat>> NumberFormat::getCurrencyInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
    static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
    static auto method = javaClass.GetStaticMethod<jni::Object<NumberFormat> (jni::Object<Locale>)>(env, "getCurrencyInstance");
    return javaClass.Call(env, method, locale);
}

jni::Local<jni::String> NumberFormat::format(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jdouble number) {
    static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
    static auto method = javaClass.GetMethod<jni::String (jni::jdouble)>(env, "format");
    return nf.Call(env, method, number);
}

void NumberFormat::setMinimumFractionDigits(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jint value) {
    static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
    static auto method = javaClass.GetMethod<void (jni::jint)>(env, "setMinimumFractionDigits");
    return nf.Call(env, method, value);
}

void NumberFormat::setMaximumFractionDigits(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jint value) {
    static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
    static auto method = javaClass.GetMethod<void (jni::jint)>(env, "setMaximumFractionDigits");
    return nf.Call(env, method, value);
}

} // namespace android

namespace platform {

std::string formatNumber(double number, const std::string& localeId, const std::string& currency,
                         uint8_t minFractionDigits, uint8_t maxFractionDigits) {

    auto env{ android::AttachEnv() };

    jni::Global<jni::Object<android::Locale>> locale;
    LanguageTag languageTag = !localeId.empty() ? LanguageTag::fromBCP47(localeId) : LanguageTag();
    if (!languageTag.language) {
        locale = jni::NewGlobal(*env, android::Locale::getDefault(*env));
    } else if (!languageTag.region) {
        locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make<jni::String>(*env, *languageTag.language)));
    } else {
        locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make<jni::String>(*env, *languageTag.language),
                                                                 jni::Make<jni::String>(*env, *languageTag.region)));
    }

    jni::Global<jni::Object<android::NumberFormat>> formatter;
    if (currency.empty()) {
        formatter = jni::NewGlobal(*env, android::NumberFormat::getInstance(*env, locale));
        android::NumberFormat::setMinimumFractionDigits(*env, formatter, static_cast<jni::jint>(minFractionDigits));
        android::NumberFormat::setMaximumFractionDigits(*env, formatter, static_cast<jni::jint>(maxFractionDigits));
    } else {
        formatter = jni::NewGlobal(*env, android::NumberFormat::getCurrencyInstance(*env, locale));
    }

    auto result = android::NumberFormat::format(*env, formatter, static_cast<jni::jdouble>(number));
    return jni::Make<std::string>(*env, result);
}

} // namespace platform
} // namespace mbgl