const char *keysave = key;
int flags = 0;
+ if (klen < 0) {
+ klen = -klen;
+ is_utf8 = TRUE;
+ }
+
if (is_utf8) {
STRLEN tmplen = klen;
/* Just casting the &klen to (STRLEN) won't work well
}
SV**
-S_hv_store_flags(pTHX_ HV *hv, const char *key, I32 klen, SV *val,
+Perl_hv_store_flags(pTHX_ HV *hv, const char *key, I32 klen, SV *val,
register U32 hash, int flags)
{
register XPVHV* xhv;
xhv->xhv_placeholders--; /* yes, can store into placeholder slot */
else
SvREFCNT_dec(HeVAL(entry));
- HeVAL(entry) = val;
+ if (flags & HVhek_PLACEHOLD) {
+ /* We have been requested to insert a placeholder. Currently
+ only Storable is allowed to do this. */
+ xhv->xhv_placeholders++;
+ HeVAL(entry) = &PL_sv_undef;
+ } else
+ HeVAL(entry) = val;
if (HeKFLAGS(entry) != flags) {
/* We match if HVhek_UTF8 bit in our flags and hash key's match.
HeKEY_hek(entry) = share_hek_flags(key, klen, hash, flags);
else /* gotta do the real thing */
HeKEY_hek(entry) = save_hek_flags(key, klen, hash, flags);
- HeVAL(entry) = val;
+ if (flags & HVhek_PLACEHOLD) {
+ /* We have been requested to insert a placeholder. Currently
+ only Storable is allowed to do this. */
+ xhv->xhv_placeholders++;
+ HeVAL(entry) = &PL_sv_undef;
+ } else
+ HeVAL(entry) = val;
HeNEXT(entry) = *oentry;
*oentry = entry;
HvMAX(hv) = hv_max;
hv_iterinit(ohv);
- while ((entry = hv_iternext(ohv))) {
+ while ((entry = hv_iternext_flags(ohv, 0))) {
hv_store_flags(hv, HeKEY(entry), HeKLEN(entry),
newSVsv(HeVAL(entry)), HeHASH(entry),
HeKFLAGS(entry));
hash buckets that happen to be in use. If you still need that esoteric
value, you can get it through the macro C<HvFILL(tb)>.
+
=cut
*/
/* used to be xhv->xhv_fill before 5.004_65 */
return XHvTOTALKEYS(xhv);
}
-
/*
=for apidoc hv_iternext
HE *
Perl_hv_iternext(pTHX_ HV *hv)
{
+ return hv_iternext_flags(hv, 0);
+}
+
+/*
+XXX=for apidoc hv_iternext
+
+Returns entries from a hash iterator. See C<hv_iterinit>.
+
+XXX=cut
+*/
+
+HE *
+Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
+{
register XPVHV* xhv;
register HE *entry;
HE *oldentry;
if (entry)
{
entry = HeNEXT(entry);
- /*
- * Skip past any placeholders -- don't want to include them in
- * any iteration.
- */
- while (entry && HeVAL(entry) == &PL_sv_undef) {
- entry = HeNEXT(entry);
+ if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) {
+ /*
+ * Skip past any placeholders -- don't want to include them in
+ * any iteration.
+ */
+ while (entry && HeVAL(entry) == &PL_sv_undef) {
+ entry = HeNEXT(entry);
+ }
}
}
while (!entry) {
/* entry = (HvARRAY(hv))[HvRITER(hv)]; */
entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter];
- /* if we have an entry, but it's a placeholder, don't count it */
- if (entry && HeVAL(entry) == &PL_sv_undef)
- entry = 0;
-
+ if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) {
+ /* if we have an entry, but it's a placeholder, don't count it */
+ if (entry && HeVAL(entry) == &PL_sv_undef)
+ entry = 0;
+ }
}
if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */
Perl_hv_iternextsv(pTHX_ HV *hv, char **key, I32 *retlen)
{
HE *he;
- if ( (he = hv_iternext(hv)) == NULL)
+ if ( (he = hv_iternext_flags(hv, 0)) == NULL)
return NULL;
*key = hv_iterkey(he, retlen);
return hv_iterval(hv, he);