2011-11-24 14 views
7

Jakie biblioteki Open Source C lub C++ mogą przekonwertować dowolny kod UTF-32 na NFC?Jakie biblioteki Open Source C lub C++ mogą konwertować dowolny kod UTF-32 na NFC?

Biblioteki, które moim zdaniem mogą to zrobić do tej pory: ICU, Qt, GLib (nie jestem pewien?).

Nie potrzebuję żadnej innej kompleksowej obsługi Unicode; tylko konwersja z dowolnego, ale znanego, poprawnego UTF-32 do UTF-32, który jest w formularzu NFC.

Najbardziej interesuje mnie biblioteka, która może to zrobić bezpośrednio. Na przykład Qt i ICU (o ile wiem), robią wszystko poprzez pośredni etap konwersji do i od UTF-16.

+0

Co to jest NFC? Normalizacja Unicode Formuła kanoniczna? –

+1

@BillyONeal: Jestem prawie pewien, że to jest to. Zobacz http://en.wikipedia.org/wiki/Unicode_equivalence#Normal_forms – wallyk

+1

Dlaczego dbasz o szczegóły implementacji? Nie obchodzi mnie, czy biblioteka używa wewnętrznie UTF-13, o ile generuje odpowiednie wyniki. – MSalters

Odpowiedz

2

ICU lub Boost.Locale (opakowanie ICU) będzie najlepsze w bardzo, bardzo długiej drodze. Odwzorowania normalizacyjne będą równoważne z odwzorowaniami z większego oprogramowania, które, jak zakładam, jest punktem tej konwersji.

+0

Istnieje tylko jedno możliwe (prawidłowe) mapowanie normalizacji NFC, więc nie ma problemu z kompatybilnością, ale przypuszczam, że OIT jest prawdopodobnie najmniej prawdopodobny, aby być kiedykolwiek błędnym. Miałem nadzieję na coś o mniejszej wadze, która mogłaby po prostu normalizować, ale po wielu poszukiwaniach zdecydowałem, że ICU jest również najlepszym wyborem, więc zaznaczam to jako zaakceptowane. =) – wjl

+0

Aby wyjaśnić, przez kompatybilność mam na myśli jak zawsze: "obie strony będą prawdopodobnie miały te same błędy" =) – rvalue

0

Oto główna część kodu, który wykorzystałem po podjęciu decyzji o OIOM. Pomyślałem, że powinienem umieścić to tutaj na wypadek, gdyby pomógł komuś, kto próbuje tego samego.

std::string normalize(const std::string &unnormalized_utf8) { 
    // FIXME: until ICU supports doing normalization over a UText 
    // interface directly on our UTF-8, we'll use the insanely less 
    // efficient approach of converting to UTF-16, normalizing, and 
    // converting back to UTF-8. 

    // Convert to UTF-16 string 
    auto unnormalized_utf16 = icu::UnicodeString::fromUTF8(unnormalized_utf8); 

    // Get a pointer to the global NFC normalizer 
    UErrorCode icu_error = U_ZERO_ERROR; 
    const auto *normalizer = icu::Normalizer2::getInstance(nullptr, "nfc", UNORM2_COMPOSE, icu_error); 
    assert(U_SUCCESS(icu_error)); 

    // Normalize our string 
    icu::UnicodeString normalized_utf16; 
    normalizer->normalize(unnormalized_utf16, normalized_utf16, icu_error); 
    assert(U_SUCCESS(icu_error)); 

    // Convert back to UTF-8 
    std::string normalized_utf8; 
    normalized_utf16.toUTF8String(normalized_utf8); 

    return normalized_utf8; 
}