Files
DocumentServer-v-9.2.0/core/PdfFile/SrcWriter/Streams.cpp
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

1061 lines
26 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "Streams.h"
#include "Utils.h"
#include "Encrypt.h"
#include "Objects.h"
//#include "FastStringToDouble.h"
#include <sstream>
#include "../../OfficeUtils/src/OfficeUtils.h"
#include "../../UnicodeConverter/UnicodeConverter.h"
#include "../../DesktopEditor/common/StringExt.h"
#define DEFLATE_BUF_SIZ ((int)(STREAM_BUF_SIZ * 1.1) + 13)
namespace PdfWriter
{
static const char* c_pHexStrings[] =
{
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
};
//----------------------------------------------------------------------------------------
// CStream
//----------------------------------------------------------------------------------------
bool CStream::CheckSize(unsigned int unSize)
{
if (Size() - Tell() >= unSize)
return true;
return false;
}
unsigned int CStream::ReadUInt()
{
if (!CheckSize(4))
return 0;
unsigned int unBytesRead = 1;
BYTE nChar0, nChar1, nChar2, nChar3;
Read(&nChar0, &unBytesRead);
Read(&nChar1, &unBytesRead);
Read(&nChar2, &unBytesRead);
Read(&nChar3, &unBytesRead);
return (unsigned int)(((unsigned int)nChar0 << 24) | ((unsigned int)nChar1 << 16) | ((unsigned int)nChar2 << 8) | nChar3);
}
unsigned char CStream::ReadUChar()
{
if (!CheckSize(1))
return 0;
BYTE nChar;
unsigned int unBytesRead = 1;
Read(&nChar, &unBytesRead);
return nChar;
}
char CStream::ReadChar()
{
return (char)ReadUChar();
}
unsigned short CStream::ReadUShort()
{
if (!CheckSize(2))
return 0;
unsigned int unBytesRead = 1;
BYTE nChar0, nChar1;
Read(&nChar0, &unBytesRead);
Read(&nChar1, &unBytesRead);
return (unsigned short)(((unsigned short)nChar0 << 8) | nChar1);
}
double CStream::ReadFixed()
{
if (!CheckSize(4))
return 0;
unsigned short integer = ReadUShort();
unsigned short fraction = ReadUShort();
return (double)integer + ((double)fraction) / (1 << 16);
}
long long CStream::ReadLongDateTime()
{
if (!CheckSize(8))
return 0;
unsigned int unBytesRead = 1;
BYTE nChar0, nChar1, nChar2, nChar3, nChar4, nChar5, nChar6, nChar7;
Read(&nChar0, &unBytesRead);
Read(&nChar1, &unBytesRead);
Read(&nChar2, &unBytesRead);
Read(&nChar3, &unBytesRead);
Read(&nChar4, &unBytesRead);
Read(&nChar5, &unBytesRead);
Read(&nChar6, &unBytesRead);
Read(&nChar7, &unBytesRead);
return (long long)(((long long)nChar0 << 56) | ((long long)nChar1 << 48) |
((long long)nChar2 << 40) | ((long long)nChar3 << 32) |
((long long)nChar4 << 24) | ((long long)nChar5 << 16) |
((long long)nChar6 << 8) | nChar7);
}
unsigned int CStream::ReadOffset(BYTE nOffset)
{
unsigned int nRes = 0;
if (nOffset < 1 || nOffset > 4 || !CheckSize(nOffset))
return nRes;
for (BYTE i = 0; i < nOffset; ++i)
{
BYTE nChar;
unsigned int unBytesRead = 1;
Read(&nChar, &unBytesRead);
nRes = (nRes << 8) | nChar;
}
return nRes;
}
void CStream::Write(const BYTE* pBuffer, unsigned int unSize, bool bCalcCheckSum)
{
Write(pBuffer, unSize);
if (bCalcCheckSum)
{
CRC32 oCRC;
oCRC.ProcessCRC((void*)pBuffer, unSize);
m_unCheckSum = oCRC.m_nCRC32;
}
}
void CStream::WriteChar(char nChar)
{
Write((BYTE*)&nChar, 1);
}
void CStream::WriteStr(const char* sString)
{
unsigned int nLen = StrLen(sString, -1);
Write((BYTE*)sString, nLen);
}
void CStream::WriteUChar(unsigned char unValue)
{
Write(&unValue, 1);
}
void CStream::WriteInt(int nValue)
{
char pBuffer[32];
memset(pBuffer, 0x00, 32);
ItoA(pBuffer, nValue, pBuffer + 31);
return WriteStr(pBuffer);
}
void CStream::WriteUInt(unsigned int unValue)
{
WriteInt((int)unValue);
}
void CStream::WriteHex(int nValue, int nLen)
{
if (2 == nLen)
Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2);
else if (4 == nLen)
{
Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 8)], 2);
Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2);
}
else if (6 == nLen)
{
Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 16)], 2);
Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 8)], 2);
Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2);
}
}
void CStream::WriteReal(float fValue)
{
char pBuffer[32];
memset(pBuffer, 0x00, 32);
FtoA(pBuffer, fValue, pBuffer + 31);
return WriteStr(pBuffer);
}
void CStream::WriteReal(double dValue)
{
//int nIVal = (int)dValue;
//int nFVal = (int)(fabs(dValue - nIVal) * 10000);
//int nLen = 0;
//const char* sString = NSFastIntToString::GetString(fabs(nIVal), nLen);
//if (nIVal < 0)
// WriteChar('-');
//Write((const BYTE*)sString, nLen);
//if (nFVal)
//{
// sString = NSFastIntToString::GetString(nFVal, nLen);
// WriteChar('.');
// int nZeros = 4 - nLen;
// if (nZeros > 0)
// Write((const BYTE*)NSFastIntToString::GetZeros(nZeros), nZeros);
// Write((const BYTE*)sString, nLen);
//}
//char pBuffer[32];
//int nResLen = 0;
//int nIVal = (int)dValue;
//int nFVal = (int)(fabs(dValue - nIVal) * 10000);
//int nLen = 0;
//const char* sString = NSFastIntToString::GetString(fabs(nIVal), nLen);
//if (nIVal < 0)
// pBuffer[nResLen++] = '-';
//memcpy(pBuffer + nResLen, sString, nLen);
//nResLen += nLen;
//if (nFVal)
//{
// int nRealLen = 0;
// sString = NSFastIntToString::GetPrecisionString(nFVal, nLen, nRealLen);
// pBuffer[nResLen++] = '.';
// int nZeros = 4 - nRealLen;
// if (nZeros > 0)
// {
// memcpy(pBuffer + nResLen, NSFastIntToString::GetZeros(nZeros), nZeros);
// nResLen += nZeros;
// }
// memcpy(pBuffer + nResLen, sString, nLen);
// nResLen += nLen;
//}
//return Write((const BYTE*)pBuffer, nResLen);
char pBuffer[32];
memset(pBuffer, 0x00, 32);
FtoA(pBuffer, dValue, pBuffer + 31);
return WriteStr(pBuffer);
}
void CStream::WriteEscapeName(const char* sValue)
{
char sTmpChar[LIMIT_MAX_NAME_LEN * 3 + 2];
const BYTE* pPos1;
char* pPos2;
pPos1 = (BYTE*)sValue;
pPos2 = sTmpChar;
*pPos2++ = '/';
int nLen = StrLen(sValue, LIMIT_MAX_NAME_LEN);
for (int nIndex = 0; nIndex < nLen; nIndex++)
{
BYTE nChar = *pPos1++;
if (NEEDS_ESCAPE(nChar))
{
*pPos2++ = '#';
*pPos2 = (char)(nChar >> 4);
if (*pPos2 <= 9)
*pPos2 += 0x30;
else
*pPos2 += 0x41 - 10;
pPos2++;
*pPos2 = (char)(nChar & 0x0f);
if (*pPos2 <= 9)
*pPos2 += 0x30;
else
*pPos2 += 0x41 - 10;
pPos2++;
}
else
*pPos2++ = nChar;
}
*pPos2 = 0;
Write((BYTE*)sTmpChar, StrLen(sTmpChar, -1));
}
void CStream::WriteEscapeText(const BYTE* sText, unsigned int unLen, bool isUTF16, bool isDictValue)
{
if (!unLen || !sText)
{
Write((BYTE*)"()", 2);
return;
}
BYTE* sTxt = const_cast<BYTE*>(sText);
unsigned short* pUtf16Data = NULL;
WriteChar('(');
if (isUTF16)
{
std::string sUtf8((char*)sText, unLen);
std::wstring sUnicode = UTF8_TO_U(sUtf8);
unsigned int unLenUtf16 = 0;
pUtf16Data = NSStringExt::CConverter::GetUtf16FromUnicode(sUnicode, unLenUtf16, false);
sTxt = (BYTE*)pUtf16Data;
unLen = unLenUtf16 << 1;
WriteChar(0xFE);
WriteChar(0xFF);
}
char sBuf[TEXT_DEFAULT_LEN];
unsigned int nIndex = 0;
for (int nCounter = 0; nCounter < unLen; nCounter++)
{
BYTE nChar = (BYTE)*sTxt++;
if ((isDictValue && NEEDS_ESCAPE_DICTVALUE(nChar)) || (!isDictValue && NEEDS_ESCAPE_STR(nChar)))
{
sBuf[nIndex++] = '\\';
sBuf[nIndex++] = 0x30 + (nChar >> 6);
sBuf[nIndex++] = 0x30 + ((nChar & 0x38) >> 3);
sBuf[nIndex++] = 0x30 + (nChar & 0x07);
}
else
{
sBuf[nIndex++] = nChar;
}
if (nIndex > TEXT_DEFAULT_LEN - 4)
{
Write((BYTE*)sBuf, nIndex);
nIndex = 0;
}
}
Write((BYTE*)sBuf, nIndex);
WriteChar(')');
if (pUtf16Data)
delete []pUtf16Data;
}
void CStream::WriteBinary(const BYTE* pData, unsigned int unLen, CEncrypt* pEncrypt)
{
char sBuf[TEXT_DEFAULT_LEN];
BYTE* pBuf = NULL;
bool bDelete = false;
unsigned int nIndex = 0;
const BYTE* pBuffer = NULL;
if (pEncrypt)
{
pBuf = new BYTE[unLen + 16 + 16]; // iv + padding
bDelete = true;
unLen = pEncrypt->CryptBuf(pData, pBuf, unLen);
pBuffer = pBuf;
}
else
{
pBuffer = pData;
}
for (int nCounter = 0; nCounter < unLen; nCounter++, pBuffer++)
{
Write((const BYTE*)c_pHexStrings[*pBuffer], 2);
}
if (nIndex > 0)
{
Write((BYTE*)sBuf, nIndex);
}
if (bDelete)
delete[] pBuf;
}
void CStream::WriteStreamWithDeflate(CStream* pStream, CEncrypt* pEncrypt)
{
unsigned long nRet = OK;
CDeflate ZStream;
BYTE inbuf[STREAM_BUF_SIZ];
BYTE otbuf[DEFLATE_BUF_SIZ];
BYTE *otbuf_all = NULL;
// initialize input stream
pStream->Seek(0, SeekSet);
unsigned long size = pStream->Size();
if (pEncrypt)
{
unsigned long size_out = (unsigned long)(size * 1.1 + 13 + 64);
otbuf_all = new BYTE[size_out];
}
// initialize decompression stream.
ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ);
ZStream.Init(DEFLATE_DEFAULT_COMPRESSION, -1);
ZStream.SetIn(inbuf, 0);
unsigned long size_crypt = 0;
unsigned int offset = 0;
while(true)
{
unsigned int unSize = STREAM_BUF_SIZ;
pStream->Read(inbuf, &unSize);
ZStream.SetIn(inbuf, unSize);
if (0 == unSize)
break;
while (ZStream.GetAvailIn() > 0)
{
ZStream.Process(DEFLATE_NO_FLUSH);
if (ZStream.GetAvailOut() == 0)
{
if (pEncrypt)
{
memcpy(otbuf_all + offset, otbuf, DEFLATE_BUF_SIZ);
offset += DEFLATE_BUF_SIZ;
}
else
Write(otbuf, DEFLATE_BUF_SIZ);
ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ);
}
}
}
bool bEnd = false;
while(true)
{
nRet = ZStream.Process(DEFLATE_FINISH);
if (DEFLATE_OK != nRet && DEFLATE_STREAM_END != nRet)
{
ZStream.End();
return;
}
if (DEFLATE_STREAM_END == nRet)
bEnd = true;
if (ZStream.GetAvailOut() < DEFLATE_BUF_SIZ)
{
unsigned int osize = DEFLATE_BUF_SIZ - ZStream.GetAvailOut();
if (pEncrypt)
{
memcpy(otbuf_all + offset, otbuf, osize);
offset += osize;
}
else
Write(otbuf, osize);
ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ);
}
if (bEnd)
break;
}
if (pEncrypt)
{
BYTE *etbuf_all = new BYTE[offset + 32];
unsigned int osize = pEncrypt->CryptBuf(otbuf_all, etbuf_all, offset);
delete []otbuf_all;
Write(etbuf_all, osize);
delete []etbuf_all;
}
ZStream.End();
}
void CStream::WriteStream(CStream* pStream, unsigned int unFilter, CEncrypt *pEncrypt)
{
if (pStream->Size() <= 0)
return;
#ifndef FILTER_FLATE_DECODE_DISABLED
if ((unFilter & STREAM_FILTER_FLATE_DECODE) && !(unFilter & STREAM_FILTER_ALREADY_DECODE))
return WriteStreamWithDeflate(pStream, pEncrypt);
#endif
pStream->Seek(0, SeekSet);
if (pEncrypt)
{
unsigned int size = pStream->Size();
BYTE *pBuf = new BYTE[size];
BYTE *pEBuf = new BYTE[size + 32];
pStream->Read(pBuf, &size);
size = pEncrypt->CryptBuf(pBuf, pEBuf, size);
Write(pEBuf, size);
delete []pBuf;
delete []pEBuf;
}
else
{
BYTE pBuf[STREAM_BUF_SIZ];
while(true)
{
unsigned int unSize = STREAM_BUF_SIZ;
pStream->Read(pBuf, &unSize);
if (0 == unSize)
break;
Write(pBuf, unSize);
}
}
}
void CStream::Write(CNullObject* pNull)
{
}
void CStream::Write(CBoolObject* pBool)
{
if (pBool->Get())
WriteStr("true");
else
WriteStr("false");
}
void CStream::Write(CNumberObject* pNumber)
{
WriteInt(pNumber->Get());
}
void CStream::Write(CRealObject* pReal)
{
WriteReal(pReal->Get());
}
void CStream::Write(CNameObject* pName)
{
WriteEscapeName(pName->Get());
}
void CStream::Write(CStringObject* pString, CEncrypt* pEncrypt)
{
if (pEncrypt)
pEncrypt->Reset();
if (pEncrypt)
{
const BYTE* pBinary = pString->GetString();
unsigned int unLen = pString->GetLength();
WriteChar('<');
BYTE* pNewBinary = NULL;
if (pString->IsUTF16())
{
std::string sUtf8((char*)pBinary, unLen);
std::wstring sUnicode = UTF8_TO_U(sUtf8);
unsigned int unLenUtf16 = 0;
unsigned short* pUtf16Data = NSStringExt::CConverter::GetUtf16FromUnicode(sUnicode, unLenUtf16, false);
unLenUtf16 *= 2;
unLen = unLenUtf16 + 2;
pNewBinary = new BYTE[unLenUtf16 + 2];
pNewBinary[0] = 0xFE;
pNewBinary[1] = 0xFF;
MemCpy(pNewBinary + 2, (BYTE*)pUtf16Data, unLenUtf16);
RELEASEARRAYOBJECTS(pUtf16Data);
pBinary = pNewBinary;
}
WriteBinary(pBinary, unLen, pEncrypt);
WriteChar('>');
RELEASEARRAYOBJECTS(pNewBinary);
}
else
{
WriteEscapeText(pString->GetString(), pString->GetLength(), pString->IsUTF16(), pString->IsDictValue());
}
}
void CStream::Write(CBinaryObject* pBinary, CEncrypt* pEncrypt)
{
unsigned int unLen = pBinary->GetLength();
BYTE* pValue = pBinary->GetValue();
if (0 == unLen || !pValue)
return WriteStr("<>");
if (pEncrypt)
pEncrypt->Reset();
WriteChar('<');
WriteBinary(pValue, unLen, pEncrypt);
WriteChar('>');
}
void CStream::Write(CArrayObject* pArray, CEncrypt* pEncrypt)
{
WriteStr("[ ");
for (int nIndex = 0, nCount = pArray->GetCount(); nIndex < nCount; nIndex++)
{
CObjectBase* pObject = pArray->Get(nIndex, false);
Write(pObject, pEncrypt);
WriteChar(' ');
}
WriteChar(']');
}
void CStream::Write(CDictObject* pDict, CEncrypt* pEncrypt)
{
WriteStr("<<\012");
pDict->BeforeWrite();
// EncryptDict не надо шифровать
if (dict_type_ENCRYPT == pDict->GetDictType())
pEncrypt = NULL;
// Добавляем запись Filter
if (pDict->GetStream())
{
unsigned int unFilter = pDict->GetFilter();
if (STREAM_FILTER_NONE != unFilter && STREAM_FILTER_ALREADY_DECODE != unFilter)
{
CArrayObject* pFilter = new CArrayObject();
pDict->Add("Filter", pFilter);
#ifndef FILTER_FLATE_DECODE_DISABLED
if (unFilter & STREAM_FILTER_FLATE_DECODE)
pFilter->Add("FlateDecode");
#endif
if (unFilter & STREAM_FILTER_DCT_DECODE)
pFilter->Add("DCTDecode");
if (unFilter & STREAM_FILTER_JPX_DECODE)
pFilter->Add("JPXDecode");
if (unFilter & STREAM_FILTER_JBIG2_DECODE)
pFilter->Add("JBIG2Decode");
if (unFilter & STREAM_FILTER_LZW_DECODE)
pFilter->Add("LZWDecode");
if (unFilter & STREAM_FILTER_CCITT_DECODE)
pFilter->Add("CCITTFaxDecode");
unsigned int unPredictor = pDict->GetPredictor();
//pDict->Remove("DecodeParams");
if (STREAM_PREDICTOR_NONE != unPredictor)
{
CArrayObject* pDecode = new CArrayObject();
pDict->Add("DecodeParams", pDecode);
#ifndef FILTER_FLATE_DECODE_DISABLED
if (unFilter & STREAM_FILTER_FLATE_DECODE)
{
//if ( STREAM_PREDICTOR_FLATE_TIFF == oDict->nPredictor )
pDecode->Add(new CNullObject());
}
#endif
if (unFilter & STREAM_FILTER_DCT_DECODE)
{
pDecode->Add(new CNullObject());
}
if (unFilter & STREAM_FILTER_JPX_DECODE)
{
pDecode->Add(new CNullObject());
}
if (unFilter & STREAM_FILTER_JBIG2_DECODE)
{
pDecode->Add(new CNullObject());
}
if (unFilter & STREAM_FILTER_LZW_DECODE)
{
pDecode->Add(new CNullObject());
}
}
}
}
pDict->WriteToStream(this, pEncrypt);
pDict->Write(this);
WriteStr(">>");
CStream* pStream = pDict->GetStream();
if (pStream)
{
CNumberObject* pLength = (CNumberObject*)pDict->Get("Length");
// "Length" должен управляться таблицей Xref (флаг Indirect)
if (pLength && object_type_NUMBER == pLength->GetType())
{
if (pEncrypt)
pEncrypt->Reset();
WriteStr("\012stream\015\012");
unsigned int unStartSize = Tell();
WriteStream(pStream, pDict->GetFilter(), pDict->GetDictType() == dict_type_STREAM ? NULL : pEncrypt);
pLength->Set(Tell() - unStartSize);
WriteStr("\012endstream");
}
}
pDict->AfterWrite(this);
}
void CStream::Write(CObjectBase* pObject, CEncrypt* pEncrypt)
{
if (pObject)
{
pObject->Write(this, pEncrypt);
}
}
//----------------------------------------------------------------------------------------
// CMemoryStream
//----------------------------------------------------------------------------------------
CMemoryStream::CMemoryStream()
{
m_bFree = true;
m_unSize = 0;
m_nBufferSize = 0;
m_pBuffer = NULL;
m_pCur = NULL;
}
CMemoryStream::CMemoryStream(unsigned int unBufferSize)
{
m_bFree = true;
m_unSize = 0;
m_nBufferSize = 0;
m_pBuffer = NULL;
m_pCur = NULL;
Shrink(unBufferSize);
}
CMemoryStream::CMemoryStream(BYTE* pBuffer, unsigned int unSize, bool bFree)
{
m_bFree = bFree;
m_unSize = unSize;
m_nBufferSize = unSize;
m_pBuffer = pBuffer;
m_pCur = pBuffer;
}
CMemoryStream::~CMemoryStream()
{
if (m_pBuffer && m_bFree)
{
free(m_pBuffer);
//delete[] m_pBuffer;
}
m_nBufferSize = 0;
m_pBuffer = NULL;
m_pCur = NULL;
m_unSize = 0;
}
bool CMemoryStream::IsEof()
{
int nRemainBytes = Size() - Tell();
if (nRemainBytes <= 0)
return true;
return false;
}
void CMemoryStream::Write(const BYTE* pBuffer, unsigned int unSize)
{
unsigned int unRemainBytes = m_nBufferSize - Tell();
if (unRemainBytes < unSize)
{
unsigned int unShrinkSize = std::max(unSize, (unsigned int)STREAM_BUF_SIZ);
Shrink(unShrinkSize);
}
MemCpy(m_pCur, pBuffer, unSize);
m_pCur += unSize;
m_unSize = (unsigned int)std::max(m_unSize, (unsigned int)(m_pCur - m_pBuffer));
}
void CMemoryStream::Read(BYTE* pBuffer, unsigned int* punSize)
{
unsigned int unRemainBytes = m_unSize - Tell();
unsigned int unReadedBytes = (punSize ? std::min(*punSize, unRemainBytes) : unRemainBytes);
MemCpy(pBuffer, m_pCur, unReadedBytes);
m_pCur += unReadedBytes;
if (punSize)
*punSize = unReadedBytes;
}
void CMemoryStream::Seek(int nPos, EWhenceMode eMode)
{
switch (eMode)
{
case SeekCur: m_pCur += nPos; break;
case SeekEnd: m_pCur = m_pBuffer + m_unSize - nPos; break;
case SeekSet: m_pCur = m_pBuffer + nPos; break;
}
}
int CMemoryStream::Tell()
{
return (int)(m_pCur - m_pBuffer);
}
void CMemoryStream::Close()
{
if (m_pBuffer && m_bFree)
{
free(m_pBuffer);
//delete[] m_pBuffer;
}
m_nBufferSize = 0;
m_pBuffer = NULL;
m_pCur = NULL;
m_unSize = 0;
}
unsigned int CMemoryStream::Size()
{
return m_unSize;
}
BYTE* CMemoryStream::GetBuffer()
{
return m_pBuffer;
}
BYTE* CMemoryStream::GetCurBuffer()
{
return m_pCur;
}
void CMemoryStream::ClearWithoutAttack()
{
m_nBufferSize = 0;
m_pBuffer = NULL;
m_pCur = NULL;
m_unSize = 0;
}
void CMemoryStream::Shrink(unsigned int unSize)
{
if (m_pBuffer)
{
long lPos = Tell();
//BYTE* pNewBuffer = new BYTE[m_nBufferSize + unSize];
//MemCpy(pNewBuffer, m_pBuffer, m_unSize);
//delete[] m_pBuffer;
//m_pBuffer = pNewBuffer;
//m_pCur = m_pBuffer + lPos;
//m_nBufferSize = m_nBufferSize + unSize;
m_pBuffer = (BYTE*)realloc(m_pBuffer, m_nBufferSize + unSize);
m_pCur = m_pBuffer + lPos;
m_nBufferSize = m_nBufferSize + unSize;
}
else
{
//m_pBuffer = new BYTE[unSize];
//m_pCur = m_pBuffer;
//m_nBufferSize = unSize;
m_pBuffer = (BYTE*)malloc(unSize);
m_pCur = m_pBuffer;
m_nBufferSize = unSize;
}
}
//----------------------------------------------------------------------------------------
// CFileStream
//----------------------------------------------------------------------------------------
CFileStream::CFileStream()
{
m_wsFilePath = L"";
}
CFileStream::~CFileStream()
{
Close();
}
bool CFileStream::IsEof()
{
if (m_oFile.TellFile() >= m_oFile.SizeFile())
return true;
return false;
}
void CFileStream::Write(const BYTE* pBuffer, unsigned int unSize)
{
m_oFile.WriteFile((BYTE*)pBuffer, unSize);
}
void CFileStream::Read(BYTE *pBuffer, unsigned int* punSize)
{
DWORD dwBytesToRead = *punSize;
DWORD dwSizeRead = 0;
m_oFile.ReadFile(pBuffer, dwBytesToRead, dwSizeRead);
*punSize = dwSizeRead;
}
void CFileStream::Seek(int nPos, EWhenceMode eMode)
{
switch (eMode)
{
case SeekCur: m_oFile.SeekFile(nPos, SEEK_CUR); break;
case SeekEnd: m_oFile.SeekFile(nPos, SEEK_END); break;
case SeekSet: m_oFile.SeekFile(nPos, SEEK_SET); break;
}
}
int CFileStream::Tell()
{
return m_oFile.TellFile();
}
void CFileStream::Close()
{
m_oFile.CloseFile();
}
unsigned int CFileStream::Size()
{
return m_oFile.SizeFile();
}
bool CFileStream::OpenFile(const std::wstring& wsFilePath, bool bWrite)
{
Close();
m_wsFilePath = wsFilePath;
if (!bWrite)
{
if (!m_oFile.OpenFile(wsFilePath, true))
return false;
m_oFile.SeekFile(m_oFile.SizeFile(), SEEK_SET);
}
else
{
if (!m_oFile.CreateFileW(wsFilePath))
return false;
}
return true;
}
//----------------------------------------------------------------------------------------
// CImageFileStream
//----------------------------------------------------------------------------------------
CImageFileStream::CImageFileStream()
{
m_wsFilePath = L"";
m_nFilePos = 0;
m_nFileSize = 0;
}
CImageFileStream::~CImageFileStream()
{
Close();
}
bool CImageFileStream::IsEof()
{
if (m_nFilePos >= m_nFileSize)
return true;
return false;
}
void CImageFileStream::Write(const BYTE* pBuffer, unsigned int unSize)
{
// not used
}
void CImageFileStream::Read(BYTE *pBuffer, unsigned int* punSize)
{
if (!OpenFile())
{
*punSize = 0;
return;
}
DWORD dwBytesToRead = *punSize;
DWORD dwSizeRead = 0;
m_oFile.ReadFile(pBuffer, dwBytesToRead, dwSizeRead);
*punSize = dwSizeRead;
CloseFile();
}
void CImageFileStream::Seek(int nPos, EWhenceMode eMode)
{
switch (eMode)
{
case SeekCur: m_nFilePos += nPos; break;
case SeekEnd: m_nFilePos = std::max(0, (m_nFileSize - nPos)); break;
case SeekSet: m_nFilePos = nPos; break;
}
}
int CImageFileStream::Tell()
{
return m_nFilePos;
}
void CImageFileStream::Close()
{
m_oFile.CloseFile();
}
unsigned int CImageFileStream::Size()
{
return m_nFileSize;
}
bool CImageFileStream::OpenFile(const std::wstring& wsFilePath, bool bWrite)
{
Close();
m_wsFilePath = wsFilePath;
if (!bWrite)
{
if (!m_oFile.OpenFile(wsFilePath))
return false;
}
else
{
if (!m_oFile.CreateFileW(wsFilePath))
return false;
}
m_nFilePos = 0;
m_nFileSize = m_oFile.SizeFile();
CloseFile();
return true;
}
bool CImageFileStream::OpenFile()
{
if (!m_oFile.OpenFile(m_wsFilePath))
return false;
m_oFile.SeekFile(m_nFilePos);
return true;
}
void CImageFileStream::CloseFile()
{
m_nFilePos = m_oFile.TellFile();
m_oFile.CloseFile();
}
}