カスタムバイナリ・メッセージ・フロー解析クラス

8222 ワード

次の操作を行います.
#include 
#include"zstream.h"
#include"string"

using namespace std;

int main()
{
    string str("123456789");
    zistream zi(str.c_str(), 10);
    unsigned char h;
    skip jj(2);
    zi>>h;
    cout << h << endl;
    zi>>jj>>h;
    cout << h << endl;
    zi>>skip(2)>>h;
    cout << h << endl;

    uint16_t yy;
    zi>>yy;
    cout << yy << endl;

    cout << endian::flag::little << endl;
    return 0;
}

クラスコード:
#ifndef __HIGINET_ZISTREAM_H__
#define __HIGINET_ZISTREAM_H__

#include 
#include 
#include 
#include 


namespace endian
{
    struct flag
    {
    #ifdef LITTLE_ENDIAN
        static const bool little=true;
    #else
        static const bool little=false;
    #endif
    };

    inline void cp_uint8_r(void*d,const void*s,size_t c)
    {
        uint8_t*di=(uint8_t*)d;
        const uint8_t*si=(const uint8_t*)s + c;

        while(c-->0)
            *di++=*--si;
    }

    inline void cp_uint8(void*d,const void*s,size_t c)
    {
        memcpy(d,s,c);
    }

    template struct copy_impl
    {
        void operator()(void*d,const void*s,size_t)const
        {
        }
    };

    template<> struct copy_impl
    {
        void operator()(void*d,const void*s,size_t count)const
        {
            cp_uint8 ((uint8_t*)d,(const uint8_t*)s,count);
        }
    };

    template<> struct copy_impl
    {
        void operator()(void*d,const void*s,size_t count)const
        {
            cp_uint8_r (d, s, count);
        }
    };

    inline void copy(void*d,const void*s,size_t count)
    {
        copy_impl<:flag::little>()(d,s,count);
    }
}

struct skip
{
    int m_count;
    skip(int count):m_count(count){}
};


struct zistream
{
private:
    const uint8_t* m_buff;
    size_t m_pos,m_size;
    bool m_owner_buff;

public:
    zistream(const void*pbuf,size_t buf_size,bool owner_buff=false)
        :m_buff((const uint8_t*)pbuf)
        ,m_pos(0)
        ,m_size(buf_size)
        ,m_owner_buff(owner_buff)
    {
        if(owner_buff)
        {
            m_buff = (const uint8_t*)malloc(buf_size);
            endian::copy((void*)m_buff, pbuf, buf_size);
        }
    }

    ~zistream()
    {
        if(m_owner_buff && m_buff)
        {
            ::free((void*)m_buff);
        }
    }

    bool   is_end() const {return m_pos >= m_size; }
    size_t size()const {return m_size;}
    const uint8_t*buff()const{return m_buff;}
    size_t pos()const{return m_pos;}

    friend zistream& operator>>(zistream&is, uint8_t &i) { i=is.load_uint8 ();return is; }
    friend zistream& operator>>(zistream&is, uint16_t&i) { i=is.load_uint16();return is; }
    friend zistream& operator>>(zistream&is, uint32_t&i) { i=is.load_uint32();return is; }
    friend zistream& operator>>(zistream&is, uint64_t&i) { i=is.load_uint64();return is; }

    friend zistream& operator>>(zistream&is, int8_t &i) { i=is.load_int8 ();return is; }
    friend zistream& operator>>(zistream&is, int16_t&i) { i=is.load_int16();return is; }
    friend zistream& operator>>(zistream&is, int32_t&i) { i=is.load_int32();return is; }
    friend zistream& operator>>(zistream&is, int64_t&i) { i=is.load_int64();return is; }

    friend zistream& operator>>(zistream&is, const skip&s)
    {
        is.m_pos+=s.m_count;

        return is;
    }

    int8_t  load_int8 (size_t pos){int8_t  rc;_get_value(&rc,sizeof(rc),pos);return rc;}
    int16_t load_int16(size_t pos){int16_t rc;_get_value(&rc,sizeof(rc),pos);return rc;}
    int32_t load_int32(size_t pos){int32_t rc;_get_value(&rc,sizeof(rc),pos);return rc;}
    int64_t load_int64(size_t pos){int64_t rc;_get_value(&rc,sizeof(rc),pos);return rc;}

    int8_t  load_int8 (){int8_t  rc; _get_value(&rc,sizeof(rc)); return rc;}
    int16_t load_int16(){int16_t rc; _get_value(&rc,sizeof(rc)); return rc;}
    int32_t load_int32(){int32_t rc; _get_value(&rc,sizeof(rc)); return rc;}
    int64_t load_int64(){int64_t rc; _get_value(&rc,sizeof(rc)); return rc;}

    uint8_t  load_uint8 (size_t pos){uint8_t  rc;_get_value(&rc,sizeof(rc),pos);return rc;}
    uint16_t load_uint16(size_t pos){uint16_t rc;_get_value(&rc,sizeof(rc),pos);return rc;}
    uint32_t load_uint32(size_t pos){uint32_t rc;_get_value(&rc,sizeof(rc),pos);return rc;}
    uint64_t load_uint64(size_t pos){uint64_t rc;_get_value(&rc,sizeof(rc),pos);return rc;}

    uint8_t  load_uint8 (){uint8_t  rc; _get_value(&rc,sizeof(rc)); return rc;}
    uint16_t load_uint16(){uint16_t rc; _get_value(&rc,sizeof(rc)); return rc;}
    uint32_t load_uint32(){uint32_t rc; _get_value(&rc,sizeof(rc)); return rc;}
    uint64_t load_uint64(){uint64_t rc; _get_value(&rc,sizeof(rc)); return rc;}

    std::vector load_bytes(size_t count)
    {
        std::vector rc(count,0);//count   ,  0

        _get_value(&*rc.begin(), count);

        return std::move(rc);
    }

    std::string load_string(size_t count)
    {
        std::string rc(count,' ');

        _get_value(&*rc.begin(), count);

        return std::move(rc);
    }

private:
    void _get_value(void*d,size_t len,size_t pos)
    {
        endian::copy(d, m_buff+pos, len);
    }

    void _get_value(void*d,size_t len)
    {
        endian::copy(d, m_buff+m_pos, len);
        m_pos+=len;
    }
};

class zostream
{
private:
    uint8_t*  m_buff;
    size_t    m_pos,m_size;
    bool      m_owner_buff;

public:
    zostream(size_t buf_size,void*buf=nullptr)
        :m_buff((uint8_t*)buf)
        ,m_pos(0)
        ,m_size(buf_size)
    {
        if(m_buff)
        {
            m_owner_buff=false;
        }
    }

    ~zostream()
    {
        if(m_owner_buff && m_buff)
            free(m_buff);
    }

    const uint8_t*data()const{return m_buff;}const
    uint8_t      *data(){return m_buff;}
    size_t size()const {return m_size;}

    zostream& save(int8_t   i,size_t pos){return _save_value(&i,sizeof(i),pos);}
    zostream& save(int16_t  i,size_t pos){return _save_value(&i,sizeof(i),pos);}
    zostream& save(int32_t  i,size_t pos){return _save_value(&i,sizeof(i),pos);}
    zostream& save(int64_t  i,size_t pos){return _save_value(&i,sizeof(i),pos);}

    zostream& save(int8_t  i) {return _save_value(&i,sizeof(i));}
    zostream& save(int16_t i) {return _save_value(&i,sizeof(i));}
    zostream& save(int32_t i) {return _save_value(&i,sizeof(i));}
    zostream& save(int64_t i) {return _save_value(&i,sizeof(i));}

    zostream& save(uint8_t   i,size_t pos){return _save_value(&i,sizeof(i),pos);}
    zostream& save(uint16_t  i,size_t pos){return _save_value(&i,sizeof(i),pos);}
    zostream& save(uint32_t  i,size_t pos){return _save_value(&i,sizeof(i),pos);}
    zostream& save(uint64_t  i,size_t pos){return _save_value(&i,sizeof(i),pos);}

    zostream& save(uint8_t  i) {return _save_value(&i,sizeof(i));}
    zostream& save(uint16_t i) {return _save_value(&i,sizeof(i));}
    zostream& save(uint32_t i) {return _save_value(&i,sizeof(i));}
    zostream& save(uint64_t i) {return _save_value(&i,sizeof(i));}

    zostream& save(const std::string&s)
    {
        return _save_value(s.c_str(), s.size());
    }

    zostream& save(const char*s)
    {
        return _save_value(s, strlen(s));
    }

    friend zostream& operator<m_pos)
            m_pos=len+pos;

        return *this;
    }

    zostream& _save_value(const void*pbuf,int len)
    {
        _grow(len+m_pos);
        endian::copy(m_buff+m_pos,pbuf,len);

        m_pos+=len;

        return *this;
    }
};

#endif