Advertisement
ikegami

FFI::Platypus::Type::LPCWSTR

Dec 11th, 2020 (edited)
1,193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.37 KB | None | 0 0
  1. package FFI::Platypus::Type::LPCWSTR;
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use Config                qw( %Config );
  7. use Encode                qw( decode encode );
  8. use FFI::Platypus::Buffer qw( scalar_to_pointer );
  9.  
  10. use constant PTR_SIZE => $Config{ptrsize};
  11.  
  12. use constant PTR_PACK_FORMAT =>
  13.      PTR_SIZE == 8 ? 'Q'
  14.    : PTR_SIZE == 4 ? 'L'
  15.    : die("Unrecognized ptrsize\n");
  16.  
  17. my @stack;  # To keep buffer alive.
  18.  
  19. sub strlenW {
  20.    my ($ptr) = @_;
  21.  
  22.    # typedef uint16_t WCHAR;
  23.    # typedef const WCHAR *LPCWSTR;
  24.    #
  25.    # size_t len = 0;
  26.    # for (; *ptr; ++ptr)
  27.    #    ++len;
  28.  
  29.    my $len = 0;
  30.    for (; unpack('S', unpack('P2', pack(PTR_PACK_FORMAT, $ptr))); $ptr += 2) {
  31.       ++$len;
  32.    }
  33.  
  34.    return $len;
  35. }
  36.  
  37. sub perl_to_native {
  38.    if (defined($_[0])) {
  39.       my $buf = encode('UTF-16le', $_[0]."\0");
  40.       push @stack, \$buf;
  41.       return scalar_to_pointer($buf);
  42.    } else {
  43.       push @stack, undef;
  44.    }
  45. }
  46.  
  47. sub perl_to_native_post {
  48.    pop @stack;
  49. }
  50.  
  51. sub native_to_perl {
  52.    return undef if !defined($_[0]);
  53.    return decode('UTF-16le', unpack('P'.strlenW($_[0]), pack(PTR_PACK_FORMAT, $_[0])));
  54. }
  55.  
  56. sub ffi_custom_type_api_1 {
  57.    return {
  58.       native_type         => 'opaque',
  59.       perl_to_native      => \&perl_to_native,
  60.       perl_to_native_post => \&perl_to_native_post,
  61.       native_to_perl      => \&native_to_perl,
  62.    }
  63. }
  64.  
  65. 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement