1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2014 PDFium Authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef CORE_SRC_FXCRT_EXTENSION_H_ 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CORE_SRC_FXCRT_EXTENSION_H_ 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <algorithm> 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "core/include/fxcrt/fx_basic.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "core/include/fxcrt/fx_safe_types.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IFXCRT_FileAccess { 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual ~IFXCRT_FileAccess() {} 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_BOOL Open(const CFX_ByteStringC& fileName, FX_DWORD dwMode) = 0; 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_BOOL Open(const CFX_WideStringC& fileName, FX_DWORD dwMode) = 0; 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual void Close() = 0; 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual void Release() = 0; 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_FILESIZE GetSize() const = 0; 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_FILESIZE GetPosition() const = 0; 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_FILESIZE SetPosition(FX_FILESIZE pos) = 0; 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual size_t Read(void* pBuffer, size_t szBuffer) = 0; 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual size_t Write(const void* pBuffer, size_t szBuffer) = 0; 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual size_t ReadPos(void* pBuffer, size_t szBuffer, FX_FILESIZE pos) = 0; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual size_t WritePos(const void* pBuffer, 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t szBuffer, 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE pos) = 0; 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_BOOL Flush() = 0; 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual FX_BOOL Truncate(FX_FILESIZE szFile) = 0; 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIFXCRT_FileAccess* FXCRT_FileAccess_Create(); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef PDF_ENABLE_XFA 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CFX_CRTFileAccess : public IFX_FileAccess { 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CFX_CRTFileAccess() : m_RefCount(0) {} 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // IFX_FileAccess 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Release() override { 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (--m_RefCount == 0) 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch delete this; 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IFX_FileAccess* Retain() override { 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_RefCount++; 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (IFX_FileAccess*)this; 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GetPath(CFX_WideString& wsPath) override { wsPath = m_path; } 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IFX_FileStream* CreateFileStream(FX_DWORD dwModes) override { 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FX_CreateFileStream(m_path, dwModes); 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL Init(const CFX_WideStringC& wsPath) { 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_path = wsPath; 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_RefCount = 1; 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CFX_WideString m_path; 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD m_RefCount; 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // PDF_ENABLE_XFA 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CFX_CRTFileStream final : public IFX_FileStream { 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit CFX_CRTFileStream(IFXCRT_FileAccess* pFA); 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~CFX_CRTFileStream() override; 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // IFX_FileStream: 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IFX_FileStream* Retain() override; 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Release() override; 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE GetSize() override; 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL IsEOF() override; 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE GetPosition() override; 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override; 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t ReadBlock(void* buffer, size_t size) override; 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL WriteBlock(const void* buffer, 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE offset, 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t size) override; 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL Flush() override; 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IFXCRT_FileAccess* m_pFile; 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD m_dwCount; 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FX_MEMSTREAM_BlockSize (64 * 1024) 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FX_MEMSTREAM_Consecutive 0x01 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FX_MEMSTREAM_TakeOver 0x02 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CFX_MemoryStream final : public IFX_MemoryStream { 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit CFX_MemoryStream(FX_BOOL bConsecutive) 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : m_dwCount(1), 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nTotalSize(0), 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurSize(0), 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurPos(0), 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nGrowSize(FX_MEMSTREAM_BlockSize) { 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_dwFlags = 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_MEMSTREAM_TakeOver | (bConsecutive ? FX_MEMSTREAM_Consecutive : 0); 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CFX_MemoryStream(uint8_t* pBuffer, size_t nSize, FX_BOOL bTakeOver) 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : m_dwCount(1), 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nTotalSize(nSize), 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurSize(nSize), 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurPos(0), 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nGrowSize(FX_MEMSTREAM_BlockSize) { 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.Add(pBuffer); 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_dwFlags = 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~CFX_MemoryStream() override { 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_dwFlags & FX_MEMSTREAM_TakeOver) { 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int32_t i = 0; i < m_Blocks.GetSize(); i++) { 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_Free(m_Blocks[i]); 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.RemoveAll(); 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // IFX_MemoryStream: 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IFX_FileStream* Retain() override { 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_dwCount++; 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return this; 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Release() override { 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD nCount = --m_dwCount; 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (nCount) { 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch delete this; 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE GetSize() override { return (FX_FILESIZE)m_nCurSize; } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL IsEOF() override { return m_nCurPos >= (size_t)GetSize(); } 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE GetPosition() override { return (FX_FILESIZE)m_nCurPos; } 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override { 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!buffer || !size) { 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_SAFE_SIZE_T newPos = size; 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch newPos += offset; 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!newPos.IsValid() || newPos.ValueOrDefault(0) == 0 || 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch newPos.ValueOrDie() > m_nCurSize) { 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurPos = newPos.ValueOrDie(); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_dwFlags & FX_MEMSTREAM_Consecutive) { 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FXSYS_memcpy(buffer, m_Blocks[0] + (size_t)offset, size); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t nStartBlock = (size_t)offset / m_nGrowSize; 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize); 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (size) { 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t nRead = m_nGrowSize - (size_t)offset; 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (nRead > size) { 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nRead = size; 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FXSYS_memcpy(buffer, m_Blocks[(int)nStartBlock] + (size_t)offset, nRead); 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = ((uint8_t*)buffer) + nRead; 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size -= nRead; 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nStartBlock++; 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset = 0; 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t ReadBlock(void* buffer, size_t size) override { 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_nCurPos >= m_nCurSize) { 175342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch return 0; 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 177342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch size_t nRead = std::min(size, m_nCurSize - m_nCurPos); 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!ReadBlock(buffer, (int32_t)m_nCurPos, nRead)) { 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nRead; 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL WriteBlock(const void* buffer, 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_FILESIZE offset, 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t size) override { 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!buffer || !size) { 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_dwFlags & FX_MEMSTREAM_Consecutive) { 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_SAFE_SIZE_T newPos = size; 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch newPos += offset; 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!newPos.IsValid()) 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurPos = newPos.ValueOrDie(); 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_nCurPos > m_nTotalSize) { 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nTotalSize = 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize; 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_Blocks.GetSize() < 1) { 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint8_t* block = FX_Alloc(uint8_t, m_nTotalSize); 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.Add(block); 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks[0] = FX_Realloc(uint8_t, m_Blocks[0], m_nTotalSize); 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!m_Blocks[0]) { 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.RemoveAll(); 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FXSYS_memcpy(m_Blocks[0] + (size_t)offset, buffer, size); 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_nCurSize < m_nCurPos) { 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurSize = m_nCurPos; 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_SAFE_SIZE_T newPos = size; 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch newPos += offset; 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!newPos.IsValid()) { 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!ExpandBlocks(newPos.ValueOrDie())) { 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FALSE; 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurPos = newPos.ValueOrDie(); 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t nStartBlock = (size_t)offset / m_nGrowSize; 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize); 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (size) { 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t nWrite = m_nGrowSize - (size_t)offset; 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (nWrite > size) { 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nWrite = size; 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FXSYS_memcpy(m_Blocks[(int)nStartBlock] + (size_t)offset, buffer, nWrite); 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer = ((uint8_t*)buffer) + nWrite; 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size -= nWrite; 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nStartBlock++; 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset = 0; 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL Flush() override { return TRUE; } 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL IsConsecutive() const override { 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return m_dwFlags & FX_MEMSTREAM_Consecutive; 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EstimateSize(size_t nInitSize, size_t nGrowSize) override { 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_dwFlags & FX_MEMSTREAM_Consecutive) { 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_Blocks.GetSize() < 1) { 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint8_t* pBlock = 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_Alloc(uint8_t, std::max(nInitSize, static_cast<size_t>(4096))); 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.Add(pBlock); 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (m_Blocks.GetSize() < 1) { 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nGrowSize = std::max(nGrowSize, static_cast<size_t>(4096)); 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint8_t* GetBuffer() const override { 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return m_Blocks.GetSize() ? m_Blocks[0] : nullptr; 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AttachBuffer(uint8_t* pBuffer, 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t nSize, 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL bTakeOver = FALSE) override { 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) { 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.RemoveAll(); 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.Add(pBuffer); 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nTotalSize = m_nCurSize = nSize; 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurPos = 0; 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_dwFlags = 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_MEMSTREAM_Consecutive | (bTakeOver ? FX_MEMSTREAM_TakeOver : 0); 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DetachBuffer() override { 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!(m_dwFlags & FX_MEMSTREAM_Consecutive)) { 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.RemoveAll(); 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nTotalSize = m_nCurSize = m_nCurPos = 0; 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_dwFlags = FX_MEMSTREAM_TakeOver; 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CFX_ArrayTemplate<uint8_t*> m_Blocks; 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD m_dwCount; 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t m_nTotalSize; 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t m_nCurSize; 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t m_nCurPos; 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t m_nGrowSize; 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD m_dwFlags; 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL ExpandBlocks(size_t size) { 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m_nCurSize < size) { 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nCurSize = size; 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (size <= m_nTotalSize) { 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t iCount = m_Blocks.GetSize(); 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size = (size - m_nTotalSize + m_nGrowSize - 1) / m_nGrowSize; 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.SetSize(m_Blocks.GetSize() + (int32_t)size); 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (size--) { 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint8_t* pBlock = FX_Alloc(uint8_t, m_nGrowSize); 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_Blocks.SetAt(iCount++, pBlock); 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch m_nTotalSize += m_nGrowSize; 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TRUE; 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef __cplusplus 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochextern "C" { 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define MT_N 848 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define MT_M 456 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define MT_Matrix_A 0x9908b0df 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define MT_Upper_Mask 0x80000000 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define MT_Lower_Mask 0x7fffffff 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef struct _FX_MTRANDOMCONTEXT { 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch _FX_MTRANDOMCONTEXT() { 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mti = MT_N + 1; 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bHaveSeed = FALSE; 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD mti; 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_BOOL bHaveSeed; 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FX_DWORD mt[MT_N]; 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} FX_MTRANDOMCONTEXT, *FX_LPMTRANDOMCONTEXT; 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef FX_MTRANDOMCONTEXT const* FX_LPCMTRANDOMCONTEXT; 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFX_BOOL FX_GenerateCryptoRandom(FX_DWORD* pBuffer, int32_t iCount); 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef __cplusplus 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // CORE_SRC_FXCRT_EXTENSION_H_ 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch