1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #ifndef INCLUDED_SOT_SOURCE_SDSTOR_STGSTRMS_HXX 21 #define INCLUDED_SOT_SOURCE_SDSTOR_STGSTRMS_HXX 22 23 #include <tools/stream.hxx> 24 #include <o3tl/sorted_vector.hxx> 25 #include <rtl/ref.hxx> 26 #include <vector> 27 #include <memory> 28 29 class StgIo; 30 class StgStrm; 31 class StgPage; 32 class StgDirEntry; 33 34 // The FAT class performs FAT operations on an underlying storage stream. 35 // This stream is either the physical FAT stream (bPhys == true ) or a normal 36 // storage stream, which then holds the FAT for small data allocations. 37 38 class StgFAT 39 { // FAT allocator 40 StgStrm& m_rStrm; // underlying stream 41 sal_Int32 m_nMaxPage; // highest page allocated so far 42 short m_nPageSize; // physical page size 43 short m_nEntries; // FAT entries per page 44 short m_nOffset; // current offset within page 45 sal_Int32 m_nLimit; // search limit recommendation 46 bool m_bPhys; // true: physical FAT 47 rtl::Reference< StgPage > GetPhysPage( sal_Int32 nPage ); 48 bool MakeChain( sal_Int32 nStart, sal_Int32 nPages ); 49 bool InitNew( sal_Int32 nPage1 ); 50 public: 51 StgFAT( StgStrm& rStrm, bool bMark ); 52 sal_Int32 FindBlock( sal_Int32& nPages ); 53 sal_Int32 GetNextPage( sal_Int32 nPg ); 54 sal_Int32 AllocPages( sal_Int32 nStart, sal_Int32 nPages ); 55 bool FreePages( sal_Int32 nStart, bool bAll ); GetMaxPage() const56 sal_Int32 GetMaxPage() const { return m_nMaxPage; } SetLimit(sal_Int32 n)57 void SetLimit( sal_Int32 n ) { m_nLimit = n; } 58 }; 59 60 // The base stream class provides basic functionality for seeking 61 // and accessing the data on a physical basis. It uses the built-in 62 // FAT class for the page allocations. 63 64 class StgStrm { // base class for all streams 65 private: 66 sal_Int32 m_nPos; // current byte position 67 bool m_bBytePosValid; // what Pos2Page returns for m_nPos 68 protected: 69 StgIo& m_rIo; // I/O system 70 std::unique_ptr<StgFAT> m_pFat; // FAT stream for allocations 71 StgDirEntry* m_pEntry; // dir entry (for ownership) 72 sal_Int32 m_nStart; // 1st data page 73 sal_Int32 m_nSize; // stream size in bytes 74 sal_Int32 m_nPage; // current logical page 75 short m_nOffset; // offset into current page 76 short m_nPageSize; // logical page size 77 std::vector<sal_Int32> m_aPagesCache; 78 o3tl::sorted_vector<sal_Int32> m_aUsedPageNumbers; 79 sal_Int32 scanBuildPageChainCache(); 80 bool Copy( sal_Int32 nFrom, sal_Int32 nBytes ); SetPos(sal_Int32 nPos,bool bValid)81 void SetPos(sal_Int32 nPos, bool bValid) { m_nPos = nPos; m_bBytePosValid = bValid; } 82 explicit StgStrm( StgIo& ); 83 public: 84 virtual ~StgStrm(); GetIo()85 StgIo& GetIo() { return m_rIo; } GetPos() const86 sal_Int32 GetPos() const { return m_nPos; } GetStart() const87 sal_Int32 GetStart() const { return m_nStart; } GetSize() const88 sal_Int32 GetSize() const { return m_nSize; } GetPage() const89 sal_Int32 GetPage() const { return m_nPage; } GetPages() const90 sal_Int32 GetPages() const { return ( m_nSize + m_nPageSize - 1 ) / m_nPageSize;} GetOffset() const91 short GetOffset() const { return m_nOffset;} 92 void SetEntry( StgDirEntry& ); 93 virtual bool SetSize( sal_Int32 ); 94 virtual bool Pos2Page( sal_Int32 nBytePos ); Read(void *,sal_Int32)95 virtual sal_Int32 Read( void*, sal_Int32 ) { return 0; } Write(const void *,sal_Int32)96 virtual sal_Int32 Write( const void*, sal_Int32 ) { return 0; } IsSmallStrm() const97 virtual bool IsSmallStrm() const { return false; } 98 }; 99 100 // The FAT stream class provides physical access to the master FAT. 101 // Since this access is implemented as a StgStrm, we can use the 102 // FAT allocator. 103 104 class StgFATStrm : public StgStrm { // the master FAT stream 105 virtual bool Pos2Page( sal_Int32 nBytePos ) override; 106 bool SetPage( short, sal_Int32 ); 107 public: 108 explicit StgFATStrm(StgIo&, sal_Int32 nFatStrmSize); 109 using StgStrm::GetPage; 110 sal_Int32 GetPage(sal_Int32, bool, sal_uInt16 *pnMasterAlloc = nullptr); 111 virtual bool SetSize( sal_Int32 ) override; 112 }; 113 114 // The stream has a size increment which normally is 1, but which can be 115 // set to any value is you want the size to be incremented by certain values. 116 117 class StgDataStrm : public StgStrm // a physical data stream 118 { 119 short m_nIncr; // size adjust increment 120 void Init( sal_Int32 nBgn, sal_Int32 nLen ); 121 public: 122 StgDataStrm( StgIo&, sal_Int32 nBgn, sal_Int32 nLen=-1 ); 123 StgDataStrm( StgIo&, StgDirEntry& ); 124 void* GetPtr( sal_Int32 nPos, bool bDirty ); SetIncrement(short n)125 void SetIncrement( short n ) { m_nIncr = n ; } 126 virtual bool SetSize( sal_Int32 ) override; 127 virtual sal_Int32 Read( void*, sal_Int32 ) override; 128 virtual sal_Int32 Write( const void*, sal_Int32 ) override; 129 }; 130 131 // The small stream class provides access to streams with a size < 4096 bytes. 132 // This stream is a StgStream containing small pages. The FAT for this stream 133 // is also a StgStream. The start of the FAT is in the header at DataRootPage, 134 // the stream itself is pointed to by the root entry (it holds start & size). 135 136 class StgSmallStrm : public StgStrm // a logical data stream 137 { 138 StgStrm* m_pData; // the data stream 139 void Init( sal_Int32 nBgn, sal_Int32 nLen ); 140 public: 141 StgSmallStrm( StgIo&, sal_Int32 nBgn ); 142 StgSmallStrm( StgIo&, StgDirEntry& ); 143 virtual sal_Int32 Read( void*, sal_Int32 ) override; 144 virtual sal_Int32 Write( const void*, sal_Int32 ) override; IsSmallStrm() const145 virtual bool IsSmallStrm() const override { return true; } 146 }; 147 148 class StgTmpStrm : public SvMemoryStream 149 { 150 OUString m_aName; 151 SvFileStream* m_pStrm; 152 using SvMemoryStream::GetData; 153 virtual std::size_t GetData( void* pData, std::size_t nSize ) override; 154 virtual std::size_t PutData( const void* pData, std::size_t nSize ) override; 155 virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override; 156 virtual void FlushData() override; 157 158 public: 159 explicit StgTmpStrm( sal_uInt64=16 ); 160 virtual ~StgTmpStrm() override; 161 bool Copy( StgTmpStrm& ); 162 virtual void SetSize( sal_uInt64 ) override; 163 sal_uInt64 GetSize() const; 164 }; 165 166 #endif 167 168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 169