From 04ff988195aea1c2115aa64b095f5730f5c285fe Mon Sep 17 00:00:00 2001 From: Jasm Sison Date: Wed, 4 Sep 2019 17:22:25 +0200 Subject: [PATCH 1/3] added utf8 support --- lib/src/box.dart | 10 +++++----- lib/src/common.dart | 2 +- lib/src/ffi/cstring.dart | 32 ++++++++++++++++++++++---------- pubspec.yaml | 3 ++- test/test.dart | 12 +++++++++--- 5 files changed, 39 insertions(+), 20 deletions(-) diff --git a/lib/src/box.dart b/lib/src/box.dart index 32e9776a..8f2e6164 100644 --- a/lib/src/box.dart +++ b/lib/src/box.dart @@ -125,25 +125,25 @@ class Box { } // transform flatbuffers byte array into memory area for C, with a length of a multiple of four - Pointer bufferPtr = allocate(count: ((buffer.length + 3.0) / 4.0).toInt() * 4); + Pointer bufferPtr = Pointer.allocate(count: ((buffer.length + 3.0) / 4.0).toInt() * 4); for(int i = 0; i < buffer.length; ++i) bufferPtr.elementAt(i).store(buffer[i] as int); // put object into box and free the buffer - checkObx(bindings.obx_box_put(_objectboxBox, propVals[_idPropIdx]["value"], fromAddress(bufferPtr.address), buffer.length, putMode)); + checkObx(bindings.obx_box_put(_objectboxBox, propVals[_idPropIdx]["value"], Pointer.fromAddress(bufferPtr.address), buffer.length, putMode)); bufferPtr.free(); } getById(int id) { - Pointer> dataPtr = allocate(); - Pointer sizePtr = allocate(); + Pointer> dataPtr = Pointer>.allocate(); + Pointer sizePtr = Pointer.allocate(); // get element with specified id from database Pointer txn = bindings.obx_txn_read(_store.ptr); check(txn != null && txn.address != 0); checkObx(bindings.obx_box_get(_objectboxBox, id, dataPtr, sizePtr)); checkObx(bindings.obx_txn_close(txn)); - Pointer data = fromAddress(dataPtr.load>().address); + Pointer data = Pointer.fromAddress(dataPtr.load>().address); var size = sizePtr.load(); // transform bytes from memory to Dart byte list diff --git a/lib/src/common.dart b/lib/src/common.dart index 36d2217a..3dbe5052 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -5,7 +5,7 @@ import "ffi/cstring.dart"; class Common { static List version() { - Pointer majorPtr = allocate(), minorPtr = allocate(), patchPtr = allocate(); + Pointer majorPtr = Pointer.allocate(), minorPtr = Pointer.allocate(), patchPtr = Pointer.allocate(); bindings.obx_version(majorPtr, minorPtr, patchPtr); var ret = [majorPtr.load(), minorPtr.load(), patchPtr.load()]; majorPtr.free(); diff --git a/lib/src/ffi/cstring.dart b/lib/src/ffi/cstring.dart index 6f04cdc8..2a637845 100644 --- a/lib/src/ffi/cstring.dart +++ b/lib/src/ffi/cstring.dart @@ -1,24 +1,36 @@ import "dart:ffi"; +import "dart:typed_data"; +import "package:utf/src/utf8.dart"; +import "package:utf/src/utf16.dart"; +// TODO check if revamp structs are relevant (https://github.com/dart-lang/sdk/issues/37229) // wrapper for a null-terminated array of characters in memory ("c-style string") class CString { Pointer _ptr; - CString(String dartStr) { // if this constructor is used, ".free" needs to be called on this instance - _ptr = allocate(count: dartStr.length + 1); - for(int i = 0; i < dartStr.length; ++i) - _ptr.elementAt(i).store(dartStr.codeUnitAt(i)); - _ptr.elementAt(dartStr.length).store(0); + // if this constructor is used, ".free" needs to be called on this instance + CString(String dartStr) { + List ints = encodeUtf8(dartStr); + var utf8Str = Uint8List.fromList(ints); + _ptr = Pointer.allocate(count: utf8Str.length + 1); + for(int i = 0; i < utf8Str.length; ++i) + _ptr.elementAt(i).store(utf8Str.elementAt(i)); + _ptr.elementAt(utf8Str.length).store(0); } CString.fromPtr(this._ptr); String get val { - String ret = "", c; - int i = 0; - while((c = String.fromCharCode(_ptr.elementAt(i++).load())).codeUnitAt(0) != 0) // TODO: unicode support - ret += c; - return ret; + List utf8CodePoints = new List(); + + int element; + + for (int i=0; element != 0; i++) { + element = _ptr.elementAt(i).load(); + utf8CodePoints.add(element); + } + + return decodeUtf8(utf8CodePoints); } String toString() => val; diff --git a/pubspec.yaml b/pubspec.yaml index e5316627..ff901d14 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,9 @@ name: objectbox -version: 0.0.1 +version: 0.0.2 description: >- ObjectBox binding for Dart. environment: sdk: '>=2.2.2 <3.0.0' dependencies: flat_buffers: ^1.11.0 + utf: ^0.9.0 diff --git a/test/test.dart b/test/test.dart index 70068f74..6507bf1a 100644 --- a/test/test.dart +++ b/test/test.dart @@ -1,4 +1,5 @@ import "../lib/objectbox.dart"; +import "package:utf/src/utf8.dart"; @Entity(id: 1, uid: 1) class Note { @@ -17,11 +18,16 @@ class Note { main() { var store = Store([Note]); var box = Box(store); + insertNote(box, decodeUtf8([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100])); + insertNote(box, decodeUtf8([228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 33])); + insertNote(box, decodeUtf8([65, 104, 111, 106, 32, 115, 118, 196, 155, 116, 101, 33])); + store.close(); +} - var note = Note.construct("Hello"); +insertNote(Box box, String str) { + var note = Note.construct(str); box.put(note); + print("new note got id ${note.id}"); print("refetched note: ${box.getById(note.id)}"); - - store.close(); } From 9026bc466f5a06e058d4c62ff8d17dc64bb52b4f Mon Sep 17 00:00:00 2001 From: Jasm Sison Date: Thu, 5 Sep 2019 15:31:02 +0200 Subject: [PATCH 2/3] I tried explicitly casting with `x as Uint8` and `(Uint) x` this triggered some weird compiler errors. Then I tried this without explicitly casting, evidently there's some type polymorphism going on, or some casting by the compiler. In any case, the Uint8List has been removed. --- lib/src/ffi/cstring.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/ffi/cstring.dart b/lib/src/ffi/cstring.dart index 2a637845..898f26e4 100644 --- a/lib/src/ffi/cstring.dart +++ b/lib/src/ffi/cstring.dart @@ -10,12 +10,12 @@ class CString { // if this constructor is used, ".free" needs to be called on this instance CString(String dartStr) { - List ints = encodeUtf8(dartStr); - var utf8Str = Uint8List.fromList(ints); - _ptr = Pointer.allocate(count: utf8Str.length + 1); - for(int i = 0; i < utf8Str.length; ++i) - _ptr.elementAt(i).store(utf8Str.elementAt(i)); - _ptr.elementAt(utf8Str.length).store(0); + final ints = encodeUtf8(dartStr); + _ptr = Pointer.allocate(count: ints.length + 1); + for(int i = 0; i < ints.length; ++i) { + _ptr.elementAt(i).store(ints.elementAt(i)); + } + _ptr.elementAt(ints.length).store(0); } CString.fromPtr(this._ptr); From c77e1b8414c68e7011744ec7ad0059ed79b8dcb0 Mon Sep 17 00:00:00 2001 From: Jasm Sison Date: Thu, 5 Sep 2019 15:52:37 +0200 Subject: [PATCH 3/3] Maintain support for 2.4's ffi TODO Revert and test this commit when 2.5 is released as stable --- lib/src/box.dart | 10 +++++----- lib/src/common.dart | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/box.dart b/lib/src/box.dart index 8f2e6164..32e9776a 100644 --- a/lib/src/box.dart +++ b/lib/src/box.dart @@ -125,25 +125,25 @@ class Box { } // transform flatbuffers byte array into memory area for C, with a length of a multiple of four - Pointer bufferPtr = Pointer.allocate(count: ((buffer.length + 3.0) / 4.0).toInt() * 4); + Pointer bufferPtr = allocate(count: ((buffer.length + 3.0) / 4.0).toInt() * 4); for(int i = 0; i < buffer.length; ++i) bufferPtr.elementAt(i).store(buffer[i] as int); // put object into box and free the buffer - checkObx(bindings.obx_box_put(_objectboxBox, propVals[_idPropIdx]["value"], Pointer.fromAddress(bufferPtr.address), buffer.length, putMode)); + checkObx(bindings.obx_box_put(_objectboxBox, propVals[_idPropIdx]["value"], fromAddress(bufferPtr.address), buffer.length, putMode)); bufferPtr.free(); } getById(int id) { - Pointer> dataPtr = Pointer>.allocate(); - Pointer sizePtr = Pointer.allocate(); + Pointer> dataPtr = allocate(); + Pointer sizePtr = allocate(); // get element with specified id from database Pointer txn = bindings.obx_txn_read(_store.ptr); check(txn != null && txn.address != 0); checkObx(bindings.obx_box_get(_objectboxBox, id, dataPtr, sizePtr)); checkObx(bindings.obx_txn_close(txn)); - Pointer data = Pointer.fromAddress(dataPtr.load>().address); + Pointer data = fromAddress(dataPtr.load>().address); var size = sizePtr.load(); // transform bytes from memory to Dart byte list diff --git a/lib/src/common.dart b/lib/src/common.dart index 3dbe5052..36d2217a 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -5,7 +5,7 @@ import "ffi/cstring.dart"; class Common { static List version() { - Pointer majorPtr = Pointer.allocate(), minorPtr = Pointer.allocate(), patchPtr = Pointer.allocate(); + Pointer majorPtr = allocate(), minorPtr = allocate(), patchPtr = allocate(); bindings.obx_version(majorPtr, minorPtr, patchPtr); var ret = [majorPtr.load(), minorPtr.load(), patchPtr.load()]; majorPtr.free();