/* * (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 #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(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(); } }