字节编码
2016-06-05 19:06
127 查看
1.对象序列化
任何一种数据类型都可以被序列化。(从字节到对象,从对象到字节)
2.大端小端
unsigned int id =0x12345678;(大端,高字节在前)
它对应的内存存储(78 56 34 12):小端
现在的PC、服务器端使用的是小端系统
而网络传输时使用大端协议。
协议中必须规定大小端
例子:小端存储
3.字节编码器
序列化<—->反序列
字节型编码(封装起来)
封装字节型编码:
实例:
#include<stdio.h> #include <string> using namespace std; class Student{ public: int id; string name; };//定义一个普通类 int Sequence(const Student &s,char output[]){ //序列化 int count=0;//定义序列长度 memcpy(output,&s.id,4);//将id存入output数组,长度为4 count+=4;//count加4 memcpy(output+count,s.name.c_str(),s.name.length()); //然后将string类型的对象转化为c风格字符串,再放入字符串 count+=s.name.length(); return count;//返回总长度 } int DeSequence(Student &s,const char *input ,int count){ //反序列化 int offset=0;//控制长度 memcpy(&s.id,input,4);//拷贝4个字节到s.id中 offset+=4;//增加长度 s.name.append((char *)input+4,count-offset); //而字符串的添加需要换一种格式。(char-》string类型) return 0; } int main(){ char buf[128]; int count =0; if(1){ Student s; s.id=8; s.name="张三"; count=Sequence(s,buf); } if(1){ Student s2; DeSequence(s2,buf,count); } return 0; }
任何一种数据类型都可以被序列化。(从字节到对象,从对象到字节)
2.大端小端
unsigned int id =0x12345678;(大端,高字节在前)
它对应的内存存储(78 56 34 12):小端
现在的PC、服务器端使用的是小端系统
而网络传输时使用大端协议。
协议中必须规定大小端
例子:小端存储
#include <stdio.h> #include <string.h> int toBytes(unsigned int a, unsigned char* buf) {//将整型转换为字节 buf[0] = a >> 24; buf[1] = a >> 16; buf[2] = a >> 8; buf[3] = a; return 4; } unsigned int fromBytes(const unsigned char* buf) {//将字节转换成整型 unsigned int result = 0; result += buf[0] << 24; result += buf[1] << 16; result += buf[2] << 8; result += buf[3]; return result; } int main() { unsigned int abc = 0x12345678; unsigned char buf[4]; //转化为字节型,小端 toBytes(abc, buf); //将其转化为unsigned int型 unsigned int b = fromBytes(buf); return 0; }
3.字节编码器
序列化<—->反序列
字节型编码(封装起来)
封装字节型编码:
#include <stdio.h> #include <string.h> #include <string> using std::string; class AfByteBuffer//字节编码器 { public: AfByteBuffer(int size) {//构造函数 m_buffer = new char[size];//初始化大小 m_offset = 0; m_length = size; m_owner = true; m_start = (unsigned char*)m_buffer + m_offset; m_written = 0; // 写计数 m_read = 0; // 读计数 } AfByteBuffer(char* buf, int off, int length) { m_buffer = buf; m_offset = off; m_length = length; m_owner = false; m_start = (unsigned char*)m_buffer + m_offset; m_written = 0; // 写计数 m_read = 0; // 读计数 } ~AfByteBuffer() { if(m_owner && m_buffer) { delete [] m_buffer; } } unsigned char* start() { return m_start; } int sizeWritten() { return m_written; } int sizeRead() const { return m_read; } //////////////////////////////////////// void putUint8(unsigned char val) { unsigned char* p = m_start + m_written; p[0] = val; m_written += 1; } void putUint16(unsigned short val) { unsigned char* p = m_start + m_written; p[0] = val>>8; p[1] = val; m_written += 2; } void putUint32(unsigned int val) { unsigned char* p = m_start + m_written; p[0] = val>>24; p[1] = val>>16; p[2] = val>>8; p[3] = val; m_written += 4; } void putUint64(unsigned long long val) { unsigned char* p = m_start + m_written; p[0] = val>>56; p[1] = val>>48; p[2] = val>>40; p[3] = val>>32; p[4] = val>>24; p[5] = val>>16; p[6] = val>>8; p[7] = val; m_written += 8; } void putString(const string& val) { unsigned short length = val.length(); putUint16(length); unsigned char* p = m_start + m_written; memcpy(p, val.c_str(), length); m_written += length; } void putBytes(const char* data, int length) { putUint16(length); unsigned char* p = m_start + m_written; memcpy(p, data, length); m_written += length; } ///////////////////////////////////////// unsigned char getUint8() { unsigned char* p = m_start + m_read; unsigned char result = p[0]; m_read += 1; return result; } unsigned short getUint16() { unsigned char* p = m_start + m_read; unsigned short result = p[0]; result = (result<<8) + p[1]; m_read += 2; return result; } unsigned int getUint32() { unsigned char* p = m_start + m_read; unsigned char result = p[0]; result = (result<<8) + p[1]; result = (result<<8) + p[2]; result = (result<<8) + p[3]; m_read += 4; return result; } unsigned long long getUint64() { unsigned char* p = m_start + m_read; unsigned char result = p[0]; result = (result<<8) + p[1]; result = (result<<8) + p[2]; result = (result<<8) + p[3]; result = (result<<8) + p[4]; result = (result<<8) + p[5]; result = (result<<8) + p[6]; result = (result<<8) + p[7]; m_read += 8; return result; } string getString() { unsigned short length = getUint16(); unsigned char* p = m_start + m_read; string result; result.append((char*)p, length); m_read+= length; return result; } // string类也可以放“不以0结束的无规则数据” int getBytes(char* buf, int maxsize) { unsigned short length = getUint16(); unsigned char* p = m_start + m_read; memcpy(buf, p, length); return length; } private: char* m_buffer; int m_offset; int m_length; bool m_owner; unsigned char* m_start; int m_written; // 已经写入的数据个数 int m_read; // 已经读取的数据个数 };
实例:
include <stdio.h> #include "AfByteBuffer.h" /* STL support */ #include <string> using namespace std; class Student { public: int id; string name; }; int main() { char buf[128]; int count = 0; if(1) {//序列化 Student s1; s1.id = 123; s1.name = "shaofa"; AfByteBuffer enc(buf, 0, 128); enc.putUint32(s1.id); enc.putString(s1.name); count = enc.sizeWritten(); } if(1) {//反序列化 Student s2; AfByteBuffer dec(buf, 0, count); s2.id = dec.getUint32(); s2.name = dec.getString(); } if(1) { Student s1; s1.id = 123; s1.name = "shaofa"; AfByteBuffer enc(512); enc.putUint32(s1.id); enc.putString(s1.name); unsigned char* ptr = enc.start(); int n = enc.sizeWritten(); } return 0; }
相关文章推荐
- Python动态类型的学习---引用的理解
- 土人系列AS入门教程 -- 对象篇
- C#托管堆对象实例包含内容分析
- C#实现获取不同对象中名称相同属性的方法
- javascript asp教程第十一课--Application 对象
- ASP编码必备的8条原则
- PowerShell中使用Out-String命令把对象转换成字符串输出的例子
- VBS教程:对象-正则表达式(RegExp)对象
- C#检查指定对象是否存在于ArrayList集合中的方法
- XML指南——XML编码
- C#中字符串编码处理
- ExtJS中文乱码之GBK格式编码解决方案及代码
- sql2008启动代理未将对象应用到实例解决方案
- 程序员趣味读物 谈谈Unicode编码
- 文本文件编码方式区别
- C#编程自学之类和对象
- C++中对象的常引用、动态建立和释放相关知识讲解
- C语言安全编码之数值中的sizeof操作符
- C#实现获取文本文件的编码的一个类(区分GB2312和UTF8)
- VC中BASE64编码和解码使用详解