Commit 6b7d7835 authored by Steven Kabbes's avatar Steven Kabbes

Pass primitive types by value

* enum
* bool
* i8
* i16
* i32
* i64
* f64
and optional<T> for all T of above
parent b08c54a0
......@@ -13,6 +13,7 @@
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
......@@ -37,25 +38,43 @@
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
</content>
<content url="file://$MODULE_DIR$/../../generated-src/java">
......
......@@ -8,14 +8,28 @@
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sort"
android:id="@+id/button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="sort" />
android:id="@+id/actions">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sort"
android:onClick="sortAsc" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reverse Sort"
android:onClick="sortDesc" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Random"
android:onClick="sortRandom" />
</LinearLayout>
<EditText
android:layout_width="wrap_content"
......@@ -26,7 +40,7 @@
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="@+id/button"
android:layout_above="@+id/actions"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:text="Type some text here"
......
item_list = record {
items: list<string>;
items: list<string>;
}
sort_order = enum {
ascending;
descending;
random;
}
sort_items = interface +c {
sort(items: item_list);
static create_with_listener(listener: textbox_listener): sort_items;
sort(order: sort_order, items: item_list);
static create_with_listener(listener: textbox_listener): sort_items;
}
textbox_listener = interface +j +o {
update(items: item_list);
update(items: item_list);
}
......@@ -4,6 +4,7 @@
#pragma once
#include "item_list.hpp"
#include "sort_order.hpp"
#include <memory>
namespace textsort {
......@@ -14,7 +15,7 @@ class SortItems {
public:
virtual ~SortItems() {}
virtual void sort(const ItemList & items) = 0;
virtual void sort(sort_order order, const ItemList & items) = 0;
static std::shared_ptr<SortItems> create_with_listener(const std::shared_ptr<TextboxListener> & listener);
};
......
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from example.djinni
#pragma once
#include <functional>
namespace textsort {
enum class sort_order : int {
ASCENDING,
DESCENDING,
RANDOM,
};
} // namespace textsort
namespace std {
template <>
struct hash<::textsort::sort_order> {
size_t operator()(::textsort::sort_order type) const {
return std::hash<int>()(static_cast<int>(type));
}
};
} // namespace std
......@@ -6,7 +6,7 @@ package com.dropbox.textsort;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class SortItems {
public abstract void sort(ItemList items);
public abstract void sort(SortOrder order, ItemList items);
public static native SortItems createWithListener(TextboxListener listener);
......@@ -34,11 +34,11 @@ public abstract class SortItems {
}
@Override
public void sort(ItemList items)
public void sort(SortOrder order, ItemList items)
{
assert !this.destroyed.get() : "trying to use a destroyed object";
native_sort(this.nativeRef, items);
native_sort(this.nativeRef, order, items);
}
private native void native_sort(long _nativeRef, ItemList items);
private native void native_sort(long _nativeRef, SortOrder order, ItemList items);
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from example.djinni
package com.dropbox.textsort;
public enum SortOrder {
ASCENDING,
DESCENDING,
RANDOM,
;
}
......@@ -4,6 +4,7 @@
#include "NativeSortItems.hpp" // my header
#include "NativeItemList.hpp"
#include "NativeSortItems.hpp"
#include "NativeSortOrder.hpp"
#include "NativeTextboxListener.hpp"
namespace djinni_generated {
......@@ -20,14 +21,15 @@ CJNIEXPORT void JNICALL Java_com_dropbox_textsort_SortItems_00024CppProxy_native
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, )
}
CJNIEXPORT void JNICALL Java_com_dropbox_textsort_SortItems_00024CppProxy_native_1sort(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_items)
CJNIEXPORT void JNICALL Java_com_dropbox_textsort_SortItems_00024CppProxy_native_1sort(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_order, jobject j_items)
{
try {
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
const std::shared_ptr<::textsort::SortItems> & ref = djinni::CppProxyHandle<::textsort::SortItems>::get(nativeRef);
::textsort::sort_order c_order = NativeSortOrder::fromJava(jniEnv, j_order);
::textsort::ItemList c_items = NativeItemList::fromJava(jniEnv, j_items);
ref->sort(c_items);
ref->sort(c_order, c_items);
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, )
}
......
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from example.djinni
#pragma once
#include "djinni_support.hpp"
#include "sort_order.hpp"
namespace djinni_generated {
class NativeSortOrder final : djinni::JniEnum {
public:
using CppType = ::textsort::sort_order;
using JniType = jobject;
static jobject toJava(JNIEnv* jniEnv, ::textsort::sort_order c) { return djinni::JniClass<NativeSortOrder>::get().create(jniEnv, static_cast<int>(c)).release(); }
static ::textsort::sort_order fromJava(JNIEnv* jniEnv, jobject j) { return static_cast<::textsort::sort_order>(djinni::JniClass<NativeSortOrder>::get().ordinal(jniEnv, j)); }
private:
NativeSortOrder() : JniEnum("com/dropbox/textsort/SortOrder") {}
friend class djinni::JniClass<NativeSortOrder>;
};
} // namespace djinni_generated
......@@ -2,6 +2,7 @@
// This file generated by Djinni from example.djinni
#import "TXSSortItems.h"
#import "TXSSortOrder.h"
#import "TXSTextboxListener.h"
#import <Foundation/Foundation.h>
@class TXSItemList;
......@@ -9,7 +10,7 @@
@protocol TXSSortItems
- (void)sort:(TXSItemList *)items;
- (void)sort:(TXSSortOrder)order items:(TXSItemList *)items;
+ (id <TXSSortItems>)createWithListener:(id <TXSTextboxListener>)listener;
......
......@@ -6,6 +6,8 @@
#import "TXSItemList+Private.h"
#import "TXSSortItems.h"
#import "TXSSortItemsCppProxy+Private.h"
#import "TXSSortOrder.h"
#import "TXSSortOrderTranslator+Private.h"
#import "TXSTextboxListenerObjcProxy+Private.h"
#include <exception>
#include <utility>
......@@ -34,10 +36,11 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
return cache.get(cppRef, [] (const std::shared_ptr<::textsort::SortItems> & p) { return [[TXSSortItemsCppProxy alloc] initWithCpp:p]; });
}
- (void)sort:(TXSItemList *)items {
- (void)sort:(TXSSortOrder)order items:(TXSItemList *)items {
try {
::textsort::sort_order cppOrder = [TXSSortOrderTranslator objcSortOrderToCppSortOrder:order];
::textsort::ItemList cppItems = std::move([items cppItemList]);
_cppRef->sort(std::move(cppItems));
_cppRef->sort(std::move(cppOrder), std::move(cppItems));
} DJINNI_TRANSLATE_EXCEPTIONS()
}
......
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from example.djinni
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, TXSSortOrder)
{
TXSSortOrderAscending,
TXSSortOrderDescending,
TXSSortOrderRandom,
TXSSortOrderCount,
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from example.djinni
#import "TXSSortOrder.h"
#include "sort_order.hpp"
#import <Foundation/Foundation.h>
@interface TXSSortOrderTranslator : NSObject
+ (TXSSortOrder)cppSortOrderToObjcSortOrder:(::textsort::sort_order)sortOrder;
+ (::textsort::sort_order)objcSortOrderToCppSortOrder:(TXSSortOrder)sortOrder;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from example.djinni
#import "TXSSortOrderTranslator+Private.h"
#import <Foundation/Foundation.h>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@implementation TXSSortOrderTranslator
+ (TXSSortOrder)cppSortOrderToObjcSortOrder:(::textsort::sort_order)sortOrder
{
return static_cast<TXSSortOrder>(sortOrder);
}
+ (::textsort::sort_order)objcSortOrderToCppSortOrder:(TXSSortOrder)sortOrder
{
return static_cast<enum ::textsort::sort_order>(sortOrder);
}
@end
#include "sort_items_impl.hpp"
#include <algorithm>
#include <random>
namespace textsort {
......@@ -11,12 +12,25 @@ SortItemsImpl::SortItemsImpl (const std::shared_ptr<TextboxListener> & listener)
this->m_listener = listener;
}
void SortItemsImpl::sort (const ItemList & items) {
auto list = items.items;
std::sort(list.begin(), list.end());
void SortItemsImpl::sort(sort_order order, const ItemList & items) {
auto lines = items.items;
switch (order) {
case sort_order::ASCENDING: {
std::sort(lines.begin(), lines.end(), std::less<std::string>());
break;
}
case sort_order::DESCENDING: {
std::sort(lines.begin(), lines.end(), std::greater<std::string>());
break;
}
case sort_order::RANDOM: {
std::shuffle(lines.begin(), lines.end(), std::default_random_engine{});
break;
}
}
// Pass result to client interface
this->m_listener->update(ItemList(list));
this->m_listener->update(ItemList(lines));
}
}
......@@ -8,8 +8,8 @@ namespace textsort {
class SortItemsImpl : public SortItems {
public:
SortItemsImpl (const std::shared_ptr<TextboxListener> & listener);
virtual void sort (const ItemList & items) override;
SortItemsImpl(const std::shared_ptr<TextboxListener> & listener);
virtual void sort(sort_order order, const ItemList & items) override;
private:
std::shared_ptr<TextboxListener> m_listener;
......
......@@ -30,11 +30,22 @@ public class MainActivity extends Activity {
sortItemsInterface = SortItems.createWithListener(textboxListener);
}
public void sort(View view) {
public void sort(SortOrder order) {
String str = text.getText().toString();
ArrayList<String> items = new ArrayList<String>(Arrays.asList(str.split("\n")));
ItemList itemList = new ItemList(items);
sortItemsInterface.sort(itemList);
sortItemsInterface.sort(order, itemList);
}
public void sortAsc(View view) {
this.sort(SortOrder.ASCENDING);
}
public void sortDesc(View view) {
this.sort(SortOrder.DESCENDING);
}
public void sortRandom(View view) {
this.sort(SortOrder.RANDOM);
}
}
......@@ -43,7 +43,7 @@
NSString *str = self.textView.text;
NSMutableArray *strList = [NSMutableArray arrayWithArray:[str componentsSeparatedByString:@"\n"]];
TXSItemList *list = [[TXSItemList alloc] initWithItems:strList];
[_sortItemInterface sort:list];
[_sortItemInterface sort:TXSSortOrderAscending items:list];
}
- (void)dismissKeyboard
......
......@@ -314,7 +314,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
w.wl
writeDoc(w, m.doc)
val ret = m.ret.fold("void")(toCppType(_))
val params = m.params.map(p => "const " + toCppType(p.ty) + " & " + idCpp.local(p.ident))
val params = m.params.map(toCppParamType)
if (m.static) {
w.wl(s"static $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")};")
} else {
......
......@@ -210,7 +210,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w.wl(s"JavaProxy(jobject obj);")
for (m <- i.methods) {
val ret = m.ret.fold("void")(toCppType(_, spec.cppNamespace))
val params = m.params.map(p => "const " + toCppType(p.ty, spec.cppNamespace) + " & " + idCpp.local(p.ident))
val params = m.params.map(p => toCppParamType(p, spec.cppNamespace))
w.wl(s"virtual $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")} override;")
}
w.wl
......@@ -239,7 +239,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
for (m <- i.methods) {
w.wl
val ret = m.ret.fold("void")(toCppType(_, spec.cppNamespace))
val params = m.params.map(p => "const " + toCppType(p.ty, spec.cppNamespace) + " & c_" + idCpp.local(p.ident))
val params = m.params.map(p => toCppParamType(p, spec.cppNamespace, "c_"))
writeJniTypeParams(w, typeParams)
w.w(s"$ret $jniClassName::JavaProxy::JavaProxy::${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}").bracedSemi {
w.wl(s"JNIEnv * const jniEnv = djinni::jniGetThreadEnv();")
......
......@@ -320,7 +320,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
w.wl(s"static std::shared_ptr<${withNs(spec.cppNamespace, idCpp.ty(ident.name))}> ${idCpp.method(ident.name + "_with_objc")} (id objcRef);")
for (m <- i.methods) {
val ret = m.ret.fold("void")(toCppType(_))
val params = m.params.map(p => "const " + toCppType(p.ty, spec.cppNamespace) + " & " + idCpp.local(p.ident))
val params = m.params.map(p => toCppParamType(p, spec.cppNamespace))
w.wl(s"virtual $ret ${idCpp.method(m.ident)} ${params.mkString("(", ", ", ")")} override;")
}
w.wl
......@@ -349,7 +349,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
for (m <- i.methods) {
w.wl
val ret = m.ret.fold("void")(toCppType(_))
val params = m.params.map(p => "const " + toCppType(p.ty, spec.cppNamespace) + " & " + idCpp.local(p.ident))
val params = m.params.map(p => toCppParamType(p, spec.cppNamespace))
w.wl(s"$ret $objcExtSelf::${idCpp.method(m.ident)} ${params.mkString("(", ", ", ")")}").braced {
w.w("@autoreleasepool").braced {
m.params.foreach(p =>
......
......@@ -238,7 +238,7 @@ abstract class Generator(spec: Spec)
w.wl
}
f(w)
}
}
)
f2(w)
})
......@@ -301,6 +301,26 @@ abstract class Generator(spec: Spec)
expr(tm)
}
// this can be used in c++ generation to know whether a const& should be applied to the parameter or not
def toCppParamType(f: Field): String = toCppParamType(f, None, "")
def toCppParamType(f: Field, namespace: Option[String] = None, prefix: String = ""): String = {
val cppType = toCppType(f.ty, namespace)
val localName = prefix + idCpp.local(f.ident);
val refType = "const " + cppType + " & " + localName
val valueType = cppType + " " + localName
def toType(expr: MExpr): String = expr.base match {
case MPrimitive(_,_,_,_,_,_,_,_) => valueType
case d: MDef => d.defType match {
case DEnum => valueType
case _ => refType
}
case MOptional => toType(expr.args.head)
case _ => refType
}
toType(f.ty.resolved)
}
def withNs(namespace: Option[String], t: String) = namespace.fold(t)("::"+_+"::"+t)
def withPackage(packageName: Option[String], t: String) = packageName.fold(t)(_+"."+t)
......
client_returned_record = record {
record_id: i64;
content: string;
}
client_interface = interface +j +o {
# Returns record of given string
get_record(utf8string: string): client_returned_record;
get_record(record_id: i64, utf8string: string): client_returned_record;
}
......@@ -4,6 +4,7 @@
#pragma once
#include "client_returned_record.hpp"
#include <cstdint>
#include <string>
class ClientInterface {
......@@ -11,5 +12,5 @@ public:
virtual ~ClientInterface() {}
/** Returns record of given string */
virtual ClientReturnedRecord get_record(const std::string & utf8string) = 0;
virtual ClientReturnedRecord get_record(int64_t record_id, const std::string & utf8string) = 0;
};
......@@ -3,16 +3,21 @@
#pragma once
#include <cstdint>
#include <string>
#include <utility>
struct ClientReturnedRecord final {
int64_t record_id;
std::string content;
ClientReturnedRecord(
int64_t record_id,
std::string content) :
record_id(std::move(record_id)),
content(std::move(content)) {
}
};
......@@ -5,5 +5,5 @@ package com.dropbox.djinni.test;
public abstract class ClientInterface {
/** Returns record of given string */
public abstract ClientReturnedRecord getRecord(String utf8string);
public abstract ClientReturnedRecord getRecord(long recordId, String utf8string);
}
......@@ -6,13 +6,21 @@ package com.dropbox.djinni.test;
public final class ClientReturnedRecord {
/*package*/ final long mRecordId;
/*package*/ final String mContent;
public ClientReturnedRecord(
long recordId,
String content) {
this.mRecordId = recordId;
this.mContent = content;
}
public long getRecordId() {
return mRecordId;
}
public String getContent() {
return mContent;
}
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from client_interface.djinni
#include "NativeClientInterface.hpp" // my header
#include "HI64.hpp"
#include "HString.hpp"
#include "NativeClientReturnedRecord.hpp"
......@@ -11,12 +12,13 @@ NativeClientInterface::NativeClientInterface() : djinni::JniInterface<ClientInte
NativeClientInterface::JavaProxy::JavaProxy(jobject obj) : JavaProxyCacheEntry(obj) {}
ClientReturnedRecord NativeClientInterface::JavaProxy::JavaProxy::get_record(const std::string & c_utf8string) {
ClientReturnedRecord NativeClientInterface::JavaProxy::JavaProxy::get_record(int64_t c_record_id, const std::string & c_utf8string) {
JNIEnv * const jniEnv = djinni::jniGetThreadEnv();
djinni::JniLocalScope jscope(jniEnv, 10);
jlong j_record_id = ::djinni::HI64::Unboxed::toJava(jniEnv, c_record_id);
djinni::LocalRef<jstring> j_utf8string(jniEnv, ::djinni::HString::toJava(jniEnv, c_utf8string));
const auto & data = djinni::JniClass<::djinni_generated::NativeClientInterface>::get();
djinni::LocalRef<jobject> jret(jniEnv, jniEnv->CallObjectMethod(getGlobalRef(), data.method_getRecord, j_utf8string.get()));
djinni::LocalRef<jobject> jret(jniEnv, jniEnv->CallObjectMethod(getGlobalRef(), data.method_getRecord, j_record_id, j_utf8string.get()));
djinni::jniExceptionCheck(jniEnv);
return NativeClientReturnedRecord::fromJava(jniEnv, jret.get());
};
......
......@@ -17,12 +17,12 @@ public:
static std::shared_ptr<ClientInterface> fromJava(JNIEnv* jniEnv, jobject j) { return djinni::JniClass<::djinni_generated::NativeClientInterface>::get()._fromJava(jniEnv, j); }
const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass("com/dropbox/djinni/test/ClientInterface") };
const jmethodID method_getRecord { djinni::jniGetMethodID(clazz.get(), "getRecord", "(Ljava/lang/String;)Lcom/dropbox/djinni/test/ClientReturnedRecord;") };
const jmethodID method_getRecord { djinni::jniGetMethodID(clazz.get(), "getRecord", "(JLjava/lang/String;)Lcom/dropbox/djinni/test/ClientReturnedRecord;") };
class JavaProxy final : djinni::JavaProxyCacheEntry, public ClientInterface {
public:
JavaProxy(jobject obj);
virtual ClientReturnedRecord get_record(const std::string & utf8string) override;
virtual ClientReturnedRecord get_record(int64_t record_id, const std::string & utf8string) override;
private:
using djinni::JavaProxyCacheEntry::getGlobalRef;
......
......@@ -2,14 +2,16 @@
// This file generated by Djinni from client_interface.djinni
#include "NativeClientReturnedRecord.hpp" // my header
#include "HI64.hpp"
#include "HString.hpp"
namespace djinni_generated {
jobject NativeClientReturnedRecord::toJava(JNIEnv* jniEnv, ClientReturnedRecord c) {
jlong j_record_id = ::djinni::HI64::Unboxed::toJava(jniEnv, c.record_id);
djinni::LocalRef<jstring> j_content(jniEnv, ::djinni::HString::toJava(jniEnv, c.content));
const auto & data = djinni::JniClass<::djinni_generated::NativeClientReturnedRecord>::get();
jobject r = jniEnv->NewObject(data.clazz.get(), data.jconstructor, j_content.get());
jobject r = jniEnv->NewObject(data.clazz.get(), data.jconstructor, j_record_id, j_content.get());
djinni::jniExceptionCheck(jniEnv);
return r;
}
......@@ -18,6 +20,7 @@ ClientReturnedRecord NativeClientReturnedRecord::fromJava(JNIEnv* jniEnv, jobjec
assert(j != nullptr);
const auto & data = djinni::JniClass<::djinni_generated::NativeClientReturnedRecord>::get();
return ClientReturnedRecord(
::djinni::HI64::Unboxed::fromJava(jniEnv, jniEnv->GetLongField(j, data.field_mRecordId)),
::djinni::HString::fromJava(jniEnv, djinni::LocalRef<jstring>(jniEnv, static_cast<jstring>(jniEnv->GetObjectField(j, data.field_mContent))).get()));
}
......
......@@ -17,7 +17,8 @@ public:
static ClientReturnedRecord fromJava(JNIEnv*, jobject);
const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass("com/dropbox/djinni/test/ClientReturnedRecord") };
const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/lang/String;)V") };
const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), "<init>", "(JLjava/lang/String;)V") };
const jfieldID field_mRecordId { djinni::jniGetFieldID(clazz.get(), "mRecordId", "J") };
const jfieldID field_mContent { djinni::jniGetFieldID(clazz.get(), "mContent", "Ljava/lang/String;") };
private:
......
......@@ -8,6 +8,6 @@
@protocol DBClientInterface
/** Returns record of given string */
- (DBClientReturnedRecord *)getRecord:(NSString *)utf8string;
- (DBClientReturnedRecord *)getRecord:(int64_t)recordId utf8string:(NSString *)utf8string;
@end
......@@ -16,7 +16,7 @@ namespace djinni_generated
ClientInterfaceObjcProxy (id objcRef);
virtual ~ClientInterfaceObjcProxy () override;
static std::shared_ptr<ClientInterface> client_interface_with_objc (id objcRef);
virtual ClientReturnedRecord get_record (const std::string & utf8string) override;
virtual ClientReturnedRecord get_record (int64_t record_id, const std::string & utf8string) override;
private:
ClientInterfaceObjcProxy () {};
......
......@@ -25,13 +25,14 @@ namespace djinni_generated
return static_cast<std::shared_ptr<ClientInterface>>(cache.get(objcRef));
}
ClientReturnedRecord ClientInterfaceObjcProxy::get_record (const std::string & utf8string)
ClientReturnedRecord ClientInterfaceObjcProxy::get_record (int64_t record_id, const std::string & utf8string)
{
@autoreleasepool {
int64_t cpp_record_id = record_id;
NSString *cpp_utf8string = [[NSString alloc] initWithBytes:utf8string.data()
length:utf8string.length()
encoding:NSUTF8StringEncoding];
DBClientReturnedRecord *objcRet = [objcRef getRecord:cpp_utf8string];
DBClientReturnedRecord *objcRet = [objcRef getRecord:cpp_record_id utf8string:cpp_utf8string];
ClientReturnedRecord cppRet = std::move([objcRet cppClientReturnedRecord]);
return cppRet;
}
......
......@@ -6,7 +6,9 @@
@interface DBClientReturnedRecord : NSObject
- (id)initWithClientReturnedRecord:(DBClientReturnedRecord *)clientReturnedRecord;
- (id)initWithContent:(NSString *)content;
- (id)initWithRecordId:(int64_t)recordId content:(NSString *)content;
@property (nonatomic, readonly) int64_t recordId;
@property (nonatomic, readonly) NSString *content;
......
......@@ -12,14 +12,16 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
- (id)initWithClientReturnedRecord:(DBClientReturnedRecord *)clientReturnedRecord
{
if (self = [super init]) {
_recordId = clientReturnedRecord.recordId;
_content = [clientReturnedRecord.content copy];
}
return self;
}
- (id)initWithContent:(NSString *)content
- (id)initWithRecordId:(int64_t)recordId content:(NSString *)content
{
if (self = [super init]) {
_recordId = recordId;
_content = [content copy];
}
return self;
......@@ -28,6 +30,7 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
- (id)initWithCppClientReturnedRecord:(const ClientReturnedRecord &)clientReturnedRecord
{
if (self = [super init]) {
_recordId = clientReturnedRecord.record_id;
_content = [[NSString alloc] initWithBytes:clientReturnedRecord.content.data()
length:clientReturnedRecord.content.length()
encoding:NSUTF8StringEncoding];
......@@ -37,8 +40,10 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
- (ClientReturnedRecord)cppClientReturnedRecord
{
int64_t recordId = _recordId;
std::string content([_content UTF8String], [_content lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ClientReturnedRecord(
std::move(recordId),
std::move(content));
}
......
......@@ -71,7 +71,7 @@ static const std::string HELLO_WORLD = "Hello World!";
static const std::string NON_ASCII = "Non-ASCII / 非 ASCII 字符";
void TestHelpers::check_client_interface_ascii(const std::shared_ptr<ClientInterface> & i) {
ClientReturnedRecord cReturnedRecord = i->get_record(HELLO_WORLD);
ClientReturnedRecord cReturnedRecord = i->get_record(5, HELLO_WORLD);
if (cReturnedRecord.content != HELLO_WORLD) {
std::string error_msg = "Expected String: " + HELLO_WORLD + " Actual: " + cReturnedRecord.content;
throw std::invalid_argument(error_msg);
......@@ -79,7 +79,7 @@ void TestHelpers::check_client_interface_ascii(const std::shared_ptr<ClientInter
}
void TestHelpers::check_client_interface_nonascii(const std::shared_ptr<ClientInterface> & i) {
ClientReturnedRecord cReturnedRecord = i->get_record(NON_ASCII);
ClientReturnedRecord cReturnedRecord = i->get_record(5, NON_ASCII);
if (cReturnedRecord.content != NON_ASCII) {
std::string error_msg = "Expected String: " + NON_ASCII + " Actual: " + cReturnedRecord.content;
throw std::invalid_argument(error_msg);
......
......@@ -4,10 +4,10 @@ import static junit.framework.Assert.assertTrue;
public class ClientInterfaceImpl extends ClientInterface {
@Override
public ClientReturnedRecord getRecord(String utf8string) {
public ClientReturnedRecord getRecord(long id, String utf8string) {
if (!utf8string.equals("Non-ASCII / 非 ASCII 字符") && !utf8string.equals("Hello World!")) {
throw new RuntimeException("Unexpected string. Check UTF-8?");
}
return new ClientReturnedRecord(utf8string);
return new ClientReturnedRecord(id, utf8string);
}
}
......@@ -6,10 +6,10 @@ static NSString *DBNonAscii = @"Non-ASCII / 非 ASCII 字符";
@implementation DBClientInterfaceImpl
- (DBClientReturnedRecord *)getRecord:(NSString *)utf8string
- (DBClientReturnedRecord *)getRecord:(int64_t)ident utf8string:(NSString *)utf8string
{
NSAssert([utf8string isEqualToString:DBHelloWorld] || [utf8string isEqualToString:DBNonAscii], @"Unexpected String");
return [[DBClientReturnedRecord alloc] initWithContent:utf8string];
return [[DBClientReturnedRecord alloc] initWithRecordId:ident content:utf8string];
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment