1.读写缓冲的设计可以直接使用stl 中的vector模板,为了更加方便,我们继承vector类,添加像string一样方便的append函数,让后声明只能指针:
typedef unsigned char uint8_t; class byte_buffer:public vector<uint8_t> { public: byte_buffer(size_t len):vector<uint8_t>(len) { } void append(const uint8_t* p, size_t len) { const size_t s = size(); //old size; resize(s+len); memcpy(data()+s,p,len); } }; //use: byte_buffer_ptr p(new byte_buffer(n)); typedef boost::shared_ptr<byte_buffer> byte_buffer_ptr;
byte_buffer_ptr p(new byte_buffer(10));
p->append((const uint8*)"12345",5);
2.在字节流读取和写入过程中,字节序是需要注意的问题。
字节序:字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序.
Little endian:将低序字节存储在起始地址
Big endian:将高序字节存储在起始地址
网络字节序:网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
将常用的字节序读写代码用宏声明出来,方便以后使用:
///读取网络字节序(网络字节序为big endian)的常用宏与函数 ///CPU_BIGENDIAN宏为主机字节序类型是否为big endian,否则视为little endian(intel x86等) #ifndef INLINE #define INLINE inline #endif #ifdef CPU_BIGENDIAN ///不同的CPU上和不同的操作系统,字节序也是不同的,读写函数就要反过来 /*! @brief 从缓冲区中以BE方式读取uint16_t @param p 缓冲区指针 */ #define read_be_w(p) (*(uint16_t*)(p)) /*! @brief 以BE方式将uint16_t写入到缓冲区当中 @param p 缓冲区指针 @param w uint16_t */ #define write_be_w(p, w) (*(uint16_t*)(p) = (w)) /*! @brief 从缓冲区中以BE方式读取uint32_t @param p 缓冲区指针 */ #define read_be_dw(p) (*(uint32_t*)(p)) /*! @brief 从缓冲区中以BE方式读取float @param p 缓冲区指针 */ #define read_be_float(p) (*(float*)(p)) /*! @brief 以BE方式将uint32_t写入到缓冲区当中 @param p 缓冲区指针 @param dw uint32_t */ #define write_be_dw(p, dw) (*(uint32_t*)(p) = (dw)) /*! @brief 以BE方式将float写入到缓冲区当中 @param p 缓冲区指针 @param dw float */ #define write_be_float(p, dw) (*(float*)(p) = (dw)) /*! @brief 从缓冲区中以BE方式读取uint64_t @param p 缓冲区指针 */ #define read_be_dd(p) (*(uint64_t*)(p)) /*! @brief 从缓冲区中以BE方式读取double @param p 缓冲区指针 */ #define read_be_double(p) (*(double*)(p)) /*! @brief 将uint64_t类型以BE方式写入缓冲区 @param p 缓冲区指针 */ #define write_be_dd(p, dd) (*(uint64_t*)(p) = (dd)) /*! @brief 将double类型以BE方式写入缓冲区 @param p 缓冲区指针 */ #define write_be_double(p, dd) (*(double*)(p) = (dd)) /*! @brief 从缓冲区中以LE方式读取uint16_t @param p 缓冲区指针 */ #define read_le_w(p) ((uint16_t(((uint8_t*)(p))[1]) << 8) | (uint16_t(((uint8_t*)(p))[0]))) /*! @brief 以LE方式将uint16写入缓冲区中 @param p 缓冲区指针 */ #define write_le_w(p, w) *((uint8_t*)(p)+1) = (((uint16_t)(w)) >> 8); *(uint8_t*)(p) = ((uint16_t)(w) &0xFF) /*! @brief 从缓冲区中以LE方式读取uint32_t @param p 缓冲区指针 */ #define read_le_dw(p) ((uint32_t(((uint8_t*)(p))[3]) << 24) | (uint32_t(((uint8_t*)(p))[2]) << 16) | (uint32_t(((uint8_t*)(p))[1]) << 8) | (uint32_t(((uint8_t*)(p))[0]))) /*! @brief 从缓冲区中以LE方式读取float @param p 缓冲区指针 */ float INLINE read_le_float(const void* p) { const uint8_t* pb = (const uint8_t*)p; pb += 3; float r; uint8_t* pd = (uint8_t*)&r; *pd++ = *pb--; *pd++ = *pb--; *pd++ = *pb--; *pd++ = *pb--; return r; } /*! @brief 以LE方式将uint32写入缓冲区中 @param p 缓冲区指针 */ #define write_le_dw(p, dw) *((uint8_t*)(p)+3) = ((uint32_t)(dw) >> 24); *((uint8_t*)(p)+2) = ((uint32_t)(dw) >> 16); *((uint8_t*)(p)+1) = ((uint32_t)(dw) >> 8); *(uint8_t*)(p) = (uint32_t)(dw) /*! @brief 以LE方式将float写入缓冲区中 @param p 缓冲区指针 */ void INLINE write_le_float(void* p, float f) { uint8_t* pb = (uint8_t*)p; pb += 3; uint8_t* ps = (uint8_t*)&f; *pb-- = *ps++; *pb-- = *ps++; *pb-- = *ps++; *pb = *ps++; } /*! @brief 从缓冲区中以LE方式读取uint64_t @param p 缓冲区指针 */ uint64_t INLINE read_le_dd(const void* p) { const uint8_t* pb = (const uint8_t*)p; pb += 7; uint64_t r; uint8_t* pd = (uint8_t*)&r; for(int i=0; i<8; ++i) { *pd++ = *pb--; } return r; } /*! @brief 从缓冲区中以LE方式读取double @param p 缓冲区指针 */ double INLINE read_le_double(const void* p) { const uint8_t* pb = (const uint8_t*)p; pb += 7; double r; uint8_t* pd = (uint8_t*)&r; for(int i=0; i<8; ++i) { *pd++ = *pb--; } return r; } /*! @brief 以LE方式将uint64写入缓冲区中 @param p 缓冲区指针 */ void INLINE write_le_dd(void* p, uint64_t dd) { uint8_t* pb = (uint8_t*)p; pb += 7; uint8_t* ps = (uint8_t*)ⅆ for(int i=0; i<8; ++i) { *pb-- = *ps++; } } /*! @brief 以LE方式将double写入缓冲区中 @param p 缓冲区指针 */ void INLINE write_le_double(void* p, double dd) { uint8_t* pb = (uint8_t*)p; pb += 7; uint8_t* ps = (uint8_t*)ⅆ for(int i=0; i<8; ++i) { *pb-- = *ps++; } } #else /*! @brief 从缓冲区中以BE方式读取uint16_t @param p 缓冲区指针 */ #define read_be_w(p) ((uint16_t(((uint8_t*)(p))[0]) << 8) | (uint32_t(((uint8_t*)(p))[1]))) /*! @brief 以BE方式将uint16_t写入到缓冲区当中 @param p 缓冲区指针 @param w uint16_t */ #define write_be_w(p, w) *(uint8_t*)(p) = ((uint16_t)(w) >> 8); *((uint8_t*)(p)+1) = ((uint16_t)(w) &0xFF) /*! @brief 从缓冲区中以BE方式读取uint32_t @param p 缓冲区指针 */ #define read_be_dw(p) ((uint32_t(((uint8_t*)(p))[0]) << 24) | (uint32_t(((uint8_t*)(p))[1]) << 16) | (uint32_t(((uint8_t*)(p))[2]) << 8) | (uint32_t(((uint8_t*)(p))[3]))) /*! @brief 从缓冲区中以BE方式读取float */ float INLINE read_be_float(const void* p) { const uint8_t* pb = (const uint8_t*)p; pb += 3; float r; uint8_t* pd = (uint8_t*)&r; *pd++ = *pb--; *pd++ = *pb--; *pd++ = *pb--; *pd++ = *pb--; return r; } /*! @brief 以BE方式将uint32_t写入到缓冲区当中 @param p 缓冲区指针 @param w uint32_t */ #define write_be_dw(p, dw) *(uint8_t*)(p) = ((uint32_t)(dw) >> 24); *((uint8_t*)(p)+1) = ((uint32_t)(dw) >> 16); *((uint8_t*)(p)+2) = ((uint32_t)(dw) >> 8); *((uint8_t*)(p)+3) = (uint32_t)(dw) /*! @brief 将float类型以BE方式写入缓冲区 @param p 缓冲区指针 */ void INLINE write_be_float(void* p, float dd) { uint8_t* pb = (uint8_t*)p; pb += 3; uint8_t* ps = (uint8_t*)ⅆ *pb-- = *ps++; *pb-- = *ps++; *pb-- = *ps++; *pb-- = *ps++; } /*! @brief 从缓冲区中以BE方式读取uint64_t @param p 缓冲区指针 */ uint64_t INLINE read_be_dd(const void* p) { const uint8_t* pb = (const uint8_t*)p; pb += 7; uint64_t r; uint8_t* pd = (uint8_t*)&r; for(int i=0; i<8; ++i) { *pd++ = *pb--; } return r; } /*! @brief 从缓冲区中以BE方式读取double @param p 缓冲区指针 */ double INLINE read_be_double(const void* p) { const uint8_t* pb = (const uint8_t*)p; pb += 7; double r; uint8_t* pd = (uint8_t*)&r; for(int i=0; i<8; ++i) { *pd++ = *pb--; } return r; } /*! @brief 将uint64_t类型以BE方式写入缓冲区 @param p 缓冲区指针 */ void INLINE write_be_dd(void* p, uint64_t dd) { uint8_t* pb = (uint8_t*)p; pb += 7; uint8_t* ps = (uint8_t*)ⅆ for(int i=0; i<8; ++i) { *pb-- = *ps++; } } /*! @brief 将double类型以BE方式写入缓冲区 @param p 缓冲区指针 */ void INLINE write_be_double(void* p, double dd) { uint8_t* pb = (uint8_t*)p; pb += 7; uint8_t* ps = (uint8_t*)ⅆ for(int i=0; i<8; ++i) { *pb-- = *ps++; } } /*! @brief 从缓冲区中以LE方式读取uint16_t @param p 缓冲区指针 */ #define read_le_w(p) (*(uint16_t*)(p)) /*! @brief 以LE方式将uint16写入缓冲区中 @param p 缓冲区指针 */ #define write_le_w(p, w) (*(uint16_t*)(p) = (w)) /*! @brief 从缓冲区中以LE方式读取uint32_t @param p 缓冲区指针 */ #define read_le_dw(p) (*(uint32_t*)(p)) /*! @brief 从缓冲区中以LE方式读取float */ #define read_le_float(p) (*(float*)(p)) /*! @brief 以LE方式将uint32写入缓冲区中 @param p 缓冲区指针 */ #define write_le_dw(p, dw) (*(uint32_t*)(p) = (dw)) /*! @brief 以LE方式将float写入缓冲区中 @param p 缓冲区指针 */ #define write_le_float(p, dw) (*(float*)(p) = (dw)) /*! @brief 从缓冲区中以LE方式读取uint64_t @param p 缓冲区指针 */ #define read_le_dd(p) (*(uint64_t*)(p)) /*! @brief 从缓冲区中以LE方式读取double */ #define read_le_double(p) (*(double*)(p)) /*! @brief 以LE方式将uint64写入缓冲区中 @param p 缓冲区指针 */ #define write_le_dd(p, dd) (*(uint64_t*)(p) = (dd)) /*! @brief 以LE方式将double写入缓冲区中 @param p 缓冲区指针 */ #define write_le_double(p, dd) (*(double*)(p) = (dd)) #endif