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 ;
}
};
/* *******************************************************************
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 ;
}
输出:
#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-------------------------
请按任意键继续. . .