C++之数据流存与取,对称原则

#pragma once
#include "afxtempl.h"
#include "GDIInclude.h"

// 【注意事项】
// 1, bool会和CString类型混淆,所以不支持bool,建议使用byte类型或者int类型代替
class DataStream
{
public:
DataStream();


DataStream(size_t mallocMemSize);


DataStream(const DataStream& copySrc);


virtual ~DataStream();


DataStream(byte* pBuffer, size_t bufferLength, size_t mallocMemSize = -1);


void Attach(byte* pDestBuffer, size_t destBufferLen);

void Detach();


void Reset(size_t mallocMemSize);


void SeekReadToBegin();


void SeekWriteToBegin();


bool CanRead(int dataLen);


byte* GetData(size_t startIndex = 0);


size_t GetDataLength();


size_t MakeSureCanWriteByIncreaseMemorySpace(size_t byteCountToWrite);


BOOL Open(CString strFilePath); //从文件获取Data
void Save(CString strFilePath); //把Data保存为文件


// short数组
DataStream& Write(IN short* val, IN UINT count);
DataStream& Read(OUT short** val, OUT UINT* count);
DataStream& Write(IN byte* val, IN UINT count);
DataStream& Read(OUT byte** val, OUT UINT* count);
DataStream& Write(IN char* val, IN UINT count);
DataStream& Read(OUT char** val, OUT UINT* count);


DataStream& AddFile(CString strSrcPath); //把文件添加到Data
DataStream& GetFile(CString& strSavePath); //从Data中获取文件并保存


DataStream& operator << (DataStream& val);
DataStream& operator >> (DataStream& val);


DataStream& operator << (CArray<int, int>& val);
DataStream& operator >> (CArray<int, int>& val);


DataStream& operator << (CStringArray& val);
DataStream& operator >> (CStringArray& val);


DataStream& operator << (CString val);
DataStream& operator >> (CString& val);


DataStream& operator << (int val);
DataStream& operator >> (int& val);

DataStream& operator << (UINT val);
DataStream& operator >> (UINT& val);


DataStream& operator << (long val);
DataStream& operator >> (long& val);


DataStream& operator << (DWORD val);
DataStream& operator >> (DWORD& val);


DataStream& operator << (byte val);
DataStream& operator >> (byte& val);


DataStream& operator << (char val);
DataStream& operator >> (char& val);


DataStream& operator << (WCHAR val);
DataStream& operator >> (WCHAR& val);


DataStream& operator << (short val);
DataStream& operator >> (short& val);


DataStream& operator << (float val);
DataStream& operator >> (float& val);


DataStream& operator << (CRect val);
DataStream& operator >> (CRect& val);


DataStream& operator << (Rect val);
DataStream& operator >> (Rect& val);


DataStream& operator << (RectF val);
DataStream& operator >> (RectF& val);


DataStream& operator << (CPoint val);
DataStream& operator >> (CPoint& val);


DataStream& operator << (Point val);
DataStream& operator >> (Point& val);


DataStream& operator << (PointF val);
DataStream& operator >> (PointF& val);


DataStream& operator << (Image* val);
DataStream& operator >> (Image** val);


DataStream& operator << (Font* val);
DataStream& operator >> (Font** val);


DataStream& operator << (Matrix* val);
DataStream& operator >> (Matrix** val);


DataStream& operator << (Color val);
DataStream& operator >> (Color &val);


private:
byte* m_pData;
size_t m_mallocMemSize;
size_t m_currWritePos;
size_t m_currReadPos;


};


#include "stdafx.h"
#include "datastream.h"
#include "String.h"
#include "PublicFunctions.h"


DataStream::DataStream()
{
m_pData = NULL;
m_mallocMemSize = 0;
m_currWritePos = 0;
m_currReadPos = 0;
}


DataStream::DataStream(size_t mallocMemSize)
{
m_pData = NULL;


Reset(mallocMemSize);
}


DataStream::DataStream(const DataStream& copySrc)
{
m_pData = new byte[copySrc.m_mallocMemSize];
m_mallocMemSize = copySrc.m_mallocMemSize;
m_currWritePos = copySrc.m_currWritePos;
m_currReadPos = copySrc.m_currReadPos;
memcpy(m_pData, copySrc.m_pData, copySrc.m_mallocMemSize);
}


void DataStream::Reset(size_t mallocMemSize)
{
SAFE_RELEASE(m_pData);


m_pData = new byte[(size_t)mallocMemSize];
m_mallocMemSize = mallocMemSize;
m_currWritePos = 0;
m_currReadPos = 0;
}


DataStream::~DataStream()
{
SAFE_RELEASE(m_pData);
m_mallocMemSize = 0;
m_currWritePos = 0;
m_currReadPos = 0;
}


DataStream::DataStream(byte* pBuffer, size_t bufferLength, size_t mallocMemSize)
{
if (mallocMemSize == -1)
mallocMemSize = bufferLength;


m_pData = NULL;
Reset(mallocMemSize);
memcpy(m_pData, pBuffer, bufferLength);
m_currWritePos = bufferLength;
m_currReadPos = 0;
}


void DataStream::Attach(byte* pDestBuffer, size_t destBufferLen)
{
m_pData = pDestBuffer;
m_currReadPos = 0;
m_currWritePos = 0;
m_mallocMemSize = destBufferLen;
}


void DataStream::Detach()
{
m_pData = NULL;
m_mallocMemSize = 0;
m_currWritePos = 0;
m_currReadPos = 0;
}


bool DataStream::CanRead(int dataLen)
{
if (m_currReadPos + dataLen > GetDataLength())
return FALSE;

return TRUE;
}


void DataStream::SeekReadToBegin()
{
m_currReadPos = 0;
}


void DataStream::SeekWriteToBegin()
{
m_currWritePos = 0;
}


byte* DataStream::GetData(size_t startIndex)
{
return m_pData + startIndex;
}


size_t DataStream::GetDataLength()
{
return m_currWritePos;
}


BOOL DataStream::Open(CString strFilePath)
{
m_pData = NULL;
m_mallocMemSize = 0;
m_currWritePos = 0;
m_currReadPos = 0;


CFile file;


if (file.Open(strFilePath, CFile::modeRead | CFile::shareDenyWrite))
{
m_mallocMemSize = (size_t)file.GetLength();
m_pData = new byte[m_mallocMemSize];
file.Read(m_pData, (UINT)m_mallocMemSize);
file.Close();
m_currWritePos = m_mallocMemSize;
return TRUE;
}


return FALSE;
}


void DataStream::Save(CString strFilePath)
{
PublicFunctions::MakesureDirPathValid(strFilePath);


CFile file;
file.Open(strFilePath, CFile::modeCreate | CFile::modeWrite);
file.Write(GetData(), (UINT)GetDataLength());
file.Close();
}


size_t DataStream::MakeSureCanWriteByIncreaseMemorySpace(size_t byteCountToWrite)
{
if (byteCountToWrite > m_mallocMemSize - m_currWritePos)
{
size_t increaseSize = byteCountToWrite * 2;


if (increaseSize < 1024)
increaseSize = 1024;


size_t newSize = m_mallocMemSize + increaseSize; 
byte* pNewData = new byte[newSize];
memset(pNewData, 0, newSize);

if (m_pData != NULL)
memcpy(pNewData, m_pData, m_mallocMemSize);


SAFE_RELEASE(m_pData);
m_pData = pNewData;
m_mallocMemSize = newSize;
}


return m_mallocMemSize;
}


DataStream& DataStream::operator << (CString val)
{
int len = val.GetLength();
MakeSureCanWriteByIncreaseMemorySpace(len * 2 + 4);
(*this) << (len);


for (int i = 0; i < len; i++)
{
(*this) << (WCHAR)val.GetAt(i);
}
return *this;
}


DataStream& DataStream::operator >> (CString& val)
{
val.Empty();
int len = 0;
(*this) >> (len);


for (int i = 0; i < len; i++)
{
WCHAR c = 0;
(*this) >> c;
val.Insert(val.GetLength(), c);
}
return *this;
}


DataStream& DataStream::operator << (int val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(int));


byte v0 = (byte) ((val << 24) >> 24);
byte v1 = (byte) ((val << 16) >> 24);
byte v2 = (byte) ((val << 8) >> 24);
byte v3 = (byte) ((val) >> 24);


*(m_pData + (m_currWritePos++)) = v0;
*(m_pData + (m_currWritePos++)) = v1;
*(m_pData + (m_currWritePos++)) = v2;
*(m_pData + (m_currWritePos++)) = v3;


return *this;
}


DataStream& DataStream::operator >> (int& val)
{
// ASSERT(CanRead(sizeof(int)));


int v0 = *(m_pData + (m_currReadPos++));
int v1 = *(m_pData + (m_currReadPos++));
int v2 = *(m_pData + (m_currReadPos++));
int v3 = *(m_pData + (m_currReadPos++));


val = v0 | (v1 << 8) | (v2 << 16) | (v3 << 24);


return *this;
}


DataStream& DataStream::operator << (UINT val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(UINT));


byte v0 = (byte) ((val << 24) >> 24);
byte v1 = (byte) ((val << 16) >> 24);
byte v2 = (byte) ((val << 8) >> 24);
byte v3 = (byte) ((val) >> 24);


*(m_pData + (m_currWritePos++)) = v0;
*(m_pData + (m_currWritePos++)) = v1;
*(m_pData + (m_currWritePos++)) = v2;
*(m_pData + (m_currWritePos++)) = v3;


return *this;
}


DataStream& DataStream::operator >> (UINT& val)
{
UINT v0 = *(m_pData + (m_currReadPos++));
UINT v1 = *(m_pData + (m_currReadPos++));
UINT v2 = *(m_pData + (m_currReadPos++));
UINT v3 = *(m_pData + (m_currReadPos++));


val = v0 | (v1 << 8) | (v2 << 16) | (v3 << 24);


return *this;
}


DataStream& DataStream::operator << (long val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(long));


int temp = val;
(*this) << temp;


return *this;
}


DataStream& DataStream::operator >> (long& val)
{
int temp;


(*this) >> temp;


val = temp;


return *this;
}


DataStream& DataStream::operator << (DWORD val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(WORD));


CString temp;
temp.Format(_T("%d"), val);


(*this) << temp;


return *this;
}


DataStream& DataStream::operator >> (DWORD& val)
{
CString temp;


(*this) >> temp;


val = _wtoi(temp.GetBuffer(temp.GetLength()));
temp.ReleaseBuffer();


return *this;
}


DataStream& DataStream::operator << (byte val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(byte));


*(m_pData + (m_currWritePos++)) = val;

return *this;
}


DataStream& DataStream::operator >> (byte& val)
{
val = *(m_pData + (m_currReadPos++));


return *this;
}


DataStream& DataStream::operator << (short val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(short));


byte v0 = (byte) ((val << 8) >> 8);
byte v1 = (byte) ((val) >> 8);


*(m_pData + (m_currWritePos++)) = v0;
*(m_pData + (m_currWritePos++)) = v1;


return *this;
}


DataStream& DataStream::operator >> (short& val)
{


short v0 = *(m_pData + (m_currReadPos++));
short v1 = *(m_pData + (m_currReadPos++));


val = v0 | (v1 << 8);


return *this;
}


DataStream& DataStream::operator << (CArray<int, int>& val)
{
int count = (int)val.GetSize();
*this << count;


MakeSureCanWriteByIncreaseMemorySpace(count * sizeof(int));


for (int i = 0; i < count; i++)
{
*this << val.GetAt(i);
}


return *this;
}


DataStream& DataStream::operator >> (CArray<int, int>& val)
{
int count = 0;
*this >> count;


for (int i = 0; i< count; i++)
{
int tempItem = 0;
*this >> tempItem;
val.Add(tempItem);
}


return *this;
}


DataStream& DataStream::operator << (CStringArray& val)
{
int count = (int)val.GetSize();
*this << count;


for (int i = 0; i < count; i++)
{
*this << val.GetAt(i);
}


return *this;
}


DataStream& DataStream::operator >> (CStringArray& val)
{
int count = 0;
*this >> count;


for (int i = 0; i < count; i++)
{
CString strTemp;
*this >> strTemp;
val.Add(strTemp);
}


return *this;
}


DataStream& DataStream::operator << (float val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(float));


CString temp;
temp.Format(_T("%f"), val);
(*this) << (temp);


return *this;
}


DataStream& DataStream::operator >> (float& val)
{
CString temp;
(*this) >> (temp);
val = (float)_wtof(temp.GetBuffer(temp.GetLength()));
temp.ReleaseBuffer();


return *this;
}


DataStream& DataStream::Write(short* val, UINT count)
{
MakeSureCanWriteByIncreaseMemorySpace(count);


(*this) << count;


for (UINT i = 0; i < count; i++)
(*this) << (short) (val[i]);


return *this;
}


DataStream& DataStream::Read(short** val, UINT* count)
{
UINT countTemp;
(*this) >> countTemp;

if (count!= NULL)
*count = countTemp;


if (*val != NULL)
delete *val;


*val = new short[countTemp];


for (UINT i = 0; i < countTemp; i++)
(*this) >> (*val)[i];


return *this;
}


DataStream& DataStream::Write(byte* val, UINT count)
{
MakeSureCanWriteByIncreaseMemorySpace(count);


(*this) << count;


memcpy(m_pData + m_currWritePos, val, count);


m_currWritePos += count;


return *this;
}


DataStream& DataStream::Read(byte** val, UINT* count)
{
UINT countTemp;
(*this) >> countTemp;


if (count != NULL)
*count = countTemp;


SAFE_RELEASE(*val);

if (countTemp == 0)
{
*val = NULL;
}
else
{
*val = new byte[countTemp];
memcpy(*val, m_pData + m_currReadPos, countTemp);
}


m_currReadPos += countTemp;


return *this;
}


DataStream& DataStream::Write(IN char* val, IN UINT count)
{
MakeSureCanWriteByIncreaseMemorySpace(count);


*this << count;


for (UINT i = 0; i < count; i++)
*this << *(val + count);


return *this;
}


DataStream& DataStream::Read(OUT char** val, OUT UINT* count)
{
*this >> *count;


*val = new char[*count];


for (UINT i = 0; i < *count; i++)
*this >> *(*val + i);


return *this;
}


DataStream& DataStream::operator << (char val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(short));


short temp = val;
(*this) << temp;
return *this;
}


DataStream& DataStream::operator >> (char& val)
{
short temp;
(*this) >> temp;
val = (char)temp;
return *this;
}


DataStream& DataStream::operator << (WCHAR val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(short));


short temp = val;
(*this) << temp;
return *this;
}


DataStream& DataStream::operator >> (WCHAR& val)
{
short temp;
(*this) >> temp;
val = (WCHAR)temp;
return *this;
}


DataStream& DataStream::operator << (DataStream& val)
{
MakeSureCanWriteByIncreaseMemorySpace(val.GetDataLength());


int cnt = (int)val.GetDataLength();
(*this) << cnt;

memcpy(m_pData + m_currWritePos, val.m_pData, cnt);

m_currWritePos += cnt;

return *this;
}


DataStream& DataStream::operator >> (DataStream& val)
{
int cnt;
(*this) >> cnt;

val.Reset(cnt);
memcpy(val.m_pData, m_pData + m_currReadPos, cnt);
val.m_currWritePos += cnt;

m_currReadPos += cnt;

return *this;
}


DataStream& DataStream::operator << (CRect val)
{
MakeSureCanWriteByIncreaseMemorySpace(4 * sizeof(long));


*this << val.left << val.top << val.right << val.bottom;


return *this;
}


DataStream& DataStream::operator >> (CRect& val)
{
int left, top, right, bottom;


*this >> left >> top >> right >> bottom;


val = CRect(left, top, right, bottom);


return *this;
}


DataStream& DataStream::operator << (Rect val)
{
MakeSureCanWriteByIncreaseMemorySpace(4 * sizeof(int));


*this << val.GetLeft() << val.GetTop() << val.Width << val.Height;


return *this;
}


DataStream& DataStream::operator >> (Rect& val)
{
int left, top, width, height;


*this >> left >> top >> width >> height;


val = Rect(left, top, width, height);


return *this;
}


DataStream& DataStream::operator << (RectF val)
{
MakeSureCanWriteByIncreaseMemorySpace(4 * sizeof(float));


*this << val.GetLeft() << val.GetTop() << val.Width << val.Height;


return *this;
}


DataStream& DataStream::operator >> (RectF& val)
{
float left, top, width, height;


*this >> left >> top >> width >> height;


val = RectF(left, top, width, height);


return *this;
}


DataStream& DataStream::operator << (CPoint val)
{
MakeSureCanWriteByIncreaseMemorySpace(2 * sizeof(long));


*this << val.x << val.y;


return *this;
}


DataStream& DataStream::operator >> (CPoint& val)
{
int x, y;


*this >> x >> y;


val = CPoint(x, y);


return *this;
}


DataStream& DataStream::operator << (Point val)
{
MakeSureCanWriteByIncreaseMemorySpace(2 * sizeof(long));


*this << val.X << val.Y;


return *this;
}


DataStream& DataStream::operator >> (Point& val)
{
int x, y;


*this >> x >> y;


val = Point(x, y);


return *this;
}


DataStream& DataStream::operator << (PointF val)
{
MakeSureCanWriteByIncreaseMemorySpace(2 * sizeof(float));


*this << val.X << val.Y;


return *this;
}


DataStream& DataStream::operator >> (PointF& val)
{
float x, y;


*this >> x >> y;


val = PointF(x, y);


return *this;
}


DataStream& DataStream::operator << (Image* val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(byte));


if (val == NULL)
{
*this << (byte)0;
}
else
{
*this << (byte)1;


UINT len = 0;
byte *pdatas = NULL;
PublicFunctions::ImageToByte(&pdatas, val, len);
MakeSureCanWriteByIncreaseMemorySpace(len);
Write(pdatas, len);


delete[] pdatas;
}


return *this;
}


DataStream& DataStream::operator >> (Image** val)
{
byte bNull = 0;
*this >> bNull;


if (bNull == 0)
{
SAFE_RELEASE((*val));
}
else
{
SAFE_RELEASE((*val));


UINT len = 0;
byte *pData = NULL;


Read(&pData, &len);
*val = PublicFunctions::ByteToImage(pData, len);


delete[] pData;
}


return *this;
}


DataStream& DataStream::AddFile(CString strSrcPath)
{
if (!PublicFunctions::IsValidFilePath(strSrcPath))
{
*this << (byte)0;
}
else
{
*this << (byte)1;
CFile  file(strSrcPath, CFile::modeRead);
CString str = file.GetFileName();
*this << file.GetFileName();


UINT wLen = (UINT)file.GetLength();
MakeSureCanWriteByIncreaseMemorySpace(wLen);
byte* pDatas = new byte[wLen];
file.Read(pDatas, wLen);
Write(pDatas, wLen);
delete[] pDatas;
file.Close();
}

return *this;
}


DataStream& DataStream::GetFile(CString& strSavePath)
{
byte bNull = 0;
*this >> bNull;

if (bNull == 0)
{
strSavePath.Empty();
}
else 
{
CString fileName;
UINT filelen = 0;
byte* pDatas = NULL;


*this >> fileName;
Read(&pDatas, &filelen);


strSavePath = strSavePath + _T("\\") + fileName;
CFile file(strSavePath, CFile::modeWrite | CFile::modeCreate);
file.Write(pDatas, filelen);
file.Close();
delete[] pDatas;
}
return *this;
}


DataStream& DataStream::operator << (Font* val)
{
MakeSureCanWriteByIncreaseMemorySpace(LF_FACESIZE + sizeof(float) + 1);


if (val == NULL)
{
*this << (byte)0;
}
else
{
*this << (byte)1;


FontFamily  fontfamily;
val->GetFamily(&fontfamily);
WCHAR  familyName[LF_FACESIZE];
fontfamily.GetFamilyName(familyName);
int style = val->GetStyle();
int unit = val->GetUnit();


*this << (CString)familyName << val->GetSize() << style << unit;
}
return *this;
}


DataStream& DataStream::operator >> (Font** val)
{
byte bNull = 0;
*this >> bNull;


if (bNull == 0)
{
SAFE_RELEASE((*val));
}
else
{
SAFE_RELEASE((*val));


CString familyName;
float   fontSize;
int style, unit;
*this >> familyName >> fontSize >> style >> unit;
FontFamily family(familyName);
(*val) = new Font(&family, fontSize, style, Unit(unit));
}
return *this;
}


DataStream& DataStream::operator << (Matrix* val)
{
MakeSureCanWriteByIncreaseMemorySpace(6 * sizeof(float) + 1);


if (val == NULL)
{
*this << (byte)0;
}
else
{
*this << (byte)1;


float m[6] = {0.0f};
val->GetElements(m);


for (int i = 0; i < 6; i++)
{
*this << m[i];
}
}
return *this;
}


DataStream& DataStream::operator >> (Matrix** val)
{
byte bNull = 0;
*this >> bNull;


if (bNull == 0)
{
SAFE_RELEASE((*val));
}
else
{
if ((*val) == NULL)
(*val) = new Matrix;


float m[6];
*this >> m[0] >> m[1] >> m[2] >> m[3] >> m[4] >> m[5];


(*val)->Reset();
(*val)->SetElements(m[0], m[1], m[2], m[3], m[4], m[5]);
}
return *this; 
}


DataStream& DataStream::operator << (Color val)
{
MakeSureCanWriteByIncreaseMemorySpace(sizeof(DWORD));


*this << val.GetAlpha() << val.GetRed() << val.GetGreen() << val.GetBlue();


return *this;
}


DataStream& DataStream::operator >> (Color &val)
{
byte a, r, g, b;


*this >> a >> r >> g >> b;


val = Color(a, r, g, b);


return *this;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值