From c48088d788a46dd8113bb13bea578f7c7dcd7f8b Mon Sep 17 00:00:00 2001 From: roker Date: Wed, 29 Sep 2021 12:33:44 +0200 Subject: [PATCH] add char* strdup_NFC(string_view s). FIXME: The more efficient implementation needs some more internal re-work, that's why this correct but stupid quick'n'dirty implementation is there for now. --- src/nfc.cc | 35 +++++++++++++++++++++++++++++++++++ src/nfc.hh | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/src/nfc.cc b/src/nfc.cc index 0f453e4..85bcbae 100644 --- a/src/nfc.cc +++ b/src/nfc.cc @@ -11,6 +11,8 @@ #include "nfc_sets.hh" +#include + namespace { // unicode to hex string @@ -628,6 +630,39 @@ std::basic_string toNFC(basic_string_view s) } +// convenience function to avoid ::strdup(pEp::toNFC(text).c_str()); +// and unecessary temporary std::string etc. +char* strdup_NFC(string_view s) +{ + if(isNFC_quick_check(s)==IsNFC::Yes) + return ::new_string(s.data(), s.size()); + + // implement the hard way more efficient +/********** FIXME: need more re-work, so I'll do the dumb way first + + const std::u32string& u32 = createNFC( fromUtf_decompose(s) ); + const size_t out_len = utf8len(u32); + char* ret = ::new_string(nullptr, out_len ); + char* iter{ret}; + for(const char32_t c : u32) + { + toUtf(c, iter); + } + + if(iter > ret+out_len) // should never happen. ;) + { + throw std::logic_error("internal error: strdup_NFC() exceeded output string size"); + } + + return ret; +********************/ + + // Correct but inefficient: + const std::string ret = toNFC(s); + return ::new_string(ret.data(), 0); +} + + // used only to initialize the NFC Compose mapping: std::map< std::pair, unsigned> generate_nfc_compose() { diff --git a/src/nfc.hh b/src/nfc.hh index 0e12ebd..a7d4154 100644 --- a/src/nfc.hh +++ b/src/nfc.hh @@ -68,6 +68,10 @@ std::basic_string toNFC(basic_string_view s); // creates a UTF-8-encoded NFC string from s std::string toNFC_8(u16string_view s); +// convenience function to avoid ::strdup(pEp::toNFC(text).c_str()); +// and unecessary temporary std::string etc. +char* strdup_NFC(string_view s); + } // end of namespace pEp