转 自定义的支持序列化的类

http://stdsoft.blogbus.com/logs/56348472.html

#pragma once

#include <fstream>
#include <string>
#include <iostream>
using namespace std;

// Archive Flag values
enum ArchiveMode
{
	AM_Loading = 0,  // 反序列化
	AM_Storing = 1,  // 序列化
	AM_UNKNOWN = 2,  // 未知操作
};

class ArchiveX
{
public:
	ArchiveX();
	virtual ~ArchiveX(void);

public:
	bool open(const string & strFilename,unsigned int nMode);

	bool IsLoading() const;
	bool IsStoring() const;

	bool IsBufferEmpty();

	void Flush();
	void Close();

public:
	ArchiveX & operator<<(bool b);
	ArchiveX & operator<<(char ch);
	ArchiveX & operator<<(unsigned char uch);
	ArchiveX & operator<<(short s);
	ArchiveX & operator<<(unsigned short us);
	ArchiveX & operator<<(int i);
	ArchiveX & operator<<(unsigned int ui);
	ArchiveX & operator<<(long l);
	ArchiveX & operator<<(unsigned long ul);
	ArchiveX & operator<<(float f);
	ArchiveX & operator<<(double d);
	ArchiveX & operator<<(const string & str);
	ArchiveX & operator<<(const wstring & str);

	ArchiveX & operator>>(bool & b);
	ArchiveX & operator>>(char & ch);
	ArchiveX & operator>>(unsigned char & uch);
	ArchiveX & operator>>(short & s);
	ArchiveX & operator>>(unsigned short & us);
	ArchiveX & operator>>(int & i);
	ArchiveX & operator>>(unsigned int & ui);
	ArchiveX & operator>>(long & l);
	ArchiveX & operator>>(unsigned long & ul);
	ArchiveX & operator>>(float & f);
	ArchiveX & operator>>(double & d);
	ArchiveX & operator>>(string & str);
	ArchiveX & operator>>(wstring & str);

protected:
	// 两个内部方法
	unsigned int Read(void* lpBuf, unsigned int nMax);
	unsigned int Write(const void* lpBuf, unsigned int nMax);

protected:
	ArchiveMode  m_nMode;
	fstream      m_File;
	string       m_strFilename;
};

  

#include "stdafx.h"
#include "ConsoleTest.h"

//#include "ArchiveX.h"

//#include "YangJing.h"

ArchiveX::ArchiveX()
{
	m_nMode = AM_UNKNOWN;
}

bool ArchiveX::open( const string & strFilename,unsigned int nMode )
{
	//为了确保各种操作都处于安全状态,要根据指定的nMode检测文件的状态
	//例如:如果是Loading操作,则要检测文件是否存在
	//
	m_strFilename = strFilename;
	if (m_strFilename.length() == 0)
	{
		m_strFilename = "unknown.dat";
	}

	switch(nMode)
	{
	case AM_Storing:
		{
			m_File.open(strFilename.c_str(), ios_base::trunc|ios_base::out|ios_base::binary);

			if (m_File.is_open() == false)
			{
				m_nMode = AM_UNKNOWN;
				return false;
			}
			m_nMode = AM_Storing;
			return true;
		}
		break;
	case AM_Loading:
		{
			m_File.open(strFilename.c_str(), ios_base::in|ios_base::binary);

			if (m_File.is_open() == false)
			{
				m_nMode = AM_UNKNOWN;
				return false;
			}
			m_nMode = AM_Loading;
			return true;
		}
		break;
	default:
		{
			m_nMode = AM_UNKNOWN;
			return false;
		}
	}

	return false;
}

ArchiveX::~ArchiveX(void)
{
	Close();
}

bool ArchiveX::IsLoading() const
{
	if (AM_UNKNOWN == m_nMode)
	{
		return false;
	}
	return (AM_Loading == m_nMode);
}

bool ArchiveX::IsStoring() const
{
	if (AM_UNKNOWN == m_nMode)
	{
		return false;
	}
	return (AM_Storing == m_nMode);
}

void ArchiveX::Flush()
{
	if (m_File.is_open())
	{
		m_File.flush();
	}
}

void ArchiveX::Close()
{
	if (m_File.is_open())
	{
		if (AM_Storing == m_nMode)
		{
			m_File.flush();
		}
		m_File.close();
	}
}

ArchiveX & ArchiveX::operator<<( bool b )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&b,sizeof(bool));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( char ch )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&ch,sizeof(char));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( unsigned char uch )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&uch,sizeof(unsigned char));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( short s )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&s,sizeof(short));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( unsigned short us )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&us,sizeof(unsigned short));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( int i )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}    
	Write((void*)&i,sizeof(int));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( unsigned int ui )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&ui,sizeof(unsigned int));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( long l )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&l,sizeof(long));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( unsigned long ul )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&ul,sizeof( unsigned long));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( float f )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&f,sizeof(float ));
	return (*this);
}

ArchiveX & ArchiveX::operator<<( double d )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write((void*)&d,sizeof(double));
	return (*this);
}

ArchiveX & ArchiveX::operator<<(const string& str)
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
	Write(str.c_str(),str.length()+1);//直接多写一个字符
	return (*this);
}

ArchiveX & ArchiveX::operator<<(const wstring & str)
{
	if (AM_UNKNOWN == m_nMode)
	{
		return (*this);
	}
//	string strtemp=YangJing::Unicode2ANSI(str);
//	Write(strtemp.c_str(),strtemp.length()+1);//直接多写一个字符
	return (*this);
}
ArchiveX & ArchiveX::operator>>( bool & b )
{
	Read(&b,sizeof(bool));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( char & ch )
{
	Read(&ch,sizeof(char));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( unsigned char & uch )
{
	Read(&uch,sizeof(unsigned char));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( short & s )
{
	Read(&s,sizeof(short));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( unsigned short & us )
{
	Read(&us,sizeof(unsigned short));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( int & i )
{
	Read(&i,sizeof(int));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( unsigned int & ui )
{
	Read(&ui,sizeof(unsigned int));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( long & l )
{
	Read(&l,sizeof(long));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( unsigned long & ul )
{
	Read(&ul,sizeof(unsigned long));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( float & f )
{
	Read(&f,sizeof(float));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( double & d )
{
	Read(&d,sizeof(double));
	return (*this);
}

ArchiveX & ArchiveX::operator>>( string & str )
{
	str="";
	char ch;
	Read(&ch,1);
	while (ch!='\0')
	{
		str.append(1,ch);
		Read(&ch,1);
	}
	return (*this);
}

ArchiveX & ArchiveX::operator>>(wstring & str)
{
	str=L"";
	string strtemp="";
	char ch;
	Read(&ch,1);
	while (ch!='\0')
	{
		strtemp.append(1,ch);
		Read(&ch,1);
	}
//	str = YangJing::ANSI2Unicode(strtemp);

	return (*this);
}

unsigned int ArchiveX::Read( void* lpBuf, unsigned int nMax )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return 0;
	}
	m_File.read((char*)lpBuf,nMax);
	if (m_File.good())
	{
		return nMax;
	}
	return 0;
}

unsigned int ArchiveX::Write( const void* lpBuf,unsigned int nMax )
{
	if (AM_UNKNOWN == m_nMode)
	{
		return 0;
	}
	m_File.write((char*)lpBuf,nMax);
	if (m_File.good())
	{
		return nMax;
	}
	return 0;
}

bool ArchiveX::IsBufferEmpty()
{
	if (AM_UNKNOWN == m_nMode)
	{
		return false;
	}
	return m_File.eof();
}





int main()
{
	ArchiveX ar;
	ar.open("hkx.dat", AM_Storing);
	string str = "hekexin";
	ar << 100;
	ar << str;
	ar << 1.2345;
	ar.Close();

	ar.open("hkx.dat", AM_Loading);
	int val;
	std::string str1;
	double dVal;
	ar >> val;
	ar >> str1;
	ar >> dVal;

	ar.Close();

	std::cout<<val<<std::endl;
	std::cout<<str1<<std::endl;
	std::cout<<dVal<<std::endl;

	return 0;
}

  

原文地址:https://www.cnblogs.com/kex1n/p/2254764.html