CBOR-XS

 view release on metacpan or  search on metacpan

XS.xs  view on Meta::CPAN

                }
            }
        }

      self->incr_pos = self->incr_need;

      if (count > 0)
        {
          while (!--count)
            {
              if (!AvFILLp (self->incr_count))
                return 1; // done

              SvREFCNT_dec_NN (av_pop (self->incr_count));
              count = SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]);
            }

          SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]) = count;
        }
    }

  return 0;
}

                  
/////////////////////////////////////////////////////////////////////////////
// XS interface functions

MODULE = CBOR::XS		PACKAGE = CBOR::XS

BOOT:
{
	cbor_stash         = gv_stashpv ("CBOR::XS"         , 1);
	cbor_tagged_stash  = gv_stashpv ("CBOR::XS::Tagged" , 1);

	types_boolean_stash = gv_stashpv ("Types::Serialiser::Boolean", 1);
	types_error_stash   = gv_stashpv ("Types::Serialiser::Error"  , 1);

        types_true  = get_bool ("Types::Serialiser::true" );
        types_false = get_bool ("Types::Serialiser::false");
        types_error = get_bool ("Types::Serialiser::error");

        default_filter = newSVpv ("CBOR::XS::default_filter", 0);

        sv_cbor = newSVpv ("CBOR", 0);
        SvREADONLY_on (sv_cbor);

        assert (("STRLEN must be an unsigned type", 0 <= (STRLEN)-1));
}

PROTOTYPES: DISABLE

void CLONE (...)
	CODE:
        cbor_stash          = 0;
        cbor_tagged_stash   = 0;
        types_error_stash   = 0;
        types_boolean_stash = 0;

void new (char *klass)
	PPCODE:
{
	SV *pv = NEWSV (0, sizeof (CBOR));
        SvPOK_only (pv);
        cbor_init ((CBOR *)SvPVX (pv));
        XPUSHs (sv_2mortal (sv_bless (
           newRV_noinc (pv),
           strEQ (klass, "CBOR::XS") ? CBOR_STASH : gv_stashpv (klass, 1)
        )));
}

void shrink (CBOR *self, int enable = 1)
	ALIAS:
        shrink            = F_SHRINK
        allow_unknown     = F_ALLOW_UNKNOWN
        allow_sharing     = F_ALLOW_SHARING
        allow_cycles      = F_ALLOW_CYCLES
        allow_weak_cycles = F_ALLOW_WEAK_CYCLES
        forbid_objects    = F_FORBID_OBJECTS
        pack_strings      = F_PACK_STRINGS
        text_keys         = F_TEXT_KEYS
        text_strings      = F_TEXT_STRINGS
        validate_utf8     = F_VALIDATE_UTF8
	PPCODE:
{
        if (enable)
          self->flags |=  ix;
        else
          self->flags &= ~ix;

        XPUSHs (ST (0));
}

void get_shrink (CBOR *self)
	ALIAS:
        get_shrink            = F_SHRINK
        get_allow_unknown     = F_ALLOW_UNKNOWN
        get_allow_sharing     = F_ALLOW_SHARING
        get_allow_cycles      = F_ALLOW_CYCLES
        get_allow_weak_cycles = F_ALLOW_WEAK_CYCLES
        get_forbid_objects    = F_FORBID_OBJECTS
        get_pack_strings      = F_PACK_STRINGS
        get_text_keys         = F_TEXT_KEYS
        get_text_strings      = F_TEXT_STRINGS
        get_validate_utf8     = F_VALIDATE_UTF8
	PPCODE:
        XPUSHs (boolSV (self->flags & ix));

void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
	PPCODE:
        self->max_depth = max_depth;
        XPUSHs (ST (0));

U32 get_max_depth (CBOR *self)
	CODE:
        RETVAL = self->max_depth;
	OUTPUT:
        RETVAL

void max_size (CBOR *self, U32 max_size = 0)
	PPCODE:
        self->max_size = max_size;
        XPUSHs (ST (0));

int get_max_size (CBOR *self)
	CODE:
        RETVAL = self->max_size;
	OUTPUT:
        RETVAL

void filter (CBOR *self, SV *filter = 0)
	PPCODE:
        SvREFCNT_dec (self->filter);
        self->filter = filter ? newSVsv (filter) : filter;
        XPUSHs (ST (0));

SV *get_filter (CBOR *self)
	CODE:
        RETVAL = self->filter ? self->filter : NEWSV (0, 0);
	OUTPUT:
        RETVAL

void encode (CBOR *self, SV *scalar)
	PPCODE:
        PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
        XPUSHs (scalar);

void decode (CBOR *self, SV *cborstr)
	PPCODE:
        PUTBACK; cborstr = decode_cbor (cborstr, self, 0); SPAGAIN;
        XPUSHs (cborstr);

void decode_prefix (CBOR *self, SV *cborstr)
	PPCODE:
{
	SV *sv;
        char *offset;
        PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN;
        EXTEND (SP, 2);
        PUSHs (sv);
        PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
}

void incr_parse (CBOR *self, SV *cborstr)
	ALIAS:
        incr_parse_multiple = 1
	PPCODE:
{
        if (SvUTF8 (cborstr))
          sv_utf8_downgrade (cborstr, 0);

        if (!self->incr_count)
          {
            self->incr_count = newAV ();
            self->incr_pos   = 0;
            self->incr_need  = 1;

            av_push (self->incr_count, newSViv (1));
          }

        do
          {
            if (!incr_parse (self, cborstr))
              {
                if (self->incr_need > self->max_size && self->max_size)
                  croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
                         (unsigned long)self->incr_need, (unsigned long)self->max_size);

                break;
              }

            SV *sv;
            char *offset;

            PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN;
            XPUSHs (sv);

            sv_chop (cborstr, offset);

            av_clear (self->incr_count);
            av_push (self->incr_count, newSViv (1));

            self->incr_pos = 0;
            self->incr_need = self->incr_pos + 1;
          }
        while (ix);
}

void incr_reset (CBOR *self)
	CODE:
{
	SvREFCNT_dec (self->incr_count);
        self->incr_count = 0;
}

void DESTROY (CBOR *self)
	PPCODE:
	cbor_free (self);

PROTOTYPES: ENABLE

void encode_cbor (SV *scalar)
	ALIAS:
        encode_cbor         = 0
        encode_cbor_sharing = F_ALLOW_SHARING
	PPCODE:
{
        CBOR cbor;
        cbor_init (&cbor);
        cbor.flags |= ix;
        PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN;
        XPUSHs (scalar);
}

void decode_cbor (SV *cborstr)
	PPCODE:
{
        CBOR cbor;
        cbor_init (&cbor);
        PUTBACK; cborstr = decode_cbor (cborstr, &cbor, 0); SPAGAIN;
        XPUSHs (cborstr);
}

#ifdef __AFL_COMPILER

void
afl_init ()
	CODE:
        __AFL_INIT ();

int
afl_loop (unsigned int count = 10000)
	CODE:
	RETVAL = __AFL_LOOP (count);
	OUTPUT:
	RETVAL

#endif



( run in 0.777 second using v1.01-cache-2.11-cpan-71847e10f99 )