描述符之间的转换

 

2009年03月25日 星期三 08:45 P.M.

转自:http://www.cppblog.com/franksunny/archive/2007/11/28/37469.html

 

虽然描述符有五类,但是作为描述符变量用的,只有三类即栈描述符、堆描述符、指针描述符。所以本文所述描述符的转换也只是在这三种类型间展开,这三类描述符之间的互相转换其实可以用下面这种伪代码方式给出:

TBuf<20> iBuf;

TPtr iPtr((const_cast<TUint16*>(iBuf.Ptr())),iBuf.Length(), iBuf.Length());

HBufC     *iHbuf;

iBuf = iPtr;

iBuf = iHbuf->Des();

iPtr.Set((const_cast<TUint16*>(iBuf.Ptr())),iBuf.Length(), iBuf.Length());

由上面可知指针型可以起堆型和栈型描述符的中间过渡的桥梁作用。

不可修改向可修改描述符的转换

原则1:通过不可修改描述符类内的Des()函数,将不可修改的描述符转换成可修改的指针描述符

示例1:TBufC转换成TPtr

       _LIT(KText, "Test Data");

       TBufC<10> NBuf ( KText );

       TPtr     Pointer = NBuf.Des();

示例2:HBufC转换成TPtr

HBufC * Buf = HBufC::NewL(15);

       _LIT (KText , "Test Text");

       *Buf = KText;

       TPtr Pointer = Buf->Des();

原则2:通过TPtr的构造函数或Set()函数可以将TPtrC描述转换为可修改的指针描述符

示例3:TPtrC到TPtr

const TText * text1 = _S("Hello World/n");

TPtrC Ptr1(text1);

TPtrC Ptr2(Ptr1);

//可以通过构造函数

TPtr Ptr3((TUint16 *)(Ptr1.Ptr()), Ptr1.Length());

//也可以通过Set()函数

Ptr3.Set((TUint16 *)(Ptr1.Ptr()),Ptr1.Length(), Ptr1.Length());

8位和16位之间的描述符转换

 

8位到16位的描述符转换

原则1:通过将两个8位描述符的内容合并为一个16位描述符的方法实现内存不动,内存块类型强转(我称其为保留描述符字节大小方法)。

示例4:8bit To 16bit保留描述符字节大小方法1

_LIT8(KText , "Test Text");

TBuf8<20> iBuf8(KText);//描述符实际占用了9个字节9个8位描述符

TBuf<20> iBuf16;

//实现内存块的强转

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

//真实的内存不动已经结束,这里是重新申请了一块内存并实现内存赋值拷贝

iBuf16 = ptr16;//描述符实际占用了8个字节4个16位描述符,导致数据丢失

由上面的这个例子明显是丢失了数据了,原因就出在设置长度时用了(iBuf8.Length()/2),为了剔除错误,我后来改了一个新的示例6

示例6:8bit To 16bit保留描述符字节大小方法2(由于上例用了TPtrC,所以该例使用TPtr指针,以扩展应用)

_LIT8(KText , "Test Text");

TBuf8<20> iBuf8;

iBuf8.FillZ(20);

iBuf8 = KText;//实际占用9字节9描述符

TBuf<20> iBuf16;

TPtr ptr16(reinterpret_cast<TUint16*>(const_cast<TUint8*>(iBuf8.Ptr())),

   ((iBuf8.Length()+1)/2),((iBuf8.Length()+1)/2));

iBuf16 = ptr16;//实际占用10字节5描述符,但是第10个字节为0零值,也即9字节大小有用

注:其实这里用堆描述符来说明可能更好些,但是本人在调试过程中为了能够看到调试的效果,所以用了TBuf;而且个人觉得通常这种方法主要在文件读取等实际过程中用到,如果要转换为16位的话,肯定是偶数大小的8位描述符。

原则2:重新构建内存块使用描述符的copy函数将8位字符的高字节置为0低字节不变,进行拷贝转换(我称其为保留描述符长度方法)。

