1#include "prism/extension.h" 
    3#ifdef PRISM_EXCLUDE_PACK 
    6Init_prism_pack(
void) {}
 
   10static VALUE rb_cPrism;
 
   11static VALUE rb_cPrismPack;
 
   12static VALUE rb_cPrismPackDirective;
 
   13static VALUE rb_cPrismPackFormat;
 
   15static VALUE v3_2_0_symbol;
 
   16static VALUE pack_symbol;
 
   17static VALUE unpack_symbol;
 
   19#if SIZEOF_UINT64_T == SIZEOF_LONG_LONG 
   20# define UINT64T2NUM(x) ULL2NUM(x) 
   21# define NUM2UINT64T(x) (uint64_t)NUM2ULL(x) 
   22#elif SIZEOF_UINT64_T == SIZEOF_LONG 
   23# define UINT64T2NUM(x) ULONG2NUM(x) 
   24# define NUM2UINT64T(x) (uint64_t)NUM2ULONG(x) 
   33            return ID2SYM(rb_intern(
"SPACE"));
 
   35            return ID2SYM(rb_intern(
"COMMENT"));
 
   37            return ID2SYM(rb_intern(
"INTEGER"));
 
   39            return ID2SYM(rb_intern(
"UTF8"));
 
   41            return ID2SYM(rb_intern(
"BER"));
 
   43            return ID2SYM(rb_intern(
"FLOAT"));
 
   44        case PM_PACK_STRING_SPACE_PADDED:
 
   45            return ID2SYM(rb_intern(
"STRING_SPACE_PADDED"));
 
   46        case PM_PACK_STRING_NULL_PADDED:
 
   47            return ID2SYM(rb_intern(
"STRING_NULL_PADDED"));
 
   48        case PM_PACK_STRING_NULL_TERMINATED:
 
   49            return ID2SYM(rb_intern(
"STRING_NULL_TERMINATED"));
 
   50        case PM_PACK_STRING_MSB:
 
   51            return ID2SYM(rb_intern(
"STRING_MSB"));
 
   52        case PM_PACK_STRING_LSB:
 
   53            return ID2SYM(rb_intern(
"STRING_LSB"));
 
   54        case PM_PACK_STRING_HEX_HIGH:
 
   55            return ID2SYM(rb_intern(
"STRING_HEX_HIGH"));
 
   56        case PM_PACK_STRING_HEX_LOW:
 
   57            return ID2SYM(rb_intern(
"STRING_HEX_LOW"));
 
   58        case PM_PACK_STRING_UU:
 
   59            return ID2SYM(rb_intern(
"STRING_UU"));
 
   60        case PM_PACK_STRING_MIME:
 
   61            return ID2SYM(rb_intern(
"STRING_MIME"));
 
   62        case PM_PACK_STRING_BASE64:
 
   63            return ID2SYM(rb_intern(
"STRING_BASE64"));
 
   64        case PM_PACK_STRING_FIXED:
 
   65            return ID2SYM(rb_intern(
"STRING_FIXED"));
 
   66        case PM_PACK_STRING_POINTER:
 
   67            return ID2SYM(rb_intern(
"STRING_POINTER"));
 
   69            return ID2SYM(rb_intern(
"MOVE"));
 
   71            return ID2SYM(rb_intern(
"BACK"));
 
   73            return ID2SYM(rb_intern(
"NULL"));
 
   81    switch (signed_type) {
 
   82        case PM_PACK_UNSIGNED:
 
   83            return ID2SYM(rb_intern(
"UNSIGNED"));
 
   85            return ID2SYM(rb_intern(
"SIGNED"));
 
   86        case PM_PACK_SIGNED_NA:
 
   87            return ID2SYM(rb_intern(
"SIGNED_NA"));
 
   96        case PM_PACK_AGNOSTIC_ENDIAN:
 
   97            return ID2SYM(rb_intern(
"AGNOSTIC_ENDIAN"));
 
   98        case PM_PACK_LITTLE_ENDIAN:
 
   99            return ID2SYM(rb_intern(
"LITTLE_ENDIAN"));
 
  100        case PM_PACK_BIG_ENDIAN:
 
  101            return ID2SYM(rb_intern(
"BIG_ENDIAN"));
 
  102        case PM_PACK_NATIVE_ENDIAN:
 
  103            return ID2SYM(rb_intern(
"NATIVE_ENDIAN"));
 
  104        case PM_PACK_ENDIAN_NA:
 
  105            return ID2SYM(rb_intern(
"ENDIAN_NA"));
 
  114        case PM_PACK_SIZE_SHORT:
 
  115            return ID2SYM(rb_intern(
"SIZE_SHORT"));
 
  116        case PM_PACK_SIZE_INT:
 
  117            return ID2SYM(rb_intern(
"SIZE_INT"));
 
  118        case PM_PACK_SIZE_LONG:
 
  119            return ID2SYM(rb_intern(
"SIZE_LONG"));
 
  120        case PM_PACK_SIZE_LONG_LONG:
 
  121            return ID2SYM(rb_intern(
"SIZE_LONG_LONG"));
 
  123            return ID2SYM(rb_intern(
"SIZE_8"));
 
  124        case PM_PACK_SIZE_16:
 
  125            return ID2SYM(rb_intern(
"SIZE_16"));
 
  126        case PM_PACK_SIZE_32:
 
  127            return ID2SYM(rb_intern(
"SIZE_32"));
 
  128        case PM_PACK_SIZE_64:
 
  129            return ID2SYM(rb_intern(
"SIZE_64"));
 
  131            return ID2SYM(rb_intern(
"SIZE_P"));
 
  132        case PM_PACK_SIZE_NA:
 
  133            return ID2SYM(rb_intern(
"SIZE_NA"));
 
  141    switch (length_type) {
 
  142        case PM_PACK_LENGTH_FIXED:
 
  143            return ID2SYM(rb_intern(
"LENGTH_FIXED"));
 
  144        case PM_PACK_LENGTH_MAX:
 
  145            return ID2SYM(rb_intern(
"LENGTH_MAX"));
 
  146        case PM_PACK_LENGTH_RELATIVE:
 
  147            return ID2SYM(rb_intern(
"LENGTH_RELATIVE"));
 
  148        case PM_PACK_LENGTH_NA:
 
  149            return ID2SYM(rb_intern(
"LENGTH_NA"));
 
  159        case PM_PACK_ENCODING_ASCII_8BIT:
 
  160            index = rb_ascii8bit_encindex();
 
  162        case PM_PACK_ENCODING_US_ASCII:
 
  163            index = rb_usascii_encindex();
 
  165        case PM_PACK_ENCODING_UTF_8:
 
  166            index = rb_utf8_encindex();
 
  171    return rb_enc_from_encoding(rb_enc_from_index(index));
 
  182    if (version_symbol != v3_2_0_symbol) {
 
  183        rb_raise(rb_eArgError, 
"invalid version");
 
  187    if (variant_symbol == pack_symbol) {
 
  188        variant = PM_PACK_VARIANT_PACK;
 
  189    } 
else if (variant_symbol == unpack_symbol) {
 
  190        variant = PM_PACK_VARIANT_UNPACK;
 
  192        rb_raise(rb_eArgError, 
"invalid variant");
 
  197    const char *format = RSTRING_PTR(format_string);
 
  198    const char *format_end = format + RSTRING_LEN(format_string);
 
  203    while (format < format_end) {
 
  211        const char *directive_start = format;
 
  213        pm_pack_result parse_result = pm_pack_parse(variant, &format, format_end, &
type, &signed_type, &endian,
 
  214                                                    &size, &length_type, &length, &encoding);
 
  216        const char *directive_end = format;
 
  218        switch (parse_result) {
 
  221            case PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE:
 
  222                rb_raise(rb_eArgError, 
"unsupported directive");
 
  223            case PM_PACK_ERROR_UNKNOWN_DIRECTIVE:
 
  224                rb_raise(rb_eArgError, 
"unsupported directive");
 
  225            case PM_PACK_ERROR_LENGTH_TOO_BIG:
 
  227            case PM_PACK_ERROR_BANG_NOT_ALLOWED:
 
  229            case PM_PACK_ERROR_DOUBLE_ENDIAN:
 
  232                rb_bug(
"parse result");
 
  235        if (
type == PM_PACK_END) {
 
  239        VALUE directive_args[9] = {
 
  243            pack_type_to_symbol(
type),
 
  244            pack_signed_to_symbol(signed_type),
 
  245            pack_endian_to_symbol(endian),
 
  246            pack_size_to_symbol(size),
 
  247            pack_length_type_to_symbol(length_type),
 
  254    VALUE format_args[2];
 
  255    format_args[0] = directives_array;
 
  256    format_args[1] = pack_encoding_to_ruby(encoding);
 
  264Init_prism_pack(
void) {
 
  271    v3_2_0_symbol = 
ID2SYM(rb_intern(
"v3_2_0"));
 
  272    pack_symbol = 
ID2SYM(rb_intern(
"pack"));
 
  273    unpack_symbol = 
ID2SYM(rb_intern(
"unpack"));
 
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module(const char *name)
Defines a top-level module.
VALUE rb_define_module_under(VALUE outer, const char *name)
Defines a module under the namespace of outer.
#define ID2SYM
Old name of RB_ID2SYM.
#define Qnil
Old name of RUBY_Qnil.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
Allocates, then initialises an instance of the given class.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US  ASCII" encoding.
VALUE type(ANYARGS)
ANYARGS-ed function type.
pm_pack_encoding
The type of encoding for a pack template string.
pm_pack_result
The result of parsing a pack template.
pm_pack_variant
The type of pack template we are parsing.
pm_pack_endian
The endianness of a pack directive.
pm_pack_signed
The signness of a pack directive.
pm_pack_size
The size of an integer pack directive.
pm_pack_length_type
The type of length of a pack directive.
pm_pack_type
A directive within the pack template.
#define StringValue(v)
Ensures that the parameter object is a String.
uintptr_t VALUE
Type that represents a Ruby object.