转-描述符

 

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

缓冲区描述符

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


二、其他类型转化

1TTimeTBuf
       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

 

2TDateTimeTBuf
       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.AppendNum(tdt.Hour());

       tmp.Append(mao);

       tmp.AppendNum(tdt.Minute());

       tmp.Append(mao);

       tmp.AppendNum(tdt.Second());

 

 

5TBufTDateTime
       _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);

 

6TPtrc8TPtrc16之间转化

       // 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);

 

7Symbian串和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的数据了,尤其是如果这个bufSocket的接收的数据是接收函数自己分配的时候。

http://www.devdiv.net/home/space-15361-do-blog-id-449.html

转载于:https://www.cnblogs.com/zziss/archive/2010/01/28/1658519.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值