xref: /aoo41x/main/store/source/lockbyte.cxx (revision 73d9b18a)
1*73d9b18aSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*73d9b18aSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*73d9b18aSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*73d9b18aSAndrew Rist  * distributed with this work for additional information
6*73d9b18aSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*73d9b18aSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*73d9b18aSAndrew Rist  * "License"); you may not use this file except in compliance
9*73d9b18aSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*73d9b18aSAndrew Rist  *
11*73d9b18aSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*73d9b18aSAndrew Rist  *
13*73d9b18aSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*73d9b18aSAndrew Rist  * software distributed under the License is distributed on an
15*73d9b18aSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*73d9b18aSAndrew Rist  * KIND, either express or implied.  See the License for the
17*73d9b18aSAndrew Rist  * specific language governing permissions and limitations
18*73d9b18aSAndrew Rist  * under the License.
19*73d9b18aSAndrew Rist  *
20*73d9b18aSAndrew Rist  *************************************************************/
21*73d9b18aSAndrew Rist 
22*73d9b18aSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_store.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "lockbyte.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "sal/types.h"
30cdf0e10cSrcweir #include "osl/diagnose.h"
31cdf0e10cSrcweir #include "osl/file.h"
32cdf0e10cSrcweir #include "osl/process.h"
33cdf0e10cSrcweir #include "rtl/alloc.h"
34cdf0e10cSrcweir #include "rtl/ustring.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "object.hxx"
37cdf0e10cSrcweir #include "storbase.hxx"
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #ifndef INCLUDED_STRING_H
40cdf0e10cSrcweir #include <string.h>
41cdf0e10cSrcweir #define INCLUDED_STRING_H
42cdf0e10cSrcweir #endif
43cdf0e10cSrcweir 
44cdf0e10cSrcweir using namespace store;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir /*========================================================================
47cdf0e10cSrcweir  *
48cdf0e10cSrcweir  * ILockBytes (non-virtual interface) implementation.
49cdf0e10cSrcweir  *
50cdf0e10cSrcweir  *======================================================================*/
51cdf0e10cSrcweir 
initialize(rtl::Reference<PageData::Allocator> & rxAllocator,sal_uInt16 nPageSize)52cdf0e10cSrcweir storeError ILockBytes::initialize (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize)
53cdf0e10cSrcweir {
54cdf0e10cSrcweir     OSL_PRECOND((STORE_MINIMUM_PAGESIZE <= nPageSize) && (nPageSize <= STORE_MAXIMUM_PAGESIZE), "invalid PageSize");
55cdf0e10cSrcweir     return initialize_Impl (rxAllocator, nPageSize);
56cdf0e10cSrcweir }
57cdf0e10cSrcweir 
readPageAt(PageHolder & rPage,sal_uInt32 nOffset)58cdf0e10cSrcweir storeError ILockBytes::readPageAt (PageHolder & rPage, sal_uInt32 nOffset)
59cdf0e10cSrcweir {
60cdf0e10cSrcweir     OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::readPageAt(): invalid Offset");
61cdf0e10cSrcweir     if (nOffset == STORE_PAGE_NULL)
62cdf0e10cSrcweir         return store_E_CantSeek;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir     return readPageAt_Impl (rPage, nOffset);
65cdf0e10cSrcweir }
66cdf0e10cSrcweir 
writePageAt(PageHolder const & rPage,sal_uInt32 nOffset)67cdf0e10cSrcweir storeError ILockBytes::writePageAt (PageHolder const & rPage, sal_uInt32 nOffset)
68cdf0e10cSrcweir {
69cdf0e10cSrcweir     // [SECURITY:ValInput]
70cdf0e10cSrcweir     PageData const * pagedata = rPage.get();
71cdf0e10cSrcweir     OSL_PRECOND(!(pagedata == 0), "store::ILockBytes::writePageAt(): invalid Page");
72cdf0e10cSrcweir     if (pagedata == 0)
73cdf0e10cSrcweir         return store_E_InvalidParameter;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir     sal_uInt32 const offset = pagedata->location();
76cdf0e10cSrcweir     OSL_PRECOND(!(nOffset != offset), "store::ILockBytes::writePageAt(): inconsistent Offset");
77cdf0e10cSrcweir     if (nOffset != offset)
78cdf0e10cSrcweir         return store_E_InvalidParameter;
79cdf0e10cSrcweir 
80cdf0e10cSrcweir     OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::writePageAt(): invalid Offset");
81cdf0e10cSrcweir     if (nOffset == STORE_PAGE_NULL)
82cdf0e10cSrcweir         return store_E_CantSeek;
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     return writePageAt_Impl (rPage, nOffset);
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
readAt(sal_uInt32 nOffset,void * pBuffer,sal_uInt32 nBytes)87cdf0e10cSrcweir storeError ILockBytes::readAt (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     // [SECURITY:ValInput]
90cdf0e10cSrcweir     sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer);
91cdf0e10cSrcweir     if (!(dst_lo != 0))
92cdf0e10cSrcweir         return store_E_InvalidParameter;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir     sal_uInt8 * dst_hi = dst_lo + nBytes;
95cdf0e10cSrcweir     if (!(dst_lo < dst_hi))
96cdf0e10cSrcweir         return (dst_lo > dst_hi) ? store_E_InvalidParameter : store_E_None;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::readAt(): invalid Offset");
99cdf0e10cSrcweir     if (nOffset == STORE_PAGE_NULL)
100cdf0e10cSrcweir         return store_E_CantSeek;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     sal_uInt64 const src_size = nOffset + nBytes;
103cdf0e10cSrcweir     if (src_size > SAL_MAX_UINT32)
104cdf0e10cSrcweir         return store_E_CantSeek;
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     return readAt_Impl (nOffset, dst_lo, (dst_hi - dst_lo));
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
writeAt(sal_uInt32 nOffset,void const * pBuffer,sal_uInt32 nBytes)109cdf0e10cSrcweir storeError ILockBytes::writeAt (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     // [SECURITY:ValInput]
112cdf0e10cSrcweir     sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer);
113cdf0e10cSrcweir     if (!(src_lo != 0))
114cdf0e10cSrcweir         return store_E_InvalidParameter;
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     sal_uInt8 const * src_hi = src_lo + nBytes;
117cdf0e10cSrcweir     if (!(src_lo < src_hi))
118cdf0e10cSrcweir         return (src_lo > src_hi) ? store_E_InvalidParameter : store_E_None;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::writeAt(): invalid Offset");
121cdf0e10cSrcweir     if (nOffset == STORE_PAGE_NULL)
122cdf0e10cSrcweir         return store_E_CantSeek;
123cdf0e10cSrcweir 
124cdf0e10cSrcweir     sal_uInt64 const dst_size = nOffset + nBytes;
125cdf0e10cSrcweir     if (dst_size > SAL_MAX_UINT32)
126cdf0e10cSrcweir         return store_E_CantSeek;
127cdf0e10cSrcweir 
128cdf0e10cSrcweir     return writeAt_Impl (nOffset, src_lo, (src_hi - src_lo));
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
getSize(sal_uInt32 & rnSize)131cdf0e10cSrcweir storeError ILockBytes::getSize (sal_uInt32 & rnSize)
132cdf0e10cSrcweir {
133cdf0e10cSrcweir     rnSize = 0;
134cdf0e10cSrcweir     return getSize_Impl (rnSize);
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
setSize(sal_uInt32 nSize)137cdf0e10cSrcweir storeError ILockBytes::setSize (sal_uInt32 nSize)
138cdf0e10cSrcweir {
139cdf0e10cSrcweir     return setSize_Impl (nSize);
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
flush()142cdf0e10cSrcweir storeError ILockBytes::flush()
143cdf0e10cSrcweir {
144cdf0e10cSrcweir     return flush_Impl();
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir /*========================================================================
148cdf0e10cSrcweir  *
149cdf0e10cSrcweir  * FileLockBytes implementation.
150cdf0e10cSrcweir  *
151cdf0e10cSrcweir  *======================================================================*/
152cdf0e10cSrcweir namespace store
153cdf0e10cSrcweir {
154cdf0e10cSrcweir 
155cdf0e10cSrcweir struct FileHandle
156cdf0e10cSrcweir {
157cdf0e10cSrcweir     oslFileHandle m_handle;
158cdf0e10cSrcweir 
FileHandlestore::FileHandle159cdf0e10cSrcweir     FileHandle() : m_handle(0) {}
160cdf0e10cSrcweir 
operator !=store::FileHandle161cdf0e10cSrcweir     bool operator != (FileHandle const & rhs)
162cdf0e10cSrcweir     {
163cdf0e10cSrcweir         return (m_handle != rhs.m_handle);
164cdf0e10cSrcweir     }
165cdf0e10cSrcweir 
errorFromNativestore::FileHandle166cdf0e10cSrcweir     static storeError errorFromNative (oslFileError eErrno)
167cdf0e10cSrcweir     {
168cdf0e10cSrcweir         switch (eErrno)
169cdf0e10cSrcweir         {
170cdf0e10cSrcweir         case osl_File_E_None:
171cdf0e10cSrcweir             return store_E_None;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir         case osl_File_E_NOENT:
174cdf0e10cSrcweir             return store_E_NotExists;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir         case osl_File_E_ACCES:
177cdf0e10cSrcweir         case osl_File_E_PERM:
178cdf0e10cSrcweir             return store_E_AccessViolation;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir         case osl_File_E_AGAIN:
181cdf0e10cSrcweir         case osl_File_E_DEADLK:
182cdf0e10cSrcweir             return store_E_LockingViolation;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir         case osl_File_E_BADF:
185cdf0e10cSrcweir             return store_E_InvalidHandle;
186cdf0e10cSrcweir 
187cdf0e10cSrcweir         case osl_File_E_INVAL:
188cdf0e10cSrcweir             return store_E_InvalidParameter;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         case osl_File_E_NOMEM:
191cdf0e10cSrcweir             return store_E_OutOfMemory;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir         case osl_File_E_NOSPC:
194cdf0e10cSrcweir             return store_E_OutOfSpace;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         case osl_File_E_OVERFLOW:
197cdf0e10cSrcweir             return store_E_CantSeek;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir         default:
200cdf0e10cSrcweir             return store_E_Unknown;
201cdf0e10cSrcweir         }
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir 
modeToNativestore::FileHandle204cdf0e10cSrcweir     static sal_uInt32 modeToNative (storeAccessMode eAccessMode)
205cdf0e10cSrcweir     {
206cdf0e10cSrcweir         sal_uInt32 nFlags = 0;
207cdf0e10cSrcweir         switch (eAccessMode)
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir         case store_AccessCreate:
210cdf0e10cSrcweir         case store_AccessReadCreate:
211cdf0e10cSrcweir             nFlags |= osl_File_OpenFlag_Create;
212cdf0e10cSrcweir             // fall through
213cdf0e10cSrcweir         case store_AccessReadWrite:
214cdf0e10cSrcweir             nFlags |= osl_File_OpenFlag_Write;
215cdf0e10cSrcweir             // fall through
216cdf0e10cSrcweir         case store_AccessReadOnly:
217cdf0e10cSrcweir             nFlags |= osl_File_OpenFlag_Read;
218cdf0e10cSrcweir             break;
219cdf0e10cSrcweir         default:
220cdf0e10cSrcweir             OSL_PRECOND(0, "store::FileHandle: unknown storeAccessMode");
221cdf0e10cSrcweir         }
222cdf0e10cSrcweir         return nFlags;
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir 
initializestore::FileHandle225cdf0e10cSrcweir     storeError initialize (rtl_uString * pFilename, storeAccessMode eAccessMode)
226cdf0e10cSrcweir     {
227cdf0e10cSrcweir         // Verify arguments.
228cdf0e10cSrcweir         sal_uInt32 nFlags = modeToNative (eAccessMode);
229cdf0e10cSrcweir         if (!pFilename || !nFlags)
230cdf0e10cSrcweir             return store_E_InvalidParameter;
231cdf0e10cSrcweir 
232cdf0e10cSrcweir         // Convert into FileUrl.
233cdf0e10cSrcweir         rtl::OUString aFileUrl;
234cdf0e10cSrcweir         if (osl_getFileURLFromSystemPath (pFilename, &(aFileUrl.pData)) != osl_File_E_None)
235cdf0e10cSrcweir         {
236cdf0e10cSrcweir             // Not system path. Assume file url.
237cdf0e10cSrcweir             rtl_uString_assign (&(aFileUrl.pData), pFilename);
238cdf0e10cSrcweir         }
239cdf0e10cSrcweir 		if (aFileUrl.compareToAscii("file://", 7) != 0)
240cdf0e10cSrcweir 		{
241cdf0e10cSrcweir 			// Not file url. Assume relative path.
242cdf0e10cSrcweir 			rtl::OUString aCwdUrl;
243cdf0e10cSrcweir 			(void) osl_getProcessWorkingDir (&(aCwdUrl.pData));
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 			// Absolute file url.
246cdf0e10cSrcweir 			(void) osl_getAbsoluteFileURL (aCwdUrl.pData, aFileUrl.pData, &(aFileUrl.pData));
247cdf0e10cSrcweir 		}
248cdf0e10cSrcweir 
249cdf0e10cSrcweir         // Acquire handle.
250cdf0e10cSrcweir         oslFileError result = osl_openFile (aFileUrl.pData, &m_handle, nFlags);
251cdf0e10cSrcweir         if (result == osl_File_E_EXIST)
252cdf0e10cSrcweir         {
253cdf0e10cSrcweir             // Already existing (O_CREAT | O_EXCL).
254cdf0e10cSrcweir             result = osl_openFile (aFileUrl.pData, &m_handle, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write);
255cdf0e10cSrcweir             if ((result == osl_File_E_None) && (eAccessMode == store_AccessCreate))
256cdf0e10cSrcweir             {
257cdf0e10cSrcweir                 // Truncate existing file.
258cdf0e10cSrcweir                 result = osl_setFileSize (m_handle, 0);
259cdf0e10cSrcweir             }
260cdf0e10cSrcweir         }
261cdf0e10cSrcweir         if (result != osl_File_E_None)
262cdf0e10cSrcweir             return errorFromNative(result);
263cdf0e10cSrcweir         return store_E_None;
264cdf0e10cSrcweir     }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     /** @see FileLockBytes destructor
267cdf0e10cSrcweir      */
closeFilestore::FileHandle268cdf0e10cSrcweir     static void closeFile (oslFileHandle hFile)
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir         (void) osl_closeFile (hFile);
271cdf0e10cSrcweir     }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     /** @see ResourceHolder<T>::destructor_type
274cdf0e10cSrcweir      */
275cdf0e10cSrcweir     struct CloseFile
276cdf0e10cSrcweir     {
operator ()store::FileHandle::CloseFile277cdf0e10cSrcweir         void operator()(FileHandle & rFile) const
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             // Release handle.
280cdf0e10cSrcweir             closeFile (rFile.m_handle);
281cdf0e10cSrcweir             rFile.m_handle = 0;
282cdf0e10cSrcweir         }
283cdf0e10cSrcweir     };
284cdf0e10cSrcweir     typedef CloseFile destructor_type;
285cdf0e10cSrcweir };
286cdf0e10cSrcweir 
287cdf0e10cSrcweir class FileLockBytes :
288cdf0e10cSrcweir     public store::OStoreObject,
289cdf0e10cSrcweir     public store::ILockBytes
290cdf0e10cSrcweir {
291cdf0e10cSrcweir     /** Representation.
292cdf0e10cSrcweir      */
293cdf0e10cSrcweir     oslFileHandle                         m_hFile;
294cdf0e10cSrcweir     sal_uInt32                            m_nSize;
295cdf0e10cSrcweir     rtl::Reference< PageData::Allocator > m_xAllocator;
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     storeError initSize_Impl (sal_uInt32 & rnSize);
298cdf0e10cSrcweir 
299cdf0e10cSrcweir     /** ILockBytes implementation.
300cdf0e10cSrcweir      */
301cdf0e10cSrcweir     virtual storeError initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
302cdf0e10cSrcweir 
303cdf0e10cSrcweir     virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
304cdf0e10cSrcweir     virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
305cdf0e10cSrcweir 
306cdf0e10cSrcweir     virtual storeError readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
307cdf0e10cSrcweir     virtual storeError writeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     virtual storeError getSize_Impl (sal_uInt32 & rnSize);
310cdf0e10cSrcweir     virtual storeError setSize_Impl (sal_uInt32 nSize);
311cdf0e10cSrcweir 
312cdf0e10cSrcweir     virtual storeError flush_Impl();
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     /** Not implemented.
315cdf0e10cSrcweir      */
316cdf0e10cSrcweir     FileLockBytes (FileLockBytes const &);
317cdf0e10cSrcweir     FileLockBytes & operator= (FileLockBytes const &);
318cdf0e10cSrcweir 
319cdf0e10cSrcweir public:
320cdf0e10cSrcweir     /** Construction.
321cdf0e10cSrcweir      */
322cdf0e10cSrcweir     explicit FileLockBytes (FileHandle & rFile);
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     /** Delegate multiple inherited IReference.
325cdf0e10cSrcweir      */
326cdf0e10cSrcweir     virtual oslInterlockedCount SAL_CALL acquire();
327cdf0e10cSrcweir     virtual oslInterlockedCount SAL_CALL release();
328cdf0e10cSrcweir 
329cdf0e10cSrcweir protected:
330cdf0e10cSrcweir     /** Destruction.
331cdf0e10cSrcweir      */
332cdf0e10cSrcweir     virtual ~FileLockBytes();
333cdf0e10cSrcweir };
334cdf0e10cSrcweir 
335cdf0e10cSrcweir } // namespace store
336cdf0e10cSrcweir 
FileLockBytes(FileHandle & rFile)337cdf0e10cSrcweir FileLockBytes::FileLockBytes (FileHandle & rFile)
338cdf0e10cSrcweir     : m_hFile (rFile.m_handle), m_nSize (SAL_MAX_UINT32), m_xAllocator()
339cdf0e10cSrcweir {
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
~FileLockBytes()342cdf0e10cSrcweir FileLockBytes::~FileLockBytes()
343cdf0e10cSrcweir {
344cdf0e10cSrcweir     FileHandle::closeFile (m_hFile);
345cdf0e10cSrcweir }
346cdf0e10cSrcweir 
acquire()347cdf0e10cSrcweir oslInterlockedCount SAL_CALL FileLockBytes::acquire()
348cdf0e10cSrcweir {
349cdf0e10cSrcweir     return OStoreObject::acquire();
350cdf0e10cSrcweir }
351cdf0e10cSrcweir 
release()352cdf0e10cSrcweir oslInterlockedCount SAL_CALL FileLockBytes::release()
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     return OStoreObject::release();
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
initSize_Impl(sal_uInt32 & rnSize)357cdf0e10cSrcweir storeError FileLockBytes::initSize_Impl (sal_uInt32 & rnSize)
358cdf0e10cSrcweir {
359cdf0e10cSrcweir     /* osl_getFileSize() uses slow 'fstat(h, &size)',
360cdf0e10cSrcweir      * instead of fast 'size = lseek(h, 0, SEEK_END)'.
361cdf0e10cSrcweir      * so, init size here, and track changes.
362cdf0e10cSrcweir      */
363cdf0e10cSrcweir     sal_uInt64 uSize = 0;
364cdf0e10cSrcweir     oslFileError result = osl_getFileSize (m_hFile, &uSize);
365cdf0e10cSrcweir     if (result != osl_File_E_None)
366cdf0e10cSrcweir         return FileHandle::errorFromNative(result);
367cdf0e10cSrcweir     if (uSize > SAL_MAX_UINT32)
368cdf0e10cSrcweir         return store_E_CantSeek;
369cdf0e10cSrcweir 
370cdf0e10cSrcweir     rnSize = sal::static_int_cast<sal_uInt32>(uSize);
371cdf0e10cSrcweir     return store_E_None;
372cdf0e10cSrcweir }
373cdf0e10cSrcweir 
initialize_Impl(rtl::Reference<PageData::Allocator> & rxAllocator,sal_uInt16 nPageSize)374cdf0e10cSrcweir storeError FileLockBytes::initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize)
375cdf0e10cSrcweir {
376cdf0e10cSrcweir     storeError result = initSize_Impl (m_nSize);
377cdf0e10cSrcweir     if (result != store_E_None)
378cdf0e10cSrcweir         return (result);
379cdf0e10cSrcweir 
380cdf0e10cSrcweir     result = PageData::Allocator::createInstance (rxAllocator, nPageSize);
381cdf0e10cSrcweir     if (result != store_E_None)
382cdf0e10cSrcweir         return (result);
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     // @see readPageAt_Impl().
385cdf0e10cSrcweir     m_xAllocator = rxAllocator;
386cdf0e10cSrcweir     return store_E_None;
387cdf0e10cSrcweir }
388cdf0e10cSrcweir 
readPageAt_Impl(PageHolder & rPage,sal_uInt32 nOffset)389cdf0e10cSrcweir storeError FileLockBytes::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
390cdf0e10cSrcweir {
391cdf0e10cSrcweir     if (m_xAllocator.is())
392cdf0e10cSrcweir     {
393cdf0e10cSrcweir         PageHolder page (m_xAllocator->construct<PageData>(), m_xAllocator);
394cdf0e10cSrcweir         page.swap (rPage);
395cdf0e10cSrcweir     }
396cdf0e10cSrcweir 
397cdf0e10cSrcweir     if (!m_xAllocator.is())
398cdf0e10cSrcweir         return store_E_InvalidAccess;
399cdf0e10cSrcweir     if (!rPage.get())
400cdf0e10cSrcweir         return store_E_OutOfMemory;
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     PageData * pagedata = rPage.get();
403cdf0e10cSrcweir     return readAt_Impl (nOffset, pagedata, pagedata->size());
404cdf0e10cSrcweir }
405cdf0e10cSrcweir 
writePageAt_Impl(PageHolder const & rPage,sal_uInt32 nOffset)406cdf0e10cSrcweir storeError FileLockBytes::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset)
407cdf0e10cSrcweir {
408cdf0e10cSrcweir     PageData const * pagedata = rPage.get();
409cdf0e10cSrcweir     OSL_PRECOND(pagedata != 0, "contract violation");
410cdf0e10cSrcweir     return writeAt_Impl (nOffset, pagedata, pagedata->size());
411cdf0e10cSrcweir }
412cdf0e10cSrcweir 
readAt_Impl(sal_uInt32 nOffset,void * pBuffer,sal_uInt32 nBytes)413cdf0e10cSrcweir storeError FileLockBytes::readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     sal_uInt64 nDone = 0;
416cdf0e10cSrcweir     oslFileError result = osl_readFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone);
417cdf0e10cSrcweir     if (result != osl_File_E_None)
418cdf0e10cSrcweir         return FileHandle::errorFromNative(result);
419cdf0e10cSrcweir     if (nDone != nBytes)
420cdf0e10cSrcweir         return (nDone != 0) ? store_E_CantRead : store_E_NotExists;
421cdf0e10cSrcweir     return store_E_None;
422cdf0e10cSrcweir }
423cdf0e10cSrcweir 
writeAt_Impl(sal_uInt32 nOffset,void const * pBuffer,sal_uInt32 nBytes)424cdf0e10cSrcweir storeError FileLockBytes::writeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
425cdf0e10cSrcweir {
426cdf0e10cSrcweir     sal_uInt64 nDone = 0;
427cdf0e10cSrcweir     oslFileError result = osl_writeFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone);
428cdf0e10cSrcweir     if (result != osl_File_E_None)
429cdf0e10cSrcweir         return FileHandle::errorFromNative(result);
430cdf0e10cSrcweir     if (nDone != nBytes)
431cdf0e10cSrcweir         return store_E_CantWrite;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     sal_uInt64 const uSize = nOffset + nBytes;
434cdf0e10cSrcweir     OSL_PRECOND(uSize < SAL_MAX_UINT32, "store::ILockBytes::writeAt() contract violation");
435cdf0e10cSrcweir     if (uSize > m_nSize)
436cdf0e10cSrcweir 		m_nSize = sal::static_int_cast<sal_uInt32>(uSize);
437cdf0e10cSrcweir     return store_E_None;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
getSize_Impl(sal_uInt32 & rnSize)440cdf0e10cSrcweir storeError FileLockBytes::getSize_Impl (sal_uInt32 & rnSize)
441cdf0e10cSrcweir {
442cdf0e10cSrcweir     rnSize = m_nSize;
443cdf0e10cSrcweir     return store_E_None;
444cdf0e10cSrcweir }
445cdf0e10cSrcweir 
setSize_Impl(sal_uInt32 nSize)446cdf0e10cSrcweir storeError FileLockBytes::setSize_Impl (sal_uInt32 nSize)
447cdf0e10cSrcweir {
448cdf0e10cSrcweir     oslFileError result = osl_setFileSize (m_hFile, nSize);
449cdf0e10cSrcweir     if (result != osl_File_E_None)
450cdf0e10cSrcweir         return FileHandle::errorFromNative(result);
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     m_nSize = nSize;
453cdf0e10cSrcweir     return store_E_None;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
flush_Impl()456cdf0e10cSrcweir storeError FileLockBytes::flush_Impl()
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     oslFileError result = osl_syncFile (m_hFile);
459cdf0e10cSrcweir     if (result != osl_File_E_None)
460cdf0e10cSrcweir         return FileHandle::errorFromNative(result);
461cdf0e10cSrcweir     return store_E_None;
462cdf0e10cSrcweir }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir /*========================================================================
465cdf0e10cSrcweir  *
466cdf0e10cSrcweir  * MappedLockBytes implementation.
467cdf0e10cSrcweir  *
468cdf0e10cSrcweir  *======================================================================*/
469cdf0e10cSrcweir namespace store
470cdf0e10cSrcweir {
471cdf0e10cSrcweir 
472cdf0e10cSrcweir struct FileMapping
473cdf0e10cSrcweir {
474cdf0e10cSrcweir     sal_uInt8 * m_pAddr;
475cdf0e10cSrcweir     sal_uInt32  m_nSize;
476cdf0e10cSrcweir 
FileMappingstore::FileMapping477cdf0e10cSrcweir     FileMapping() : m_pAddr(0), m_nSize(0) {}
478cdf0e10cSrcweir 
operator !=store::FileMapping479cdf0e10cSrcweir     bool operator != (FileMapping const & rhs) const
480cdf0e10cSrcweir     {
481cdf0e10cSrcweir         return ((m_pAddr != rhs.m_pAddr) || (m_nSize != rhs.m_nSize));
482cdf0e10cSrcweir     }
483cdf0e10cSrcweir 
initializestore::FileMapping484cdf0e10cSrcweir     oslFileError initialize (oslFileHandle hFile)
485cdf0e10cSrcweir     {
486cdf0e10cSrcweir         // Determine mapping size.
487cdf0e10cSrcweir         sal_uInt64   uSize  = 0;
488cdf0e10cSrcweir         oslFileError result = osl_getFileSize (hFile, &uSize);
489cdf0e10cSrcweir         if (result != osl_File_E_None)
490cdf0e10cSrcweir             return result;
491cdf0e10cSrcweir 
492cdf0e10cSrcweir         // [SECURITY:IntOver]
493cdf0e10cSrcweir         if (uSize > SAL_MAX_UINT32)
494cdf0e10cSrcweir             return osl_File_E_OVERFLOW;
495cdf0e10cSrcweir         m_nSize = sal::static_int_cast<sal_uInt32>(uSize);
496cdf0e10cSrcweir 
497cdf0e10cSrcweir         // Acquire mapping.
498cdf0e10cSrcweir         return osl_mapFile (hFile, reinterpret_cast<void**>(&m_pAddr), m_nSize, 0, osl_File_MapFlag_RandomAccess);
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir 
501cdf0e10cSrcweir     /** @see MappedLockBytes::destructor.
502cdf0e10cSrcweir      */
unmapFilestore::FileMapping503cdf0e10cSrcweir     static void unmapFile (sal_uInt8 * pAddr, sal_uInt32 nSize)
504cdf0e10cSrcweir     {
505cdf0e10cSrcweir         (void) osl_unmapFile (pAddr, nSize);
506cdf0e10cSrcweir     }
507cdf0e10cSrcweir 
508cdf0e10cSrcweir     /** @see ResourceHolder<T>::destructor_type
509cdf0e10cSrcweir      */
510cdf0e10cSrcweir     struct UnmapFile
511cdf0e10cSrcweir     {
operator ()store::FileMapping::UnmapFile512cdf0e10cSrcweir         void operator ()(FileMapping & rMapping) const
513cdf0e10cSrcweir         {
514cdf0e10cSrcweir             // Release mapping.
515cdf0e10cSrcweir             unmapFile (rMapping.m_pAddr, rMapping.m_nSize);
516cdf0e10cSrcweir             rMapping.m_pAddr = 0, rMapping.m_nSize = 0;
517cdf0e10cSrcweir         }
518cdf0e10cSrcweir     };
519cdf0e10cSrcweir     typedef UnmapFile destructor_type;
520cdf0e10cSrcweir };
521cdf0e10cSrcweir 
522cdf0e10cSrcweir class MappedLockBytes :
523cdf0e10cSrcweir     public store::OStoreObject,
524cdf0e10cSrcweir     public store::PageData::Allocator,
525cdf0e10cSrcweir     public store::ILockBytes
526cdf0e10cSrcweir {
527cdf0e10cSrcweir     /** Representation.
528cdf0e10cSrcweir      */
529cdf0e10cSrcweir     sal_uInt8 * m_pData;
530cdf0e10cSrcweir     sal_uInt32  m_nSize;
531cdf0e10cSrcweir     sal_uInt16  m_nPageSize;
532cdf0e10cSrcweir 
533cdf0e10cSrcweir     /** PageData::Allocator implementation.
534cdf0e10cSrcweir      */
535cdf0e10cSrcweir     virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize);
536cdf0e10cSrcweir     virtual void deallocate_Impl (void * pPage);
537cdf0e10cSrcweir 
538cdf0e10cSrcweir     /** ILockBytes implementation.
539cdf0e10cSrcweir      */
540cdf0e10cSrcweir     virtual storeError initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
543cdf0e10cSrcweir     virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     virtual storeError readAt_Impl  (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
546cdf0e10cSrcweir     virtual storeError writeAt_Impl (sal_uInt32 nOffset, const void * pBuffer, sal_uInt32 nBytes);
547cdf0e10cSrcweir 
548cdf0e10cSrcweir     virtual storeError getSize_Impl (sal_uInt32 & rnSize);
549cdf0e10cSrcweir     virtual storeError setSize_Impl (sal_uInt32 nSize);
550cdf0e10cSrcweir 
551cdf0e10cSrcweir     virtual storeError flush_Impl();
552cdf0e10cSrcweir 
553cdf0e10cSrcweir     /** Not implemented.
554cdf0e10cSrcweir      */
555cdf0e10cSrcweir     MappedLockBytes (MappedLockBytes const &);
556cdf0e10cSrcweir     MappedLockBytes & operator= (MappedLockBytes const &);
557cdf0e10cSrcweir 
558cdf0e10cSrcweir public:
559cdf0e10cSrcweir     /** Construction.
560cdf0e10cSrcweir      */
561cdf0e10cSrcweir     explicit MappedLockBytes (FileMapping & rMapping);
562cdf0e10cSrcweir 
563cdf0e10cSrcweir     /** Delegate multiple inherited IReference.
564cdf0e10cSrcweir      */
565cdf0e10cSrcweir     virtual oslInterlockedCount SAL_CALL acquire();
566cdf0e10cSrcweir     virtual oslInterlockedCount SAL_CALL release();
567cdf0e10cSrcweir 
568cdf0e10cSrcweir protected:
569cdf0e10cSrcweir     /* Destruction.
570cdf0e10cSrcweir      */
571cdf0e10cSrcweir     virtual ~MappedLockBytes();
572cdf0e10cSrcweir };
573cdf0e10cSrcweir 
574cdf0e10cSrcweir } // namespace store
575cdf0e10cSrcweir 
MappedLockBytes(FileMapping & rMapping)576cdf0e10cSrcweir MappedLockBytes::MappedLockBytes (FileMapping & rMapping)
577cdf0e10cSrcweir     : m_pData (rMapping.m_pAddr), m_nSize (rMapping.m_nSize), m_nPageSize(0)
578cdf0e10cSrcweir {
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
~MappedLockBytes()581cdf0e10cSrcweir MappedLockBytes::~MappedLockBytes()
582cdf0e10cSrcweir {
583cdf0e10cSrcweir     FileMapping::unmapFile (m_pData, m_nSize);
584cdf0e10cSrcweir }
585cdf0e10cSrcweir 
acquire()586cdf0e10cSrcweir oslInterlockedCount SAL_CALL MappedLockBytes::acquire()
587cdf0e10cSrcweir {
588cdf0e10cSrcweir     return OStoreObject::acquire();
589cdf0e10cSrcweir }
590cdf0e10cSrcweir 
release()591cdf0e10cSrcweir oslInterlockedCount SAL_CALL MappedLockBytes::release()
592cdf0e10cSrcweir {
593cdf0e10cSrcweir     return OStoreObject::release();
594cdf0e10cSrcweir }
595cdf0e10cSrcweir 
allocate_Impl(void ** ppPage,sal_uInt16 * pnSize)596cdf0e10cSrcweir void MappedLockBytes::allocate_Impl (void ** ppPage, sal_uInt16 * pnSize)
597cdf0e10cSrcweir {
598cdf0e10cSrcweir     OSL_PRECOND((ppPage != 0) && (pnSize != 0), "contract violation");
599cdf0e10cSrcweir     if ((ppPage != 0) && (pnSize != 0))
600cdf0e10cSrcweir         *ppPage = 0, *pnSize = m_nPageSize;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir 
deallocate_Impl(void * pPage)603cdf0e10cSrcweir void MappedLockBytes::deallocate_Impl (void * pPage)
604cdf0e10cSrcweir {
605cdf0e10cSrcweir     OSL_PRECOND((m_pData <= pPage) && (pPage < m_pData + m_nSize), "contract violation");
606cdf0e10cSrcweir     (void)pPage; // UNUSED
607cdf0e10cSrcweir }
608cdf0e10cSrcweir 
initialize_Impl(rtl::Reference<PageData::Allocator> & rxAllocator,sal_uInt16 nPageSize)609cdf0e10cSrcweir storeError MappedLockBytes::initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize)
610cdf0e10cSrcweir {
611cdf0e10cSrcweir     rxAllocator = this;
612cdf0e10cSrcweir     m_nPageSize = nPageSize;
613cdf0e10cSrcweir     return store_E_None;
614cdf0e10cSrcweir }
615cdf0e10cSrcweir 
readPageAt_Impl(PageHolder & rPage,sal_uInt32 nOffset)616cdf0e10cSrcweir storeError MappedLockBytes::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
617cdf0e10cSrcweir {
618cdf0e10cSrcweir     sal_uInt8 * src_lo = m_pData + nOffset;
619cdf0e10cSrcweir     if ((m_pData > src_lo) || (src_lo >= m_pData + m_nSize))
620cdf0e10cSrcweir         return store_E_NotExists;
621cdf0e10cSrcweir 
622cdf0e10cSrcweir     sal_uInt8 * src_hi = src_lo + m_nPageSize;
623cdf0e10cSrcweir     if ((m_pData > src_hi) || (src_hi > m_pData + m_nSize))
624cdf0e10cSrcweir         return store_E_CantRead;
625cdf0e10cSrcweir 
626cdf0e10cSrcweir     PageHolder page (reinterpret_cast< PageData* >(src_lo), static_cast< PageData::Allocator* >(this));
627cdf0e10cSrcweir     page.swap (rPage);
628cdf0e10cSrcweir 
629cdf0e10cSrcweir     return store_E_None;
630cdf0e10cSrcweir }
631cdf0e10cSrcweir 
writePageAt_Impl(PageHolder const &,sal_uInt32)632cdf0e10cSrcweir storeError MappedLockBytes::writePageAt_Impl (PageHolder const & /*rPage*/, sal_uInt32 /*nOffset*/)
633cdf0e10cSrcweir {
634cdf0e10cSrcweir     return store_E_AccessViolation;
635cdf0e10cSrcweir }
636cdf0e10cSrcweir 
readAt_Impl(sal_uInt32 nOffset,void * pBuffer,sal_uInt32 nBytes)637cdf0e10cSrcweir storeError MappedLockBytes::readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
638cdf0e10cSrcweir {
639cdf0e10cSrcweir     sal_uInt8 const * src_lo = m_pData + nOffset;
640cdf0e10cSrcweir     if ((m_pData > src_lo) || (src_lo >= m_pData + m_nSize))
641cdf0e10cSrcweir         return store_E_NotExists;
642cdf0e10cSrcweir 
643cdf0e10cSrcweir     sal_uInt8 const * src_hi = src_lo + nBytes;
644cdf0e10cSrcweir     if ((m_pData > src_hi) || (src_hi > m_pData + m_nSize))
645cdf0e10cSrcweir         return store_E_CantRead;
646cdf0e10cSrcweir 
647cdf0e10cSrcweir     memcpy (pBuffer, src_lo, (src_hi - src_lo));
648cdf0e10cSrcweir     return store_E_None;
649cdf0e10cSrcweir }
650cdf0e10cSrcweir 
writeAt_Impl(sal_uInt32,void const *,sal_uInt32)651cdf0e10cSrcweir storeError MappedLockBytes::writeAt_Impl (sal_uInt32 /*nOffset*/, void const * /*pBuffer*/, sal_uInt32 /*nBytes*/)
652cdf0e10cSrcweir {
653cdf0e10cSrcweir     return store_E_AccessViolation;
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
getSize_Impl(sal_uInt32 & rnSize)656cdf0e10cSrcweir storeError MappedLockBytes::getSize_Impl (sal_uInt32 & rnSize)
657cdf0e10cSrcweir {
658cdf0e10cSrcweir     rnSize = m_nSize;
659cdf0e10cSrcweir     return store_E_None;
660cdf0e10cSrcweir }
661cdf0e10cSrcweir 
setSize_Impl(sal_uInt32)662cdf0e10cSrcweir storeError MappedLockBytes::setSize_Impl (sal_uInt32 /*nSize*/)
663cdf0e10cSrcweir {
664cdf0e10cSrcweir     return store_E_AccessViolation;
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
flush_Impl()667cdf0e10cSrcweir storeError MappedLockBytes::flush_Impl()
668cdf0e10cSrcweir {
669cdf0e10cSrcweir     return store_E_None;
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
672cdf0e10cSrcweir /*========================================================================
673cdf0e10cSrcweir  *
674cdf0e10cSrcweir  * MemoryLockBytes implementation.
675cdf0e10cSrcweir  *
676cdf0e10cSrcweir  *======================================================================*/
677cdf0e10cSrcweir namespace store
678cdf0e10cSrcweir {
679cdf0e10cSrcweir 
680cdf0e10cSrcweir class MemoryLockBytes :
681cdf0e10cSrcweir     public store::OStoreObject,
682cdf0e10cSrcweir     public store::ILockBytes
683cdf0e10cSrcweir {
684cdf0e10cSrcweir     /** Representation.
685cdf0e10cSrcweir      */
686cdf0e10cSrcweir     sal_uInt8 * m_pData;
687cdf0e10cSrcweir     sal_uInt32  m_nSize;
688cdf0e10cSrcweir     rtl::Reference< PageData::Allocator > m_xAllocator;
689cdf0e10cSrcweir 
690cdf0e10cSrcweir     /** ILockBytes implementation.
691cdf0e10cSrcweir      */
692cdf0e10cSrcweir     virtual storeError initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
695cdf0e10cSrcweir     virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
696cdf0e10cSrcweir 
697cdf0e10cSrcweir     virtual storeError readAt_Impl  (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
698cdf0e10cSrcweir     virtual storeError writeAt_Impl (sal_uInt32 nOffset, const void * pBuffer, sal_uInt32 nBytes);
699cdf0e10cSrcweir 
700cdf0e10cSrcweir     virtual storeError getSize_Impl (sal_uInt32 & rnSize);
701cdf0e10cSrcweir     virtual storeError setSize_Impl (sal_uInt32 nSize);
702cdf0e10cSrcweir 
703cdf0e10cSrcweir     virtual storeError flush_Impl();
704cdf0e10cSrcweir 
705cdf0e10cSrcweir     /** Not implemented.
706cdf0e10cSrcweir      */
707cdf0e10cSrcweir     MemoryLockBytes (MemoryLockBytes const &);
708cdf0e10cSrcweir     MemoryLockBytes& operator= (MemoryLockBytes const &);
709cdf0e10cSrcweir 
710cdf0e10cSrcweir public:
711cdf0e10cSrcweir     /** Construction.
712cdf0e10cSrcweir      */
713cdf0e10cSrcweir     MemoryLockBytes();
714cdf0e10cSrcweir 
715cdf0e10cSrcweir     /** Delegate multiple inherited IReference.
716cdf0e10cSrcweir      */
717cdf0e10cSrcweir     virtual oslInterlockedCount SAL_CALL acquire();
718cdf0e10cSrcweir     virtual oslInterlockedCount SAL_CALL release();
719cdf0e10cSrcweir 
720cdf0e10cSrcweir protected:
721cdf0e10cSrcweir     /** Destruction.
722cdf0e10cSrcweir      */
723cdf0e10cSrcweir     virtual ~MemoryLockBytes();
724cdf0e10cSrcweir };
725cdf0e10cSrcweir 
726cdf0e10cSrcweir } // namespace store
727cdf0e10cSrcweir 
MemoryLockBytes()728cdf0e10cSrcweir MemoryLockBytes::MemoryLockBytes()
729cdf0e10cSrcweir     : m_pData (0), m_nSize (0), m_xAllocator()
730cdf0e10cSrcweir {}
731cdf0e10cSrcweir 
~MemoryLockBytes()732cdf0e10cSrcweir MemoryLockBytes::~MemoryLockBytes()
733cdf0e10cSrcweir {
734cdf0e10cSrcweir     rtl_freeMemory (m_pData);
735cdf0e10cSrcweir }
736cdf0e10cSrcweir 
acquire(void)737cdf0e10cSrcweir oslInterlockedCount SAL_CALL MemoryLockBytes::acquire (void)
738cdf0e10cSrcweir {
739cdf0e10cSrcweir     return OStoreObject::acquire();
740cdf0e10cSrcweir }
741cdf0e10cSrcweir 
release(void)742cdf0e10cSrcweir oslInterlockedCount SAL_CALL MemoryLockBytes::release (void)
743cdf0e10cSrcweir {
744cdf0e10cSrcweir     return OStoreObject::release();
745cdf0e10cSrcweir }
746cdf0e10cSrcweir 
initialize_Impl(rtl::Reference<PageData::Allocator> & rxAllocator,sal_uInt16 nPageSize)747cdf0e10cSrcweir storeError MemoryLockBytes::initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize)
748cdf0e10cSrcweir {
749cdf0e10cSrcweir     storeError result = PageData::Allocator::createInstance (rxAllocator, nPageSize);
750cdf0e10cSrcweir     if (result == store_E_None)
751cdf0e10cSrcweir     {
752cdf0e10cSrcweir         // @see readPageAt_Impl().
753cdf0e10cSrcweir         m_xAllocator = rxAllocator;
754cdf0e10cSrcweir     }
755cdf0e10cSrcweir     return result;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir 
readPageAt_Impl(PageHolder & rPage,sal_uInt32 nOffset)758cdf0e10cSrcweir storeError MemoryLockBytes::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
759cdf0e10cSrcweir {
760cdf0e10cSrcweir     if (m_xAllocator.is())
761cdf0e10cSrcweir     {
762cdf0e10cSrcweir         PageHolder page (m_xAllocator->construct<PageData>(), m_xAllocator);
763cdf0e10cSrcweir         page.swap (rPage);
764cdf0e10cSrcweir     }
765cdf0e10cSrcweir 
766cdf0e10cSrcweir     if (!m_xAllocator.is())
767cdf0e10cSrcweir         return store_E_InvalidAccess;
768cdf0e10cSrcweir     if (!rPage.get())
769cdf0e10cSrcweir         return store_E_OutOfMemory;
770cdf0e10cSrcweir 
771cdf0e10cSrcweir     PageData * pagedata = rPage.get();
772cdf0e10cSrcweir     return readAt_Impl (nOffset, pagedata, pagedata->size());
773cdf0e10cSrcweir }
774cdf0e10cSrcweir 
writePageAt_Impl(PageHolder const & rPage,sal_uInt32 nOffset)775cdf0e10cSrcweir storeError MemoryLockBytes::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset)
776cdf0e10cSrcweir {
777cdf0e10cSrcweir     PageData const * pagedata = rPage.get();
778cdf0e10cSrcweir     OSL_PRECOND(!(pagedata == 0), "contract violation");
779cdf0e10cSrcweir     return writeAt_Impl (nOffset, pagedata, pagedata->size());
780cdf0e10cSrcweir }
781cdf0e10cSrcweir 
readAt_Impl(sal_uInt32 nOffset,void * pBuffer,sal_uInt32 nBytes)782cdf0e10cSrcweir storeError MemoryLockBytes::readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
783cdf0e10cSrcweir {
784cdf0e10cSrcweir     sal_uInt8 const * src_lo = m_pData + nOffset;
785cdf0e10cSrcweir     if ((m_pData > src_lo) || (src_lo >= m_pData + m_nSize))
786cdf0e10cSrcweir         return store_E_NotExists;
787cdf0e10cSrcweir 
788cdf0e10cSrcweir     sal_uInt8 const * src_hi = src_lo + nBytes;
789cdf0e10cSrcweir     if ((m_pData > src_hi) || (src_hi > m_pData + m_nSize))
790cdf0e10cSrcweir         return store_E_CantRead;
791cdf0e10cSrcweir 
792cdf0e10cSrcweir     memcpy (pBuffer, src_lo, (src_hi - src_lo));
793cdf0e10cSrcweir     return store_E_None;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir 
writeAt_Impl(sal_uInt32 nOffset,const void * pBuffer,sal_uInt32 nBytes)796cdf0e10cSrcweir storeError MemoryLockBytes::writeAt_Impl (sal_uInt32 nOffset, const void * pBuffer, sal_uInt32 nBytes)
797cdf0e10cSrcweir {
798cdf0e10cSrcweir     sal_uInt64 const dst_size = nOffset + nBytes;
799cdf0e10cSrcweir     OSL_PRECOND(dst_size < SAL_MAX_UINT32, "store::ILockBytes::writeAt() contract violation");
800cdf0e10cSrcweir     if (dst_size > m_nSize)
801cdf0e10cSrcweir     {
802cdf0e10cSrcweir         storeError eErrCode = setSize_Impl (sal::static_int_cast<sal_uInt32>(dst_size));
803cdf0e10cSrcweir         if (eErrCode != store_E_None)
804cdf0e10cSrcweir             return eErrCode;
805cdf0e10cSrcweir     }
806cdf0e10cSrcweir     OSL_POSTCOND(dst_size <= m_nSize, "store::MemoryLockBytes::setSize_Impl() contract violation");
807cdf0e10cSrcweir 
808cdf0e10cSrcweir     sal_uInt8 * dst_lo = m_pData + nOffset;
809cdf0e10cSrcweir     if (dst_lo >= m_pData + m_nSize)
810cdf0e10cSrcweir         return store_E_CantSeek;
811cdf0e10cSrcweir 
812cdf0e10cSrcweir     sal_uInt8 * dst_hi = dst_lo + nBytes;
813cdf0e10cSrcweir     if (dst_hi > m_pData + m_nSize)
814cdf0e10cSrcweir         return store_E_CantWrite;
815cdf0e10cSrcweir 
816cdf0e10cSrcweir     memcpy (dst_lo, pBuffer, (dst_hi - dst_lo));
817cdf0e10cSrcweir     return store_E_None;
818cdf0e10cSrcweir }
819cdf0e10cSrcweir 
getSize_Impl(sal_uInt32 & rnSize)820cdf0e10cSrcweir storeError MemoryLockBytes::getSize_Impl (sal_uInt32 & rnSize)
821cdf0e10cSrcweir {
822cdf0e10cSrcweir     rnSize = m_nSize;
823cdf0e10cSrcweir     return store_E_None;
824cdf0e10cSrcweir }
825cdf0e10cSrcweir 
setSize_Impl(sal_uInt32 nSize)826cdf0e10cSrcweir storeError MemoryLockBytes::setSize_Impl (sal_uInt32 nSize)
827cdf0e10cSrcweir {
828cdf0e10cSrcweir     if (nSize != m_nSize)
829cdf0e10cSrcweir     {
830cdf0e10cSrcweir         sal_uInt8 * pData = reinterpret_cast<sal_uInt8*>(rtl_reallocateMemory (m_pData, nSize));
831cdf0e10cSrcweir         if (pData != 0)
832cdf0e10cSrcweir         {
833cdf0e10cSrcweir             if (nSize > m_nSize)
834cdf0e10cSrcweir                 memset (pData + m_nSize, 0, sal::static_int_cast<size_t>(nSize - m_nSize));
835cdf0e10cSrcweir         }
836cdf0e10cSrcweir         else
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             if (nSize != 0)
839cdf0e10cSrcweir                 return store_E_OutOfMemory;
840cdf0e10cSrcweir         }
841cdf0e10cSrcweir         m_pData = pData, m_nSize = nSize;
842cdf0e10cSrcweir     }
843cdf0e10cSrcweir     return store_E_None;
844cdf0e10cSrcweir }
845cdf0e10cSrcweir 
flush_Impl()846cdf0e10cSrcweir storeError MemoryLockBytes::flush_Impl()
847cdf0e10cSrcweir {
848cdf0e10cSrcweir     return store_E_None;
849cdf0e10cSrcweir }
850cdf0e10cSrcweir 
851cdf0e10cSrcweir /*========================================================================
852cdf0e10cSrcweir  *
853cdf0e10cSrcweir  * ILockBytes factory implementations.
854cdf0e10cSrcweir  *
855cdf0e10cSrcweir  *======================================================================*/
856cdf0e10cSrcweir namespace store
857cdf0e10cSrcweir {
858cdf0e10cSrcweir 
859cdf0e10cSrcweir template< class T > struct ResourceHolder
860cdf0e10cSrcweir {
861cdf0e10cSrcweir     typedef typename T::destructor_type destructor_type;
862cdf0e10cSrcweir 
863cdf0e10cSrcweir     T m_value;
864cdf0e10cSrcweir 
ResourceHolderstore::ResourceHolder865cdf0e10cSrcweir     explicit ResourceHolder (T const & value = T()) : m_value (value) {}
~ResourceHolderstore::ResourceHolder866cdf0e10cSrcweir     ~ResourceHolder() { reset(); }
867cdf0e10cSrcweir 
getstore::ResourceHolder868cdf0e10cSrcweir     T & get() { return m_value; }
getstore::ResourceHolder869cdf0e10cSrcweir     T const & get() const { return m_value; }
870cdf0e10cSrcweir 
setstore::ResourceHolder871cdf0e10cSrcweir     void set (T const & value) { m_value = value; }
resetstore::ResourceHolder872cdf0e10cSrcweir     void reset (T const & value = T())
873cdf0e10cSrcweir     {
874cdf0e10cSrcweir         T tmp (m_value);
875cdf0e10cSrcweir         if (tmp != value)
876cdf0e10cSrcweir             destructor_type()(tmp);
877cdf0e10cSrcweir         set (value);
878cdf0e10cSrcweir     }
releasestore::ResourceHolder879cdf0e10cSrcweir     T release()
880cdf0e10cSrcweir     {
881cdf0e10cSrcweir         T tmp (m_value);
882cdf0e10cSrcweir         set (T());
883cdf0e10cSrcweir         return tmp;
884cdf0e10cSrcweir     }
885cdf0e10cSrcweir 
ResourceHolderstore::ResourceHolder886cdf0e10cSrcweir     ResourceHolder (ResourceHolder & rhs)
887cdf0e10cSrcweir     {
888cdf0e10cSrcweir         set (rhs.release());
889cdf0e10cSrcweir     }
operator =store::ResourceHolder890cdf0e10cSrcweir     ResourceHolder & operator= (ResourceHolder & rhs)
891cdf0e10cSrcweir     {
892cdf0e10cSrcweir         reset (rhs.release());
893cdf0e10cSrcweir         return *this;
894cdf0e10cSrcweir     }
895cdf0e10cSrcweir };
896cdf0e10cSrcweir 
897cdf0e10cSrcweir storeError
FileLockBytes_createInstance(rtl::Reference<ILockBytes> & rxLockBytes,rtl_uString * pFilename,storeAccessMode eAccessMode)898cdf0e10cSrcweir FileLockBytes_createInstance (
899cdf0e10cSrcweir     rtl::Reference< ILockBytes > & rxLockBytes,
900cdf0e10cSrcweir     rtl_uString *                  pFilename,
901cdf0e10cSrcweir     storeAccessMode                eAccessMode
902cdf0e10cSrcweir )
903cdf0e10cSrcweir {
904cdf0e10cSrcweir     // Acquire file handle.
905cdf0e10cSrcweir     ResourceHolder<FileHandle> xFile;
906cdf0e10cSrcweir     storeError result = xFile.get().initialize (pFilename, eAccessMode);
907cdf0e10cSrcweir     if (result != store_E_None)
908cdf0e10cSrcweir         return (result);
909cdf0e10cSrcweir 
910cdf0e10cSrcweir     if (eAccessMode == store_AccessReadOnly)
911cdf0e10cSrcweir     {
912cdf0e10cSrcweir         ResourceHolder<FileMapping> xMapping;
913cdf0e10cSrcweir         if (xMapping.get().initialize (xFile.get().m_handle) == osl_File_E_None)
914cdf0e10cSrcweir         {
915cdf0e10cSrcweir             rxLockBytes = new MappedLockBytes (xMapping.get());
916cdf0e10cSrcweir             if (!rxLockBytes.is())
917cdf0e10cSrcweir                 return store_E_OutOfMemory;
918cdf0e10cSrcweir             (void) xMapping.release();
919cdf0e10cSrcweir         }
920cdf0e10cSrcweir     }
921cdf0e10cSrcweir     if (!rxLockBytes.is())
922cdf0e10cSrcweir     {
923cdf0e10cSrcweir         rxLockBytes = new FileLockBytes (xFile.get());
924cdf0e10cSrcweir         if (!rxLockBytes.is())
925cdf0e10cSrcweir             return store_E_OutOfMemory;
926cdf0e10cSrcweir         (void) xFile.release();
927cdf0e10cSrcweir     }
928cdf0e10cSrcweir 
929cdf0e10cSrcweir     return store_E_None;
930cdf0e10cSrcweir }
931cdf0e10cSrcweir 
932cdf0e10cSrcweir storeError
MemoryLockBytes_createInstance(rtl::Reference<ILockBytes> & rxLockBytes)933cdf0e10cSrcweir MemoryLockBytes_createInstance (
934cdf0e10cSrcweir     rtl::Reference< ILockBytes > & rxLockBytes
935cdf0e10cSrcweir )
936cdf0e10cSrcweir {
937cdf0e10cSrcweir     rxLockBytes = new MemoryLockBytes();
938cdf0e10cSrcweir     if (!rxLockBytes.is())
939cdf0e10cSrcweir         return store_E_OutOfMemory;
940cdf0e10cSrcweir 
941cdf0e10cSrcweir     return store_E_None;
942cdf0e10cSrcweir }
943cdf0e10cSrcweir 
944cdf0e10cSrcweir } // namespace store
945