• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            franksunny的個(gè)人技術(shù)空間
            獲得人生中的成功需要的專注與堅(jiān)持不懈多過天才與機(jī)會(huì)。 ——C.W. Wendte

             

            描述符<>轉(zhuǎn)換

             

            業(yè)余有時(shí)候把一個(gè)事情當(dāng)作任務(wù)來(lái)做的時(shí)候,往往會(huì)很受限制,就象這篇文檔,上次寫了個(gè)上篇,關(guān)于描述符的下篇,自己就遲遲沒有勇氣和時(shí)間寫完,好幾次都想靜下心來(lái)好好完成它,但是都未能如愿,可如果不寫顯然我也不好意思寫其它的一些東西,閑話提到這里,花了幾天業(yè)余時(shí)間總算是完成了,該文質(zhì)量不足之處還望讀者您見諒。

             

            通過前面關(guān)于描述符概念和使用的簡(jiǎn)單描述,下面我們直接進(jìn)入描述符轉(zhuǎn)換的主題。

            雖然描述符有五類,但是作為描述符變量用的,只有三類即棧描述符、堆描述符、指針描述符。所以本文所述描述符的轉(zhuǎn)換也只是在這三種類型間展開,這三類描述符之間的互相轉(zhuǎn)換其實(shí)可以用下面這種偽代碼方式給出:

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

            由上面可知指針型可以起堆型和棧型描述符的中間過渡的橋梁作用。

             

            不可修改向可修改描述符的轉(zhuǎn)換

            原則1:通過不可修改描述符類內(nèi)的Des()函數(shù),將不可修改的描述符轉(zhuǎn)換成可修改的指針描述符

            示例1TBufC轉(zhuǎn)換成TPtr

                   _LIT(KText, "Test Data");

                   TBufC<10> NBuf ( KText );

                   TPtr     Pointer = NBuf.Des();

            示例2HBufC轉(zhuǎn)換成TPtr

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

                   _LIT (KText , "Test Text");

                   *Buf = KText;

                   TPtr Pointer = Buf->Des();

             

            原則2:通過TPtr的構(gòu)造函數(shù)或Set()函數(shù)可以將TPtrC描述轉(zhuǎn)換為可修改的指針描述符

            示例3TPtrCTPtr

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

            TPtrC Ptr1(text1);

            TPtrC Ptr2(Ptr1);

            //可以通過構(gòu)造函數(shù)

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

            //也可以通過Set()函數(shù)

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

             

            8位和16位之間的描述符轉(zhuǎn)換

            8位到16位的描述符轉(zhuǎn)換

            原則1:通過將兩個(gè)8位描述符的內(nèi)容合并為一個(gè)16位描述符的方法實(shí)現(xiàn)內(nèi)存不動(dòng),內(nèi)存塊類型強(qiáng)轉(zhuǎn)(我稱其為保留描述符字節(jié)大小方法)。

            示例48bit To 16bit保留描述符字節(jié)大小方法1

            _LIT8(KText , "Test Text");

            TBuf8<20> iBuf8(KText);//描述符實(shí)際占用了9個(gè)字節(jié)9個(gè)8位描述符

            TBuf<20> iBuf16;

            //實(shí)現(xiàn)內(nèi)存塊的強(qiáng)轉(zhuǎn)

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

            //真實(shí)的內(nèi)存不動(dòng)已經(jīng)結(jié)束,這里是重新申請(qǐng)了一塊內(nèi)存并實(shí)現(xiàn)內(nèi)存賦值拷貝

            iBuf16 = ptr16;//描述符實(shí)際占用了8個(gè)字節(jié)4個(gè)16位描述符,導(dǎo)致數(shù)據(jù)丟失

            由上面的這個(gè)例子明顯是丟失了數(shù)據(jù)了,原因就出在設(shè)置長(zhǎng)度時(shí)用了(iBuf8.Length()/2),為了剔除錯(cuò)誤,我后來(lái)改了一個(gè)新的示例6

            示例68bit To 16bit保留描述符字節(jié)大小方法2(由于上例用了TPtrC,所以該例使用TPtr指針,以擴(kuò)展應(yīng)用)

            _LIT8(KText , "Test Text");

            TBuf8<20> iBuf8;

            iBuf8.FillZ(20);

            iBuf8 = KText;//實(shí)際占用9字節(jié)9描述符

            TBuf<20> iBuf16;

            TPtr ptr16(reinterpret_cast<TUint16*>(const_cast<TUint8*>(iBuf8.Ptr())),
               ((iBuf8.Length()+1)/2),((iBuf8.Length()+1)/2));

            iBuf16 = ptr16;//實(shí)際占用10字節(jié)5描述符,但是第10個(gè)字節(jié)為0零值,也即9字節(jié)大小有用

            注:其實(shí)這里用堆描述符來(lái)說(shuō)明可能更好些,但是本人在調(diào)試過程中為了能夠看到調(diào)試的效果,所以用了TBuf;而且個(gè)人覺得通常這種方法主要在文件讀取等實(shí)際過程中用到,如果要轉(zhuǎn)換為16位的話,肯定是偶數(shù)大小的8位描述符。

             

            原則2:重新構(gòu)建內(nèi)存塊使用描述符的copy函數(shù)將8位字符的高字節(jié)置為0低字節(jié)不變,進(jìn)行拷貝轉(zhuǎn)換(我稱其為保留描述符長(zhǎng)度方法)。

            示例7

            _LIT8(KText , "Test Text");

            TBuf8<20> iBuf8(KText);//實(shí)際占用了9個(gè)描述符9個(gè)字節(jié)

            TBuf<20> iBuf16;

            iBuf16.Copy(iBuf8);//實(shí)際占用了9個(gè)描述符18個(gè)字節(jié)

             

            原則3:使用charconv.lib內(nèi)的API函數(shù)8位的UTF8描述符轉(zhuǎn)換為16位的Unicode 描述符

            CnvUtfConverter::ConvertToUnicodeFromUtf8(iBuf, iBuf8);

            注:在使用這種方法時(shí)除了包含charconv.lib庫(kù),還應(yīng)該包含utf.h頭文件

             

            原則4:使用GBK轉(zhuǎn)Unicode的方法

            注:原則34是我在實(shí)際中常用的方法,涉及到各種編碼的問題,暫時(shí)不做大的展開,下次使用中文的整理時(shí)再展開。

             

            16位到8位的描述符轉(zhuǎn)換

            原則1:通過將一個(gè)16位描述符拆分為兩個(gè)8位描述符的方法實(shí)現(xiàn)內(nèi)存不動(dòng),內(nèi)存塊類型強(qiáng)轉(zhuǎn)(我稱其為保留描述符字節(jié)大小方法)

            示例8

            _LIT(KText , "Test 文本");

            TBuf<20> iBuf(KText);//描述符實(shí)際占用了14個(gè)字節(jié)7個(gè)16位描述符                            //實(shí)現(xiàn)內(nèi)存塊的強(qiáng)轉(zhuǎn)

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

            //真實(shí)的內(nèi)存不動(dòng)已經(jīng)結(jié)束,這里是重新申請(qǐng)了一塊內(nèi)存并實(shí)現(xiàn)內(nèi)存賦值拷貝

            TBuf8<20> iBuf8;

            iBuf8 = ptr8;//描述符實(shí)際占用了14個(gè)字節(jié)14個(gè)8位描述符

            以上

            原則2:重新構(gòu)建內(nèi)存塊使用描述符的copy函數(shù)將16位描述符的,進(jìn)行拷貝轉(zhuǎn)換(我稱其為保留描述符長(zhǎng)度方法)。

            示例9

            _LIT(KText , "Test 文本");

            TBuf<20> iBuf(KText);// 描述符實(shí)際占用了14個(gè)字節(jié)7個(gè)16位描述符

            TBuf8<20> iBuf8;

            iBuf8.Copy(iBuf);//描述符實(shí)際占用了7個(gè)字節(jié)7個(gè)描述符,非ASCII字符值轉(zhuǎn)為1

            注:該種方法在純ASCII碼的轉(zhuǎn)換時(shí)可行,其它數(shù)據(jù)大于255的時(shí)候就會(huì)丟失數(shù)據(jù)。

             

            原則3:使用charconv.lib內(nèi)的API函數(shù)16位的Unicode描述符轉(zhuǎn)換為8位的UTF8描述符。

            CnvUtfConverter::ConvertFromUnicodeToUtf8(iBuf8, iBuf);

             

            原則4:使用Unicode轉(zhuǎn)GBK的方法

            同前面理,以后我會(huì)再講到。

             

            由于最近做通信模塊時(shí)組解包用的比較多,為此經(jīng)常會(huì)將memcpystrcpysprintfsscanf等函數(shù)在char字符串和描述符串內(nèi)存塊之間的直接使用,個(gè)人覺得描述符一旦取得了后面數(shù)據(jù)區(qū)的首指針,那么內(nèi)存塊的這些操作沒有什么好展開,直接用函數(shù)大家都會(huì),當(dāng)然本人也推薦讀者使用文后的char字符串和Symbian描述符串的轉(zhuǎn)換方法。

             

            在整理過程種,也有其它類型與描述符的轉(zhuǎn)換,我就摘錄在本文后面作為mark和備查:

            1.    TTime轉(zhuǎn)TBuf

            TBuf<32> theTime;//存儲(chǔ)轉(zhuǎn)換后的時(shí)間

            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轉(zhuǎn)TBuf

            TTime currentTime;//聲明一個(gè)TTime類型

            currentTime.HomeTime();//設(shè)置TTime為當(dāng)前時(shí)間

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

            TBuf<32> tmp;//存儲(chǔ)轉(zhuǎn)換完的Buf

            tmp.AppendNum(tdt.Year());//AppendNum()方法將一個(gè)Tint加入到TBuf中。

            _LIT(gang,"-");//聲明一個(gè)橫線分隔年月日,同樣可聲明冒號(hào)分隔小時(shí)分秒

            tmp.Append(gang);

            tmp.AppendNum(tdt.Month());

            tmp.Append(gang);

            tmp.AppendNum(tdt.Day());//…………時(shí)分秒的轉(zhuǎn)換同上

             

            3.    TBufTint互轉(zhuǎn)型

            // 15位數(shù)字

            TInt iNum1(123456789009876);

            // TInt轉(zhuǎn)TBuf

            iBuf.Num(iNum1);//當(dāng)buf只用來(lái)轉(zhuǎn)Tint時(shí)可以使用AppendNum,但是性質(zhì)是不一樣的

             

            // 使用iBuf包含的內(nèi)容創(chuàng)建TLex對(duì)象

            TLex iLex(iBuf);

            TInt iNum2;

            //TBuf轉(zhuǎn)TInt

            iLex.Val(iNum2);// Num2現(xiàn)在包含了15位數(shù)字

             

            4.    TBuf轉(zhuǎn)TDateTime

            將長(zhǎng)的TBuf截成小段,分別是年月日時(shí)分秒,通過下面TBuf轉(zhuǎn)TInt ,再分別把轉(zhuǎn)換成TInt的年月日取出,通過TDateTimesetYear(),setMonth()等方法將時(shí)間set進(jìn)TdateTime

             

            5. .symbian串轉(zhuǎn)換成char

            char* p = NULL;

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

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

             

            6.char串轉(zhuǎn)換成symbian

            char* cc = "aaaa";

            TPtrC8 a;

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

             

            本文參考了一些論壇資料,至于資料索引,我也無(wú)法給出,望讀者見諒,有錯(cuò)誤之處還望指出。

            posted on 2007-11-28 22:51 frank.sunny 閱讀(4960) 評(píng)論(15)  編輯 收藏 引用 所屬分類: symbian 開發(fā)

            FeedBack:
            # re: 描述符轉(zhuǎn)換
            2007-11-29 22:25 | helixapp
            真的挺全的 贊一個(gè)  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-03 15:37 | myh
            博主的示例6:8bit To 16bit保留描述符字節(jié)大小方法2(由于上例用了TPtrC,所以該例使用TPtr指針,以擴(kuò)展應(yīng)用)


            _LIT8(KText , "Test Text");

            TBuf8<20> iBuf8;

            iBuf8.FillZ(20);

            iBuf8 = KText;//實(shí)際占用9字節(jié)9描述符

            TBuf<20> iBuf16;

            TPtr ptr16(reinterpret_cast<TUint16*>(const_cast<TUint8*>(iBuf8.Ptr())),
            ((iBuf8.Length()+1)/2),((iBuf8.Length()+1)/2));

            iBuf16 = ptr16;//

            // 本人在Draw函數(shù)中引用了你上面的代碼,,同時(shí)調(diào)用下面語(yǔ)句
            gc.DrawText(iBuf16,TPoint(0,20));
            在模擬器上顯示的是亂碼,,不知為什么,,
              回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-04 10:50 | frank.sunny
            @myh
            好久沒來(lái)更新了,今天在郵箱里看到來(lái)自博客園的郵件感覺好親切

            謝謝myh兄,還自己去做過實(shí)驗(yàn),其實(shí)8位到16位的前兩個(gè)原則只是保證在內(nèi)存塊中數(shù)據(jù)一致,不放你可以自己調(diào)試看看內(nèi)存里面內(nèi)容,但是你在顯示的時(shí)候8位和16位的編碼不一樣自然就會(huì)出現(xiàn)亂碼了

            其實(shí)這個(gè)問題還是涉及編碼的問題,由于后來(lái)項(xiàng)目緊就一直沒有更新博客了,myh兄可以采用原則3和4,肯定不會(huì)出現(xiàn)亂碼的,并且如果是中文,在模擬器上如果采用了中文SDK是不會(huì)出現(xiàn)亂碼的,在手機(jī)上可能還會(huì)出現(xiàn)亂碼,這個(gè)只能以后詳細(xì)解說(shuō)了

            再次感謝myh兄參與討論


              回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 11:26 | myh
            多謝回復(fù),,最近在學(xué)習(xí)真機(jī)上中文顯示問題,,感覺比較復(fù)雜,,

            用兩種方法實(shí)現(xiàn)了真機(jī)上中文顯示,,
            1、CnvUtfConverter::ConvertToUnicodeFromUtf8(iBuf, iBuf8);

            2、CCnvCharacterSetConverter中的ConvertToUnicode

            但第一種方法存在文件保存時(shí)的格式問題,,選擇UTF-8 無(wú) BOM格式,,當(dāng)文件中的內(nèi)容改變時(shí)又會(huì)出問題,,
            能不能把整個(gè)項(xiàng)目發(fā)到你的郵箱里,,幫我看一下,,

            另外第二種方法比較耗時(shí),,但比較方便,,  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 11:58 | frank.sunny
            閣下連耗時(shí)與否都做過比較了,非常感激,但是不知道具體是怎樣耗時(shí)法,本人未做過這方面的實(shí)驗(yàn)。
            照理轉(zhuǎn)成utf8應(yīng)該無(wú)問題啊,不知道怎么聯(lián)系閣下,我的郵箱是:frank.sunny@163.com
              回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 12:03 | myh

            第一種方法,,
            _LIT8(KOpentoMap8, "返回我的最愛");
            會(huì)報(bào)以下錯(cuò)
            error C2001: 常數(shù)中有換行符
            fatal error C1057: 宏展開中遇到意外的文件結(jié)束

            但是將文字改成以下幾種情況又不會(huì)報(bào)錯(cuò)
            1、_LIT8(KOpeap8, "返回我的最");
            2、_LIT8(KOpeap8, "城市設(shè)置成功");
            3、_LIT8(KOpeap8, "返回我的最w");


              回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 12:12 | frank.sunny
            不知道你是怎么考慮的,照理“_LIT8(KOpentoMap8, "返回我的最愛");”這個(gè)語(yǔ)句應(yīng)該是“_LIT(KOpentoMap8, "返回我的最愛");”吧 ?

            我不是很清楚你要實(shí)現(xiàn)什么目的


              回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 12:50 | myh
            我定義了一個(gè)專門存放字符常量的頭文件,,Common.h

            其中有_LIT8(KOpentoMap8, "返回我的最愛");
            ccp文件中調(diào)用
            CnvUtfConverter::ConvertToUnicodeFromUtf8(iBuf, KOpentoMap8);


            最后調(diào)用DrawText; 以顯示中文,,“返回我的最愛”
              回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 13:27 | frank.sunny
            不好意思,剛剛午睡下
            你這樣是不對(duì)的,“_LIT8(KOpentoMap8, "返回我的最愛");"中的"返回我的最愛"是GBK編碼的,而_LIT8并非轉(zhuǎn)化為utf-8的,仍然是GBK編碼的。這個(gè)在symbian中現(xiàn)在一般不推薦使用,只針對(duì)ASCII碼時(shí)是適用的。
            關(guān)于GBK轉(zhuǎn)化到Unicode另外有代碼實(shí)現(xiàn)的,也怪自己偷懶老是沒有整理這個(gè)東西,我有時(shí)間整理下吧。  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 13:58 | myh
            沒事,,



            _LIT8(KOpentoMap8, "返回我的最愛");"中的"返回我的最愛"是GBK編碼的,

            我已經(jīng)將文件Commom.h頭文件存為UTF-8 無(wú) BOM 格式 了,,所以

            返回我的最愛 應(yīng)該是UTF-8 無(wú) BOM 編碼了,,  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 14:28 | frank.sunny
            不知道閣下如何聯(lián)系,想問下無(wú)bom和有bom具體是什么關(guān)系啊
            我不懂呢,查了下有bom多了內(nèi)容為“FFFE”,對(duì)吧,但是有什么用,能告知下嗎  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-03-20 15:20 | myh
            644621379

            其實(shí)我也不太懂,,昨天看到的,,你加我吧,,咱們QQ聊,,  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-06-25 19:42 | wangfsun
            symbian學(xué)習(xí)中,借用了你的一些資料,很感謝  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2008-11-28 09:36 | liuhz
            很好得文章,非常感謝分享。再接再厲,呵呵。  回復(fù)  更多評(píng)論
              
            # re: 描述符轉(zhuǎn)換
            2011-01-13 11:24 | longteng9
            // 15位數(shù)字

            TInt iNum1(123456789009876);

            // TInt轉(zhuǎn)TBuf

            iBuf.Num(iNum1);//當(dāng)buf只用來(lái)轉(zhuǎn)Tint時(shí)可以使用AppendNum,但是性質(zhì)是不一樣的
            我用寫在文件中
            TBuf8<20> buf=iBuf.Num(iNum1);
            iFile.Write(buf);  回復(fù)  更多評(píng)論
              

            常用鏈接

            留言簿(13)

            隨筆分類

            個(gè)人其它博客

            基礎(chǔ)知識(shí)鏈接

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品国产精品亚洲人人| 国产婷婷成人久久Av免费高清| 久久无码人妻精品一区二区三区| 久久电影网| 思思久久99热只有频精品66| 久久99热这里只有精品国产| 亚洲精品无码久久久久久| 国产精品久久亚洲不卡动漫| 99久久精品国产一区二区三区| 亚洲精品无码专区久久同性男| 午夜人妻久久久久久久久| 中文字幕亚洲综合久久| 伊人久久大香线蕉综合网站| 精品久久久久久国产潘金莲| 久久人人超碰精品CAOPOREN | 亚洲综合久久夜AV | 婷婷久久久亚洲欧洲日产国码AV| 亚洲一区中文字幕久久| 久久午夜无码鲁丝片秋霞| 久久99精品国产99久久| 久久无码AV一区二区三区| 久久99中文字幕久久| 久久婷婷是五月综合色狠狠| 久久99精品国产一区二区三区| 欧美亚洲国产精品久久| 一本大道久久a久久精品综合| 久久无码AV一区二区三区| 国内精品久久久久国产盗摄| 亚洲AV无码久久寂寞少妇| 久久久久18| 精品综合久久久久久97超人| 亚洲乱码精品久久久久..| 亚洲v国产v天堂a无码久久| 久久99毛片免费观看不卡| 性做久久久久久久| 国产99久久久国产精品小说| 精品久久久久久无码免费| 久久久久夜夜夜精品国产| 69久久精品无码一区二区| 中文字幕乱码人妻无码久久| 一本色道久久综合狠狠躁篇|