2011-11-24 21 views
7

Quali librerie C o C++ open source possono convertire l'UTF-32 arbitrario in NFC?Quali librerie C o C++ open source possono convertire da UTF-32 a NFC arbitrario?

Librerie che penso possano fare questo finora: ICU, Qt, GLib (non sono sicuro?).

Non è necessario alcun altro supporto Unicode complesso; solo conversione da UTF-32 a UTF-32 arbitraria ma nota-corretta che si trova nel modulo NFC.

Sono molto interessato a una libreria in grado di farlo direttamente. Ad esempio, Qt e ICU (per quanto posso dire) entrambi fanno tutto tramite uno stadio intermedio di conversione da e verso UTF-16.

+0

Che cos'è NFC? Modulo di normalizzazione Unicode Composizione canonica? –

+1

@BillyONeal: Sono abbastanza sicuro che sia così. Vedi http://en.wikipedia.org/wiki/Unicode_equivalence#Normal_forms – wallyk

+1

Perché ti preoccupi dei dettagli di implementazione? Non mi interessa se una libreria utilizza UTF-13 internamente, purché produca i risultati corretti. – MSalters

risposta

2

ICU o Boost.Locale (avvolgimento ICU) sarà il vostro meglio da molto, molto lungo. I mapping di normalizzazione saranno equivalenti a quelli di più software, che presumo sia il punto di questa conversione.

+0

C'è solo una possibile (corretta) mappatura della normalizzazione NFC, quindi non c'è alcuna preoccupazione di compatibilità, ma suppongo che ICU sia forse la meno probabile che sia mai stata infetta. Speravo in qualcosa di un po 'più leggero che potesse solo fare la normalizzazione, ma dopo un sacco di ricerche ho finito per decidere che anche l'ICU era la scelta migliore, quindi lo segnalo come accettato. =) – wjl

+0

Per chiarire, per compatibilità intendo come sempre: 'entrambe le parti avranno probabilmente gli stessi bug' =) – rvalue

0

Ecco la parte principale del codice che ho utilizzato dopo aver deciso su ICU. Ho pensato che dovrei metterlo qui nel caso in cui aiuti qualcuno che cerca la stessa cosa.

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; 
}