struct mro_meta *xhv_mro_meta;
};
+#define _XPVHV_ALLOCATED_HEAD \
+ STRLEN xhv_fill; /* how full xhv_array currently is */ \
+ STRLEN xhv_max /* subscript of last element of xhv_array */
+
+#define _XPVHV_HEAD \
+ union _xnvu xnv_u; \
+ _XPVHV_ALLOCATED_HEAD
+
/* hash structure: */
/* This structure must match the beginning of struct xpvmg in sv.h. */
struct xpvhv {
- union {
- NV xnv_nv; /* numeric value, if any */
- HV * xgv_stash;
- struct {
- U32 xlow;
- U32 xhigh;
- } xpad_cop_seq; /* used by pad.c for cop_sequence */
- struct {
- U32 xbm_previous; /* how many characters in string before rare? */
- U8 xbm_flags;
- U8 xbm_rare; /* rarest character in string */
- } xbm_s; /* fields from PVBM */
- } xnv_u;
- STRLEN xhv_fill; /* how full xhv_array currently is */
- STRLEN xhv_max; /* subscript of last element of xhv_array */
- union {
- IV xivu_iv; /* integer value or pv offset */
- UV xivu_uv;
- void * xivu_p1;
- I32 xivu_i32;
- HEK * xivu_namehek;
- } xiv_u;
- union {
- MAGIC* xmg_magic; /* linked list of magicalness */
- HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
- } xmg_u;
- HV* xmg_stash; /* class package */
+ _XPVHV_HEAD;
+ _XPVMG_HEAD;
};
#define xhv_keys xiv_u.xivu_iv
typedef struct {
- STRLEN xhv_fill; /* how full xhv_array currently is */
- STRLEN xhv_max; /* subscript of last element of xhv_array */
- union {
- IV xivu_iv; /* integer value or pv offset */
- UV xivu_uv;
- void * xivu_p1;
- I32 xivu_i32;
- HEK * xivu_namehek;
- } xiv_u;
- union {
- MAGIC* xmg_magic; /* linked list of magicalness */
- HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
- } xmg_u;
- HV* xmg_stash; /* class package */
+ _XPVHV_ALLOCATED_HEAD;
+ _XPVMG_HEAD;
} xpvhv_allocated;
+#undef _XPVHV_ALLOCATED_HEAD
+#undef _XPVHV_HEAD
+
/* hash a key */
/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins
* from requirements by Colin Plumb.
variable. Remember though, that hash keys in perl are free to contain
embedded nulls, so using C<strlen()> or similar is not a good way to find
the length of hash keys. This is very similar to the C<SvPV()> macro
-described elsewhere in this document.
+described elsewhere in this document. See also C<HeUTF8>.
+
+If you are using C<HePV> to get values to pass to C<newSVpvn()> to create a
+new SV, you should consider using C<newSVhek(HeKEY_hek(he))> as it is more
+efficient.
+
+=for apidoc Am|char*|HeUTF8|HE* he|STRLEN len
+Returns whether the C<char *> value returned by C<HePV> is encoded in UTF-8,
+doing any necessary dereferencing of possibly C<SV*> keys. The value returned
+will be 0 or non-0, not necesarily 1 (or even a value with any low bits set),
+so B<do not> blindly assign this to a C<bool> variable, as C<bool> may be a
+typedef for C<char>.
=for apidoc Am|SV*|HeSVKEY|HE* he
Returns the key as an C<SV*>, or C<NULL> if the hash entry does not
#define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \
SvPV(HeKEY_sv(he),lp) : \
((lp = HeKLEN(he)), HeKEY(he)))
+#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \
+ SvUTF8(HeKEY_sv(he)) : \
+ (U32)HeKUTF8(he))
#define HeSVKEY(he) ((HeKEY(he) && \
HeKLEN(he) == HEf_SVKEY) ? \
#define HeSVKEY_force(he) (HeKEY(he) ? \
((HeKLEN(he) == HEf_SVKEY) ? \
HeKEY_sv(he) : \
- sv_2mortal(newSVpvn(HeKEY(he), \
- HeKLEN(he)))) : \
+ newSVpvn_flags(HeKEY(he), \
+ HeKLEN(he), SVs_TEMP)) : \
&PL_sv_undef)
#define HeSVKEY_set(he,sv) ((HeKLEN(he) = HEf_SVKEY), (HeKEY_sv(he) = sv))