Repository: lucy-clownfish
Updated Branches:
  refs/heads/master 1fc8c00a1 -> a3992dd9d


Implement XSBind_hash_key_to_utf8

Make it possible for Lucy to reuse this non-trivial piece of code.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/a3992dd9
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/a3992dd9
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/a3992dd9

Branch: refs/heads/master
Commit: a3992dd9de89ad7e00bfd68c8fda15fb2941256b
Parents: ea26823
Author: Nick Wellnhofer <[email protected]>
Authored: Sat Aug 1 18:15:35 2015 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Tue Aug 4 21:17:02 2015 +0200

----------------------------------------------------------------------
 runtime/perl/xs/XSBind.c | 70 ++++++++++++++++++++++++-------------------
 runtime/perl/xs/XSBind.h |  6 ++++
 2 files changed, 45 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a3992dd9/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 6360b29..f426bc0 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -189,43 +189,51 @@ XSBind_perl_to_cfish(pTHX_ SV *sv) {
     return retval;
 }
 
+const char*
+XSBind_hash_key_to_utf8(pTHX_ HE *entry, STRLEN *size_ptr) {
+    const char *key_str = NULL;
+    STRLEN key_len = HeKLEN(entry);
+
+    if (key_len == (STRLEN)HEf_SVKEY) {
+        // Key is stored as an SV.  Use its UTF-8 flag?  Not sure about
+        // this.
+        SV *key_sv = HeKEY_sv(entry);
+        key_str = SvPVutf8(key_sv, key_len);
+    }
+    else {
+        key_str = HeKEY(entry);
+
+        if (!HeKUTF8(entry)) {
+            for (STRLEN i = 0; i < key_len; i++) {
+                if ((key_str[i] & 0x80) == 0x80) {
+                    // Force key to UTF-8 if necessary.
+                    SV *key_sv = HeSVKEY_force(entry);
+                    key_str = SvPVutf8(key_sv, key_len);
+                    break;
+                }
+            }
+        }
+    }
+
+    *size_ptr = key_len;
+    return key_str;
+}
+
 static cfish_Hash*
 S_perl_hash_to_cfish_hash(pTHX_ HV *phash) {
     uint32_t    num_keys = hv_iterinit(phash);
     cfish_Hash *retval   = cfish_Hash_new(num_keys);
 
     while (num_keys--) {
-        HE        *entry    = hv_iternext(phash);
-        STRLEN     key_len  = HeKLEN(entry);
-        SV        *value_sv = HeVAL(entry);
-        cfish_Obj *value    = XSBind_perl_to_cfish(aTHX_ value_sv); // Recurse.
-
-        // Force key to UTF-8 if necessary.
-        if (key_len == (STRLEN)HEf_SVKEY) {
-            // Key is stored as an SV.  Use its UTF-8 flag?  Not sure about
-            // this.
-            SV   *key_sv  = HeKEY_sv(entry);
-            char *key_str = SvPVutf8(key_sv, key_len);
-            CFISH_Hash_Store_Utf8(retval, key_str, key_len, value);
-        }
-        else if (HeKUTF8(entry)) {
-            CFISH_Hash_Store_Utf8(retval, HeKEY(entry), key_len, value);
-        }
-        else {
-            char *key_str = HeKEY(entry);
-            bool pure_ascii = true;
-            for (STRLEN i = 0; i < key_len; i++) {
-                if ((key_str[i] & 0x80) == 0x80) { pure_ascii = false; }
-            }
-            if (pure_ascii) {
-                CFISH_Hash_Store_Utf8(retval, key_str, key_len, value);
-            }
-            else {
-                SV *key_sv = HeSVKEY_force(entry);
-                key_str = SvPVutf8(key_sv, key_len);
-                CFISH_Hash_Store_Utf8(retval, key_str, key_len, value);
-            }
-        }
+        HE         *entry    = hv_iternext(phash);
+        STRLEN      key_len  = 0;
+        const char *key_str  = XSBind_hash_key_to_utf8(aTHX_ entry, &key_len);
+        SV         *value_sv = HeVAL(entry);
+
+        // Recurse.
+        cfish_Obj *value = XSBind_perl_to_cfish(aTHX_ value_sv);
+
+        CFISH_Hash_Store_Utf8(retval, key_str, key_len, value);
     }
 
     return retval;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a3992dd9/runtime/perl/xs/XSBind.h
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.h b/runtime/perl/xs/XSBind.h
index 465574d..5fabb32 100644
--- a/runtime/perl/xs/XSBind.h
+++ b/runtime/perl/xs/XSBind.h
@@ -130,6 +130,11 @@ cfish_XSBind_cfish_to_perl(pTHX_ cfish_Obj *obj) {
 CFISH_VISIBLE cfish_Obj*
 cfish_XSBind_perl_to_cfish(pTHX_ SV *sv);
 
+/** Return the contents of the hash entry's key as UTF-8.
+ */
+CFISH_VISIBLE const char*
+cfish_XSBind_hash_key_to_utf8(pTHX_ HE *entry, STRLEN *size_ptr);
+
 /** Perl-specific wrapper for Err#trap.  The "routine" must be either a
  * subroutine reference or the name of a subroutine.
  */
@@ -302,6 +307,7 @@ cfish_XSBind_allot_params(pTHX_ SV** stack, int32_t start,
 #define XSBind_cfish_obj_to_sv_noinc   cfish_XSBind_cfish_obj_to_sv_noinc
 #define XSBind_cfish_to_perl           cfish_XSBind_cfish_to_perl
 #define XSBind_perl_to_cfish           cfish_XSBind_perl_to_cfish
+#define XSBind_hash_key_to_utf8        cfish_XSBind_hash_key_to_utf8
 #define XSBind_trap                    cfish_XSBind_trap
 #define XSBind_allot_params            cfish_XSBind_allot_params
 #define ALLOT_I8                       XSBIND_ALLOT_I8

Reply via email to