-
Notifications
You must be signed in to change notification settings - Fork 32
Helpers for null-terminated Utf8 #3
Changes from 5 commits
f328914
7199de7
79acb9d
8fd8f51
5c49a3e
1c6d08d
d9a79de
2335e7f
6551a80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.packages | ||
pubspec.lock | ||
.dart_tool | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// 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. | ||
|
||
library ffi; | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export 'src/utf8.dart'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// 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. | ||
|
||
library utf8; | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import 'dart:convert'; | ||
import 'dart:ffi'; | ||
import 'dart:typed_data'; | ||
|
||
/// [Utf8] implements conversion between Dart strings and null-termianted | ||
/// Utf8-encoded "char*" strings in C. | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
class Utf8 extends Struct<Utf8> { | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
static String fromUtf8(Pointer<Utf8> str) { | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
final Pointer<Uint8> array = str.cast(); | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int count = 0x1000; | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Uint8List string = array.asExternalTypedData(count: count); | ||
int i = 0; | ||
for (; string[i] != 0; ++i) { | ||
if (i == count) { | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
count *= 2; | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we use a precise bound here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, because the length of the string can be only be detected by scanning until the first NULL byte. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But, why times 2 every time? Why not scan until null and use that as count? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is scanning until null. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I was confused by |
||
string = array.asExternalTypedData(count: count); | ||
} | ||
} | ||
return Utf8Decoder().convert(Uint8List.view(string.buffer, 0, i)); | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
static Pointer<Utf8> toUtf8(String s) { | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
final List<int> units = Utf8Encoder().convert(s); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe You can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the new type: abstract class Encoding extends Codec<String, List<int>> { |
||
final Pointer<Uint8> result = | ||
Pointer<Uint8>.allocate(count: units.length + 1); | ||
final Uint8List string = | ||
result.asExternalTypedData(count: units.length + 1); | ||
string.setAll(0, units); | ||
string[units.length] = 0; | ||
return result.cast(); | ||
} | ||
|
||
String toString() => fromUtf8(addressOf); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ dependencies: | |
|
||
dev_dependencies: | ||
pedantic: ^1.0.0 | ||
test: ^1.6.8 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// 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 'package:test/test.dart'; | ||
import 'package:ffi/ffi.dart'; | ||
|
||
main() { | ||
test("fromUtf8 . toUtf8 is identity", () { | ||
final String start = "Hello World!\n"; | ||
final String end = Utf8.fromUtf8(Utf8.toUtf8(start)); | ||
expect(end, equals(start)); | ||
}); | ||
sjindel-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Uh oh!
There was an error while loading. Please reload this page.