描述符

近来在家中休息,想整理一下自己的笔记,还是从基本的开始吧

缓冲区描述符

TBufC   //e32cmn.h

基本用法

       _LIT (KText1, "Hello World/n" );

       TBufC <30> bufText1;

       bufText1 = KText1;   // 这个“ = ”已经被重载过了

       console-> Write (bufText1);

      

       _LIT (KText2, "Hello World/n" );

       TBufC <30> bufText2(KText2);

       console-> Write (bufText2);

 

类函数

template < TInt S >

#if defined(_UNICODE) && !defined(__KERNEL_MODE__)

class TBufC : public TBufCBase16

#else

class TBufC : public TBufCBase8

#endif

       {

public :

       inline TBufC ();

       inline TBufC ( const TText * aString);

       inline TBufC ( const TDesC & aDes);

 

       inline TBufC < S >& operator= ( const TText * aString);   // 这个“ = ”已经被重载过了

       inline TBufC < S >& operator= ( const TDesC & aDes);    // 这个“ = ”已经被重载过了

 

       inline TPtr Des ();

private :

       TText iBuf [ __Align ( S )];

       };

 

// 拷贝构造函数和默认的重载操作符

       TBufC ( const TBufC <S>& buf);

       TBufC < S >& operator = ( const TBufC <S>& aBuf);

 

 

TBuf    //e32cmn.h

基本用法

       _LIT (KText, "YunYun/n" );

       TBuf <100> buf;

       buf. Copy (KText);

       console-> Write (buf);

      

       TBufC <30> bufText(KText);

       buf. Copy (bufText);

       console-> Write (buf);

      

       buf. Zero ();

       buf. AppendFormat ( _L ( "this is a TBuf example,%S" ),&KText);

       buf. AppendFormat ( _L ( "++_ %S" ),&bufText);

       console-> Write (buf);

// 也可以用 = ,但是那样多了一个 32 位的最大长度 iMaxLength ,不好

 

 

使用方法基本跟 TBufC 相同,在栈上分配空间,直接声明使用

修改方法都是从 TDes 中继承的

 

类函数

template < TInt S >

#if defined(_UNICODE) && !defined(__KERNEL_MODE__)

class TBuf : public TBufBase16

#else

class TBuf : public TBufBase8

#endif

       {

public :

       inline TBuf ();

       inline explicit TBuf ( TInt aLength);   //explicit 不能被隐式转换

       inline TBuf ( const TText * aString);

       inline TBuf ( const TDesC & aDes);

 

       inline TBuf < S >& operator= ( const TText * aString);

       inline TBuf < S >& operator= ( const TDesC & aDes);

       inline TBuf < S >& operator= ( const TBuf < S >& aBuf);

private :

       TText iBuf [ __Align ( S )];

       };

 

 

指针描述符

TPtrC    //e32des16.h

  //iPtr 存放指向 buffer 的指针

基本用法

       _LIT (KText, "YunYun/n" );

       TBuf <100> buf;

       buf. Copy (KText);

      

       TPtrC ptrc1 = buf. Left (3);

       TPtrC ptrc2(ptrc1);

       TPtrC ptrc3;

       ptrc3. Set (buf);

       console-> Write (ptrc1);

       console-> Write (ptrc2);

       console-> Write (ptrc3);

 

类函数

class TPtrC16 : public TDesC16

       {

public :

// 构造函数, 第一种 TPtrC 设置缓冲区的方法

       IMPORT_C TPtrC16 ();

       IMPORT_C TPtrC16 ( const TDesC16 &aDes);

       IMPORT_C TPtrC16 ( const TUint16 *aString);   // 以“ 0 结尾的字符串指针

       IMPORT_C TPtrC16 ( const TUint16 *aBuf, TInt aLength);    // 传递一个缓冲区的指针,设置 TPtrC 对象的长度

// 默认的拷贝构造函数

       TPtrC ( const TPrtC &aDes);

// 可以通过 set 方法设置缓冲区, 第二种 TPtrC 设置缓冲区的方法

       inline void Set ( const TUint16 *aBuf, TInt aLength);

       inline void Set ( const TDesC16 &aDes);

       inline void Set ( const TPtrC16 &aPtr);

//Set 方法不能改变缓冲区里面的数据,但是可以改变 TPtrC 对象指向的缓冲区

private :

       TPtrC16 & operator= ( const TPtrC16 &aDes);  //TPtrC 也重载了“ =

protected :

       const TUint16 * iPtr ;

private :

       __DECLARE_TEST ;

       };

 

第三种 TPtrC 设置缓冲区的方法 ,直接通过其他缓冲区描述符获取 TPtrC 对象

       _LIT (KText1, "YunYun/n" );

       TBuf <100> bufText1;

       bufText1. Copy (KText1);

      

       TPtrC ptrcLeft = bufText1. Left (3);

       TPtrC ptrcRight;

       ptrcRight. Set (bufText1. Right (4));

 

TPtr   //e32des16.h

基本用法

       _LIT (KText1, "YunYun/n" );

       TBufC <100> bufText1;

       bufText1 = KText1;

      

       _LIT (KText2, "YunYun" );

       TBufC <30> bufText2(KText2);

      

       TPtr ptr = bufText1.Des();  // 变成 Ptr 型的

       ptr. Set (bufText2.Des());

       ptr. AppendFormat ( _L ( " %d" ),20);

       console-> Write (ptr);

// 通过指针描述符轻松的绕过了 TBufC 的不能修改的限制

 

// 还可以用这个

       TText text[100];

       TPtr ptrText(text,100);

 

类方法

class TPtr16 : public TDes16

       {

public :

// 注意没有空的构造函数

       IMPORT_C TPtr16 ( TUint16 *aBuf, TInt aMaxLength);

       IMPORT_C TPtr16 ( TUint16 *aBuf, TInt aLength, TInt aMaxLength);

// 拷贝构造函数

       TPtr ( TPtr & aTPtr);

       // 重载的“ = ”运算符

       inline TPtr16 & operator= ( const TUint16 *aString);

       inline TPtr16 & operator= ( const TDesC16 & aDes);

       inline TPtr16 & operator= ( const TPtr16 & aDes);

 

       inline void Set ( TUint16 *aBuf, TInt aLength, TInt aMaxLength);

       inline void Set ( const TPtr16 &aPtr);

private :

       IMPORT_C TPtr16 ( TBufCBase16 &aLcb, TInt aMaxLength);  // 注意这个是一个私有的方法

protected :

       TUint16 * iPtr ;

private :

       friend class TBufCBase16 ;

       __DECLARE_TEST ;

       };

 

实际开发过程中,很多时候是直接取得指向缓存区的指针描述符 TPtr 对象,然后使用 TPtr 对象操作缓冲区中的数据,常用的方法有下面两种

1 )取得 TBufC 的指针描述符

       _LIT (KText2, "YunYun" );

       TBufC <30> bufText2(KText2);

      

       TPtr ptr = bufText1.Des();  // 变成 Ptr 型的

2 )取得缓冲区描述符 HBufC 的指针描述符

       HBufC * pBuf = HBufC :: New (30);

       TPtr ptrBuf = pBuf-> Des ();              // 注意堆是 -> TBufC .

 

堆缓冲区描述符

HBufC

在堆上,要用 New 方法

class RReadStream ;

class HBufC16 : public TBufCBase16

{

public :

       IMPORT_C static HBufC16 *New ( TInt aMaxLength);

       IMPORT_C static HBufC16 *NewL ( TInt aMaxLength);

       IMPORT_C static HBufC16 *NewLC ( TInt aMaxLength);

       IMPORT_C static HBufC16 *NewMax ( TInt aMaxLength);

       IMPORT_C static HBufC16 *NewMaxL ( TInt aMaxLength);

       IMPORT_C static HBufC16 *NewMaxLC ( TInt aMaxLength);

       IMPORT_C static HBufC16 *NewL ( RReadStream &aStream, TInt aMaxLength);

       IMPORT_C static HBufC16 *NewLC ( RReadStream &aStream, TInt aMaxLength);

      

       // 也重载了“ = ”操作符

       IMPORT_C HBufC16 & operator= ( const TUint16 *aString);

       IMPORT_C HBufC16 & operator= ( const TDesC16 &aDes);

       inline HBufC16 & operator= ( const HBufC16 &aLcb);

 

       IMPORT_C HBufC16 *ReAlloc ( TInt aMaxLength);  // 失败返回 NULL ,且原来的 buffer 的内容不变

       IMPORT_C HBufC16 *ReAllocL ( TInt aMaxLength); // 失败返回 Leave 。且原来的 buffer 的内容不变

 

       IMPORT_C TPtr16 Des ();

private :

       inline HBufC16 ( TInt aLength);

private :

       TText16 iBuf [1];

       __DECLARE_TEST ;

       };

 

注意:

一旦重新分配,必须改变指向原来 buffer 的指针的指向,包括 cleanup stack 中的指针

       HBufC * buf = HBufC :: New (15);

       CleanupStack :: PushL (buf);

       _LIT (KText, "YunYun/n" );

       *buf = KText;

       console-> Write (*buf);

       buf = buf-> ReAlloc (20);

       CleanupStack :: Pop (buf);

       CleanupStack :: PushL (buf);

       _LIT (KRepText, "&YunYun&&YunYun&/n" );

       *buf = KRepText;

       console-> Write (*buf);

       CleanupStack :: PopAndDestroy (buf);

