summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2013-03-13 16:02:52 -0600
committerKarl Williamson <public@khwilliamson.com>2013-08-29 09:56:02 -0600
commite8e5e5b33e8b014d1b66f2a313ac50e677f6cdb4 (patch)
tree1d1fe25981f697ce927d27c90f3f256dcd08d00f /hv.c
parentf466f02af43a0c1cae4b73d00ebd208e56d3ad4c (diff)
downloadperl-e8e5e5b33e8b014d1b66f2a313ac50e677f6cdb4.tar.gz
hv.c: Stop being ASCII-centric
This uses macros which work cross-platform. This has the added advantge what is going on is much clearer.
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/hv.c b/hv.c
index 07837ab991..3cb0b079f8 100644
--- a/hv.c
+++ b/hv.c
@@ -3122,12 +3122,12 @@ Perl_refcounted_he_fetch_pvn(pTHX_ const struct refcounted_he *chain,
const char *keyend = keypv + keylen, *p;
STRLEN nonascii_count = 0;
for (p = keypv; p != keyend; p++) {
- U8 c = (U8)*p;
- if (c & 0x80) {
- if (!((c & 0xfe) == 0xc2 && ++p != keyend &&
- (((U8)*p) & 0xc0) == 0x80))
+ if (! UTF8_IS_INVARIANT(*p)) {
+ if (! UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(p, keyend)) {
goto canonicalised_key;
+ }
nonascii_count++;
+ p++;
}
}
if (nonascii_count) {
@@ -3139,8 +3139,13 @@ Perl_refcounted_he_fetch_pvn(pTHX_ const struct refcounted_he *chain,
keypv = q;
for (; p != keyend; p++, q++) {
U8 c = (U8)*p;
- *q = (char)
- ((c & 0x80) ? ((c & 0x03) << 6) | (((U8)*++p) & 0x3f) : c);
+ if (UTF8_IS_INVARIANT(c)) {
+ *q = (char) c;
+ }
+ else {
+ p++;
+ *q = (char) TWO_BYTE_UTF8_TO_NATIVE(c, *p);
+ }
}
}
flags &= ~REFCOUNTED_HE_KEY_UTF8;
@@ -3292,12 +3297,12 @@ Perl_refcounted_he_new_pvn(pTHX_ struct refcounted_he *parent,
const char *keyend = keypv + keylen, *p;
STRLEN nonascii_count = 0;
for (p = keypv; p != keyend; p++) {
- U8 c = (U8)*p;
- if (c & 0x80) {
- if (!((c & 0xfe) == 0xc2 && ++p != keyend &&
- (((U8)*p) & 0xc0) == 0x80))
+ if (! UTF8_IS_INVARIANT(*p)) {
+ if (! UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(p, keyend)) {
goto canonicalised_key;
+ }
nonascii_count++;
+ p++;
}
}
if (nonascii_count) {
@@ -3309,8 +3314,13 @@ Perl_refcounted_he_new_pvn(pTHX_ struct refcounted_he *parent,
keypv = q;
for (; p != keyend; p++, q++) {
U8 c = (U8)*p;
- *q = (char)
- ((c & 0x80) ? ((c & 0x03) << 6) | (((U8)*++p) & 0x3f) : c);
+ if (UTF8_IS_INVARIANT(c)) {
+ *q = (char) c;
+ }
+ else {
+ p++;
+ *q = (char) TWO_BYTE_UTF8_TO_NATIVE(c, *p);
+ }
}
}
flags &= ~REFCOUNTED_HE_KEY_UTF8;