• datastream, C++数据序列化与反序列化容器


    其实本来不想自己写这样一个类的,但找来找去都没有找到符合生活习惯的,于是在经过反复的推敲设计后,呜,我终于承认自己功力不够---无法将内存管理与迭代器完美地结合在一起,只好只好先用std::vector了,于是便有了下面的代码。到目前为止还不能号称功能完善,但,但应该基本可用了,堪堪记在这里,也许能给以后的自己一些帮助,或可得到高手指点一二:
      类文件被保存为datastream.hpp
    #pragma once
    /********************************************************************
    purpose:    used for data serialization and deserialization
    ********************************************************************
    */
    #include <vector>
    #include <cassert>
    class datastream:public std::vector<char>
    {
    public:
        datastream& operator<<(bool data){return push(data);}
        datastream& operator<<(char data){return push(data);}
        datastream& operator<<(wchar_t data){return push(data);}
        datastream& operator<<(short data){return push(data);}
        datastream& operator<<(int data){return push(data);}
        datastream& operator<<(long data){return push(data);}
        datastream& operator<<(float data){return push(data);}
        datastream& operator<<(double data){return push(data);}
        datastream& operator<<(unsigned char data){return push(data);}    
        datastream& operator<<(unsigned short data){return push(data);}    
        datastream& operator<<(unsigned int data){return push(data);}
        datastream& operator<<(unsigned long data){return push(data);}

        datastream& operator>>(bool& data){return pop(data);}
        datastream& operator>>(char& data){return pop(data);}
        datastream& operator>>(wchar_t& data){return pop(data);}
        datastream& operator>>(short& data){return pop(data);}
        datastream& operator>>(int& data){return pop(data);}
        datastream& operator>>(long& data){return pop(data);}
        datastream& operator>>(float& data){return pop(data);}
        datastream& operator>>(double& data){return pop(data);}
        datastream& operator>>(unsigned char& data){return pop(data);}    
        datastream& operator>>(unsigned short& data){return pop(data);}    
        datastream& operator>>(unsigned int& data){return pop(data);}
        datastream& operator>>(unsigned long& data){return pop(data);}

        datastream& test(bool& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(char& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(short& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(int& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(long& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(float& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(double& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(unsigned char& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(unsigned short& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(unsigned int& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}
        datastream& test(unsigned long& data){memcpy(&data, &operator[](0), sizeof(data));return *this;}    

        //std::string处理
        datastream& operator<<(const char* data){return push(strlen(data), (void*)data);}
        datastream& operator<<(const wchar_t* data){return push(wcslen(data)<<1, (void*)data);}
        datastream& operator<<(const std::string& data){return push(data.size(), (void*)data.c_str());}    
        datastream& operator<<(const std::wstring& data){return push(data.size()<<1, (void*)data.c_str());}
        datastream& operator>>(std::string& data)
        {
            size_t nSize;
            pop(nSize);
            std::vector<char>::iterator first=begin(), last=first+nSize;
            data.assign(first, last);
            erase(first, last);
            return *this;
        }
        datastream& operator>>(std::wstring& data)
        {
            size_t nSize;
            pop(nSize);
            wchar_t* a=(wchar_t*)&operator[](0), *b=a+(nSize>>1);
            data.assign(a, b);
            std::vector<char>::iterator first=begin();    
            erase(first, first+nSize);
            return *this;
        }
        datastream& test(std::string& data)
        {
            size_t nSize;
            test(nSize);
            std::vector<char>::iterator first=begin()+sizeof(nSize);
            data.assign(first, first+nSize);
            return *this;
        }
        datastream& test(std::wstring& data)
        {
            size_t nSize;
            test(nSize);
            wchar_t* first=(wchar_t*)&operator[](sizeof(nSize));
            data.assign(first, first+(nSize>>1));
            return *this;
        }
        //std::vector处理
        template<typename C>
        datastream& operator<<(const std::vector<C>& data)
        {
            size_t nSize=data.size();
            push(nSize);
            for (int i=0; i<nSize; ++i)
            {
                operator<<(data[i]);
            }
            return *this;
        }
        template<typename C>
        datastream& operator>>(std::vector<C>& data)
        {
            size_t nSize;
            pop(nSize);
            C tmp;
            for (int i=0; i<nSize; ++i)
            {
                operator>>(tmp);
                data.push_back(tmp);
            }            
            return *this;
        }
    private:
        char* inc_size(size_t delta_size)
        {
            size_t last_size=size();
            resize(last_size+delta_size);
            return &operator[](last_size);
        }
        template<typename C>
        datastream& push(C data)
        {
            memcpy(inc_size(sizeof(data)), &data, sizeof(data));
            return *this;
        }
        datastream& push(size_t size, void* data)
        {
            push(size);
            memcpy(inc_size(size), data, size);
            return *this;
        }
        template<typename C>
        datastream& pop(C& data)
        {
            memcpy(&data, &operator[](0), sizeof(data));
            erase(begin(), begin()+sizeof(data));
            return *this;
        }
    };
      测试代码:
    #include <iostream>
    #include <fstream>
    #include <iterator>
    #include "datastream.hpp"

    template<typename T>
    void print_vector(const std::vector<T>& v)
    {
        std::cout<<"---------------------------Print Vector---------------------------"<<std::endl;
        std::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, " "));
        std::cout<<"-------------------------Print Vector End-------------------------"<<std::endl;
    }
    int main(int argc, char* argv[])
    {
        std::string strPath="c:\abc.txt";

        std::vector<std::string> v;
        v.push_back("hello world");
        v.push_back("向量测试");
        
        datastream ds;
        ds<<318<<3.14159<<"hello world"<<std::string("中文测试")<<v;

        std::ofstream outfile(strPath.c_str());
        if (outfile)
        {
            std::copy(ds.begin(), ds.end(), std::ostreambuf_iterator<char>(outfile));
            outfile.close();
            std::cout<<"write to file successfully!"<<std::endl;
        }
        
        ds.clear();                            //清空数据(但不释放ds的内存)
        std::ifstream infile(strPath.c_str());
        if (infile)
        {
            ds.assign(std::istreambuf_iterator<char>(infile), std::istreambuf_iterator<char>());    //别忘了std::vector有个assign函数
            int a;
            double b;
            std::string c, d;
            std::vector<std::string> v2;
            ds>>a>>b>>c>>d>>v2;
            datastream(ds).swap(ds);        //释放datastream内存
            std::cout<<"a="<<a<<", b="<<b<<", c="<<c<<", d="<<d<<std::endl;
            print_vector(v2);
        }
        system("pause");
        return 0;
    }
      输出:
    write to file successfully!
    a=318, b=3.14159, c=hello world, d=中文测试
    ---------------------------Print Vector---------------------------
    hello world
    向量测试
    -------------------------Print Vector End-------------------------
    请按任意键继续. . .
  • 相关阅读:
    图片服务器的搭建
    Nginx的安装和部署
    Zookeeper安装和部署
    集合框架
    案例-学生成绩管理
    java 时间类
    Java 正则表达式
    Java字符串
    Java学生管理系统
    shell实例利用crontab自动清除日志
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318625.html
Copyright © 2020-2023  润新知