Skip to content

Commit 12512d5

Browse files
authored
[ffi] Add initial utf16 support (dart-archive/ffi#5)
1 parent efc9acb commit 12512d5

File tree

5 files changed

+71
-2
lines changed

5 files changed

+71
-2
lines changed

pkgs/ffi/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.1.1
4+
5+
* Add basic Utf16 support
6+
37
## 0.1.0
48

5-
* Initial release
9+
* Initial release supporting Utf8

pkgs/ffi/lib/ffi.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
export 'src/utf8.dart';
6+
export 'src/utf16.dart';

pkgs/ffi/lib/src/utf16.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:convert';
6+
import 'dart:ffi';
7+
import 'dart:typed_data';
8+
9+
/// [Utf16] implements conversion between Dart strings and null-terminated
10+
/// Utf6-encoded "char*" strings in C.
11+
///
12+
/// [Utf16] is respresented as a struct so that `Pointer<Utf16>` can be used in
13+
/// native function signatures.
14+
class Utf16 extends Struct<Utf16> {
15+
/// Convert a [String] to a Utf16-encoded null-terminated C string.
16+
///
17+
/// If 'string' contains NULL bytes, the converted string will be truncated
18+
/// prematurely. Unpaired surrogate code points in [string] will be preserved
19+
/// in the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
20+
///
21+
/// Returns a malloc-allocated pointer to the result.
22+
static Pointer<Utf16> toUtf16(String s) {
23+
final units = s.codeUnits;
24+
final Pointer<Uint16> result =
25+
Pointer<Uint16>.allocate(count: units.length + 1);
26+
final Uint16List nativeString =
27+
result.asExternalTypedData(count: units.length + 1);
28+
nativeString.setAll(0, units);
29+
nativeString[units.length] = 0;
30+
return result.cast();
31+
}
32+
}

pkgs/ffi/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: ffi
2-
version: 0.1.0
2+
version: 0.1.1
33
author: Dart Team <[email protected]>
44
homepage: https://github.com/dart-lang/ffi
55
description: Utilities for working with Foreign Function Interface (FFI) code.

pkgs/ffi/test/utf16_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:ffi';
6+
import 'dart:typed_data';
7+
8+
import 'package:test/test.dart';
9+
import 'package:ffi/ffi.dart';
10+
11+
main() {
12+
test("toUtf16 ASCII", () {
13+
final String start = "Hello World!\n";
14+
final Pointer<Uint16> converted = Utf16.toUtf16(start).cast();
15+
final Uint16List end =
16+
converted.asExternalTypedData(count: start.codeUnits.length + 1);
17+
final matcher = equals(start.codeUnits.toList()..add(0));
18+
expect(end, matcher);
19+
converted.free();
20+
});
21+
22+
test("toUtf16 emoji", () {
23+
final String start = "😎";
24+
final Pointer<Utf16> converted = Utf16.toUtf16(start).cast();
25+
final int length = start.codeUnits.length;
26+
final Uint16List end =
27+
converted.cast<Uint16>().asExternalTypedData(count: length + 1);
28+
final matcher = equals(start.codeUnits.toList()..add(0));
29+
expect(end, matcher);
30+
converted.free();
31+
});
32+
}

0 commit comments

Comments
 (0)