The Perl Advent Calendar needs more articles for 2022. Submit your idea today!

Name

SPVM::Document::Resource - How to write the resource module

Resource

A resource is a native module that contains a set of sources and headers of native language such as C language or C++.

A resource doesn't has the native module file such as Foo.c. It has a config file such as Foo.config. Header files are placed at Foo.native/include. Source filies are placed at Foo.native/src.

Let's see the files of Resource::Zlib::V1_2_11 as an example.

SPVM/Resource/Zlib/V1_2_11.config

  use strict;
  use warnings;
   
  use SPVM::Builder::Config;
  my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);
   
  # C souce files
  my @source_files = qw(
    adler32.c
    compress.c
    crc32.c
    deflate.c
    gzclose.c
    gzlib.c
    gzread.c
    gzwrite.c
    infback.c
    inffast.c
    inflate.c
    inftrees.c
    trees.c
    uncompr.c
    zutil.c
  );
  $config->add_source_files(@source_files);
   
  my @ccflags = qw(-D_GNU_SOURCE);
   
  $config->add_ccflags(@ccflags);
   
  $config;  

The list of the files in include directory

The header files of zlib. These files are the header files extracted from src directory.

  crc32.h
  deflate.h
  gzguts.h
  inffast.h
  inffixed.h
  inflate.h
  inftrees.h
  trees.h
  zconf.h
  zlib.h
  zutil.h

The list of the files in src directory

The source files of zlib.

  adler32.c
  amiga
  ChangeLog
  CMakeLists.txt
  compress.c
  configure
  contrib
  crc32.c
  crc32.h
  deflate.c
  deflate.h
  doc
  examples
  FAQ
  gzclose.c
  gzguts.h
  gzlib.c
  gzread.c
  gzwrite.c
  INDEX
  infback.c
  inffast.c
  inffast.h
  inffixed.h
  inflate.c
  inflate.h
  inftrees.c
  inftrees.h
  Makefile
  Makefile.in
  make_vms.com
  msdos
  nintendods
  old
  os400
  qnx
  README
  test
  treebuild.xml
  trees.c
  trees.h
  uncompr.c
  watcom
  win32
  zconf.h
  zconf.h.cmakein
  zconf.h.in
  zlib2ansi
  zlib.3
  zlib.3.pdf
  zlib.h
  zlib.map
  zlib.pc.cmakein
  zlib.pc.in
  zutil.c
  zutil.h

Using Resource

The method "use_resource" in SPVM::Builder::Config loads a resource. MyZlib is a native module to use Resource::Zlib::V1_2_11.

lib/SPVM/MyZlib.config

  use strict;
  use warnings;
  
  my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);
  
  $config->use_resource('Resource::Zlib::V1_2_11');
  
  $config;

lib/SPVM/MyZlib.spvm

Define a native method test_gzopen_gzread.

  class MyZlib {
    native static method test_gzopen_gzread : void ($file : string);
  }

lib/SPVM/MyZlib.c

zlib.h can be included because Resource::Zlib::V1_2_11 is used.

  #include "spvm_native.h"
  
  #include <zlib.h>
  
  int32_t SPVM__MyZlib__test_gzopen_gzread(SPVM_ENV* env, SPVM_VALUE* stack) {
    (void)env;
    
    void* sp_file = stack[0].oval;
    
    const char* file = env->get_chars(env, stack, sp_file);
    
    z_stream z;
    
    gzFile gz_fh = gzopen(file, "rb");
    
    if (gz_fh == NULL){
      return env->die(env, stack, "Can't open file \"%s\"\n", file);
    }
    
    char buffer[256] = {0};
    int32_t cnt;
    while((cnt = gzread(gz_fh, buffer, sizeof(buffer))) > 0){
      
    }
    
    printf("%s", buffer);
    
    return 0;
  }

myzlib.pl

A Perl script to call test_gzopen_gzread method of MyZlib class.

  use strict;
  use warnings;
  use FindBin;
  use lib "$FindBin::Bin/lib";
  BEGIN { $ENV{SPVM_BUILD_DIR} = "$FindBin::Bin/.spvm_build"; }

  use SPVM 'MyZlib';

  my $gz_file = "$FindBin::Bin/minitest.txt.gz";
  SPVM::MyZlib->test_gzopen_gzread($gz_file);

Creating Resource Distribution

spvmdist command with --resource option create a resource distribution.

  # C language resource
  spvmdist --resource Resource::Foo::V1_0_0

  # C++ resource
  spvmdist --resource --native c++ Resource::Foo::V1_0_0

Resource Modules

Resource::Zlib