Olá, estou criando um pequeno software para aparelhos CLDC1.0 e MIDP1.0. Como há uma quantidade considerável de textos nesse software, criei arquivos txt que são lidos durante a execução. E aí surge um problema.
Se os arquivos txt são gravados em ANSI, aparelhos nokia os lêem normalmente, mas motorola não, apresentando caracteres acentuados incorretamente. Já em UTF-8 acontece o contrário…
Imagino que a resposta seja “não”, mas há alguma forma “universal” para gravar/ler esses textos? Caso não, há alguma função que eu possa usar para converter ANSI para UTF-8 ou vice-versa, como o utf8_encode do php?
Mais uma questão relacionada: uso esses arquivos externos assumindo que isso irá reduzir o consumo de memória de execução no aparelho, carregando os textos apenas no momento em que vou usá-los. Estou certo? Ou incorporar esses textos no código geraria o mesmo resultado?
Encontrei a saída em um site, usando funções de conversão da codificação dos caracters. Daí foi só fazer um teste simples com um arquivo padronizado e ao que parece está tudo ok. O código é o seguinte:
[code]/*
Author : Shivakumar
Mail : shiva (at) blisspark.com
Disclaimer : This code is provided without any implied or expressed warranty and may not work as
expected. If have any bugs, inform me or post the fix here.
*/
public static String UTF8Decode(byte in[], int offset, int length)
{
StringBuffer buff = new StringBuffer();
int max = offset + length;
for( int i = offset ; i < max ; i++)
{
char c = 0;
if((in[i] & 0x80) == 0)
{
c = (char) in[i];
}
else if(( in[i] & 0xe0 ) == 0xc0) // 11100000
{
c |= ((in[i] & 0x1f) << 6); // 00011111
i++;
c |= ((in[i] & 0x3f) << 0); // 00111111
}
else if(( in[i] & 0xf0) == 0xe0) // 11110000
{
c |= ((in[i] & 0x0f) << 12); // 00001111
i++;
c |= ((in[i] & 0x3f) << 6); // 00111111
i++;
c |= ((in[i] & 0x3f) << 0); // 00111111
}
else if((in[i] & 0xf8) == 0xf0) // 11111000
{
c |= ((in[i] & 0x07) << 18); // 00000111 (move 18, not 16?)
i++;
c |= ((in[i] & 0x3f) << 12); // 00111111
i++;
c |= ((in[i] & 0x3f) << 6); // 00111111
i++;
c |= ((in[i] & 0x3f) << 0); // 00111111
}
else
{
c = ‘?’;
}
buff.append(c);
}
return buff.toString();
}
public static byte[] UTF8Encode(String str)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
int strlen = str.length();
for( int i = 0 ; i < strlen ; i++ )
{
char t = str.charAt(i);
int c = 0;
c |= ( t & 0xffff );
if(c >= 0 && c < 0x80)
{
bos.write((byte)( c & 0xff ));
}
else if(c > 0x7f && c < 0x800)
{
bos.write( (byte) ((( c >>> 6 ) & 0x1f ) | 0xc0 ));
bos.write( (byte) ((( c >>> 0 ) & 0x3f ) | 0x80 ));
}
else if(c > 0x7ff && c < 0x10000)
{
bos.write( (byte) ((( c >>> 12 ) & 0x0f ) | 0xe0 )); // <-- correction (mb)
bos.write( (byte) ((( c >>> 6 ) & 0x3f ) | 0x80 ));
bos.write( (byte) ((( c >>> 0 ) & 0x3f ) | 0x80 ));
}
else if(c > 0x00ffff && c < 0xfffff)
{
bos.write( (byte) ((( c >>> 18 ) & 0x07 ) | 0xf0 ));
bos.write( (byte) ((( c >>> 12 ) & 0x3f ) | 0x80 ));
bos.write( (byte) ((( c >>> 6 ) & 0x3f ) | 0x80 ));
bos.write( (byte) ((( c >>> 0 ) & 0x3f ) | 0x80 ));
}
}
bos.flush();
}
catch(Exception e)
{
}
return bos.toByteArray();
}
[/code]
A função de teste simples que criei foi:
[code]private void checkUTF8() {
// loading the check file that must have only an ã char and saved as UTF-8
// var
StringBuffer buffer = null;
InputStream is = null;
InputStreamReader isr = null;
// loading the file
try {
Class c = this.getClass();
is = c.getResourceAsStream("/data/check.txt");
if (is == null) {
throw new Exception("The file check.txt does not exist!");
}
isr = new InputStreamReader(is);
buffer = new StringBuffer();
int ch;
while ((ch = isr.read()) > -1) {
buffer.append((char) ch);
}
if (isr != null) {
isr.close();
}
} catch (Exception ex) {
System.out.println(ex.toString());
}
// now that the text is loaded, comparing the char read
if (buffer.toString() == "ã") {
// this system reads texts as UTF-8
this.useUTF8 = true;
} else {
// this system does not read as UTF-8
this.useUTF8 = false;
}
}[/code]
O código foi retirado de http://www.j2meforums.com/wiki/index.php/UTF-8_Encoder/Decoder
Mas ainda fica a questão sobre o uso desses arquivos externos. Ele é mesmo justificável pelos motivos que coloquei aí em cima?