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
