清风竹林

ぷ雪飘绛梅映残红
   ぷ花舞霜飞映苍松
     ----- Do more,suffer less

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

  其实本来不想自己写这样一个类的,但找来找去都没有找到符合生活习惯的,于是在经过反复的推敲设计后,呜,我终于承认自己功力不够---无法将内存管理与迭代器完美地结合在一起,只好只好先用std::vector了,于是便有了下面的代码。到目前为止还不能号称功能完善,但,但应该基本可用了,堪堪记在这里,也许能给以后的自己一些帮助,或可得到高手指点一二:
  类文件被保存为datastream.hpp
#pragma once
/********************************************************************
created:    2008-10-13
author:        lixianmin

purpose:    used for data serialization and deserialization
Copyright (C) 2008 - All Rights Reserved
********************************************************************
*/
#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, "\n"));
    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-------------------------
请按任意键继续. . .








posted on 2008-10-15 14:55 李现民 阅读(1718) 评论(0)  编辑 收藏 引用 所属分类: 语法试炼


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理