C++字符数字的编码(Encode)与解码(Decode)
在日常应用中,我们常用结构体或者类来存储一条信息,这种方式很方便,但是不利于数据的传输。例如在网络编程中,我们需要将结构中的数据转化为字节流才能进行传输,我们可以利用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 }