×
Namespaces

Variants
Actions
Revision as of 22:22, 16 February 2013 by lpvalente (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Descritores

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngAquivado: Este artigo foi arquivado, pois o conteúdo não é mais considerado relevante para se criar soluções comerciais atuais. Se você achar que este artigo ainda é importante, inclua o template {{ForArchiveReview|escreva a sua justificativa}}.

Acredita-se que este artigo ainda seja válido no contexto original (quando ele foi escrito)


Article Metadata

Artigo
Criado por lpvalente em Lpvalente
Última alteração feita por lpvalente em 16 Feb 2013


Contents

Introdução

Descritores são a alternativa existente no Symbian C++ para representar strings de caracteres. Ao contrário do C padrão, não existe um tipo char* para representar strings, nem uma classe string como no C++.

Basicamente, os descritores são classes que encapsulam duas informações: um buffer de dados e o tamanho desse buffer. Esse valor é usado para detectar erros de buffer overrun (escrever fora da área de memória permitida). Quando isso acontece, o sistema sinaliza com um erro. Ao contrário do C, as strings não precisam terminar com NULL para sinalizar o final da string.

Existem diversos tipos de descritores, que podem ser modificáveis ou não, e podem ser alocados na pilha (Stack) ou na Heap. Essas estruturas podem armazenar caracteres (strings) ou dados binários. Por padrão, os caracteres possuem 16 bits (Unicode), mas quando usados para armazenar dados binários, o descritor usará normalmente 8 bits, pelo fato de funcionar apenas como um buffer de bytes.

Em termos gerais, os descritores são agrupados como:

  • literais;
  • descritores baseados em buffer local;
  • descritores baseados em ponteiros;
  • descritores baseados na heap.

Todas as classes possuem versões para armazenar caracteres de 8 e 16 bits, como TBuf8 e TBuf16. Por padrão os descritores armazenam caracteres de 16 bits, ou seja, a classe TBuf é mapeada para TBuf16, por exemplo.

Base

A classe base para descritores é TDesC, que representa um descritor não-modificável. Dessa forma, essa classe possui métodos somente para a leitura de informações sobre descritores. Dois desses métodos são Length(), que retorna o número de caracteres armazenados e Size(), que retorna o total de bytes ocupados por esses caracteres.

A classe TDes representa um descritor modificável. Uma propriedade importante existente nessa classe é um campo que indica o tamanho máximo do buffer encapsulado pela classe, que pode ser acessada pelos métodos MaxLength() e MaxSize().

Essas classes não podem ser usadas diretamente, mas muitas vezes são usadas como parâmetros de funções no Symbian C++.

Literais

Os literais são usados para se armazenar cadeias de caracteres (strings). São criados com as macros _LIT e _L. Exemplo:

_LIT( KHello, "Hello ");
_LIT( KWorld, "World");

Internamente, a macro _LIT cria um objeto da classe TLitC, que não tem relação com as classes base de descritores. Entretanto, é possível usá-la como se fosse um descritor não-modificável, ou seja, pode-se passar um literal para funções que aceitem um TDesC ou atribuí-la a um TDesC.

Já a macro _L cria um descritor temporário em cada parte onde é utilizada. Internamente, é expandida para um TPtrC (dinamicamente). Já com a outra macro, a expansão é em tempo de compilação. A macro _L foi depreciada e seu uso é recomendado apenas em testes no desenvolvimento.

Descritores baseados em buffer

Esses tipos de descritores são representados pelas classes TBuf e TBufC. Esses descritores armazenam internamente o buffer para armazenar os dados. Exemplos de uso:

_LIT( KHello, "Hello ");
_LIT( KWorld, "World");
 
TBuf <100> str;
 
str.Copy (KHello);
str.Append (KWorld);
 
// str será igual a "Hello World"
 
TBuf <30> b1 (KHello);

No exemplo, str representa um descritor modificável que tem tamanho máximo igual a 100. O equivalente em C seria declarar como char[100]. Mas ao contrário do C padrão, o valor 100 é usado para se detectar tentativas de escrever além da memória reservada para o descritor. Esses descritores também podem ser inicializados diretamente a partir de literais.

Os descritores TBufC representam a versão não-modifiável, são usados de maneira parecida.

TBufC <20> b1 (KWorld);
 
TBufC <30> b2;
b2 = KHello;

O conteúdo desses descritores não pode ser modificado, mas pode ser substituído em uma única operação. Em ambas as versões, caso se tente armazenar uma string maior que o tamanho máximo um erro será gerado.

Descritores baseados em pointeiros

São representados pelas classes TPtr e TPtrC. Ao contrário dos descritores baseados em buffer, esses descritores armazenam um ponteiro que indica onde o buffer de dados está localizado.

Esses descritores funcionam de maneira semelhante àqueles baseados em buffer. Para se construir um descritor desse tipo, é preciso criar um outro descritor (como TBuf) e associá-lo, de modo parecido como se faz com ponteiros. Exemplos:

// 1
TBufC <10> b1 (KWorld);
TPtrC p1 (b2);
 
// 2
TUint16 b2 [50];
TPtr p2 (b2, sizeof (b2) );
 
_LIT( KHello, "Hello ");
_LIT( KWorld, "World");
 
p2.Copy (KHello);
p2.Append (KWorld);
 
// b2 terá "Hello World"

O primeiro exemplo cria um descritor não-modificável e o associa com um TBufC. O segundo exemplo aloca um array e o utiliza para criar um descritor modificável, para então modificar o buffer. Existem outros métodos na API para alterar o buffer que é referenciado pelo descritor (como Set() ).

Descritores baseados na heap

A classe HBufC representa esse tipo de descritor e como a convenção de nomes indica ele é não-modificável, a princípio. É possível modificá-lo usando métodos que retornam um objeto TDes a partir de um HBufC. Existem várias maneiras de se criar esse descritor. Algumas delas:

// 1
HBufC* b1 = HBufC::NewL (100);
 
// 2
TBuf <40> buffer (...);
HBufC* b2 = buffer.AllocL();
 
// 3
_LIT(KHello, "Hello ");
HBufC * b3 = KHello.AllocL();

A primeira versão aloca na Heap uma sequência de 100 elementos de 16 bits, ou seja, 200 bytes. A segunda maneira aloca uma nova área de memória e copia o conteúdo da variável. A terceira alternativa faz a mesma coisa, só que a partir de um literal.

A classe HBufC possui um método Des() que retorna um objeto do tipo TPtr. Dessa forma, é possível alterar os dados desse descritor. Uma outra função útil é Realloc(), que altera o tamanho original da área de memória alocada.

Outras notas

Existem vários métodos úteis nas classes dos descritores, como por exemplo:

  • Copiar dados a partir de um outro descritor. Existem variações que permitem, por exemplo, copiar os caracteres e já converter para maiúsculas ou minúsculas, por exemplo;
  • Comparação de strings, extração de substrings, apagar strings dentro de uma outra string;
  • Adicionar caracteres ao final de uma string;
  • Apagar uma sequência de caracteres existente em uma string;
  • Converter para uma string padrão C (com caracter terminador NULL);
  • Acessar caracteres do descritor como um array, usando colchetes, como é feito em strings do C.

Para maiores informações, por favor consultar a documentação de descritores TDesC typedef.

Convertendo descritores entre 8 bits e 16 bits

Para converter strings de 8 bits para 16 bits, pode ser usado o método Copy (TDesC8 & c) a partir do descritor de 16 bits. Exemplo:

// declaração de um descritor de 8 bits
_LIT8(name, "Name");
 
// declaração de um descritor de 16 bits
TBuf16 <40> name16;
 
// copiando
name16.Copy (name);

Entretanto, se o texto original estiver codificado em UTF-8, essa conversão poderá funcionar incorretamente. Para resolver esse problema, existe uma classe denominada CnvUtfConverter que possui diversos métodos estáticos para se realizar essas conversões.

Para se converter de UFT-8 para Unicode, a classe possui este método:

CnvUtfConverter::ConvertToUnicodeFromUtf8 (dest16, src8);

O parâmetro src8 representa o descritor de 8 bits e dest16 representa o descritor que receberá o texto convertido para Unicode. Analogamente, o método a seguir faz a conversão inversa:

CnvUtfConverter::ConvertFromUnicodeToUtf8 (dest8, src16);

Para utilizar essa classe é necessário incluir o arquivo utf.h e utilizar a biblioteca charconv.lib.

This page was last modified on 16 February 2013, at 22:22.
105 page views in the last 30 days.