Convert-Binary-C

 view release on metacpan or  search on metacpan

cbc/pack.c  view on Meta::CPAN

                                int *pSize, u_32 *pFlags);

static void pack_pointer(pPACKARGS, SV *sv);
static void pack_struct(pPACKARGS, const Struct *pStruct, SV *sv, int inlined);
static void pack_enum(pPACKARGS, const EnumSpecifier *pEnumSpec, const BitfieldInfo *pBI, SV *sv);
static void pack_basic(pPACKARGS, u_32 flags, const BitfieldInfo *pBI, SV *sv);
static void pack_format(pPACKARGS, const CtTag *format, unsigned size, u_32 flags, SV *sv);
static void pack_type(pPACKARGS, const TypeSpec *pTS, const Declarator *pDecl, int dimension,
                                 const BitfieldInfo *pBI, SV *sv);

static SV *unpack_pointer(pPACKARGS);
static SV *unpack_struct(pPACKARGS, const Struct *pStruct, HV *hash);
static SV *unpack_enum(pPACKARGS, const EnumSpecifier *pEnumSpec, const BitfieldInfo *pBI);
static SV *unpack_basic(pPACKARGS, u_32 flags, const BitfieldInfo *pBI);
static SV *unpack_format(pPACKARGS, const CtTag *format, unsigned size, u_32 flags);
static SV *unpack_type(pPACKARGS, const TypeSpec *pTS, const Declarator *pDecl, int dimension,
                                  const BitfieldInfo *pBI);

static SV *hook_call_typespec(pTHX_ SV *self, const TypeSpec *pTS,
                              enum HookId hook_id, SV *in, int mortal);

/*===== EXTERNAL VARIABLES ===================================================*/

/*===== GLOBAL VARIABLES =====================================================*/

/*===== STATIC VARIABLES =====================================================*/

lib/Convert/Binary/C.pm  view on Meta::CPAN

But using the above definition, it'll get a reference to the calling
object (C<SELF>), the name of the type being processed (C<TYPE>) and
the data (C<DATA>).

But how does our hook look like?

  sub unpack_ptr {
    my($self, $type, $ptr) = @_;
    $ptr or return '<NULL>';
    my $size = $self->sizeof($type);
    $self->unpack($type, unpack("P$size", pack('Q', $ptr)));
  }

As you can see, the hook is rather simple. First, it receives the
arguments mentioned above. It performs a quick check if the pointer
is C<NULL> and shouldn't be processed any further. Next, it determines
the size of the type being processed. And finally, it'll just use
the C<P>I<n> unpack template to read from that memory location and
recursively call L<C<unpack>|/"unpack"> to unpack the type. (And yes,
this may of course again call other hooks.)

tests/228_hooks.t  view on Meta::CPAN

                               pack_ptr   => [$pack, $c->arg('DATA')] });
  $c->tag('Date',   Hooks => { unpack_ptr => [sub { sprintf "$_[1]\{0x%X}", $_[0] }, $c->arg('DATA', 'TYPE')],
                               pack_ptr   => $pack });
  $c->tag('Enum',   Hooks => { unpack_ptr => [sub { sprintf "$_[0]\{0x%X}", $_[1] }, $c->arg('TYPE', 'DATA')],
                               pack_ptr   => [$pack, $c->arg('DATA', 'SELF'), 'foo'] });
  $c->tag('TextId', Hooks => { unpack_ptr => [sub { sprintf "Text\{0x%X}", $_[0] }, $c->arg('DATA')],
                               pack_ptr   => $pack });

  my $str = pack('N*', 0xdeadbeef, 0x2badc0de, 0x12345678, 0xdeadc0de);

  my $u = $c->unpack('PtrHookTest', $str);

  ok($u->{pTest}, "Test{0xDEADBEEF}");
  ok($u->{pDate}, "struct Date{0x2BADC0DE}");
  ok($u->{pEnum}, "enum Enum{0x12345678}");
  ok($u->{pText}, "Text{0xDEADC0DE}");

  my $p = $c->pack('PtrHookTest', $u);

  ok($p, $str);

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.868 second using v1.00-cache-2.02-grep-82fe00e-cpan-48ebf85a1963 )