附:

1 、小补充

1) 、跟 C++ 的小类比

TPtrC 可以被看作是 const char* 的使用
TBufC
可以被看作是 char[] 的使用

 

2) 、对于所有的描述符,要访问其中数据,通过基类 TDesC 的非虚方法 Ptr (),获取指向数据的指针。

 

3) 、两种赋值方式的比较

TPtr p=buf->Des();

TPtr p(buf->Des());

第一句只是根据 buf 当前的真实长度得到一个指针( p 的最大长度与当前的实际长度一样,就是 buf 此时的真实长度 11 ),而第二句则完全用 buf 的信息来构造了 p ,所以它的最大长度应该是 64, 虽然当前的真实长度也是 11

 

4) _LIT _L

_LIT(KSayHelloSTR,"Hello world.");

而那个 _L 宏不提倡用了,因为效率太低的原因。

这里的 KSayHelloSTR 是另一种描述符 TLitC 。而 TLitC 提供两个运算符要注意:

& 操作符 能得到它的 const TDesC* ,而 () 操作符 则得到它的 const TDesC&

KSayHelloSTR().Length(); // 得到这个字串的长度

 

_L() 可以生成一个指向字符值的地址( TPtrC ),它经常被用来传递字符串到函数中:
NEikonEnvironment::MessageBox(_L("Error: init file not found!"));

 

TBuf<256> str;

str.Format(KFormatSTR,&KSayHelloSTR); // 得到这个字串的引用地址

 

5) 两种字符串附值方法

HBufC* textResource;

textResource = StringLoader::LoadLC( R_HEWP_TIME_FORMAT_ERROR );
textResource =iEikonEnv->AllocReadResourceL(R_EXAMPLE_TEXT_HELLO);

TBuf<32> timeAsText;
timeAsText = *textResource;

 

6) C++ 的字符串不一样, Symbian 中的描述符都是用一个附加的整数描述其长度,而不是以 '/0' 做终结符。因此,描述符可以表达任意数据,字符串或者二进制串。

   

2 、选择描述符

 

使用原则

如果描述符里面包含二进制内容,应该使用 8bit 的描述符。
如果描述符里面包含宽字符,应该使用 16bit 的描述符。
否则应该使用没有制定 bit 的描述符。

 

 

一些常用的转化

一、描述符之间的转换

//TBuf  转换为 TPtrC16   

       TBuf <32> tText( _L ( "&YunYun& Miss You&" ));   

       TPtrC16 tPtrSecond=tText. Mid (1,3);

 

//TPtrC16 转换为 TBufC16     

       TBufC16 <10> bufcs(tPtrSecond);

 

//TBufC16 转换为   TPtr16   

       TPtr16 f =bufcs.Des();

 

//TPtr16 转换为 TBuf   

       TBuf <10> bufSecond;  

       bufSecond. Copy (f);

 

//TBuf 转换为 TPtr16    

       TBuf <10> buf1( _L ( "12132" ));   

       TPtr16 ptr(f);   

       ptr. Copy (buf1);

 

//TBuf 转换为 TInt   

       TInt aSecond;   

       TLex iLexS(buf1);  

       iLexS. Val (aSecond);  // 现在 aSecond 里面就是 buf1 的值

 

 

       //TInt 转换为 TBuf   

       TBuf <32> tbuf;   

       TInt i=200;   

       tbuf. Num (i);

       tbuf. Format ( _L ( "%d" ) , aSecond);

       tbuf. AppendNum (aSecond); // 又加了一次的 aSecond

       console-> Write (tbuf);   //12132


二、其他类型转化

1 TTime TBuf
       TBuf <32> theTime ; // 存储转换后的时间

       TTime tt;

       tt. HomeTime ();

       _LIT (KTimeFormat, "%Y%M%D%1-%2-%3 %H:%T:%S" ); // 格式为: 2009-8-29 11:37:50

       tt. FormatL (theTime ,KTimeFormat); //FormatL() 会以 KTimeFormat 字符串的形式来格式化时间在赋值给 theTime

 

2 TDateTime TBuf
       TTime currentTime; // 声明一个 TTime 类型

       currentTime. HomeTime (); // 设置 TTime 为当前时间

       TDateTime tdt=currentTime. DateTime (); //TTime    --->    TDateTime

       TBuf <32> tmp; // 存储转换完的 Buf

       tmp. AppendNum (tdt. Year ()); // AppendNum() 方法将一个 Tint 加入到 TBuf 中。

       _LIT (gang, "-" ); // 声明一个横线分隔年月日,同样可声明冒号分隔小时分秒

       tmp. Append (gang);

       tmp. AppendNum (tdt. Month ());

       tmp. Append (gang);

       tmp. AppendNum (tdt. Day ()); //………… 时分秒的转换同上

      