示例7

_LIT8(KText , "Test Text");

TBuf8<20> iBuf8(KText);//实际占用了9个描述符9个字节

TBuf<20> iBuf16;

iBuf16.Copy(iBuf8);//实际占用了9个描述符18个字节

原则3:使用charconv.lib内的API函数将8位的UTF8描述符转换为16位的Unicode 描述符

CnvUtfConverter::ConvertToUnicodeFromUtf8(iBuf, iBuf8);

注:在使用这种方法时除了包含charconv.lib库,还应该包含utf.h头文件

原则4:使用GBK转Unicode的方法

注:原则3和4是我在实际中常用的方法,涉及到各种编码的问题,暂时不做大的展开,下次使用中文的整理时再展开。

16位到8位的描述符转换

原则1:通过将一个16位描述符拆分为两个8位描述符的方法实现内存不动,内存块类型强转(我称其为保留描述符字节大小方法)

示例8

_LIT(KText , "Test 文本");

TBuf<20> iBuf(KText);//描述符实际占用了14个字节7个16位描述符                            //实现内存块的强转

TPtrC8 ptr8(reinterpret_cast<const TUint8*>(iBuf.Ptr()), (iBuf.Size()));

//真实的内存不动已经结束,这里是重新申请了一块内存并实现内存赋值拷贝

TBuf8<20> iBuf8;

iBuf8 = ptr8;//描述符实际占用了14个字节14个8位描述符

以上

原则2:重新构建内存块使用描述符的copy函数将16位描述符的,进行拷贝转换(我称其为保留描述符长度方法)。

示例9:

_LIT(KText , "Test 文本");

TBuf<20> iBuf(KText);// 描述符实际占用了14个字节7个16位描述符

TBuf8<20> iBuf8;

iBuf8.Copy(iBuf);//描述符实际占用了7个字节7个描述符,非ASCII字符值转为1

注:该种方法在纯ASCII码的转换时可行,其它数据大于255的时候就会丢失数据。

原则3:使用charconv.lib内的API函数将16位的Unicode描述符转换为8位的UTF8描述符。

CnvUtfConverter::ConvertFromUnicodeToUtf8(iBuf8, iBuf);

原则4:使用Unicode转GBK的方法

同前面理,以后我会再讲到。

由于最近做通信模块时组解包用的比较多,为此经常会将memcpy,strcpy,sprintf,sscanf等函数在char字符串和描述符串内存块之间的直接使用,个人觉得描述符一旦取得了后面数据区的首指针,那么内存块的这些操作没有什么好展开,直接用函数大家都会,当然本人也推荐读者使用文后的char字符串和Symbian描述符串的转换方法。

在整理过程种,也有其它类型与描述符的转换,我就摘录在本文后面作为mark和备查:

1.    TTime转TBuf型

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

TTime tt;

tt.HomeTime();

_LIT(KTimeFormat,"%Y%M%D%1-%2-%3 %H:%T:%S");//格式为:2006-03-04 12:12:12

tt.FormatL(theTime,KTimeFormat);

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());//…………时分秒的转换同上

3.    TBuf和Tint互转型

// 15位数字

TInt iNum1(123456789009876);

// TInt转TBuf

iBuf.Num(iNum1);//当buf只用来转Tint时可以使用AppendNum,但是性质是不一样的

// 使用iBuf包含的内容创建TLex对象

TLex iLex(iBuf);

TInt iNum2;

//TBuf转TInt

iLex.Val(iNum2);// Num2现在包含了15位数字

4.    TBuf转TDateTime型

将长的TBuf截成小段,分别是年月日时分秒,通过下面TBuf转TInt ,再分别把转换成TInt的年月日取出,通过TDateTime的setYear(),setMonth()等方法将时间set进TdateTime。

5. .将symbian串转换成char串

char* p = NULL;

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

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

6.将char串转换成symbian串

char* cc = "aaaa";

TPtrC8 a;

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

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值