Skip to content

How to store binary data in a buffer? #22

mrhdias opened this Issue Mar 25, 2013 · 1 comment

2 participants

mrhdias commented Mar 25, 2013

I need to get binary data from a function to a buffer and then pass that data to a perl6 filehandle. Is there any solution using the NativeCall module that allows store the data in a buffer?

C code:

gdImagePtr im;
int size;
char* data = (char*)gdImagePngPtr(im, &size);
fwrite(data, sizeof(char), size, out);

Perl6 Code Example:

sub gdImagePngPtr(GD::Image $gdImagePtr, CArray[int32] $size)
    returns Buf is native('') { ... };
my $size = CArray[int32].new();
$size[0] = 0;
my $fh = open "test_save_data.png", :w :bin;
my Buf $data = gdImagePngPtr($im, $size);

Example from the GD Library FAQ
How do I load an image file from a buffer in memory?

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>

gdImagePtr myLoadPng(char *filename) {
    FILE *in;
    struct stat stat_buf;
    gdImagePtr im;
    in = fopen("myimage.png", "rb");
    if (!in) {
        /* Error */
    if (fstat(fileno(in), &stat_buf) != 0) {
        /* Error */
    /* Read the entire thing into a buffer that we allocate */
    char *buffer = malloc(stat_buf.st_size);
    if (!buffer) {
        /* Error */
    if (fread(buffer, 1, stat_buf.st_size, in) != stat_buf.st_size) {
        /* Error */
    im = gdImageCreateFromPngPtr(stat_buf.st_size, buffer);
    /* WE allocated the memory, WE free it with our normal free function */
    return im;

There's no way at the moment to easily get Buf objects from CArrays. gdImgPngPtr should return a CArray[int8] in any case, and then you'll have to create a Buf object and populate it with a loop based on the CArray and the size you get from the function call. In terms of library design, it's probably best to keep the raw library function library-internal and do the CArray to Buf conversion in a function/method you expose to the user.

I'm working on making this part of Zavolaj better (it's a known sore spot), but it's blocking on me getting a fair amount of plumbing done internally in NQP and Rakudo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.