--- Convert-Scalar/Scalar.xs 2014/02/03 03:32:13 1.11 +++ Convert-Scalar/Scalar.xs 2017/08/15 07:29:07 1.12 @@ -4,18 +4,49 @@ #define RETCOPY(sv) \ if (GIMME_V != G_VOID) \ - { \ + { \ dXSTARG; \ sv_setsv (TARG, (sv)); \ EXTEND (SP, 1); \ PUSHs (TARG); \ } +static void +extend (SV *scalar, STRLEN addlen) +{ + SvUPGRADE (scalar, SVt_PV); + + STRLEN cur = SvCUR (scalar); + STRLEN len = SvLEN (scalar); + + if (cur + addlen < len) + return; + + STRLEN l = len; + STRLEN o = cur + addlen >= 4096 ? sizeof (void *) * 4 : 0; + + if (l < 64) + l = 64; + + /* for big sizes, leave a bit of space for malloc management, and assume 4kb or smaller pages */ + addlen += o; + + while (cur + addlen >= l) + l <<= 1; + + sv_grow (scalar, l - o); +} + MODULE = Convert::Scalar PACKAGE = Convert::Scalar +TYPEMAP: < 1) @@ -119,37 +142,31 @@ void readonly_on (SV *scalar) - PROTOTYPE: $ CODE: SvREADONLY_on (scalar); void readonly_off (SV *scalar) - PROTOTYPE: $ CODE: SvREADONLY_off (scalar); void unmagic (SV *scalar, char type) - PROTOTYPE: $$ CODE: sv_unmagic (scalar, type); void weaken (SV *scalar) - PROTOTYPE: $ CODE: sv_rvweaken (scalar); void taint (SV *scalar) - PROTOTYPE: $ CODE: SvTAINTED_on (scalar); bool tainted (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvTAINTED (scalar); OUTPUT: @@ -157,13 +174,11 @@ void untaint (SV *scalar) - PROTOTYPE: $ CODE: SvTAINTED_off (scalar); STRLEN len (SV *scalar) - PROTOTYPE: $ CODE: if (SvTYPE (scalar) < SVt_PV) XSRETURN_UNDEF; @@ -173,46 +188,111 @@ void grow (SV *scalar, STRLEN newlen) - PROTOTYPE: $$ PPCODE: sv_grow (scalar, newlen); if (GIMME_V != G_VOID) XPUSHs (sv_2mortal (SvREFCNT_inc (scalar))); void -extend (SV *scalar, STRLEN addlen) - PROTOTYPE: $$ +extend (SV *scalar, STRLEN addlen = 64) PPCODE: { - if (SvTYPE (scalar) < SVt_PV) - sv_upgrade (scalar, SVt_PV); + extend (scalar, addlen); - if (SvCUR (scalar) + addlen >= SvLEN (scalar)) - { - STRLEN l = SvLEN (scalar); - STRLEN o = SvCUR (scalar) + addlen >= 4096 ? sizeof (void *) * 4 : 0; + if (GIMME_V != G_VOID) + XPUSHs (sv_2mortal (SvREFCNT_inc (scalar))); +} + +SSize_t +extend_read (PerlIO *fh, SV *scalar, STRLEN addlen = 64) + CODE: +{ + if (SvUTF8 (scalar)) + sv_utf8_downgrade (scalar, 0); - if (l < 64) - l = 64; + extend (scalar, addlen); - /* for big sizes, leave a bit of space for malloc management, and assume 4kb or smaller pages */ - addlen += o; + RETVAL = PerlLIO_read (PerlIO_fileno (fh), SvEND (scalar), SvLEN (scalar) - SvCUR (scalar)); - while (SvCUR (scalar) + addlen >= l) - l <<= 1; + if (RETVAL < 0) + XSRETURN_UNDEF; - l -= o; + SvPOK_only (scalar); + SvCUR_set (scalar, SvCUR (scalar) + RETVAL); +} + OUTPUT: RETVAL - sv_grow (scalar, l); +SSize_t +read_all (PerlIO *fh, SV *scalar, STRLEN count) + CODE: +{ + SvUPGRADE (scalar, SVt_PV); + if (SvUTF8 (scalar)) + sv_utf8_downgrade (scalar, 0); + + SvPOK_only (scalar); + + int fd = PerlIO_fileno (fh); + RETVAL = 0; + + SvGROW (scalar, count); + + for (;;) + { + STRLEN rem = count - RETVAL; + + if (!rem) + break; + + STRLEN got = PerlLIO_read (fd, SvPVX (scalar) + RETVAL, rem); + + if (got == 0) + break; + else if (got < 0) + if (RETVAL) + break; + else + XSRETURN_UNDEF; + + RETVAL += got; } - if (GIMME_V != G_VOID) - XPUSHs (sv_2mortal (SvREFCNT_inc (scalar))); + SvCUR_set (scalar, RETVAL); +} + OUTPUT: RETVAL + +SSize_t +write_all (PerlIO *fh, SV *scalar) + CODE: +{ + STRLEN count; + char *ptr = SvPVbyte (scalar, count); + + int fd = PerlIO_fileno (fh); + RETVAL = 0; + + for (;;) + { + STRLEN rem = count - RETVAL; + + if (!rem) + break; + + STRLEN got = PerlLIO_write (fd, ptr + RETVAL, rem); + + if (got < 0) + if (RETVAL) + break; + else + XSRETURN_UNDEF; + + RETVAL += got; + } } + OUTPUT: RETVAL int refcnt (SV *scalar, U32 newrefcnt = NO_INIT) - PROTOTYPE: $;$ ALIAS: refcnt_rv = 1 CODE: @@ -231,7 +311,6 @@ refcnt_inc (SV *scalar) ALIAS: refcnt_inc_rv = 1 - PROTOTYPE: $ CODE: if (ix) { @@ -244,7 +323,6 @@ refcnt_dec (SV *scalar) ALIAS: refcnt_dec_rv = 1 - PROTOTYPE: $ CODE: if (ix) { @@ -255,7 +333,6 @@ bool ok (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvOK (scalar); OUTPUT: @@ -263,7 +340,6 @@ bool uok (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvUOK (scalar); OUTPUT: @@ -271,7 +347,6 @@ bool rok (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvROK (scalar); OUTPUT: @@ -279,7 +354,6 @@ bool pok (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvPOK (scalar); OUTPUT: @@ -287,7 +361,6 @@ bool nok (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvNOK (scalar); OUTPUT: @@ -295,7 +368,6 @@ bool niok (SV *scalar) - PROTOTYPE: $ CODE: RETVAL = !!SvNIOK (scalar); OUTPUT: