symbian C++描述符

Symbian描述符
描述符是symbian的基本类,不同于字符串,它可以处理字符串,也可以处理二进制
T类型的描述符,跟其他基本类(Tint)一样,都是在栈中创建
描述符同时支持8位和16位两种:TPtr8,TPtr16等
在创建时并不需要指定它时那种类型,它是在创建时的设置决定的
当用来存储二进制数据的时候,使用的是8位的版本

可实例化的类
TBufC:缓冲区描述符(不能直接创建)
TBuf:缓冲区描述符(可改变)
TPtrC:指针描述符(不能改变)
TPtr:指针描述符(可改变)
HBufC:堆缓冲区描述符(不能改变,也能声明在栈中)

这些描述符常用的属性都有如下:
Length:可以存储在buffer中的数据项(item)数目
Size:buffer中有效数据所占用的字节数
Maximum length:可能存储在buffer中数据项的最大数目
_LIT(KHello, "hello");
TBuf<12> buf(KHello);
这里length=5 size如果是ASCII构建的就是5,如果是Unicode构建的就是10
max length是12

越界问题
所有描述符都不能赋予超过它自身长度的数据,不然会发生panic,这是一种内部机制
对于TPtr和TBuf都不能改变一个已经存在的描述符的长度使其超过MAXLENGTH

_LIT宏
它用来声明一个字符串成员
可以产生一个8位或16位的TLitC对象
TLitC提供了转换操作符,因此可以作为TDesC&类型传递给各种函数,包括构造函数
注意:TLitC并不是描述符

TBufC<S>和TBuf<S>
前者数据是不可以修改的,后者可以修改数据
TBufC有四个构造函数
TBufC();
TBufC(const TBufC<s>& aLcb);
TBufC(const TDesC& aDesc);
TBufC(const TUint* aString);
TBuf与TBufC的构造函数相同,其中<S>代表最大长度

TBufC<S>的赋值操作符
TBufC<S>& operator=(const TBufC<S>& aBuf);
TBufC<S>& operator=(const TDesC& aDes);
TBufC<S>& operator=(const TUint* aString);
TBuf<S>跟它一样

TPtrC
它的数据是只读的,它指向一个数据缓冲区
它的构造函数
TPtrC();
TPtrC(const TPtrC& aDes);
TPtrC(const TDesC& aDes);
TPtrC(const TUint* aString);
TPtrC(const TUint* aBuf, TInt aLength);
最后一种可以进行字符集转换
TPtrC16 myPtr(reinterpret_cast<const TUint16*>(iDataBuffer.Ptr()),
(iDataBuffer.Size()/2));
iDataBuffer16 = myPtr;

也可以通过set方法对其进行设置
void Set(const TDesC& aDes);
void Set(const TPtrC& aPtr);
void Set(const TUint* aBuf, TInt aLength);

 

 

 

 

描述符是Symbian C++字符串的描述类,不同于string,它既可以表示字符串,也可以表示二进制数据;同时支持8位和16位,但是用来存储字符串时并不需要指定哪种类型 ,而是由编译时的设置决定,也可以在创建对象时声明,如TDes8,TDes16等等

      #if defined(_UNICODE)

           typedef TPtrC16 TPtrC

        else

           typedef TPtrC8 TPtrC

  一般来说用来存储二进制数据时通常使用8位版本。

上面的宏定义在symbian里面到处可见,在e32def.h里面,有很多symbian重新定义的类型。

类型

描述符可以分为五大类,分别是抽象描述符、文字描述符、缓冲区描述符、指针描述符和堆缓冲区描述符。下图为类继承关系图(抽象类不能创建对象,一般用于参数,C结尾的为不可修改const)

 


 

 

说明

1、抽象描述符

     抽象描述符包含TDesCTDes,TDes 是从TDes派生的,因为这些类是抽象的,所以不能实例化,它们多数用于函数参数。TDesC是所有描述符的基类,而TDes与TDesC不同的是 TDes可以对数据进行修改,并引入数据最大长度的概念。因为它是所有描述符的基类,继承它的所有类型都拥有它的方法。

  2、文字描述符

     文字描述符是我们用的比较多,它主要用来保存字符串常量,常用方法如下:

_LIT(KHelloWorld,"Hello World!");

_L("Hello world!");

上面是根据宏定义来建立文字描述符对象,建议这样使用,不建议使用TLitC来创建文字对象;

 

当使用_LIT()宏的时候,产生的其实是一个TLitC对象(8位或16位),数据实际上被存储在装载到RAM的二进制应用程序内,虽然它们实际上并不存储在ROM(或与ROM类似的闪存)中,所以可以把它们看成是只读的

可以使用()操作符将描述符转换成常量的TDesC对象,比如:

TInt length=KHelloWorld().Length();

 

 3、缓冲区描述符

   缓冲区描述符TBufCTBuf将它们的数据存储为本身的一部分,既然该描述符使用在编译时就确定的固定数量的内存,因此可以在栈上对其进行声明(作为局部或者成员变量),这里看个小例子。

_LIT(KHelloWorld,"Hello World");

const TInt maxBuf=32;

...

TBufC<maxBuf> buf;//空缓冲器,长度为0,从这里也可以看得出,缓冲描述符一定要声明一个长度。

TInt currentLen=buf.Length();//==0

buf=KHelloWorld;//在构造函数之后设置内容

currenLen=buf.Length();//==11

TText ch=buf[2]//=="l"

  这里要注意的是TBufC是TDesC的子类,而TBuf是TDes的子类,因此TBuf也提供了修改数据等的多种功能。后面会总结它的修改的方法。

4、指针描述符

      指针描述符TPtrCTPtr用于引用存储在别处的、不属于该描述符所拥有的数据。使用TPtr或者TPtrC来访问字符串比维护指向零值终止(zero-terminated)字符串指针更加安全。下面是一个小例子:

_LIT(KHelloWorld,"Hello World");

TBufC<maxBuf> buf;

buf=KHelloWorld;//设置内容

TPtr ptr=buf.Des();//取得指向该缓冲器的指针

ptr[7]='a';//将‘0’变成'a'

ptr[8]='l';//将‘r’变成'l'

ptr[9]='e';//将'l'变成‘e’

ptr[10]='s';//将‘d’变成‘s’

//现在缓冲器的内容为“Hello Wales”

 5、堆缓冲区描述符

      堆描述符HBufC封装了存储在堆上的、属于该描述符所拥有的数据。由于这些数据是动态分配的,因此通过重新分配堆缓冲器,可以在运行时对描述符的最大长度进行设置很改变。

      BufC是基于TDesC,并且提供了方法来改变所存储数据的长度(HBufC::ReAlloc()和HBufC::ReAllocL()),以及赋值 操作来设置数据的内容(受限于最大长度,不能超过最大长度)。可以通过使用HBufC::Des()获取可修改指针描述符来修改描述符的内容,下面是一个 小例子:

_LIT(KHelloWorld,"Hello World!");

HBufC *heapBuf=HBufC::NewL(KelloWorld().Length());//声明一个长度为KHelloWorld长的堆描述符

*heapBuf=KHelloWorld;

delete heapBuf;

 

转换

描述符之间的转换,如TDesC8和TDesC16之间的转换有两种方式:

1、使用Copy

_LIT8(KTestStr,  " This is a string " );
TBufC8
< 50 >  buf(KTestStr);

TBuf
< 100 >  newBuf;
newBuf.Copy(buf);

TBuf8
< 50 >  newBuf1;
newBuf1.Copy(newBuf);

 

2、使用CCnvCharacterSetConverter

 _LIT8(KTestStr, "This is a String"n");
TBufC8<50> buf(KTestStr);

CCnvCharacterSetConverter
* conv = CCnvCharacterSetConverter::NewL();

CleanupStack::PushL(conv);

RFs fs;
User::LeaveIfError(fs.Connect());

if (conv->PrepareToConvertToOrFromL(KCharacterSetIdentifierAscii, fs) != CCnvCharacterSetConverter::EAvailable)
{
User::Leave(KErrNotSupported);
}

HBufC
* str = HBufC::NewL(buf.Length());
CleanupStack::PushL(str);

TPtr ptr 
= str->Des();
TInt state 
= CCnvCharacterSetConverter::KStateDefault;

if (conv->ConvertToUnicode(ptr, buf, state) == CCnvCharacterSetConverter::EErrorIllFormedInput)
{
User::Leave(KErrArgument);
}

fs.Close();
console
->Write(ptr);

CleanupStack::PopAndDestroy(2); 

 

方法

1、描述符都有的方法:

   Locate():    定位指定字符的位置;

   Compare(): 按字节比较两个描述符大小

   Match():     搜索指定描述符的位置,可使用? *等通配符

   Find():       搜索指定描述符在当前描述符中第一次出现的位置

   Left():       提取描述符最左边的数据

   Right():     提取描述符最右边的数据

   Mid():        提取描述符中间的位置

 2、只有TPtr和TBuf才有的函数

   Append():    在描述符后面添加一个字符;

   LowerCase():将描述符转为小写字母

   UpperCase():将描述符转为大写字母

   Insert():在指定位置插入新的描述符

   Delete():在指定位置删除指定长度个数据项

 3、描述符的典型用法:

    1、TBuf/TBufC:栈上的小数据量存储

    2、TPtrC:常量字符串或数据

    3、TPtr:指向常量字符串或数据,通过Des()方法进行数据修改

    4、HBufC:大数据量时的处理

 

 

 

 

 

如何将HBuf转化为TBuf?

 

LIT(KSomeText, "Symbian");

HBufC* heapBuffer=HBufC::NewLC(15);

*heapBuffer = KSomeText;

TBuf<15> buffer(*heapBuffer);

CleanupStack::PopAndDestroy( heapBuffer );

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值