ByteStream

22 篇文章 0 订阅

前公司有个这样的类(感觉很像stringstream),主要是网络中传数据用的(大概是因为要考虑字节序的问题,所以有了这么一个类),不过公司的实现有一个可移植性的问题:比如将网络中的一端流入一个int/long类型的数据,只要两端int/long占用字节大小不一致,那么在网络的另一端流出就会出问题。

今天自己依据其原理写了个,当然我的实现在空间上是不及前公司的,因为前公司的有一些优化,比如bool只占1bit,一个int数据可能占1/2/3/4byte;我的没有这些,bool占1bit的思想,我感觉写在上层更好,如果有必要的话;对于比较小的数压缩下空间倒是不错的想法。另外,公司是一个类,我的是三个。

写这篇文章不会被告侵权吧?!

#ifndef __BYTE_STREAM_H__
#define __BYTE_STREAM_H__

#include <string>
using std::string;

class ByteStream
{
public:
    ByteStream(unsigned short len);
    ~ByteStream();

private:
    ByteStream(const ByteStream &);
    ByteStream & operator = (const ByteStream &);

public:
    static void big2little(void * obj, unsigned int size);

    bool seek(unsigned short offset);
    unsigned short tell();
    unsigned short left();

protected:
    unsigned short m_length;
    unsigned short m_offset;
};

class OBStream : public ByteStream
{
public:
    OBStream(char * byte, unsigned short len);
    ~OBStream();

public:
    void init(char * byte, unsigned short len);

    bool writebytes(unsigned short offset, 
                    const void * obj, unsigned short size);

public:
    OBStream & write(const char * ptr, unsigned short size);

    OBStream & operator << (bool);
    OBStream & operator << (signed char);
    OBStream & operator << (unsigned char);
    OBStream & operator << (signed short);
    OBStream & operator << (unsigned short);
    OBStream & operator << (signed int);
    OBStream & operator << (unsigned int);
    OBStream & operator << (signed long);
    OBStream & operator << (unsigned long);
    OBStream & operator << (float);
    OBStream & operator << (double);

    OBStream & operator << (const string &);

private:
    char * m_byte;
};

class IBStream : public ByteStream
{
public:
    IBStream(const char * byte, unsigned short len);
    ~IBStream();

public:
    void init(const char * byte, unsigned short len);

    bool readbytes(unsigned short offset, 
                   void * obj, unsigned short size);

public:
    IBStream & read(char * ptr, unsigned short size);

    IBStream & operator >> (bool &);
    IBStream & operator >> (signed char &);
    IBStream & operator >> (unsigned char &);
    IBStream & operator >> (signed short &);
    IBStream & operator >> (unsigned short &);
    IBStream & operator >> (signed int &);
    IBStream & operator >> (unsigned int &);
    IBStream & operator >> (signed long &);
    IBStream & operator >> (unsigned long &);
    IBStream & operator >> (float &);
    IBStream & operator >> (double &);

    IBStream & operator >> (string &);

private:
    const char * m_byte;
};

#endif
#include <cassert>
#include <cstring>
#include "ByteStream.h"


ByteStream::ByteStream(unsigned short len)
 : m_length(len), m_offset(0)
{
    
}

ByteStream::~ByteStream()
{
    
}

void ByteStream::big2little(void * obj, unsigned int size)
{
    static union {
        unsigned short us;
        unsigned char  uc[sizeof(unsigned short)];
    } un;
    un.us = 0x0001;

    if (0x00 == un.uc[0]) {
        char * ptr = static_cast<char *>(obj);
        for (int i = 0; i < size / 2; ++i) {
            char temp = ptr[i];
            ptr[i] = ptr[size - 1 - i];
            ptr[size - 1 - i] = temp;
        }
    }
}

bool ByteStream::seek(unsigned short offset)
{
    if (offset <= m_length) {
        m_offset = offset;
        return(true);
    }
    else {
        return(false);
    }
}

unsigned short ByteStream::tell()
{
    return(m_offset);
}

unsigned short ByteStream::left()
{
    return(m_length - m_offset);
}

OBStream::OBStream(char * byte, unsigned short len)
 : ByteStream(len), m_byte(byte)
{
    
}

OBStream::~OBStream()
{
    
}

void OBStream::init(char * byte, unsigned short len)
{
    m_length = len;
    m_offset = 0;
    m_byte = byte;
}

bool OBStream::writebytes(unsigned short offset, 
                          const void * obj, unsigned short size)
{
    if (offset + size <= m_length) {
        memcpy(m_byte + offset, obj, size);
        return(true);
    }
    else {
        return(false);
    }
}

OBStream & OBStream::write(const char * ptr, unsigned short size)
{
    assert(m_offset + size <= m_length);
    writebytes(m_offset, ptr, size);
    m_offset += size;
    return(*this);
}

OBStream & OBStream::operator << (bool value)
{
    assert(m_offset + sizeof(bool) <= m_length);
    big2little(&value, sizeof(bool));
    writebytes(m_offset, &value, sizeof(bool));
    m_offset += sizeof(bool);
    return(*this);
}

OBStream & OBStream::operator << (signed char value)
{
    assert(m_offset + sizeof(signed char) <= m_length);
    big2little(&value, sizeof(signed char));
    writebytes(m_offset, &value, sizeof(signed char));
    m_offset += sizeof(signed char);
    return(*this);
}

OBStream & OBStream::operator << (unsigned char value)
{
    assert(m_offset + sizeof(unsigned char) <= m_length);
    big2little(&value, sizeof(unsigned char));
    writebytes(m_offset, &value, sizeof(unsigned char));
    m_offset += sizeof(unsigned char);
    return(*this);
}

OBStream & OBStream::operator << (signed short value)
{
    assert(m_offset + sizeof(signed short) <= m_length);
    big2little(&value, sizeof(signed short));
    writebytes(m_offset, &value, sizeof(signed short));
    m_offset += sizeof(signed short);
    return(*this);
}
OBStream & OBStream::operator << (unsigned short value)
{
    assert(m_offset + sizeof(unsigned short) <= m_length);
    big2little(&value, sizeof(unsigned short));
    writebytes(m_offset, &value, sizeof(unsigned short));
    m_offset += sizeof(unsigned short);
    return(*this);
}

OBStream & OBStream::operator << (signed int value)
{
    assert(m_offset + sizeof(unsigned char) + sizeof(signed int) <= m_length);
    unsigned char size = static_cast<unsigned char>(sizeof(signed int));
    operator << (size);
    big2little(&value, sizeof(signed int));
    writebytes(m_offset, &value, sizeof(signed int));
    m_offset += sizeof(signed int);
    return(*this);
}

OBStream & OBStream::operator << (unsigned int value)
{
    assert(m_offset + sizeof(unsigned char) + sizeof(unsigned int) <= m_length);
    unsigned char size = static_cast<unsigned char>(sizeof(unsigned int));
    operator << (size);
    big2little(&value, sizeof(unsigned int));
    writebytes(m_offset, &value, sizeof(unsigned int));
    m_offset += sizeof(unsigned int);
    return(*this);
}

OBStream & OBStream::operator << (signed long value)
{
    assert(m_offset + sizeof(unsigned char) + sizeof(signed long) <= m_length);
    unsigned char size = static_cast<unsigned char>(sizeof(signed long));
    operator << (size);
    big2little(&value, sizeof(signed long));
    writebytes(m_offset, &value, sizeof(signed long));
    m_offset += sizeof(signed long);
    return(*this);
}

OBStream & OBStream::operator << (unsigned long value)
{
    assert(m_offset + sizeof(unsigned char) + sizeof(unsigned long) <= m_length);
    unsigned char size = static_cast<unsigned char>(sizeof(unsigned long));
    operator << (size);
    big2little(&value, sizeof(unsigned long));
    writebytes(m_offset, &value, sizeof(unsigned long));
    m_offset += sizeof(unsigned long);
    return(*this);
}

OBStream & OBStream::operator << (float value)
{
    assert(m_offset + sizeof(float) <= m_length);
    big2little(&value, sizeof(float));
    writebytes(m_offset, &value, sizeof(float));
    m_offset += sizeof(float);
    return(*this);
}

OBStream & OBStream::operator << (double value)
{
    assert(m_offset + sizeof(double) <= m_length);
    big2little(&value, sizeof(double));
    writebytes(m_offset, &value, sizeof(double));
    m_offset += sizeof(double);
    return(*this);
}

OBStream & OBStream::operator << (const string & value)
{
    assert(m_offset + sizeof(unsigned short) + value.size() <= m_length);
    unsigned short size = static_cast<unsigned short>(value.size());
    operator << (size);
    write(value.c_str(), size);
    return(*this);
}


IBStream::IBStream(const char * byte, unsigned short len)
 : ByteStream(len), m_byte(byte)
{
    
}

IBStream::~IBStream()
{
    
}

void IBStream::init(const char * byte, unsigned short len)
{
    m_length = len;
    m_offset = 0;
    m_byte = byte;
}

bool IBStream::readbytes(unsigned short offset, 
                         void * obj, unsigned short size)
{
    if (offset + size <= m_length) {
        memcpy(obj, m_byte + offset, size);
        return(true);
    }
    else {
        return(false);
    }
}

IBStream & IBStream::read(char * ptr, unsigned short size)
{
    assert(m_offset + size <= m_length);
    readbytes(m_offset, ptr, size);
    m_offset += size;
    return(*this);
}

IBStream & IBStream::operator >> (bool & value)
{
    assert(m_offset + sizeof(bool) <= m_length);
    readbytes(m_offset, &value, sizeof(bool));
    big2little(&value, sizeof(bool));
    m_offset += sizeof(bool);
    return(*this);
}

IBStream & IBStream::operator >> (signed char & value)
{
    assert(m_offset + sizeof(signed char) <= m_length);
    readbytes(m_offset, &value, sizeof(signed char));
    big2little(&value, sizeof(signed char));
    m_offset += sizeof(signed char);
    return(*this);
}

IBStream & IBStream::operator >> (unsigned char & value)
{
    assert(m_offset + sizeof(unsigned char) <= m_length);
    readbytes(m_offset, &value, sizeof(unsigned char));
    big2little(&value, sizeof(unsigned char));
    m_offset += sizeof(unsigned char);
    return(*this);
}

IBStream & IBStream::operator >> (signed short & value)
{
    assert(m_offset + sizeof(signed short) <= m_length);
    readbytes(m_offset, &value, sizeof(signed short));
    big2little(&value, sizeof(signed short));
    m_offset += sizeof(signed short);
    return(*this);
}

IBStream & IBStream::operator >> (unsigned short & value)
{
    assert(m_offset + sizeof(unsigned short) <= m_length);
    readbytes(m_offset, &value, sizeof(unsigned short));
    big2little(&value, sizeof(unsigned short));
    m_offset += sizeof(unsigned short);
    return(*this);
}

IBStream & IBStream::operator >> (signed int & value)
{
    assert(m_offset + sizeof(unsigned char) <= m_length);
    unsigned char size = 0;
    operator >> (size);
    assert(m_offset + size <= m_length);
    if (sizeof(signed int) == size) {
        readbytes(m_offset, &value, sizeof(signed int));
        big2little(&value, sizeof(signed int));
        m_offset += sizeof(signed int);
    }
    else if (sizeof(signed int) > size) {
        value = 0;
        unsigned char * ptr = reinterpret_cast<unsigned char *>(&value);
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(&value, sizeof(signed int));
    }
    else {
        assert(sizeof(signed int) <= 8);
        unsigned char ptr[8] = { 0 };
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(ptr, size);
        value = *(reinterpret_cast<signed int *>(ptr));
    }
    return(*this);
}

IBStream & IBStream::operator >> (unsigned int & value)
{
    assert(m_offset + sizeof(unsigned char) <= m_length);
    unsigned char size = 0;
    operator >> (size);
    assert(m_offset + size <= m_length);
    if (sizeof(unsigned int) == size) {
        readbytes(m_offset, &value, sizeof(unsigned int));
        big2little(&value, sizeof(unsigned int));
        m_offset += sizeof(unsigned int);
    }
    else if (sizeof(unsigned int) > size) {
        value = 0;
        unsigned char * ptr = reinterpret_cast<unsigned char *>(&value);
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(&value, sizeof(unsigned int));
    }
    else {
        assert(sizeof(unsigned int) <= 8);
        unsigned char ptr[8] = { 0 };
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(ptr, size);
        value = *(reinterpret_cast<unsigned int *>(ptr));
    }
    return(*this);
}

IBStream & IBStream::operator >> (signed long & value)
{
    assert(m_offset + sizeof(unsigned char) <= m_length);
    unsigned char size = 0;
    operator >> (size);
    assert(m_offset + size <= m_length);
    if (sizeof(signed long) == size) {
        readbytes(m_offset, &value, sizeof(signed long));
        big2little(&value, sizeof(signed long));
        m_offset += sizeof(signed long);
    }
    else if (sizeof(signed long) > size) {
        value = 0;
        unsigned char * ptr = reinterpret_cast<unsigned char *>(&value);
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(&value, sizeof(signed long));
    }
    else {
        assert(sizeof(signed long) <= 8);
        unsigned char ptr[8] = { 0 };
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(ptr, size);
        value = *(reinterpret_cast<signed long *>(ptr));
    }
    return(*this);
}

IBStream & IBStream::operator >> (unsigned long & value)
{
    assert(m_offset + sizeof(unsigned char) <= m_length);
    unsigned char size = 0;
    operator >> (size);
    assert(m_offset + size <= m_length);
    if (sizeof(unsigned long) == size) {
        readbytes(m_offset, &value, sizeof(unsigned long));
        big2little(&value, sizeof(unsigned long));
        m_offset += sizeof(unsigned long);
    }
    else if (sizeof(unsigned long) > size) {
        value = 0;
        unsigned char * ptr = reinterpret_cast<unsigned char *>(&value);
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(&value, sizeof(unsigned long));
    }
    else {
        assert(sizeof(unsigned long) <= 8);
        unsigned char ptr[8] = { 0 };
        for (int i = 0; i < size; ++i) {
            operator >> (ptr[i]);
        }
        big2little(ptr, size);
        value = *(reinterpret_cast<unsigned long *>(ptr));
    }
    return(*this);
}

IBStream & IBStream::operator >> (float & value)
{
    assert(m_offset + sizeof(float) <= m_length);
    readbytes(m_offset, &value, sizeof(float));
    big2little(&value, sizeof(float));
    m_offset += sizeof(float);
    return(*this);
}

IBStream & IBStream::operator >> (double & value)
{
    assert(m_offset + sizeof(double) <= m_length);
    readbytes(m_offset, &value, sizeof(double));
    big2little(&value, sizeof(double));
    m_offset += sizeof(double);
    return(*this);
}

IBStream & IBStream::operator >> (string & value)
{
    assert(m_offset + sizeof(unsigned short) <= m_length);
    unsigned short size = 0;
    operator >> (size);
    assert(m_offset + size <= m_length);
    value.resize(size);
    read(&value[0], size);
    return(*this);
}
#include <complex>
#include <string>
#include <iostream>
using namespace std;

#include "ByteStream.h"

template <typename T>
OBStream & operator << (OBStream & obs, const complex<T> & comp)
{
    return(obs << comp.real() << comp.imag());
}

template <typename T>
IBStream & operator >> (IBStream & ibs, complex<T> & comp)
{
    T real;
    T imag;
    ibs >> real >> imag;
    comp = complex<T>(real, imag);
    return(ibs);
}

int main(int argc, char * argv[])
{
    char buffer[100] = { 0 };

    bool           in_b = true;
    signed char    in_sc = 'a';
    unsigned char  in_uc = 'A';
    signed short   in_ss = 12345;
    unsigned short in_us = 65535;
    signed int     in_si = 123456789;
    unsigned int   in_ui = 987654321;
    signed long    in_sl = 11223344;
    unsigned long  in_ul = 66554433;
    float          in_f  = 123456.789f;
    double         in_d = 987654321.123456789;
    const char   * in_ptr = "ByteStream";
    string         in_str("Hello World");
    complex<int>   in_comp(123, 456);

    cout << in_b << endl;
    cout << in_sc << endl;
    cout << in_uc << endl;
    cout << in_ss << endl;
    cout << in_us << endl;
    cout << in_si << endl;
    cout << in_ui << endl;
    cout << in_sl << endl;
    cout << in_ul << endl;
    cout << in_f << endl;
    cout << in_d << endl;
    cout << in_ptr << endl;
    cout << in_str << endl;
    cout << in_comp << endl;

    unsigned short in_size = 0;
    OBStream obs(buffer, 100);
    (obs << in_size << in_b << in_sc << in_uc << in_ss 
         << in_us << in_si << in_ui << in_sl << in_ul 
         << in_f << in_d).write(in_ptr, 10) << in_str << in_comp;
    in_size = obs.tell();
    obs.seek(0);
    obs << in_size;
    obs.seek(in_size);

    cout << "write " << in_size << " Bytes" << endl;

    unsigned short out_size;
    bool           out_b;
    signed char    out_sc;
    unsigned char  out_uc;
    signed short   out_ss;
    unsigned short out_us;
    signed int     out_si;
    unsigned int   out_ui;
    signed long    out_sl;
    unsigned long  out_ul;
    float          out_f;
    double         out_d;
    char           out_ptr[11] = { 0 };
    string         out_str;
    complex<int>   out_comp;

    IBStream ibs(buffer, obs.tell());
    (ibs >> out_size >> out_b >> out_sc >> out_uc >> out_ss 
         >> out_us >> out_si >> out_ui >> out_sl >> out_ul 
         >> out_f >> out_d).read(out_ptr, 10) >> out_str >> out_comp;

    cout << "read " << out_size << " Bytes" << endl;
    cout << out_b << endl;
    cout << out_sc << endl;
    cout << out_uc << endl;
    cout << out_ss << endl;
    cout << out_us << endl;
    cout << out_si << endl;
    cout << out_ui << endl;
    cout << out_sl << endl;
    cout << out_ul << endl;
    cout << out_f << endl;
    cout << out_d << endl;
    cout << out_ptr << endl;
    cout << out_str << endl;
    cout << out_comp << endl;

    return(0);
}

#include <iostream>
using namespace std;

#include "ByteStream.h"

int main(int argc, char * argv[])
{
    char buffer[32] = { 0 };
    unsigned short in_int = 65535;
    unsigned char  in_int_len = sizeof(unsigned short);
    long in_long = 123456;
    double * in_p_long = reinterpret_cast<double *>(&in_long);
    unsigned char in_long_len = sizeof(double);

    unsigned short in_size = 0;
    OBStream obs(buffer, 100);
    obs << in_size;
    obs << in_int_len << in_int;        /* less-int: (len + short) like a 16bit-int*/
    obs << in_long_len << (*in_p_long); /* large-long: (len + double) like a 64bit-long */
    in_size = obs.tell();
    obs.seek(0);
    obs << in_size;
    obs.seek(in_size);

    cout << in_int << endl;
    cout << in_long << endl;
    cout << "write " << in_size << " Bytes" << endl;

    unsigned short out_size = 0;
    signed int     out_int = 0;
    signed long    out_long = 0;

    IBStream ibs(buffer, obs.tell());
    ibs >> out_size;
    ibs >> out_int;  /* large-int */
    ibs >> out_long; /* less-long */

    cout << "read " << out_size << " Bytes" << endl;
    cout << out_int << endl;
    cout << out_long << endl;

    return(0);
}

今天被complex<T>整了,1是对它不熟,2是模板报错乱七八糟


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值