FFI-Platypus
view release on metacpan or search on metacpan
lib/FFI/Platypus/Type/WideString.pm view on Meta::CPAN
package FFI::Platypus::Type::WideString;
use strict;
use warnings;
use 5.008004;
use FFI::Platypus;
use FFI::Platypus::Memory qw( memcpy );
use FFI::Platypus::Buffer qw( buffer_to_scalar scalar_to_pointer scalar_to_buffer );
use Encode qw( decode encode find_encoding );
use Carp ();
# ABSTRACT: Platypus custom type for Unicode "wide" strings
our $VERSION = '2.11'; # VERSION
my @stack; # To keep buffer alive.
sub _compute_wide_string_encoding
{
foreach my $need (qw( wcslen wcsnlen ))
{
die "This type plugin needs $need from libc, and cannot find it"
unless FFI::Platypus::Memory->can("_$need");
}
my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
my $size = eval { $ffi->sizeof('wchar_t') };
die 'no wchar_t' if $@;
my %orders = (
join('', 1..$size) => 'BE',
join('', reverse 1..$size) => 'LE',
);
my $byteorder = join '', @{ $ffi->cast( "wchar_t*", "uint8[$size]", \hex(join '', map { "0$_" } 1..$size) ) };
my $encoding;
if($size == 2)
{
$encoding = 'UTF-16';
}
elsif($size == 4)
{
$encoding = 'UTF-32';
}
else
{
die "not sure what encoding to use for size $size";
}
if(defined $orders{$byteorder})
{
$encoding .= $orders{$byteorder};
}
else
{
die "odd byteorder $byteorder not (yet) supported";
}
die "Perl doesn't recognize $encoding as an encoding"
unless find_encoding($encoding);
return ($encoding, $size);
}
sub ffi_custom_type_api_1
{
my %args = @_;
# TODO: it wold be nice to allow arbitrary encodings, but we are
# relying on a couple of wcs* functions to compute the string, so
# we will leave that for future development.
my($encoding, $width) = __PACKAGE__->_compute_wide_string_encoding();
( run in 0.441 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )