Introduzione

Il linguaggio LUA si interfaccia con le applicazioni native (C++/ARX) e con il mondo .NET. Noi utilizziamo la versione 4 che non ha alcun supporto all’unicode e utilizza internamente il tipo char per gestire le stringhe.

Prima di affrontare il supporto unicode negli applicativi C++ è necessario introdurre la gestione dell’Unicode nel LUA visto il largo uso che ne facciamo in tutti gli applicativi. In questo documento tracciamo la prima bozza di gestione LUA unicode.

Gestione della codifica caratteri in LUA

Il LUA utilizza il tipo di dato 'char' per gestire le stringhe. Il fatto che utilizzi questo tipo di dati non significa che si perdano informazioni. Per esempio, se leggiamo un file di testo in russo codificato in UTF-8 le stringhe vengono lette come array di char (array di byte) mantenendo tutti i dati. Se le stringhe vengono trasferite e di nuovo serializzate non ci sono problemi.

Possibili problemi

Le stringhe ANSI e UTF-8 sono identiche per tutti i primi 127 caratteri. Se si cerca di visualizzare una stringa letta da un file UTF-8 il risultato ottenuto non sarà corretto per tutti i caratteri oltre il 127. Questo vale anche se si cerca di calcolare la lunghezza della stringa e, in generale, per tutte le operazioni che confidano sul fatto che un carattere di testo corrisponda ad un char (1 byte), cosa non vera in UTF-8 per i caratteri sopra il 127.

Files .lua con caratteri UTF8

L’interprete LUA ha bisogno di files testuali senza intestazione. Quindi non possono essere usati files con codifica UTF-16, UTF-8 con BOM e così via. Possono essere utilizzati files ANSI con varie codepages o files UTF-8 senza BOM. Usate Notepad++ con la codifica "UTF-8 without BOM" oppure il nostro editor LUA con codifica "UTF8".

Stringhe UTF-8 in LUA

Abbiamo bisogno di uno strumento che ci consenta di:

  • eseguire le normali operazioni sulle stringhe ma con stringhe UTF-8m
  • trasferire correttamente stringhe tra LUA, C++ (wchar_t) o .NET.

Lua4 consente di espandere il set di tipi nativi introducendo degli “userdata”. Questi oggetti non sono altro che dei wrapper sui tipi nativi fatti in modo tale che il lua possa gestirne il ciclo di vita e il posizionamento sullo stack. Gli userdata consentono di incapsulare delle classi C++ definite dall’utente.

La soluzione che proponiamo prevede di creare uno userdata che incapsuli la classe “stringw”. Questa classe nasce come clone della classe "stringa" per gestire le stringhe unicode. Utilizza internamente wchar_t ed è già utilizzata (e testata!) nel software. Definiamo uno userdata "lua_stringw" che incapsula la classe “stringw”.