Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active April 18, 2016 02:17
Show Gist options
  • Save Xliff/53f4c7e86c2e0711b177ac89cbf5d87a to your computer and use it in GitHub Desktop.
Save Xliff/53f4c7e86c2e0711b177ac89cbf5d87a to your computer and use it in GitHub Desktop.

In working on trying to write Perl6 library bindings for libogg, I ran into this interesting problem.

How would you represent this piece of a struct in NativeCall:

unsigned char header[282]

Turns out that this is one of the shortcomings of NativeCall.

Until Perl6 can adequately represent pre-defined character arrays, you can do something like this:

class ogg_stream_state_header is repr('CStruct') {
        has uint64  $.header00;
        has uint64  $.header01;
        has uint64  $.header02;
        has uint64  $.header03;
        has uint64  $.header04;
        has uint64  $.header05;
        has uint64  $.header06;
        has uint64  $.header07;
        has uint64  $.header08;
        has uint64  $.header09;
        has uint64  $.header10;
        has uint64  $.header11;
        has uint64  $.header12;
        has uint64  $.header13;
        has uint64  $.header14;
        has uint64  $.header15;
        has uint64  $.header16;
        has uint64  $.header17;
        has uint64  $.header18;
        has uint64  $.header19;
        has uint64  $.header20;
        has uint64  $.header21;
        has uint64  $.header22;
        has uint64  $.header23;
        has uint64  $.header24;
        has uint64  $.header25;
        has uint64  $.header26;
        has uint64  $.header27;
        has uint64  $.header28;
        has uint64  $.header29;
        has uint64  $.header30;
        has uint64  $.header31;
        has uint64  $.header32;
        has uint64  $.header33;
        has uint64  $.header34;
        has uint8   $.header35;

        method as_blob {
                my @uint64_list = (
                        $.header00,
                        $.header01,
                        $.header02,
                        $.header03,
                        $.header04,
                        $.header05,
                        $.header06,
                        $.header07,
                        $.header08,
                        $.header09,
                        $.header10,
                        $.header11,
                        $.header12,
                        $.header13,
                        $.header14,
                        $.header15,
                        $.header16,
                        $.header17,
                        $.header18,
                        $.header19,
                        $.header20,
                        $.header21,
                        $.header22,
                        $.header23,
                        $.header24,
                        $.header25,
                        $.header26,
                        $.header27,
                        $.header28,
                        $.header29,
                        $.header30,
                        $.header31,
                        $.header32,
                        $.header33,
                        $.header34
                );

                my @b;
                for @uint64_list -> $u {
                        # cw: Break the uint64 into 8 uint8 chunks.
                        my $ca = Buf[uint8].new(
                                nativecast(CArray[uint8], array[uint64].new($u)[^8]
                                );
                        for ^8 -> $i {
                                @b.push($ca[$i]);
                        }
                }
                @b.push($.header35);

                # Return BLOB containing assembled 282 byte header.
                return Blob.new(@b);
        }
}

sortis from #perl6 provided this, more elegant, version:

# sortiz++
method as_blob2 {
    return Blob[uint8].new(
        nativecast(CArray[uint8], self)[
            ^nativesizeof(ogg_stream_state_header)
        ]
    );
}

Hope this gets solved, soon. 282 bytes was manageable, but 2820 bytes is another matter entirely.

Thanks to #perl6's timotimo for this suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment