AUI Framework  master
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
Converter.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13
   14#include <AUI/Traits/concepts.h>
   15#include <AUI/Util/AStringLiteral.h>
   16#include "GlobalRef.h"
   17#include <string_view>
   18
   19namespace aui::jni {
   20    template<typename T>
   21    struct Converter;
   22
   23    namespace impl {
   24        template<typename T>
   25        concept convertible = std::is_void_v<T> || requires(T&& t) {
   26            { Converter<T>::signature } -> ::aui::convertible_to<const char*>;
   27            Converter<T>::toJni(t);
   28            { Converter<T>::fromJni(Converter<T>::toJni(t)) } -> ::aui::convertible_to<T>;
   29        };
   30    }
   31
   32    template<typename T>
   33    concept convertible = ::aui::jni::impl::convertible<std::decay_t<T>>;
   34
   35
   36    template<convertible T>
   37    auto toJni(const T& t) -> decltype(Converter<T>::toJni(t)) {
   38        return Converter<T>::toJni(t);
   39    }
   40
   41    template<convertible T>
   42    T fromJni(const auto& t) {
   43        return Converter<T>::fromJni(t);
   44    }
   45
   46    template<typename CppType>
   47    using java_t_from_cpp_t = decltype(aui::jni::toJni(std::declval<CppType>()));
   48
   49    template <>
   50    struct Converter<std::string> {
   51        static constexpr auto signature = "Ljava/lang/String;"_asl;
   52
   53        static std::string fromJni(jobject val) {
   54            if (val) {
   55                static GlobalRef stringClass = jni::env()->GetObjectClass(val);
   56                static jmethodID getBytes = jni::env()->GetMethodID(stringClass.asClass(), "getBytes", "(Ljava/lang/String;)[B");
   57                jbyteArray b = jbyteArray(jni::env()->CallObjectMethod(val, getBytes, jni::env()->NewStringUTF("UTF-8")));
   58                size_t length = jni::env()->GetArrayLength(b);
   59                jbyte* elems = jni::env()->GetByteArrayElements(b, nullptr);
   60                std::string str(reinterpret_cast<char*>(elems), length);
   61                jni::env()->ReleaseByteArrayElements(b, elems, JNI_ABORT);
   62                jni::env()->DeleteLocalRef(b);
   63                return str;
   64            }
   65            return {};
   66        }
   67
   68        static jstring toJni(std::string_view value) {
   69            auto bytes = env()->NewByteArray(value.length());
   70            if (!bytes) {
   71                return nullptr;
   72            }
   73
   74            env()->SetByteArrayRegion(bytes, 0, value.length(), reinterpret_cast<const jbyte*>(value.data()));
   75
   76            static jmethodID stringConstructor = env()->GetMethodID(stringClass(), "<init>", "([BLjava/lang/String;)V");
   77            auto str = env()->NewObject(stringClass(), stringConstructor, bytes, env()->NewStringUTF("UTF-8"));
   78            env()->DeleteLocalRef(bytes);
   79            return static_cast<jstring>(str);
   80        }
   81
   82    private:
   83        static jclass stringClass() {
   84            static GlobalRef ref = jni::env()->FindClass("java/lang/String");
   85            return ref.asClass();
   86        }
   87    };
   88
   89    template <>
   90    struct Converter<AString>: public Converter<std::string> {
   91        static constexpr auto signature = "Ljava/lang/String;"_asl;
   92
   93        static jstring toJni(const AString& value) {
   94            return Converter<std::string>::toJni(value.toStdString());
   95        }
   96    };
   97
   98    template<typename T, char sign>
   99    struct ConverterPrimitive {
  100        static constexpr AStringLiteral<sign> signature;
  101
  102        static constexpr T toJni(T t) noexcept {
  103            return t;
  104        }
  105
  106        static constexpr T fromJni(T t) noexcept {
  107            return t;
  108        }
  109    };
  110
  111    template<> struct Converter<jboolean>: ConverterPrimitive<jboolean, 'Z'> {};
  112    template<> struct Converter<jbyte   >: ConverterPrimitive<jbyte   , 'B'> {};
  113    template<> struct Converter<jchar   >: ConverterPrimitive<jchar   , 'C'> {};
  114    template<> struct Converter<jshort  >: ConverterPrimitive<jshort  , 'S'> {};
  115    template<> struct Converter<jint    >: ConverterPrimitive<jint    , 'I'> {};
  116    template<> struct Converter<jlong   >: ConverterPrimitive<jlong   , 'J'> {};
  117    template<> struct Converter<jfloat  >: ConverterPrimitive<jfloat  , 'F'> {};
  118    template<> struct Converter<jdouble >: ConverterPrimitive<jdouble , 'D'> {};
  119
  120    template<> struct Converter<bool>: Converter<jboolean> {};
  121    template<> struct Converter<void    > {
  122        static constexpr AStringLiteral<'V'> signature;
  123
  124        static constexpr void fromJni() noexcept {
  125
  126        }
  127    };
  128
  129
  130    template<typename T>
  131    concept ExposableClass = requires(T&& t) {
  132        { T::JAVA_CLASS_NAME } -> ::aui::convertible_to<const char*>;
  133    };
  134
  135    template<ExposableClass T> struct Converter<T> {
  136        static constexpr auto signature = "L"_asl + T::JAVA_CLASS_NAME + ";"_asl;
  137
  138        static T fromJni(jobject val) {
  139            T t;
  140            GlobalRef::assignLocalRef(t, val);
  141            return t;
  142        }
  143
  144        static jobject toJni(const T& value) {
  145            return value.asObject();
  146        }
  147
  148    };
  149}
Represents a Unicode character string.
Definition AString.h:38
Global ref.
Definition GlobalRef.h:23
Definition Converter.h:131
Definition Converter.h:33
Definition Converter.h:25
JNIEnv * env()
Definition Globals.h:38
Compile-time string literal.
Definition AStringLiteral.h:21
Definition Converter.h:99
Definition Converter.h:21