From: Nicholas Clark Date: Sun, 16 Apr 2006 11:35:38 +0000 (+0000) Subject: Provide a new flag for sv_usepvn_flags, SV_HAS_TRAILING_NUL, which X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c1c21316ed394affd6841f00fb82bc62eb5fd0a5;p=p5sagit%2Fp5-mst-13.2.git Provide a new flag for sv_usepvn_flags, SV_HAS_TRAILING_NUL, which signals that the buffer passed in is already well-formed for use as SvPVX (i.e. it is followed by a trailing NUL), and hence the realloc() to add a NUL can be skipped. p4raw-id: //depot/perl@27841 --- diff --git a/pp.c b/pp.c index a1f51aa..8914545 100644 --- a/pp.c +++ b/pp.c @@ -2458,9 +2458,9 @@ PP(pp_complement) p = uvchr_to_utf8_flags(p, ~c, UNICODE_ALLOW_ANY); } *p = '\0'; - sv_setpvn(TARG, (char*)result, targlen); + sv_usepvn_flags(TARG, (char*)result, targlen, + SV_HAS_TRAILING_NUL); SvUTF8_on(TARG); - Safefree(result); } else { U8 *result; @@ -2474,9 +2474,8 @@ PP(pp_complement) *p++ = ~c; } *p = '\0'; - sv_setpvn(TARG, (char*)result, nchar); + sv_usepvn_flags(TARG, (char*)result, nchar, SV_HAS_TRAILING_NUL); SvUTF8_off(TARG); - Safefree(result); } SETs(TARG); RETURN; diff --git a/sv.c b/sv.c index 85290bb..247ab31 100644 --- a/sv.c +++ b/sv.c @@ -3890,12 +3890,16 @@ Perl_sv_setpv_mg(pTHX_ register SV *sv, register const char *ptr) Tells an SV to use C to find its string value. Normally the string is stored inside the SV but sv_usepvn allows the SV to use an outside string. The C should point to memory that was allocated -by C. The string length, C, must be supplied. This -function will realloc (i.e. move) the memory pointed to by C, +by C. The string length, C, must be supplied. By default +this function will realloc (i.e. move) the memory pointed to by C, so that pointer should not be freed or used by the programmer after giving it to sv_usepvn, and neither should any pointers from "behind" -that pointer (e.g. ptr + 1) be used. If C & SV_SMAGIC is true, will -call SvSETMAGIC. +that pointer (e.g. ptr + 1) be used. + +If C & SV_SMAGIC is true, will call SvSETMAGIC. If C & +SV_HAS_TRAILING_NUL is true, then C must be NUL, and the realloc +I be skipped. (i.e. the buffer is actually at least 1 byte longer than +C, and already meets the requirements for storing in C) =cut */ @@ -3916,7 +3920,8 @@ Perl_sv_usepvn_flags(pTHX_ SV *sv, char *ptr, STRLEN len, U32 flags) if (SvPVX_const(sv)) SvPV_free(sv); - allocate = PERL_STRLEN_ROUNDUP(len + 1); + allocate = (flags & SV_HAS_TRAILING_NUL) + ? len : PERL_STRLEN_ROUNDUP(len + 1); #ifdef DEBUGGING { /* Force a move to shake out bugs in callers. */ @@ -3927,12 +3932,16 @@ Perl_sv_usepvn_flags(pTHX_ SV *sv, char *ptr, STRLEN len, U32 flags) ptr = new_ptr; } #else - ptr = saferealloc (ptr, allocate); + if (!(flags & SV_HAS_TRAILING_NUL)) { + ptr = saferealloc (ptr, allocate); + } #endif SvPV_set(sv, ptr); SvCUR_set(sv, len); SvLEN_set(sv, allocate); - *SvEND(sv) = '\0'; + if (!(flags & SV_HAS_TRAILING_NUL)) { + *SvEND(sv) = '\0'; + } (void)SvPOK_only_UTF8(sv); /* validate pointer */ SvTAINT(sv); if (flags & SV_SMAGIC) diff --git a/sv.h b/sv.h index e887497..b6d4b14 100644 --- a/sv.h +++ b/sv.h @@ -1637,6 +1637,7 @@ Like C but doesn't process magic. #define SV_CONST_RETURN 32 #define SV_MUTABLE_RETURN 64 #define SV_SMAGIC 128 +#define SV_HAS_TRAILING_NUL 256 #define sv_unref(sv) sv_unref_flags(sv, 0) #define sv_force_normal(sv) sv_force_normal_flags(sv, 0)