1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SOT_SOURCE_SDSTOR_STGCACHE_HXX
21 #define INCLUDED_SOT_SOURCE_SDSTOR_STGCACHE_HXX
23 #include <o3tl/safeint.hxx>
24 #include <osl/endian.h>
25 #include <rtl/ref.hxx>
26 #include <tools/stream.hxx>
27 #include "stgelem.hxx"
28 #include <salhelper/simplereferenceobject.hxx>
31 #include <unordered_map>
33 class UCBStorageStream
;
39 typedef std::unordered_map
41 sal_Int32
, rtl::Reference
< StgPage
>
44 typedef std::vector
< rtl::Reference
< StgPage
> > LRUList
;
46 ErrCode m_nError
; // error code
47 sal_Int32 m_nPages
; // size of data area in pages
48 sal_uInt16 m_nRef
; // reference count
49 IndexToStgPage maDirtyPages
; // hash of all dirty pages
50 int m_nReplaceIdx
; // index into maLRUPages to replace next
51 LRUList maLRUPages
; // list of last few non-dirty pages.
52 short m_nPageSize
; // page size of the file
53 UCBStorageStream
* m_pStorageStream
; // holds reference to UCB storage stream
55 void Erase( const rtl::Reference
< StgPage
>& ); // delete a cache element
56 rtl::Reference
< StgPage
> Create( sal_Int32
); // create a cached page
57 SvStream
* m_pStrm
; // physical stream
58 bool m_bMyStream
; // true: delete stream in dtor
60 bool m_bFile
; // true: file stream
61 sal_Int32
Page2Pos( sal_Int32
) const; // page address --> file position
65 void IncRef() { m_nRef
++; }
66 sal_uInt16
DecRef() { return --m_nRef
; }
67 void SetPhysPageSize( short );
68 sal_Int32
GetPhysPages() const { return m_nPages
; }
69 short GetPhysPageSize() const { return m_nPageSize
; }
70 SvStream
* GetStrm() { return m_pStrm
; }
71 void SetStrm( SvStream
*, bool );
72 void SetStrm( UCBStorageStream
* );
73 bool Good() const { return m_nError
== ERRCODE_NONE
; }
74 ErrCode
const & GetError() const { return m_nError
; }
75 void MoveError( StorageBase
const & );
76 void SetError( ErrCode
);
78 bool Open( const OUString
& rName
, StreamMode
);
80 bool Read( sal_Int32 nPage
, void* pBuf
);
81 bool Write( sal_Int32 nPage
, void const * pBuf
);
83 // two routines for accessing FAT pages
84 // Assume that the data is a FAT page and get/put FAT data.
85 void SetToPage ( const rtl::Reference
< StgPage
>& rPage
, short nOff
, sal_Int32 nVal
);
86 static inline sal_Int32
GetFromPage ( const rtl::Reference
< StgPage
>& rPage
, short nOff
);
87 void SetDirty ( const rtl::Reference
< StgPage
> &rPage
);
88 bool SetSize( sal_Int32 nPages
);
89 rtl::Reference
< StgPage
> Find( sal_Int32
); // find a cached page
90 rtl::Reference
< StgPage
> Get( sal_Int32
, bool ); // get a cached page
91 rtl::Reference
< StgPage
> Copy( sal_Int32
, sal_Int32
=STG_FREE
); // copy a page
92 bool Commit(); // flush all pages
93 void Clear(); // clear the cache
96 class StgPage
: public salhelper::SimpleReferenceObject
98 const sal_Int32 mnPage
; // page index
99 std::unique_ptr
<sal_uInt8
[]>
100 mpData
; // nSize bytes
101 short mnSize
; // size of this page
102 StgPage( short nData
, sal_Int32 nPage
);
103 virtual ~StgPage() override
;
105 StgPage(const StgPage
&) = delete;
106 StgPage
& operator=(const StgPage
&) = delete;
107 static rtl::Reference
< StgPage
> Create( short nData
, sal_Int32 nPage
);
109 sal_Int32
GetPage() const { return mnPage
; }
110 void* GetData() { return mpData
.get(); }
111 short GetSize() const { return mnSize
; }
114 static bool IsPageGreater( const StgPage
*pA
, const StgPage
*pB
);
117 inline sal_Int32
StgCache::GetFromPage ( const rtl::Reference
< StgPage
>& rPage
, short nOff
)
119 if( nOff
< 0 || ( o3tl::make_unsigned(nOff
) >= rPage
->GetSize() / sizeof( sal_Int32
) ) )
121 sal_Int32 n
= static_cast<sal_Int32
*>(rPage
->GetData())[ nOff
];
123 return OSL_SWAPDWORD(n
);
131 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */