AUI Framework  develop
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-2024 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*>;
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>
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:37
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