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
;
37 typedef boost::unordered_map
39 sal_Int32
, rtl::Reference
< StgPage
>,
40 boost::hash
< sal_Int32
>, std::equal_to
< sal_Int32
>
43 typedef std::vector
< rtl::Reference
< StgPage
> > LRUList
;
45 sal_uLong nError
; // error code
46 sal_Int32 nPages
; // size of data area in pages
47 sal_uInt16 nRef
; // reference count
48 IndexToStgPage maDirtyPages
; // hash of all dirty pages
49 int nReplaceIdx
; // index into maLRUPages to replace next
50 LRUList maLRUPages
; // list of last few non-dirty pages.
51 short nPageSize
; // page size of the file
52 UCBStorageStream
* pStorageStream
; // holds reference to UCB storage stream
54 void Erase( const rtl::Reference
< StgPage
>& ); // delete a cache element
55 rtl::Reference
< StgPage
> Create( sal_Int32
); // create a cached page
57 SvStream
* pStrm
; // physical stream
58 sal_Bool bMyStream
; // sal_True: delete stream in dtor
59 sal_Bool bFile
; // sal_True: file stream
60 sal_Int32
Page2Pos( sal_Int32
); // page address --> file position
64 void IncRef() { nRef
++; }
65 sal_uInt16
DecRef() { return --nRef
; }
66 void SetPhysPageSize( short );
67 sal_Int32
GetPhysPages() { return nPages
; }
68 short GetPhysPageSize() { return nPageSize
; }
69 SvStream
* GetStrm() { return pStrm
; }
70 void SetStrm( SvStream
*, sal_Bool
);
71 void SetStrm( UCBStorageStream
* );
72 sal_Bool
IsWritable() { return ( pStrm
&& pStrm
->IsWritable() ); }
73 sal_Bool
Good() { return sal_Bool( nError
== SVSTREAM_OK
); }
74 sal_Bool
Bad() { return sal_Bool( nError
!= SVSTREAM_OK
); }
75 sal_uLong
GetError() { return nError
; }
76 void MoveError( StorageBase
& );
77 void SetError( sal_uLong
);
79 sal_Bool
Open( const String
& rName
, StreamMode
);
81 sal_Bool
Read ( sal_Int32 nPage
, void* pBuf
, sal_Int32 nPages
);
82 sal_Bool
Write ( sal_Int32 nPage
, void* pBuf
, sal_Int32 nPages
);
84 // two routines for accessing FAT pages
85 // Assume that the data is a FAT page and get/put FAT data.
86 void SetToPage ( const rtl::Reference
< StgPage
> xPage
, short nOff
, sal_Int32 nVal
);
87 inline sal_Int32
GetFromPage ( const rtl::Reference
< StgPage
> xPage
, short nOff
);
88 void SetDirty ( const rtl::Reference
< StgPage
> &xPage
);
89 sal_Bool
SetSize( sal_Int32 nPages
);
90 rtl::Reference
< StgPage
> Find( sal_Int32
); // find a cached page
91 rtl::Reference
< StgPage
> Get( sal_Int32
, sal_Bool
); // get a cached page
92 rtl::Reference
< StgPage
> Copy( sal_Int32
, sal_Int32
=STG_FREE
); // copy a page
93 sal_Bool
Commit(); // flush all pages
94 void Clear(); // clear the cache
97 class StgPage
: public rtl::IReference
, private boost::noncopyable
{
98 sal_uInt32 mnRefCount
;
99 const sal_Int32 mnPage
; // page index
100 sal_uInt8
* mpData
; // nSize bytes
101 short mnSize
; // size of this page
102 StgPage( short nData
, sal_Int32 nPage
);
105 static rtl::Reference
< StgPage
> Create( short nData
, sal_Int32 nPage
);
107 sal_Int32
GetPage() { return mnPage
; }
108 void* GetData() { return mpData
; }
109 short GetSize() { return mnSize
; }
112 virtual oslInterlockedCount SAL_CALL
acquire()
116 virtual oslInterlockedCount SAL_CALL
release()
118 if ( --mnRefCount
== 0)
125 static bool IsPageGreater( const StgPage
*pA
, const StgPage
*pB
);
128 inline sal_Int32
StgCache::GetFromPage ( const rtl::Reference
< StgPage
> xPage
, short nOff
)
130 if( ( nOff
>= (short) ( xPage
->GetSize() / sizeof( sal_Int32
) ) ) || nOff
< 0 )
132 sal_Int32 n
= ((sal_Int32
*) xPage
->GetData() )[ nOff
];
134 return OSL_SWAPDWORD(n
);
142 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */