Commit d1153188 authored by j4cbo's avatar j4cbo

Merge pull request #35 from skabbes/fix/pass_by_val_3

Pass primitive types by value
parents 87772958 6b7d7835
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" /> <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" /> <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" /> <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="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
...@@ -37,25 +38,43 @@ ...@@ -37,25 +38,43 @@
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" /> <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/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" 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/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/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" 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/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> <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/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/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" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" 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/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" 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/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/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" 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" /> <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
</content> </content>
<content url="file://$MODULE_DIR$/../../generated-src/java"> <content url="file://$MODULE_DIR$/../../generated-src/java">
......
...@@ -8,14 +8,28 @@ ...@@ -8,14 +8,28 @@
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"> tools:context=".MainActivity">
<Button <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Sort"
android:id="@+id/button"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_centerHorizontal="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 <EditText
android:layout_width="wrap_content" android:layout_width="wrap_content"
...@@ -26,7 +40,7 @@ ...@@ -26,7 +40,7 @@
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_above="@+id/button" android:layout_above="@+id/actions"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:text="Type some text here" android:text="Type some text here"
......
item_list = record { item_list = record {
items: list<string>; items: list<string>;
}
sort_order = enum {
ascending;
descending;
random;
} }
sort_items = interface +c { sort_items = interface +c {
sort(items: item_list); sort(order: sort_order, items: item_list);
static create_with_listener(listener: textbox_listener): sort_items; static create_with_listener(listener: textbox_listener): sort_items;
} }
textbox_listener = interface +j +o { textbox_listener = interface +j +o {
update(items: item_list); update(items: item_list);
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "item_list.hpp" #include "item_list.hpp"
#include "sort_order.hpp"
#include <memory> #include <memory>
namespace textsort { namespace textsort {
...@@ -14,7 +15,7 @@ class SortItems { ...@@ -14,7 +15,7 @@ class SortItems {
public: public:
virtual ~SortItems() {} 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); 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; ...@@ -6,7 +6,7 @@ package com.dropbox.textsort;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public abstract class SortItems { 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); public static native SortItems createWithListener(TextboxListener listener);
...@@ -34,11 +34,11 @@ public abstract class SortItems { ...@@ -34,11 +34,11 @@ public abstract class SortItems {
} }
@Override @Override
public void sort(ItemList items) public void sort(SortOrder order, ItemList items)
{ {
assert !this.destroyed.get() : "trying to use a destroyed object"; 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 @@ ...@@ -4,6 +4,7 @@
#include "NativeSortItems.hpp" // my header #include "NativeSortItems.hpp" // my header
#include "NativeItemList.hpp" #include "NativeItemList.hpp"
#include "NativeSortItems.hpp" #include "NativeSortItems.hpp"
#include "NativeSortOrder.hpp"
#include "NativeTextboxListener.hpp" #include "NativeTextboxListener.hpp"
namespace djinni_generated { namespace djinni_generated {
...@@ -20,14 +21,15 @@ CJNIEXPORT void JNICALL Java_com_dropbox_textsort_SortItems_00024CppProxy_native ...@@ -20,14 +21,15 @@ CJNIEXPORT void JNICALL Java_com_dropbox_textsort_SortItems_00024CppProxy_native
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) } 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 { try {
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
const std::shared_ptr<::textsort::SortItems> & ref = djinni::CppProxyHandle<::textsort::SortItems>::get(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); ::textsort::ItemList c_items = NativeItemList::fromJava(jniEnv, j_items);
ref->sort(c_items); ref->sort(c_order, c_items);
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) } 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 @@ ...@@ -2,6 +2,7 @@
// This file generated by Djinni from example.djinni // This file generated by Djinni from example.djinni
#import "TXSSortItems.h" #import "TXSSortItems.h"
#import "TXSSortOrder.h"
#import "TXSTextboxListener.h" #import "TXSTextboxListener.h"
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class TXSItemList; @class TXSItemList;
...@@ -9,7 +10,7 @@ ...@@ -9,7 +10,7 @@
@protocol TXSSortItems @protocol TXSSortItems
- (void)sort:(TXSItemList *)items; - (void)sort:(TXSSortOrder)order items:(TXSItemList *)items;
+ (id <TXSSortItems>)createWithListener:(id <TXSTextboxListener>)listener; + (id <TXSSortItems>)createWithListener:(id <TXSTextboxListener>)listener;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#import "TXSItemList+Private.h" #import "TXSItemList+Private.h"
#import "TXSSortItems.h" #import "TXSSortItems.h"
#import "TXSSortItemsCppProxy+Private.h" #import "TXSSortItemsCppProxy+Private.h"
#import "TXSSortOrder.h"
#import "TXSSortOrderTranslator+Private.h"
#import "TXSTextboxListenerObjcProxy+Private.h" #import "TXSTextboxListenerObjcProxy+Private.h"
#include <exception> #include <exception>
#include <utility> #include <utility>
...@@ -34,10 +36,11 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th ...@@ -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]; }); 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 { try {
::textsort::sort_order cppOrder = [TXSSortOrderTranslator objcSortOrderToCppSortOrder:order];
::textsort::ItemList cppItems = std::move([items cppItemList]); ::textsort::ItemList cppItems = std::move([items cppItemList]);
_cppRef->sort(std::move(cppItems)); _cppRef->sort(std::move(cppOrder), std::move(cppItems));
} DJINNI_TRANSLATE_EXCEPTIONS() } 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 "sort_items_impl.hpp"
#include <algorithm> #include <algorithm>
#include <random>
namespace textsort { namespace textsort {
...@@ -11,12 +12,25 @@ SortItemsImpl::SortItemsImpl (const std::shared_ptr<TextboxListener> & listener) ...@@ -11,12 +12,25 @@ SortItemsImpl::SortItemsImpl (const std::shared_ptr<TextboxListener> & listener)
this->m_listener = listener; this->m_listener = listener;
} }
void SortItemsImpl::sort (const ItemList & items) { void SortItemsImpl::sort(sort_order order, const ItemList & items) {
auto list = items.items; auto lines = items.items;
std::sort(list.begin(), list.end()); 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 // Pass result to client interface
this->m_listener->update(ItemList(list)); this->m_listener->update(ItemList(lines));
} }
} }
...@@ -8,8 +8,8 @@ namespace textsort { ...@@ -8,8 +8,8 @@ namespace textsort {
class SortItemsImpl : public SortItems { class SortItemsImpl : public SortItems {
public: public:
SortItemsImpl (const std::shared_ptr<TextboxListener> & listener); SortItemsImpl(const std::shared_ptr<TextboxListener> & listener);
virtual void sort (const ItemList & items) override; virtual void sort(sort_order order, const ItemList & items) override;
private: private:
std::shared_ptr<TextboxListener> m_listener; std::shared_ptr<TextboxListener> m_listener;
......
...@@ -30,11 +30,22 @@ public class MainActivity extends Activity { ...@@ -30,11 +30,22 @@ public class MainActivity extends Activity {
sortItemsInterface = SortItems.createWithListener(textboxListener); sortItemsInterface = SortItems.createWithListener(textboxListener);
} }
public void sort(View view) { public void sort(SortOrder order) {
String str = text.getText().toString(); String str = text.getText().toString();
ArrayList<String> items = new ArrayList<String>(Arrays.asList(str.split("\n"))); ArrayList<String> items = new ArrayList<String>(Arrays.asList(str.split("\n")));
ItemList itemList = new ItemList(items); 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 @@ ...@@ -43,7 +43,7 @@
NSString *str = self.textView.text; NSString *str = self.textView.text;
NSMutableArray *strList = [NSMutableArray arrayWithArray:[str componentsSeparatedByString:@"\n"]]; NSMutableArray *strList = [NSMutableArray arrayWithArray:[str componentsSeparatedByString:@"\n"]];
TXSItemList *list = [[TXSItemList alloc] initWithItems:strList]; TXSItemList *list = [[TXSItemList alloc] initWithItems:strList];
[_sortItemInterface sort:list]; [_sortItemInterface sort:TXSSortOrderAscending items:list];
} }
- (void)dismissKeyboard - (void)dismissKeyboard
......
...@@ -314,7 +314,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { ...@@ -314,7 +314,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
w.wl w.wl
writeDoc(w, m.doc) writeDoc(w, m.doc)
val ret = m.ret.fold("void")(toCppType(_)) 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) { if (m.static) {
w.wl(s"static $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")};") w.wl(s"static $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")};")
} else { } else {
......
...@@ -210,7 +210,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { ...@@ -210,7 +210,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w.wl(s"JavaProxy(jobject obj);") w.wl(s"JavaProxy(jobject obj);")
for (m <- i.methods) { for (m <- i.methods) {
val ret = m.ret.fold("void")(toCppType(_, spec.cppNamespace)) 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(s"virtual $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")} override;")
} }
w.wl w.wl
...@@ -239,7 +239,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { ...@@ -239,7 +239,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
for (m <- i.methods) { for (m <- i.methods) {
w.wl w.wl
val ret = m.ret.fold("void")(toCppType(_, spec.cppNamespace)) 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) writeJniTypeParams(w, typeParams)
w.w(s"$ret $jniClassName::JavaProxy::JavaProxy::${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}").bracedSemi { w.w(s"$ret $jniClassName::JavaProxy::JavaProxy::${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}").bracedSemi {
w.wl(s"JNIEnv * const jniEnv = djinni::jniGetThreadEnv();") w.wl(s"JNIEnv * const jniEnv = djinni::jniGetThreadEnv();")
......
...@@ -320,7 +320,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) { ...@@ -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);") 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) { for (m <- i.methods) {
val ret = m.ret.fold("void")(toCppType(_)) 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(s"virtual $ret ${idCpp.method(m.ident)} ${params.mkString("(", ", ", ")")} override;")
} }
w.wl w.wl
...@@ -349,7 +349,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) { ...@@ -349,7 +349,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
for (m <- i.methods) { for (m <- i.methods) {
w.wl w.wl
val ret = m.ret.fold("void")(toCppType(_)) 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.wl(s"$ret $objcExtSelf::${idCpp.method(m.ident)} ${params.mkString("(", ", ", ")")}").braced {
w.w("@autoreleasepool").braced { w.w("@autoreleasepool").braced {
m.params.foreach(p => m.params.foreach(p =>
......
...@@ -238,7 +238,7 @@ abstract class Generator(spec: Spec) ...@@ -238,7 +238,7 @@ abstract class Generator(spec: Spec)
w.wl w.wl
} }
f(w) f(w)
} }
) )
f2(w) f2(w)
}) })
...@@ -301,6 +301,26 @@ abstract class Generator(spec: Spec) ...@@ -301,6 +301,26 @@ abstract class Generator(spec: Spec)
expr(tm) 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 withNs(namespace: Option[String], t: String) = namespace.fold(t)("::"+_+"::"+t)
def withPackage(packageName: Option[String], t: String) = packageName.fold(t)(_+"."+t) def withPackage(packageName: Option[String], t: String) = packageName.fold(t)(_+"."+t)
......
client_returned_record = record { client_returned_record = record {
record_id: i64;
content: string; content: string;
} }
client_interface = interface +j +o { client_interface = interface +j +o {
# Returns record of given string # 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 @@ ...@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "client_returned_record.hpp" #include "client_returned_record.hpp"
#include <cstdint>
#include <string> #include <string>
class ClientInterface { class ClientInterface {
...@@ -11,5 +12,5 @@ public: ...@@ -11,5 +12,5 @@ public:
virtual ~ClientInterface() {} virtual ~ClientInterface() {}
/** Returns record of given string */ /** 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 @@ ...@@ -3,16 +3,21 @@
#pragma once #pragma once
#include <cstdint>
#include <string> #include <string>
#include <utility> #include <utility>
struct ClientReturnedRecord final { struct ClientReturnedRecord final {
int64_t record_id;
std::string content; std::string content;
ClientReturnedRecord( ClientReturnedRecord(
int64_t record_id,
std::string content) : std::string content) :
record_id(std::move(record_id)),
content(std::move(content)) { content(std::move(content)) {
} }
}; };
...@@ -5,5 +5,5 @@ package com.dropbox.djinni.test; ...@@ -5,5 +5,5 @@ package com.dropbox.djinni.test;
public abstract class ClientInterface { public abstract class ClientInterface {
/** Returns record of given string */ /** 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; ...@@ -6,13 +6,21 @@ package com.dropbox.djinni.test;
public final class ClientReturnedRecord { public final class ClientReturnedRecord {
/*package*/ final long mRecordId;
/*package*/ final String mContent; /*package*/ final String mContent;
public ClientReturnedRecord( public ClientReturnedRecord(
long recordId,
String content) { String content) {
this.mRecordId = recordId;
this.mContent = content; this.mContent = content;
} }
public long getRecordId() {
return mRecordId;
}
public String getContent() { public String getContent() {
return mContent; return mContent;
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// This file generated by Djinni from client_interface.djinni // This file generated by Djinni from client_interface.djinni
#include "NativeClientInterface.hpp" // my header #include "NativeClientInterface.hpp" // my header
#include "HI64.hpp"
#include "HString.hpp" #include "HString.hpp"
#include "NativeClientReturnedRecord.hpp" #include "NativeClientReturnedRecord.hpp"
...@@ -11,12 +12,13 @@ NativeClientInterface::NativeClientInterface() : djinni::JniInterface<ClientInte ...@@ -11,12 +12,13 @@ NativeClientInterface::NativeClientInterface() : djinni::JniInterface<ClientInte
NativeClientInterface::JavaProxy::JavaProxy(jobject obj) : JavaProxyCacheEntry(obj) {} 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(); JNIEnv * const jniEnv = djinni::jniGetThreadEnv();
djinni::JniLocalScope jscope(jniEnv, 10); 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)); djinni::LocalRef<jstring> j_utf8string(jniEnv, ::djinni::HString::toJava(jniEnv, c_utf8string));
const auto & data = djinni::JniClass<::djinni_generated::NativeClientInterface>::get(); 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); djinni::jniExceptionCheck(jniEnv);
return NativeClientReturnedRecord::fromJava(jniEnv, jret.get()); return NativeClientReturnedRecord::fromJava(jniEnv, jret.get());
}; };
......
...@@ -17,12 +17,12 @@ public: ...@@ -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); } 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 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 { class JavaProxy final : djinni::JavaProxyCacheEntry, public ClientInterface {
public: public:
JavaProxy(jobject obj); 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: private:
using djinni::JavaProxyCacheEntry::getGlobalRef; using djinni::JavaProxyCacheEntry::getGlobalRef;
......
...@@ -2,14 +2,16 @@ ...@@ -2,14 +2,16 @@
// This file generated by Djinni from client_interface.djinni // This file generated by Djinni from client_interface.djinni
#include "NativeClientReturnedRecord.hpp" // my header #include "NativeClientReturnedRecord.hpp" // my header
#include "HI64.hpp"
#include "HString.hpp" #include "HString.hpp"
namespace djinni_generated { namespace djinni_generated {
jobject NativeClientReturnedRecord::toJava(JNIEnv* jniEnv, ClientReturnedRecord c) { 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)); djinni::LocalRef<jstring> j_content(jniEnv, ::djinni::HString::toJava(jniEnv, c.content));
const auto & data = djinni::JniClass<::djinni_generated::NativeClientReturnedRecord>::get(); 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); djinni::jniExceptionCheck(jniEnv);
return r; return r;
} }
...@@ -18,6 +20,7 @@ ClientReturnedRecord NativeClientReturnedRecord::fromJava(JNIEnv* jniEnv, jobjec ...@@ -18,6 +20,7 @@ ClientReturnedRecord NativeClientReturnedRecord::fromJava(JNIEnv* jniEnv, jobjec
assert(j != nullptr); assert(j != nullptr);
const auto & data = djinni::JniClass<::djinni_generated::NativeClientReturnedRecord>::get(); const auto & data = djinni::JniClass<::djinni_generated::NativeClientReturnedRecord>::get();
return ClientReturnedRecord( 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())); ::djinni::HString::fromJava(jniEnv, djinni::LocalRef<jstring>(jniEnv, static_cast<jstring>(jniEnv->GetObjectField(j, data.field_mContent))).get()));
} }
......
...@@ -17,7 +17,8 @@ public: ...@@ -17,7 +17,8 @@ public:
static ClientReturnedRecord fromJava(JNIEnv*, jobject); static ClientReturnedRecord fromJava(JNIEnv*, jobject);
const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass("com/dropbox/djinni/test/ClientReturnedRecord") }; 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;") }; const jfieldID field_mContent { djinni::jniGetFieldID(clazz.get(), "mContent", "Ljava/lang/String;") };
private: private:
......
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
@protocol DBClientInterface @protocol DBClientInterface
/** Returns record of given string */ /** Returns record of given string */
- (DBClientReturnedRecord *)getRecord:(NSString *)utf8string; - (DBClientReturnedRecord *)getRecord:(int64_t)recordId utf8string:(NSString *)utf8string;
@end @end
...@@ -16,7 +16,7 @@ namespace djinni_generated ...@@ -16,7 +16,7 @@ namespace djinni_generated
ClientInterfaceObjcProxy (id objcRef); ClientInterfaceObjcProxy (id objcRef);
virtual ~ClientInterfaceObjcProxy () override; virtual ~ClientInterfaceObjcProxy () override;
static std::shared_ptr<ClientInterface> client_interface_with_objc (id objcRef); 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: private:
ClientInterfaceObjcProxy () {}; ClientInterfaceObjcProxy () {};
......
...@@ -25,13 +25,14 @@ namespace djinni_generated ...@@ -25,13 +25,14 @@ namespace djinni_generated
return static_cast<std::shared_ptr<ClientInterface>>(cache.get(objcRef)); 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 { @autoreleasepool {
int64_t cpp_record_id = record_id;
NSString *cpp_utf8string = [[NSString alloc] initWithBytes:utf8string.data() NSString *cpp_utf8string = [[NSString alloc] initWithBytes:utf8string.data()
length:utf8string.length() length:utf8string.length()
encoding:NSUTF8StringEncoding]; encoding:NSUTF8StringEncoding];
DBClientReturnedRecord *objcRet = [objcRef getRecord:cpp_utf8string]; DBClientReturnedRecord *objcRet = [objcRef getRecord:cpp_record_id utf8string:cpp_utf8string];
ClientReturnedRecord cppRet = std::move([objcRet cppClientReturnedRecord]); ClientReturnedRecord cppRet = std::move([objcRet cppClientReturnedRecord]);
return cppRet; return cppRet;
} }
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
@interface DBClientReturnedRecord : NSObject @interface DBClientReturnedRecord : NSObject
- (id)initWithClientReturnedRecord:(DBClientReturnedRecord *)clientReturnedRecord; - (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; @property (nonatomic, readonly) NSString *content;
......
...@@ -12,14 +12,16 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th ...@@ -12,14 +12,16 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
- (id)initWithClientReturnedRecord:(DBClientReturnedRecord *)clientReturnedRecord - (id)initWithClientReturnedRecord:(DBClientReturnedRecord *)clientReturnedRecord
{ {
if (self = [super init]) { if (self = [super init]) {
_recordId = clientReturnedRecord.recordId;
_content = [clientReturnedRecord.content copy]; _content = [clientReturnedRecord.content copy];
} }
return self; return self;
} }
- (id)initWithContent:(NSString *)content - (id)initWithRecordId:(int64_t)recordId content:(NSString *)content
{ {
if (self = [super init]) { if (self = [super init]) {
_recordId = recordId;
_content = [content copy]; _content = [content copy];
} }
return self; return self;
...@@ -28,6 +30,7 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th ...@@ -28,6 +30,7 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
- (id)initWithCppClientReturnedRecord:(const ClientReturnedRecord &)clientReturnedRecord - (id)initWithCppClientReturnedRecord:(const ClientReturnedRecord &)clientReturnedRecord
{ {
if (self = [super init]) { if (self = [super init]) {
_recordId = clientReturnedRecord.record_id;
_content = [[NSString alloc] initWithBytes:clientReturnedRecord.content.data() _content = [[NSString alloc] initWithBytes:clientReturnedRecord.content.data()
length:clientReturnedRecord.content.length() length:clientReturnedRecord.content.length()
encoding:NSUTF8StringEncoding]; encoding:NSUTF8StringEncoding];
...@@ -37,8 +40,10 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th ...@@ -37,8 +40,10 @@ static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for th
- (ClientReturnedRecord)cppClientReturnedRecord - (ClientReturnedRecord)cppClientReturnedRecord
{ {
int64_t recordId = _recordId;
std::string content([_content UTF8String], [_content lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); std::string content([_content UTF8String], [_content lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ClientReturnedRecord( return ClientReturnedRecord(
std::move(recordId),
std::move(content)); std::move(content));
} }
......
...@@ -71,7 +71,7 @@ static const std::string HELLO_WORLD = "Hello World!"; ...@@ -71,7 +71,7 @@ static const std::string HELLO_WORLD = "Hello World!";
static const std::string NON_ASCII = "Non-ASCII / 非 ASCII 字符"; static const std::string NON_ASCII = "Non-ASCII / 非 ASCII 字符";
void TestHelpers::check_client_interface_ascii(const std::shared_ptr<ClientInterface> & i) { 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) { if (cReturnedRecord.content != HELLO_WORLD) {
std::string error_msg = "Expected String: " + HELLO_WORLD + " Actual: " + cReturnedRecord.content; std::string error_msg = "Expected String: " + HELLO_WORLD + " Actual: " + cReturnedRecord.content;
throw std::invalid_argument(error_msg); throw std::invalid_argument(error_msg);
...@@ -79,7 +79,7 @@ void TestHelpers::check_client_interface_ascii(const std::shared_ptr<ClientInter ...@@ -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) { 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) { if (cReturnedRecord.content != NON_ASCII) {
std::string error_msg = "Expected String: " + NON_ASCII + " Actual: " + cReturnedRecord.content; std::string error_msg = "Expected String: " + NON_ASCII + " Actual: " + cReturnedRecord.content;
throw std::invalid_argument(error_msg); throw std::invalid_argument(error_msg);
......
...@@ -4,10 +4,10 @@ import static junit.framework.Assert.assertTrue; ...@@ -4,10 +4,10 @@ import static junit.framework.Assert.assertTrue;
public class ClientInterfaceImpl extends ClientInterface { public class ClientInterfaceImpl extends ClientInterface {
@Override @Override
public ClientReturnedRecord getRecord(String utf8string) { public ClientReturnedRecord getRecord(long id, String utf8string) {
if (!utf8string.equals("Non-ASCII / 非 ASCII 字符") && !utf8string.equals("Hello World!")) { if (!utf8string.equals("Non-ASCII / 非 ASCII 字符") && !utf8string.equals("Hello World!")) {
throw new RuntimeException("Unexpected string. Check UTF-8?"); 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 字符"; ...@@ -6,10 +6,10 @@ static NSString *DBNonAscii = @"Non-ASCII / 非 ASCII 字符";
@implementation DBClientInterfaceImpl @implementation DBClientInterfaceImpl
- (DBClientReturnedRecord *)getRecord:(NSString *)utf8string - (DBClientReturnedRecord *)getRecord:(int64_t)ident utf8string:(NSString *)utf8string
{ {
NSAssert([utf8string isEqualToString:DBHelloWorld] || [utf8string isEqualToString:DBNonAscii], @"Unexpected String"); NSAssert([utf8string isEqualToString:DBHelloWorld] || [utf8string isEqualToString:DBNonAscii], @"Unexpected String");
return [[DBClientReturnedRecord alloc] initWithContent:utf8string]; return [[DBClientReturnedRecord alloc] initWithRecordId:ident content:utf8string];
} }
@end @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