方案 1:

       _LIT (KTimeFormat , " %H:%T:%S" );

       TBuf <32> theTime;

       currentTime. FormatL (theTime,KTimeFormat );

       tmp. Append (theTime);

方案 2:

       _LIT (mao, ":" );

       _LIT (kong, " " );

       tmp. Append (kong);

       tmp. Append Num (tdt. Hour ());

       tmp. Append (mao);

       tmp. AppendNum (tdt. Minute ());

       tmp. Append (mao);

       tmp. AppendNum (tdt. Second ());

 

 

5 TBuf TDateTime
       _LIT (buf1, "2009-8-29 16:30:03" );

       TBuf <32> timeBuf(buf1);

       TInt tmpInt = 0;

       TDateTime nowDate;

       _LIT (gang, "-" );

       _LIT (mao, ":" );

       _LIT (kong, " " );

      

       timeBuf. TrimAll ();

      

       TBuf <4> sYear(timeBuf. Left (4));

       timeBuf. Delete (0,5);

       TLex iLexSY(sYear);  

       iLexSY. Val (tmpInt);

       nowDate. SetYear (tmpInt);

 

       TBuf <4> sMonth(timeBuf. Left (timeBuf. Find (gang)));

       timeBuf. Delete (0,timeBuf. Find (gang)+1);

       TLex iLexSM(sMonth);  

       iLexSM. Val (tmpInt);

       nowDate. SetMonth (TMonth(tmpInt));

      

       TBuf <4> sDay(timeBuf. Left (timeBuf. Find (kong)));

       TLex iLexSD(sDay);  

       iLexSD. Val (tmpInt);

       nowDate. SetDay (tmpInt);

       timeBuf. Delete (0,timeBuf. Find (kong)+1);

      

       TBuf <2> sHour(timeBuf. Left (timeBuf. Find (mao)));

       TLex iLexSH(sHour);  

       iLexSH. Val (tmpInt);

       nowDate. SetHour (tmpInt);

       timeBuf. Delete (0,timeBuf. Find (mao)+1);

      

       TBuf <2> sMinute(timeBuf. Left (timeBuf. Find (mao)));

       TLex iLexSm(sMinute);  

       iLexSm. Val (tmpInt);

       nowDate. SetMinute (tmpInt);

 

       TBuf <2> sSecond(timeBuf. Right (2));

       TLex iLexSS(sSecond);  

       iLexSS. Val (tmpInt);

       nowDate. SetSecond (tmpInt);

 

6 TPtrc8 TPtrc16 之间转化

       // Get a iBuf8 from a iBuf16 (data are not modified)

       _LIT (KText , "YunYun" );

       TBuf16 <6> iBuf16(KText );

       TPtrC8 ptr8( reinterpret_cast < const TUint8 *>(iBuf16. Ptr ()),(iBuf16. Length ()*2));

// Length () 函数,返回字符串的长度 (16 位跟 8 位是 2 关系 ) Size () 函数,描述符所占的字节数( 16 位跟 8 位是 4 关系)       

TBuf8 <12> iBuf8(ptr8);

 

       // Get a iBuf16 from a iBuf8 (data are not modified)

       TPtrC16 ptr16( reinterpret_cast < const TUint16 *>(iBuf8. Ptr ()),(iBuf8. Size ()/2));

       iBuf16=ptr16;

 

       // Get a iBuf8 from a iBuf16 (data are modified)

       CnvUtfConverter :: ConvertFromUnicodeToUtf8 (iBuf8,iBuf16);

 

       // Get a iBuf16 from a iBuf8 (data are modified)

       CnvUtfConverter :: ConvertToUnicodeFromUtf8 (iBuf16,iBuf8);

 

7 Symbian 串和 char 串间的转换

// symbian 串转换成 char

           char * p = NULL ;

           TBuf8 <20> buf( _L ( "aaaaa" ) );

           p = ( char *)buf. Ptr ();

 

 

// char 串转换成 symbian

           char * cc = "aaaa" ;

           TPtrC8 a ;

            a.Set ( ( const TUint8 *)cc , strlen (cc) );

8) 再加一点
       TDesC8 & buf ;

       TUint8 * pdata ;

       pdata = buf. Ptr () ;
然后,这个 pdata 就可以当成 unsigned char * 用了,这在网络通讯的时候很重要。
如果,怕 pdata 破坏的话,可以
   
TBuf8 <1024> tmp_buf ;

       tmp_buf . Copy (buf) ;

       pdata = tmp_buf . Ptr ();
这样就可以保护一下 buf 的数据了,尤其是如果这个 buf Socket 的接收的数据是接收函数自己分配的时候。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值