Skip to content
This repository has been archived by the owner on Jan 17, 2024. It is now read-only.

Commit

Permalink
Add initial utf16 support (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
mit-mit authored Sep 9, 2019
1 parent 9c3cb7b commit e6aea0a
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 2 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.1.1

* Add basic Utf16 support

## 0.1.0

* Initial release
* Initial release supporting Utf8
1 change: 1 addition & 0 deletions lib/ffi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
// BSD-style license that can be found in the LICENSE file.

export 'src/utf8.dart';
export 'src/utf16.dart';
32 changes: 32 additions & 0 deletions lib/src/utf16.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// 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.

import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data';

/// [Utf16] implements conversion between Dart strings and null-terminated
/// Utf6-encoded "char*" strings in C.
///
/// [Utf16] is respresented as a struct so that `Pointer<Utf16>` can be used in
/// native function signatures.
class Utf16 extends Struct<Utf16> {
/// Convert a [String] to a Utf16-encoded null-terminated C string.
///
/// If 'string' contains NULL bytes, the converted string will be truncated
/// prematurely. Unpaired surrogate code points in [string] will be preserved
/// in the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
///
/// Returns a malloc-allocated pointer to the result.
static Pointer<Utf16> toUtf16(String s) {
final units = s.codeUnits;
final Pointer<Uint16> result =
Pointer<Uint16>.allocate(count: units.length + 1);
final Uint16List nativeString =
result.asExternalTypedData(count: units.length + 1);
nativeString.setAll(0, units);
nativeString[units.length] = 0;
return result.cast();
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: ffi
version: 0.1.0
version: 0.1.1
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/ffi
description: Utilities for working with Foreign Function Interface (FFI) code.
Expand Down
32 changes: 32 additions & 0 deletions test/utf16_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// 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.

import 'dart:ffi';
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:ffi/ffi.dart';

main() {
test("toUtf16 ASCII", () {
final String start = "Hello World!\n";
final Pointer<Uint16> converted = Utf16.toUtf16(start).cast();
final Uint16List end =
converted.asExternalTypedData(count: start.codeUnits.length + 1);
final matcher = equals(start.codeUnits.toList()..add(0));
expect(end, matcher);
converted.free();
});

test("toUtf16 emoji", () {
final String start = "😎";
final Pointer<Utf16> converted = Utf16.toUtf16(start).cast();
final int length = start.codeUnits.length;
final Uint16List end =
converted.cast<Uint16>().asExternalTypedData(count: length + 1);
final matcher = equals(start.codeUnits.toList()..add(0));
expect(end, matcher);
converted.free();
});
}

0 comments on commit e6aea0a

Please sign in to comment.