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

Making Utf8/Utf16 a subclass of Struct is misleading #34

Closed
jason-simmons opened this issue Mar 31, 2020 · 3 comments
Closed

Making Utf8/Utf16 a subclass of Struct is misleading #34

jason-simmons opened this issue Mar 31, 2020 · 3 comments

Comments

@jason-simmons
Copy link

Utf8 and Utf16 are subclasses of Struct. This makes it possible to pass a Pointer<Utf8> as a parameter to native methods.

However, the Utf8 and Utf16 classes do not have any fields. A Utf8 instance does not actually contain a UTF-8 character, and sizeOf<Utf8>() returns zero. This means that a call to allocate<Utf8>() will return a zero length buffer, which is probably not what the user expects.

It may be preferable to make Utf8/Utf16 purely helper classes that do not extend NativeType. UTF-8/UTF-16 strings can then be more accurately represented with Pointer<Uint8> and Pointer<Uint16> types.

@mit-mit @timsneath

@timsneath
Copy link
Contributor

Just to add to this, it's compounded because a string should currently be represented in two different ways:

  1. When you're passing a string to a Win32 API, you use Utf16.toUtf16() to create a Pointer<Utf16> that you pass into a function.
  2. When you're receiving a string, the right approach is to create a Pointer<Uint16> because of the need to allocate a buffer in advance.

This bifurcation means that I have to choose in my typedef to make it easier to pass in strings or receive strings.

@dcharkes
Copy link
Contributor

dcharkes commented Apr 1, 2020

Thanks for the report!

If we change it to non-struct, one can no longer have a Pointer<Utf16>. This package:ffi library does not live in dart: and only dart: is allowed to extend NativeType directly. That means that your function signatures would have Pointer<Int16> instead, providing less documentation and safety. If we move the Strings to dart:ffi we can make them extend NativeType instead of Struct.

Alternatively, we could opt for adding fields to Utf8 and Utf16 so that their size is 1 and 2 bytes, but allocation up front with allocate<Utf8> only works correctly if you know the amount of code units. cc @askeksa-google who's working on String encoding in the VM at the moment.

And while on the topic of fixing the Strings design, if we could allow copy-free strings, that would be great dart-lang/sdk#39787. That might also require moving Strings to dart:ffi itself.

@dcharkes
Copy link
Contributor

dcharkes commented Feb 9, 2021

#72

@dcharkes dcharkes closed this as completed Feb 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

3 participants