codificação de textos

1 resposta
C

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?

1 Resposta

C

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:

/*

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

A função de teste simples que criei foi:

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

O código foi retirado de [url]http://www.j2meforums.com/wiki/index.php/UTF-8_Encoder/Decoder[/url]

Mas ainda fica a questão sobre o uso desses arquivos externos. Ele é mesmo justificável pelos motivos que coloquei aí em cima?

Criado 31 de outubro de 2007
Ultima resposta 1 de nov. de 2007
Respostas 1
Participantes 1