標籤:
在日常應用中,我們常用結構體或者類來儲存一條資訊,這種方式很方便,但是不利於資料的傳輸。例如在網路編程中,我們需要將結構中的資料轉化為位元組流才能進行傳輸,我們可以利用memcpy強行將結構化的資料轉化為字串,在接收方以同樣的方式轉化為來。此法簡單易用,但是由於結構化的資料涉及到字元對齊的問題,這種方法會造成額外的資料開銷,所以我們最好自己手動對結構化的資料進行編碼,當然這種方法也有弊端,雖然在一定程度上節省了傳輸串流量,但結構中的欄位很多時,代碼量會增大,最好編寫工具自動產生一些代碼。
1 #include <iostream> 3 #include <memory.h> 4 #include <string.h> 5 using namespace std; 6 7 #define ENCODE(buf, size, offset, data) 8 if ((NULL == buf) || (0 == size)) 9 { 10 return -1; 11 } 12 if (offset + sizeof(data) > size) 13 { 14 return -1; 15 } 16 { 17 uint8_t *p = (uint8_t*)buf; 18 p=p+offset; 19 memcpy(p,&data,sizeof(data)); 20 offset = offset + sizeof(data); 21 } 22 23 #define DECODE(buf, size, offset, data) 24 if ((NULL == buf) || (0 == size)) 25 { 26 return -1; 27 } 28 if (offset + sizeof(data) > size) 29 { 30 return -1; 31 } 32 { 33 uint8_t *p = (uint8_t*)buf; 34 p=p+offset; 35 memcpy(&data,p,sizeof(data)); 36 offset = offset + sizeof(data); 37 } 38 39 #define ENCODE_STR(buf, size, offset, data, length) 40 if ((NULL == buf) || (0 == size) || (0 >= length) ) 41 { 42 return -1; 43 } 44 if (offset + length > size) 45 { 46 return -1; 47 } 48 { 49 uint8_t *p = (uint8_t*)buf; 50 p=p+offset; 51 memcpy(p,data,length); 52 offset = offset+ length; 53 } 54 55 #define DECODE_STR(buf, size, offset, data, length) 56 if ((NULL == buf) || (0 == size) || (0 >= length) ) 57 { 58 return -1; 59 } 60 if (offset + length > size) 61 { 62 return -1; 63 } 64 { 65 uint8_t *p = (uint8_t*)buf; 66 p=p+offset; 67 memcpy(data,p,length); 68 offset = offset+ length; 69 } 70 71 enum{ 72 enmMaxMsgLength = 1024, 73 enmMaxNameLength = 20 74 }; 75 76 class Msg{ 77 int iAge; 78 char szName[enmMaxNameLength]; 79 double dScore; 80 public: 81 Msg() 82 { 83 84 } 85 Msg(int age,const char* name,double score):iAge(age),dScore(score) 86 { 87 strcpy(szName,name); 88 } 89 virtual ~Msg(){} 90 virtual int encode(char *buf) 91 { 92 size_t offset = 0; 93 memset(buf,‘0‘,enmMaxMsgLength); 94 ENCODE(buf,enmMaxMsgLength,offset,iAge); 95 ENCODE_STR(buf,enmMaxMsgLength,offset,szName,enmMaxNameLength); 96 ENCODE(buf,enmMaxMsgLength,offset,dScore); 97 return offset; 98 }; 99 virtual int decode(char *buf,size_t bufSize)100 {101 size_t offset = 0;102 DECODE(buf,bufSize,offset,iAge);103 DECODE_STR(buf,bufSize,offset,szName,enmMaxNameLength);104 DECODE(buf,bufSize,offset,dScore);105 return offset;106 }107 void display()108 {109 cout<<iAge<<" "<<szName<<" "<<dScore<<endl;110 }111 };112 113 int main(int argc, char* argv[])114 {115 size_t offset = 0;116 char buf[enmMaxMsgLength],*recv = NULL;117 Msg msg(23,"hwllo world",23.69),msg1;118 msg.display();119 offset = msg.encode(buf);120 cout<<offset<<endl;121 cout<<sizeof(Msg)<<endl;122 recv = new char[offset];123 memcpy(recv,buf,offset);124 msg1.decode(recv,offset);125 msg1.display();126 return 0;127 }
C++字元數位編碼(Encode)與解碼(Decode)