mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:08:01 +00:00
[samples] Migrate ffi samples to NNBD
Closes: https://github.com/dart-lang/sdk/issues/43600. TEST=samples/ffi Change-Id: I620e6a73c8e37dd72f8f3921fa37dd4f8966e45c Cq-Include-Trybots: luci.dart.try:vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,dart-sdk-linux-try,analyzer-nnbd-linux-release-try,analyzer-linux-release-try,front-end-nnbd-linux-release-x64-try,front-end-linux-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173542 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
parent
1245a196ce
commit
da008fb3fc
|
@ -6,8 +6,6 @@
|
|||
//
|
||||
// SharedObjects=ffi_test_dynamic_library ffi_test_functions
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'sample_async_callback.dart' as sample0;
|
||||
import 'sample_native_port_call.dart' as sample1;
|
||||
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
//
|
||||
// TODO(dartbug.com/37022): Update this when we get real async callbacks.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:isolate';
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
// The advantage is that finalizers can be used when passing ownership of data
|
||||
// (buffers) from C to Dart.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
@ -79,8 +77,8 @@ void myCallback2(int a) {
|
|||
}
|
||||
|
||||
class CppRequest {
|
||||
final SendPort replyPort;
|
||||
final int pendingCall;
|
||||
final SendPort? replyPort;
|
||||
final int? pendingCall;
|
||||
final String method;
|
||||
final Uint8List data;
|
||||
|
||||
|
@ -114,9 +112,9 @@ void handleCppRequests(dynamic message) {
|
|||
final int argument = cppRequest.data[0];
|
||||
final int result = myCallback1(argument);
|
||||
final cppResponse =
|
||||
CppResponse(cppRequest.pendingCall, Uint8List.fromList([result]));
|
||||
CppResponse(cppRequest.pendingCall!, Uint8List.fromList([result]));
|
||||
print('Dart: Responding: $cppResponse');
|
||||
cppRequest.replyPort.send(cppResponse.toCppMessage());
|
||||
cppRequest.replyPort!.send(cppResponse.toCppMessage());
|
||||
} else if (cppRequest.method == 'myCallback2') {
|
||||
final int argument = cppRequest.data[0];
|
||||
myCallback2(argument);
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import "package:ffi/ffi.dart";
|
||||
|
@ -11,12 +9,12 @@ import "package:ffi/ffi.dart";
|
|||
/// Sample struct for dart:ffi library.
|
||||
class Coordinate extends Struct {
|
||||
@Double()
|
||||
double x;
|
||||
external double x;
|
||||
|
||||
@Double()
|
||||
double y;
|
||||
external double y;
|
||||
|
||||
Pointer<Coordinate> next;
|
||||
external Pointer<Coordinate> next;
|
||||
|
||||
factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
|
||||
return allocate<Coordinate>().ref
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
String _platformPath(String name, {String path}) {
|
||||
if (path == null) path = "";
|
||||
String _platformPath(String name, String path) {
|
||||
if (Platform.isLinux || Platform.isAndroid)
|
||||
return path + "lib" + name + ".so";
|
||||
if (Platform.isMacOS) return path + "lib" + name + ".dylib";
|
||||
|
@ -16,7 +13,7 @@ String _platformPath(String name, {String path}) {
|
|||
throw Exception("Platform not implemented");
|
||||
}
|
||||
|
||||
DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
|
||||
String fullPath = _platformPath(name, path: path);
|
||||
DynamicLibrary dlopenPlatformSpecific(String name, {String path = ""}) {
|
||||
String fullPath = _platformPath(name, path);
|
||||
return DynamicLibrary.open(fullPath);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//
|
||||
// Explicit pool used for managing resources.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "dart:async";
|
||||
import 'dart:convert';
|
||||
import 'dart:ffi';
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//
|
||||
// Sample illustrating resources are not cleaned up when isolate is shutdown.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:io';
|
||||
import "dart:isolate";
|
||||
import 'dart:ffi';
|
||||
|
@ -24,7 +22,7 @@ void main() {
|
|||
receiveFromHelper.sendPort,
|
||||
);
|
||||
print("Main: Helper started.");
|
||||
Pointer<SomeResource> resource;
|
||||
Pointer<SomeResource> resource = nullptr;
|
||||
receiveFromHelper.listen((message) {
|
||||
if (message is int) {
|
||||
resource = Pointer<SomeResource>.fromAddress(message);
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//
|
||||
// Sample illustrating resource management with an explicit pool.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//
|
||||
// Sample illustrating resource management with an implicit pool in the zone.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
//
|
||||
// SharedObjects=ffi_test_dynamic_library ffi_test_functions
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'pool_isolate_shutdown_sample.dart' as pool_isolate;
|
||||
import 'pool_sample.dart' as pool;
|
||||
import 'pool_zoned_sample.dart' as pool_zoned;
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//
|
||||
// Sample illustrating manual resource management, not advised.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
@ -20,7 +18,7 @@ import 'package:expect/expect.dart';
|
|||
/// } ScreenCellAttrs;
|
||||
class ScreenCellAttrs extends Struct {
|
||||
@Int16()
|
||||
int bits;
|
||||
external int bits;
|
||||
|
||||
int get bold => getBits(kBoldFieldOffset, kBoldFieldLength);
|
||||
void set bold(int value) =>
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
@ -201,46 +199,6 @@ main() {
|
|||
print(result.value);
|
||||
}
|
||||
|
||||
{
|
||||
// Passing in null for an int argument throws a null pointer exception.
|
||||
BinaryOp sumPlus42 =
|
||||
ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
|
||||
|
||||
int x = null;
|
||||
try {
|
||||
sumPlus42(43, x);
|
||||
} on Error {
|
||||
print('Expected exception on passing null for int');
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Passing in null for a double argument throws a null pointer exception.
|
||||
DoubleUnaryOp times1_337Double = ffiTestFunctions
|
||||
.lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
|
||||
|
||||
double x = null;
|
||||
try {
|
||||
times1_337Double(x);
|
||||
} on Error {
|
||||
print('Expected exception on passing null for double');
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Passing in null for an int argument throws a null pointer exception.
|
||||
VigesimalOp sumManyNumbers = ffiTestFunctions
|
||||
.lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
|
||||
|
||||
int x = null;
|
||||
try {
|
||||
sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13,
|
||||
14.0, 15, 16.0, 17, 18.0, x, 20.0);
|
||||
} on Error {
|
||||
print('Expected exception on passing null for int');
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Passing in nullptr for a pointer argument results in a nullptr in c.
|
||||
Int64PointerUnOp nullableInt64ElemAt1 =
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'coordinate.dart';
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'coordinate.dart';
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
//
|
||||
// SharedObjects=ffi_test_dynamic_library ffi_test_functions
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'sample_ffi_bitfield.dart' as bitfield;
|
||||
import 'sample_ffi_data.dart' as data;
|
||||
import 'sample_ffi_dynamic_library.dart' as dynamic_library;
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "../lib/sqlite.dart";
|
||||
|
||||
void main() {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// A synchronous SQLite wrapper.
|
||||
///
|
||||
/// Written using dart:ffi.
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "dart:ffi";
|
||||
import "package:ffi/ffi.dart";
|
||||
|
||||
|
@ -13,7 +11,7 @@ import "signatures.dart";
|
|||
import "types.dart";
|
||||
|
||||
class _SQLiteBindings {
|
||||
DynamicLibrary sqlite;
|
||||
late DynamicLibrary sqlite;
|
||||
|
||||
/// Opening A New Database Connection
|
||||
///
|
||||
|
@ -29,10 +27,13 @@ class _SQLiteBindings {
|
|||
/// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
|
||||
/// an English language description of the error following a failure of any
|
||||
/// of the sqlite3_open() routines.
|
||||
int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
|
||||
int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
|
||||
late int Function(
|
||||
Pointer<Utf8> filename,
|
||||
Pointer<Pointer<Database>> databaseOut,
|
||||
int flags,
|
||||
Pointer<Utf8> vfs) sqlite3_open_v2;
|
||||
|
||||
int Function(Pointer<Database> database) sqlite3_close_v2;
|
||||
late int Function(Pointer<Database> database) sqlite3_close_v2;
|
||||
|
||||
/// Compiling An SQL Statement
|
||||
///
|
||||
|
@ -81,7 +82,7 @@ class _SQLiteBindings {
|
|||
/// that is returned (the sqlite3_stmt object) contains a copy of the
|
||||
/// original SQL text. This causes the [sqlite3_step] interface to
|
||||
/// behave differently in three ways:
|
||||
int Function(
|
||||
late int Function(
|
||||
Pointer<Database> database,
|
||||
Pointer<Utf8> query,
|
||||
int nbytes,
|
||||
|
@ -164,7 +165,7 @@ class _SQLiteBindings {
|
|||
/// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
|
||||
/// then the more specific [error codes] are returned directly
|
||||
/// by sqlite3_step(). The use of the "v2" interface is recommended.
|
||||
int Function(Pointer<Statement> statement) sqlite3_step;
|
||||
late int Function(Pointer<Statement> statement) sqlite3_step;
|
||||
|
||||
/// CAPI3REF: Reset A Prepared Statement Object
|
||||
///
|
||||
|
@ -187,7 +188,7 @@ class _SQLiteBindings {
|
|||
/// [sqlite3_reset] returns an appropriate [Errors].
|
||||
///
|
||||
/// ^The [sqlite3_reset] interface does not change the values
|
||||
int Function(Pointer<Statement> statement) sqlite3_reset;
|
||||
late int Function(Pointer<Statement> statement) sqlite3_reset;
|
||||
|
||||
/// Destroy A Prepared Statement Object
|
||||
///
|
||||
|
@ -212,14 +213,14 @@ class _SQLiteBindings {
|
|||
/// a prepared statement after it has been finalized. Any use of a prepared
|
||||
/// statement after it has been finalized can result in undefined and
|
||||
/// undesirable behavior such as segfaults and heap corruption.
|
||||
int Function(Pointer<Statement> statement) sqlite3_finalize;
|
||||
late int Function(Pointer<Statement> statement) sqlite3_finalize;
|
||||
|
||||
/// Number Of Columns In A Result Set
|
||||
///
|
||||
/// ^Return the number of columns in the result set returned by the
|
||||
/// prepared statement. ^This routine returns 0 if pStmt is an SQL
|
||||
/// statement that does not return data (for example an [UPDATE]).
|
||||
int Function(Pointer<Statement> statement) sqlite3_column_count;
|
||||
late int Function(Pointer<Statement> statement) sqlite3_column_count;
|
||||
|
||||
/// Column Names In A Result Set
|
||||
///
|
||||
|
@ -244,7 +245,7 @@ class _SQLiteBindings {
|
|||
/// ^The name of a result column is the value of the "AS" clause for
|
||||
/// that column, if there is an AS clause. If there is no AS clause
|
||||
/// then the name of the column is unspecified and may change from
|
||||
Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
|
||||
late Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_name;
|
||||
|
||||
/// CAPI3REF: Declared Datatype Of A Query Result
|
||||
|
@ -274,28 +275,28 @@ class _SQLiteBindings {
|
|||
/// strongly typed, but the typing is dynamic not static. ^Type
|
||||
/// is associated with individual values, not with the containers
|
||||
/// used to hold those values.
|
||||
Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
|
||||
late Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_decltype;
|
||||
|
||||
int Function(Pointer<Statement> statement, int columnIndex)
|
||||
late int Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_type;
|
||||
|
||||
Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
|
||||
late Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_value;
|
||||
|
||||
double Function(Pointer<Statement> statement, int columnIndex)
|
||||
late double Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_double;
|
||||
|
||||
int Function(Pointer<Statement> statement, int columnIndex)
|
||||
late int Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_int;
|
||||
|
||||
Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
|
||||
late Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
|
||||
sqlite3_column_text;
|
||||
|
||||
/// The sqlite3_errstr() interface returns the English-language text that
|
||||
/// describes the result code, as UTF-8. Memory to hold the error message
|
||||
/// string is managed internally and must not be freed by the application.
|
||||
Pointer<Utf8> Function(int code) sqlite3_errstr;
|
||||
late Pointer<Utf8> Function(int code) sqlite3_errstr;
|
||||
|
||||
/// Error Codes And Messages
|
||||
///
|
||||
|
@ -328,7 +329,7 @@ class _SQLiteBindings {
|
|||
/// If an interface fails with SQLITE_MISUSE, that means the interface
|
||||
/// was invoked incorrectly by the application. In that case, the
|
||||
/// error code and message may or may not be set.
|
||||
Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
|
||||
late Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
|
||||
|
||||
_SQLiteBindings() {
|
||||
sqlite = dlopenPlatformSpecific("sqlite3");
|
||||
|
@ -392,5 +393,5 @@ class _SQLiteBindings {
|
|||
}
|
||||
}
|
||||
|
||||
_SQLiteBindings _cachedBindings;
|
||||
_SQLiteBindings? _cachedBindings;
|
||||
_SQLiteBindings get bindings => _cachedBindings ??= _SQLiteBindings();
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// Result Codes
|
||||
///
|
||||
/// Many SQLite functions return an integer result code from the set shown
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "dart:ffi";
|
||||
|
||||
import "package:ffi/ffi.dart";
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "dart:ffi";
|
||||
|
||||
/// Database Connection Handle
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// This iterator should be [close]d after use.
|
||||
///
|
||||
/// [ClosableIterator]s often use resources which should be freed after use.
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "dart:collection";
|
||||
import "dart:ffi";
|
||||
|
||||
|
@ -23,7 +21,7 @@ import "collections/closable_iterator.dart";
|
|||
///
|
||||
/// This database interacts with SQLite synchonously.
|
||||
class Database {
|
||||
Pointer<types.Database> _database;
|
||||
late Pointer<types.Database> _database;
|
||||
bool _open = false;
|
||||
|
||||
/// Open a database located at the file [path].
|
||||
|
@ -108,11 +106,8 @@ class Database {
|
|||
return Result._(this, statement, columnIndices);
|
||||
}
|
||||
|
||||
SQLiteException _loadError([int errorCode]) {
|
||||
SQLiteException _loadError(int errorCode) {
|
||||
String errorMessage = bindings.sqlite3_errmsg(_database).ref.toString();
|
||||
if (errorCode == null) {
|
||||
return SQLiteException(errorMessage);
|
||||
}
|
||||
String errorCodeExplanation =
|
||||
bindings.sqlite3_errstr(errorCode).ref.toString();
|
||||
return SQLiteException(
|
||||
|
@ -126,18 +121,13 @@ class Database {
|
|||
/// Please note that this iterator should be [close]d manually if not all [Row]s
|
||||
/// are consumed.
|
||||
class Result extends IterableBase<Row> implements ClosableIterable<Row> {
|
||||
final Database _database;
|
||||
final ClosableIterator<Row> _iterator;
|
||||
final Pointer<Statement> _statement;
|
||||
final Map<String, int> _columnIndices;
|
||||
|
||||
Row _currentRow = null;
|
||||
|
||||
Result._(
|
||||
this._database,
|
||||
this._statement,
|
||||
this._columnIndices,
|
||||
) : _iterator = _ResultIterator(_statement, _columnIndices) {}
|
||||
Database database,
|
||||
Pointer<Statement> statement,
|
||||
Map<String, int> columnIndices,
|
||||
) : _iterator = _ResultIterator(statement, columnIndices) {}
|
||||
|
||||
void close() => _iterator.close();
|
||||
|
||||
|
@ -148,7 +138,7 @@ class _ResultIterator implements ClosableIterator<Row> {
|
|||
final Pointer<Statement> _statement;
|
||||
final Map<String, int> _columnIndices;
|
||||
|
||||
Row _currentRow = null;
|
||||
Row? _currentRow;
|
||||
bool _closed = false;
|
||||
|
||||
_ResultIterator(this._statement, this._columnIndices) {}
|
||||
|
@ -172,7 +162,7 @@ class _ResultIterator implements ClosableIterator<Row> {
|
|||
if (_closed) {
|
||||
throw SQLiteException("The result has already been closed.");
|
||||
}
|
||||
return _currentRow;
|
||||
return _currentRow!;
|
||||
}
|
||||
|
||||
void close() {
|
||||
|
@ -197,7 +187,7 @@ class Row {
|
|||
/// for the column by the query compiler.
|
||||
dynamic readColumn(String columnName,
|
||||
{Convert convert = Convert.DynamicType}) {
|
||||
return readColumnByIndex(_columnIndices[columnName], convert: convert);
|
||||
return readColumnByIndex(_columnIndices[columnName]!, convert: convert);
|
||||
}
|
||||
|
||||
/// Reads column [columnName].
|
||||
|
@ -227,7 +217,6 @@ class Row {
|
|||
return readColumnByIndexAsText(columnIndex);
|
||||
case Type.Null:
|
||||
return null;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +224,7 @@ class Row {
|
|||
/// Reads column [columnName] and converts to [Type.Integer] if not an
|
||||
/// integer.
|
||||
int readColumnAsInt(String columnName) {
|
||||
return readColumnByIndexAsInt(_columnIndices[columnName]);
|
||||
return readColumnByIndexAsInt(_columnIndices[columnName]!);
|
||||
}
|
||||
|
||||
/// Reads column [columnIndex] and converts to [Type.Integer] if not an
|
||||
|
@ -247,7 +236,7 @@ class Row {
|
|||
|
||||
/// Reads column [columnName] and converts to [Type.Text] if not text.
|
||||
String readColumnAsText(String columnName) {
|
||||
return readColumnByIndexAsText(_columnIndices[columnName]);
|
||||
return readColumnByIndexAsText(_columnIndices[columnName]!);
|
||||
}
|
||||
|
||||
/// Reads column [columnIndex] and converts to [Type.Text] if not text.
|
||||
|
@ -298,7 +287,6 @@ Type _typeFromText(String textRepresentation) {
|
|||
case "null":
|
||||
return Type.Null;
|
||||
}
|
||||
if (textRepresentation == null) return Type.Null;
|
||||
throw Exception("Unknown type [$textRepresentation]");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import "dart:async";
|
||||
import "dart:ffi";
|
||||
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
String _platformPath(String name, {String path}) {
|
||||
if (path == null) path = "";
|
||||
String _platformPath(String name, String path) {
|
||||
if (Platform.isLinux || Platform.isAndroid)
|
||||
return path + "lib" + name + ".so";
|
||||
if (Platform.isMacOS) return path + "lib" + name + ".dylib";
|
||||
|
@ -16,7 +13,7 @@ String _platformPath(String name, {String path}) {
|
|||
throw Exception("Platform not implemented");
|
||||
}
|
||||
|
||||
DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
|
||||
String fullPath = _platformPath(name, path: path);
|
||||
DynamicLibrary dlopenPlatformSpecific(String name, {String path = ""}) {
|
||||
String fullPath = _platformPath(name, path);
|
||||
return DynamicLibrary.open(fullPath);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ description: >-
|
|||
Sqlite3 wrapper. Demo for dart:ffi.
|
||||
author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
|
||||
environment:
|
||||
sdk: '>=2.1.0 <3.0.0'
|
||||
sdk: '>=2.12.0-0 <3.0.0'
|
||||
dependencies:
|
||||
ffi: ^0.1.3
|
||||
ffi: ^0.2.0-nullsafety.1
|
||||
dev_dependencies:
|
||||
test: ^1.5.3
|
||||
test: ^1.16.0-nullsafety.12
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
// VMOptions=--optimization-counter-threshold=5
|
||||
|
||||
import "dart:ffi";
|
||||
|
@ -49,8 +47,7 @@ void main() {
|
|||
expect(true, 1 <= id && id <= 3);
|
||||
String name = r.readColumnByIndex(1);
|
||||
expect(true, name is String);
|
||||
String alternativeName = r.readColumn("alternative_name");
|
||||
expect(true, alternativeName is String || alternativeName == null);
|
||||
final alternativeName = r.readColumn("alternative_name") as String?;
|
||||
dynamic multiTypedValue = r.readColumn("multi_typed_column");
|
||||
expect(
|
||||
true,
|
||||
|
@ -76,8 +73,7 @@ void main() {
|
|||
expect(true, 1 <= id && id <= 3);
|
||||
String name = r.readColumnByIndex(1);
|
||||
expect(true, name is String);
|
||||
String alternativeName = r.readColumn("alternative_name");
|
||||
expect(true, alternativeName is String || alternativeName == null);
|
||||
final alternativeName = r.readColumn("alternative_name") as String?;
|
||||
dynamic multiTypedValue = r.readColumn("multi_typed_column");
|
||||
expect(
|
||||
true,
|
||||
|
|
Loading…
Reference in a new issue