You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libpEpDatatypes/src/nfc.hh

123 lines
3.5 KiB

// This file is under GNU General Public License 3.0
// see LICENSE.txt
#ifndef LIBPEPDATATYPES_NFC_HH
#define LIBPEPDATATYPES_NFC_HH
#include "string_view.hh" // to switch between std::string_view or boost::string_view.hh
#include <string>
#include <stdexcept>
#include <iosfwd>
#include <pEp/identity_list.h>
namespace pEp {
enum class IsNFC
{
No=0, // contains a character that cannot occur in NFC
Maybe=1, // contains a character that is only allowed in certain positions in NFC
Yes=2 // contains no invalid or partially valid character
};
std::ostream& operator<<(std::ostream& o, IsNFC is_nfc);
class illegal_utf : public std::runtime_error
{
public:
illegal_utf( string_view, unsigned position, const std::string& reason);
illegal_utf(u16string_view, unsigned position, const std::string& reason);
protected:
explicit illegal_utf(const std::string& message);
};
/// Common class template to define the same functions for all 3 Unicode Transfer Formats.
template<class CharT>
class UTF
{
public:
/// parses a sequence of input code units into one Unicode code point and updates the input iterator c.
/// \todo change to iterator templates?
static
uint32_t parse(const CharT*& c, const CharT* end);
/// generates a UTF sequence from a given Unicode code point.
template<class OutIter>
static
void generate(const char32_t c, OutIter& out);
/// return No or Maybe, if at least one character with NFC_Quickcheck class is "No" or "Maybe"
/// might throw illegal_utf exception
static
IsNFC isNFC_quick_check(basic_string_view<CharT> s);
/// runs first quick check and a deep test if quick check returns "Maybe".
static
bool isNFC(basic_string_view<CharT> s);
/// returns true if the sequence is valid UTF-8
bool isUtf(const CharT* begin, const CharT* end);
/// converts a C++ string (in UTF-8/-16) into NFC form
static
std::basic_string<CharT> toNFC(basic_string_view<CharT> s);
/// calculates the number of "code units" in the target Unicode Transfer Format.
static
size_t utf_length(u32string_view s);
/// generates a whole u32string at once
static
std::basic_string<CharT> generate(const std::u32string& s);
/// creates an NFD u32string from UTF-8/UTF-16 input string s
static
std::u32string fromUtf_decompose(basic_string_view<CharT> s);
};
using UTF8 = UTF<char>;
using UTF16 = UTF<char16_t>;
// throws illegal_utf8 exception if s is not valid UTF-8
void assert_utf8(string_view s);
// convert NFD to NFC
std::u32string createNFC(std::u32string nfd_string);
/*
// return No or Maybe, if at least one character with NFC_Quickcheck class is "No" or "Maybe"
// might throw illegal_utf exception
template<class CharT>
IsNFC isNFC_quick_check(basic_string_view<CharT> s);
// runs first quick check and a deep test if quick check returns "Maybe".
template<class CharT>
bool isNFC(basic_string_view<CharT> s);
// returns true if the sequence is valid UTF-8
bool isUtf8(const char* begin, const char* end);
// converts a C++ string (in UTF-8) into NFC form
// s is ''moved'' to the return value if possible so no copy is done here.
template<class CharT>
std::basic_string<CharT> toNFC(basic_string_view<CharT> s);
*/
// creates a UTF-8-encoded NFC string from s
std::string toNFC_8(u16string_view s);
// convenience functions to avoid ::strdup(pEp::toNFC<char>(text).c_str());
// and unecessary temporary std::string etc.
char* strdup_NFC(string_view s);
pEp_identity *identity_dup_NFC(const ::pEp_identity* value);
::identity_list* identity_list_dup_NFC(const ::identity_list* value);
} // end of namespace pEp
#endif // LIBPEPDATATYPES_NFC_HH