Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sot/source/sdstor/stgstrms.hxx
Line
Count
Source
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 );
56
823k
    sal_Int32 GetMaxPage() const { return m_nMaxPage; }
57
2.51M
    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 );
81
69.3M
    void SetPos(sal_Int32 nPos, bool bValid) { m_nPos = nPos; m_bBytePosValid = bValid; }
82
    explicit StgStrm( StgIo& );
83
public:
84
    virtual ~StgStrm();
85
25.9M
    StgIo&  GetIo()     { return m_rIo;    }
86
271M
    sal_Int32   GetPos() const   { return m_nPos; }
87
261k
    sal_Int32   GetStart() const { return m_nStart; }
88
2.28M
    sal_Int32   GetSize() const  { return m_nSize;  }
89
12.4M
    sal_Int32   GetPage() const  { return m_nPage;  }
90
2.64M
    sal_Int32   GetPages() const { return ( m_nSize + m_nPageSize - 1 ) / m_nPageSize;}
91
12.3M
    short       GetOffset() const { return m_nOffset;}
92
    void        SetEntry( StgDirEntry& );
93
    virtual bool SetSize( sal_Int32 );
94
    virtual bool Pos2Page( sal_Int32 nBytePos );
95
0
    virtual sal_Int32 Read( void*, sal_Int32 )        { return 0; }
96
0
    virtual sal_Int32 Write( const void*, sal_Int32 ) { return 0; }
97
0
    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 );
125
337k
    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;
145
0
    virtual bool IsSmallStrm() const override { return true; }
146
};
147
148
class StgTmpStrm : public SvMemoryStream
149
{
150
    OUString m_aName;
151
    std::unique_ptr<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: */