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 .
23 #include <osl/endian.h>
24 #include <rtl/ref.hxx>
25 #include <tools/solar.h>
26 #include <tools/stream.hxx>
27 #include <stgelem.hxx>
28 #include <boost/noncopyable.hpp>
29 #include <boost/unordered_map.hpp>
31 class UCBStorageStream
;
38 typedef boost::unordered_map
40 sal_Int32
, rtl::Reference
< StgPage
>,
41 boost::hash
< sal_Int32
>, std::equal_to
< sal_Int32
>
44 typedef std::vector
< rtl::Reference
< StgPage
> > LRUList
;
46 sal_uLong nError
; // error code
47 sal_Int32 nPages
; // size of data area in pages
48 sal_uInt16 nRef
; // reference count
49 IndexToStgPage maDirtyPages
; // hash of all dirty pages
50 int nReplaceIdx
; // index into maLRUPages to replace next
51 LRUList maLRUPages
; // list of last few non-dirty pages.
52 short nPageSize
; // page size of the file
53 UCBStorageStream
* 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
58 SvStream
* pStrm
; // physical stream
59 bool bMyStream
; // true: delete stream in dtor
60 bool bFile
; // true: file stream
61 sal_Int32
Page2Pos( sal_Int32
); // page address --> file position
65 void IncRef() { nRef
++; }
66 sal_uInt16
DecRef() { return --nRef
; }
67 void SetPhysPageSize( short );
68 sal_Int32
GetPhysPages() { return nPages
; }
69 short GetPhysPageSize() { return nPageSize
; }
70 SvStream
* GetStrm() { return pStrm
; }
71 void SetStrm( SvStream
*, bool );
72 void SetStrm( UCBStorageStream
* );
73 bool IsWritable() { return ( pStrm
&& pStrm
->IsWritable() ); }
74 bool Good() { return nError
== SVSTREAM_OK
; }
75 bool Bad() { return nError
!= SVSTREAM_OK
; }
76 sal_uLong
GetError() { return nError
; }
77 void MoveError( StorageBase
& );
78 void SetError( sal_uLong
);
80 bool Open( const OUString
& rName
, StreamMode
);
82 bool Read( sal_Int32 nPage
, void* pBuf
, sal_Int32 nPages
);
83 bool Write( sal_Int32 nPage
, void* pBuf
, sal_Int32 nPages
);
85 // two routines for accessing FAT pages
86 // Assume that the data is a FAT page and get/put FAT data.
87 void SetToPage ( const rtl::Reference
< StgPage
> xPage
, short nOff
, sal_Int32 nVal
);
88 inline sal_Int32
GetFromPage ( const rtl::Reference
< StgPage
> xPage
, short nOff
);
89 void SetDirty ( const rtl::Reference
< StgPage
> &xPage
);
90 bool SetSize( sal_Int32 nPages
);
91 rtl::Reference
< StgPage
> Find( sal_Int32
); // find a cached page
92 rtl::Reference
< StgPage
> Get( sal_Int32
, bool ); // get a cached page
93 rtl::Reference
< StgPage
> Copy( sal_Int32
, sal_Int32
=STG_FREE
); // copy a page
94 bool Commit(); // flush all pages
95 void Clear(); // clear the cache
98 class StgPage
: public rtl::IReference
, private boost::noncopyable
{
99 sal_uInt32 mnRefCount
;
100 const sal_Int32 mnPage
; // page index
101 sal_uInt8
* mpData
; // nSize bytes
102 short mnSize
; // size of this page
103 StgPage( short nData
, sal_Int32 nPage
);
106 static rtl::Reference
< StgPage
> Create( short nData
, sal_Int32 nPage
);
108 sal_Int32
GetPage() { return mnPage
; }
109 void* GetData() { return mpData
; }
110 short GetSize() { return mnSize
; }
113 virtual oslInterlockedCount SAL_CALL
acquire()
117 virtual oslInterlockedCount SAL_CALL
release()
119 if ( --mnRefCount
== 0)
126 static bool IsPageGreater( const StgPage
*pA
, const StgPage
*pB
);
129 inline sal_Int32
StgCache::GetFromPage ( const rtl::Reference
< StgPage
> xPage
, short nOff
)
131 if( ( nOff
>= (short) ( xPage
->GetSize() / sizeof( sal_Int32
) ) ) || nOff
< 0 )
133 sal_Int32 n
= ((sal_Int32
*) xPage
->GetData() )[ nOff
];
135 return OSL_SWAPDWORD(n
);
143 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */