mirror of
https://github.com/Team-Resurgent/XBMC4Xbox.git
synced 2026-08-15 11:18:13 -07:00
If ever adding the XBMC4Xbox source to GitHub use "git add -f -A" or it wont add all the files.
497 lines
9.3 KiB
C++
497 lines
9.3 KiB
C++
/*
|
|
* Copyright (C) 2005-2013 Team XBMC
|
|
* http://xbmc.org
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with XBMC; see the file COPYING. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "Archive.h"
|
|
#include "FileSystem/File.h"
|
|
#include "Variant.h"
|
|
|
|
using namespace XFILE;
|
|
|
|
using namespace XFILE;
|
|
|
|
#define BUFFER_MAX 4096
|
|
|
|
CArchive::CArchive(CFile* pFile, int mode)
|
|
{
|
|
m_pFile = pFile;
|
|
m_iMode = mode;
|
|
|
|
m_pBuffer = new BYTE[BUFFER_MAX];
|
|
memset(m_pBuffer, 0, BUFFER_MAX);
|
|
|
|
m_BufferPos = 0;
|
|
}
|
|
|
|
CArchive::~CArchive()
|
|
{
|
|
FlushBuffer();
|
|
delete[] m_pBuffer;
|
|
m_BufferPos = 0;
|
|
}
|
|
|
|
void CArchive::Close()
|
|
{
|
|
FlushBuffer();
|
|
}
|
|
|
|
bool CArchive::IsLoading()
|
|
{
|
|
return (m_iMode == load);
|
|
}
|
|
|
|
bool CArchive::IsStoring()
|
|
{
|
|
return (m_iMode == store);
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(float f)
|
|
{
|
|
int size = sizeof(float);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &f, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(double d)
|
|
{
|
|
int size = sizeof(double);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &d, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(int i)
|
|
{
|
|
int size = sizeof(int);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &i, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(unsigned int i)
|
|
{
|
|
int size = sizeof(unsigned int);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &i, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(int64_t i64)
|
|
{
|
|
int size = sizeof(int64_t);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &i64, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(uint64_t ui64)
|
|
{
|
|
int size = sizeof(uint64_t);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &ui64, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(bool b)
|
|
{
|
|
int size = sizeof(bool);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &b, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(char c)
|
|
{
|
|
int size = sizeof(char);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &c, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(const CStdString& str)
|
|
{
|
|
*this << str.GetLength();
|
|
|
|
int size = str.GetLength();
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
int iBufferMaxParts=size/BUFFER_MAX;
|
|
for (int i=0; i<iBufferMaxParts; i++)
|
|
{
|
|
memcpy(&m_pBuffer[m_BufferPos], str.c_str()+(i*BUFFER_MAX), BUFFER_MAX);
|
|
m_BufferPos+=BUFFER_MAX;
|
|
FlushBuffer();
|
|
}
|
|
|
|
int iPos=iBufferMaxParts*BUFFER_MAX;
|
|
int iSizeLeft=size-iPos;
|
|
memcpy(&m_pBuffer[m_BufferPos], str.c_str()+iPos, iSizeLeft);
|
|
m_BufferPos+=iSizeLeft;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(const CStdStringW& str)
|
|
{
|
|
*this << str.GetLength();
|
|
|
|
int size = str.GetLength();
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
int iBufferMaxParts=size/BUFFER_MAX;
|
|
for (int i=0; i<iBufferMaxParts; ++i)
|
|
{
|
|
memcpy(&m_pBuffer[m_BufferPos], str.c_str()+(i*BUFFER_MAX), BUFFER_MAX);
|
|
m_BufferPos+=BUFFER_MAX;
|
|
FlushBuffer();
|
|
}
|
|
|
|
int iPos=iBufferMaxParts*BUFFER_MAX;
|
|
int iSizeLeft=size-iPos;
|
|
memcpy(&m_pBuffer[m_BufferPos], str.c_str()+iPos, iSizeLeft);
|
|
m_BufferPos+=iSizeLeft;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(const SYSTEMTIME& time)
|
|
{
|
|
int size = sizeof(SYSTEMTIME);
|
|
if (m_BufferPos + size >= BUFFER_MAX)
|
|
FlushBuffer();
|
|
|
|
memcpy(&m_pBuffer[m_BufferPos], &time, size);
|
|
m_BufferPos += size;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(IArchivable& obj)
|
|
{
|
|
obj.Archive(*this);
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(const CVariant& variant)
|
|
{
|
|
*this << (int)variant.type();
|
|
switch (variant.type())
|
|
{
|
|
case CVariant::VariantTypeInteger:
|
|
*this << variant.asInteger();
|
|
break;
|
|
case CVariant::VariantTypeUnsignedInteger:
|
|
*this << variant.asUnsignedInteger();
|
|
break;
|
|
case CVariant::VariantTypeBoolean:
|
|
*this << variant.asBoolean();
|
|
break;
|
|
case CVariant::VariantTypeString:
|
|
*this << CStdString(variant.asString());
|
|
break;
|
|
case CVariant::VariantTypeDouble:
|
|
*this << variant.asDouble();
|
|
break;
|
|
case CVariant::VariantTypeArray:
|
|
*this << variant.size();
|
|
for (unsigned int index = 0; index < variant.size(); index++)
|
|
*this << variant[index];
|
|
break;
|
|
case CVariant::VariantTypeObject:
|
|
*this << variant.size();
|
|
for (CVariant::const_iterator_map itr = variant.begin_map(); itr != variant.end_map(); itr++)
|
|
{
|
|
*this << CStdString(itr->first);
|
|
*this << itr->second;
|
|
}
|
|
break;
|
|
case CVariant::VariantTypeNull:
|
|
case CVariant::VariantTypeConstNull:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(const std::vector<std::string>& strArray)
|
|
{
|
|
*this << (unsigned int)strArray.size();
|
|
for (unsigned int index = 0; index < strArray.size(); index++)
|
|
*this << CStdString(strArray.at(index));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator<<(const std::vector<int>& iArray)
|
|
{
|
|
*this << (unsigned int)iArray.size();
|
|
for (unsigned int index = 0; index < iArray.size(); index++)
|
|
*this << iArray.at(index);
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(float& f)
|
|
{
|
|
m_pFile->Read((void*)&f, sizeof(float));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(double& d)
|
|
{
|
|
m_pFile->Read((void*)&d, sizeof(double));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(int& i)
|
|
{
|
|
m_pFile->Read((void*)&i, sizeof(int));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(unsigned int& i)
|
|
{
|
|
m_pFile->Read((void*)&i, sizeof(unsigned int));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(int64_t& i64)
|
|
{
|
|
m_pFile->Read((void*)&i64, sizeof(int64_t));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(uint64_t& ui64)
|
|
{
|
|
m_pFile->Read((void*)&ui64, sizeof(uint64_t));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(bool& b)
|
|
{
|
|
m_pFile->Read((void*)&b, sizeof(bool));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(char& c)
|
|
{
|
|
m_pFile->Read((void*)&c, sizeof(char));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(CStdString& str)
|
|
{
|
|
int iLength = 0;
|
|
*this >> iLength;
|
|
|
|
m_pFile->Read((void*)str.GetBufferSetLength(iLength), iLength);
|
|
str.ReleaseBuffer();
|
|
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(CStdStringW& str)
|
|
{
|
|
int iLength = 0;
|
|
*this >> iLength;
|
|
|
|
m_pFile->Read((void*)str.GetBufferSetLength(iLength), iLength);
|
|
str.ReleaseBuffer();
|
|
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(SYSTEMTIME& time)
|
|
{
|
|
m_pFile->Read((void*)&time, sizeof(SYSTEMTIME));
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(IArchivable& obj)
|
|
{
|
|
obj.Archive(*this);
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(CVariant& variant)
|
|
{
|
|
int type;
|
|
*this >> type;
|
|
variant = CVariant((CVariant::VariantType)type);
|
|
|
|
switch (variant.type())
|
|
{
|
|
case CVariant::VariantTypeInteger:
|
|
{
|
|
int64_t value;
|
|
*this >> value;
|
|
variant = value;
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeUnsignedInteger:
|
|
{
|
|
uint64_t value;
|
|
*this >> value;
|
|
variant = value;
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeBoolean:
|
|
{
|
|
bool value;
|
|
*this >> value;
|
|
variant = value;
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeString:
|
|
{
|
|
CStdString value;
|
|
*this >> value;
|
|
variant = value;
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeDouble:
|
|
{
|
|
double value;
|
|
*this >> value;
|
|
variant = value;
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeArray:
|
|
{
|
|
unsigned int size;
|
|
*this >> size;
|
|
for (; size > 0; size--)
|
|
{
|
|
CVariant value;
|
|
*this >> value;
|
|
variant.append(value);
|
|
}
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeObject:
|
|
{
|
|
unsigned int size;
|
|
*this >> size;
|
|
for (; size > 0; size--)
|
|
{
|
|
CStdString name;
|
|
CVariant value;
|
|
*this >> name;
|
|
*this >> value;
|
|
variant[name] = value;
|
|
}
|
|
break;
|
|
}
|
|
case CVariant::VariantTypeNull:
|
|
case CVariant::VariantTypeConstNull:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(std::vector<std::string>& strArray)
|
|
{
|
|
int size;
|
|
*this >> size;
|
|
strArray.clear();
|
|
for (int index = 0; index < size; index++)
|
|
{
|
|
CStdString str;
|
|
*this >> str;
|
|
strArray.push_back(str);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CArchive& CArchive::operator>>(std::vector<int>& iArray)
|
|
{
|
|
int size;
|
|
*this >> size;
|
|
iArray.clear();
|
|
for (int index = 0; index < size; index++)
|
|
{
|
|
int i;
|
|
*this >> i;
|
|
iArray.push_back(i);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
void CArchive::FlushBuffer()
|
|
{
|
|
if (m_BufferPos > 0)
|
|
{
|
|
m_pFile->Write(m_pBuffer, m_BufferPos);
|
|
m_BufferPos = 0;
|
|
}
|
|
}
|