1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: lockbyte.cxx,v $
9 * last change: $Author: mhu $ $Date: 2008/11/25 15:44:56 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_store.hxx"
39 #include "lockbyte.hxx"
41 #include "sal/types.h"
42 #include "osl/diagnose.h"
44 #include "osl/process.h"
45 #include "rtl/alloc.h"
46 #include "rtl/ustring.hxx"
49 #include "storbase.hxx"
51 #ifndef INCLUDED_STRING_H
53 #define INCLUDED_STRING_H
56 using namespace store
;
58 /*========================================================================
60 * ILockBytes (non-virtual interface) implementation.
62 *======================================================================*/
64 storeError
ILockBytes::initialize (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
66 OSL_PRECOND((STORE_MINIMUM_PAGESIZE
<= nPageSize
) && (nPageSize
<= STORE_MAXIMUM_PAGESIZE
), "invalid PageSize");
67 return initialize_Impl (rxAllocator
, nPageSize
);
70 storeError
ILockBytes::readPageAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
72 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readPageAt(): invalid Offset");
73 if (nOffset
== STORE_PAGE_NULL
)
74 return store_E_CantSeek
;
76 return readPageAt_Impl (rPage
, nOffset
);
79 storeError
ILockBytes::writePageAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
81 // [SECURITY:ValInput]
82 PageData
const * pagedata
= rPage
.get();
83 OSL_PRECOND(!(pagedata
== 0), "store::ILockBytes::writePageAt(): invalid Page");
85 return store_E_InvalidParameter
;
87 sal_uInt32
const offset
= pagedata
->location();
88 OSL_PRECOND(!(nOffset
!= offset
), "store::ILockBytes::writePageAt(): inconsistent Offset");
89 if (nOffset
!= offset
)
90 return store_E_InvalidParameter
;
92 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writePageAt(): invalid Offset");
93 if (nOffset
== STORE_PAGE_NULL
)
94 return store_E_CantSeek
;
96 return writePageAt_Impl (rPage
, nOffset
);
99 storeError
ILockBytes::readAt (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
101 // [SECURITY:ValInput]
102 sal_uInt8
* dst_lo
= static_cast<sal_uInt8
*>(pBuffer
);
104 return store_E_InvalidParameter
;
106 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
107 if (!(dst_lo
< dst_hi
))
108 return (dst_lo
> dst_hi
) ? store_E_InvalidParameter
: store_E_None
;
110 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readAt(): invalid Offset");
111 if (nOffset
== STORE_PAGE_NULL
)
112 return store_E_CantSeek
;
114 sal_uInt64
const src_size
= nOffset
+ nBytes
;
115 if (src_size
> SAL_MAX_UINT32
)
116 return store_E_CantSeek
;
118 return readAt_Impl (nOffset
, dst_lo
, (dst_hi
- dst_lo
));
121 storeError
ILockBytes::writeAt (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
123 // [SECURITY:ValInput]
124 sal_uInt8
const * src_lo
= static_cast<sal_uInt8
const*>(pBuffer
);
126 return store_E_InvalidParameter
;
128 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
129 if (!(src_lo
< src_hi
))
130 return (src_lo
> src_hi
) ? store_E_InvalidParameter
: store_E_None
;
132 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writeAt(): invalid Offset");
133 if (nOffset
== STORE_PAGE_NULL
)
134 return store_E_CantSeek
;
136 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
137 if (dst_size
> SAL_MAX_UINT32
)
138 return store_E_CantSeek
;
140 return writeAt_Impl (nOffset
, src_lo
, (src_hi
- src_lo
));
143 storeError
ILockBytes::getSize (sal_uInt32
& rnSize
)
146 return getSize_Impl (rnSize
);
149 storeError
ILockBytes::setSize (sal_uInt32 nSize
)
151 return setSize_Impl (nSize
);
154 storeError
ILockBytes::flush()
159 storeError
ILockBytes::lockRange (sal_uInt32 nOffset
, sal_uInt32 nBytes
)
161 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::lockRange(): invalid Offset");
162 if (nOffset
== STORE_PAGE_NULL
)
163 return store_E_CantSeek
;
165 sal_uInt64 size
= nOffset
+ nBytes
;
166 if (size
> SAL_MAX_UINT32
)
167 return store_E_CantSeek
;
169 #ifdef STORE_FEATURE_LOCKING
170 return lockRange_Impl (nOffset
, nBytes
);
172 return store_E_None
; // E_Unsupported
173 #endif /* STORE_FEATURE_LOCKING */
176 storeError
ILockBytes::unlockRange (sal_uInt32 nOffset
, sal_uInt32 nBytes
)
178 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::unlockRange(): invalid Offset");
179 if (nOffset
== STORE_PAGE_NULL
)
180 return store_E_CantSeek
;
182 sal_uInt64 size
= nOffset
+ nBytes
;
183 if (size
> SAL_MAX_UINT32
)
184 return store_E_CantSeek
;
186 #ifdef STORE_FEATURE_LOCKING
187 return unlockRange_Impl (nOffset
, nBytes
);
189 return store_E_None
; // E_Unsupported
190 #endif /* STORE_FEATURE_LOCKING */
193 /*========================================================================
195 * FileLockBytes implementation.
197 *======================================================================*/
203 oslFileHandle m_handle
;
205 FileHandle() : m_handle(0) {}
207 bool operator != (FileHandle
const & rhs
)
209 return (m_handle
!= rhs
.m_handle
);
212 static storeError
errorFromNative (oslFileError eErrno
)
216 case osl_File_E_None
:
219 case osl_File_E_NOENT
:
220 return store_E_NotExists
;
222 case osl_File_E_ACCES
:
223 case osl_File_E_PERM
:
224 return store_E_AccessViolation
;
226 case osl_File_E_AGAIN
:
227 case osl_File_E_DEADLK
:
228 return store_E_LockingViolation
;
230 case osl_File_E_BADF
:
231 return store_E_InvalidHandle
;
233 case osl_File_E_INVAL
:
234 return store_E_InvalidParameter
;
236 case osl_File_E_NOMEM
:
237 return store_E_OutOfMemory
;
239 case osl_File_E_NOSPC
:
240 return store_E_OutOfSpace
;
242 case osl_File_E_OVERFLOW
:
243 return store_E_CantSeek
;
246 return store_E_Unknown
;
250 static sal_uInt32
modeToNative (storeAccessMode eAccessMode
)
252 sal_uInt32 nFlags
= 0;
255 case store_AccessCreate
:
256 case store_AccessReadCreate
:
257 nFlags
|= osl_File_OpenFlag_Create
;
259 case store_AccessReadWrite
:
260 nFlags
|= osl_File_OpenFlag_Write
;
262 case store_AccessReadOnly
:
263 nFlags
|= osl_File_OpenFlag_Read
;
266 OSL_PRECOND(0, "store::FileHandle: unknown storeAccessMode");
271 storeError
initialize (rtl_uString
* pFilename
, storeAccessMode eAccessMode
)
274 sal_uInt32 nFlags
= modeToNative (eAccessMode
);
275 if (!pFilename
|| !nFlags
)
276 return store_E_InvalidParameter
;
278 // Convert into FileUrl.
279 rtl::OUString aFileUrl
;
280 if (osl_getFileURLFromSystemPath (pFilename
, &(aFileUrl
.pData
)) != osl_File_E_None
)
282 // Not system path. Assume file url.
283 rtl_uString_assign (&(aFileUrl
.pData
), pFilename
);
285 if (aFileUrl
.compareToAscii("file://", 7) != 0)
287 // Not file url. Assume relative path.
288 rtl::OUString aCwdUrl
;
289 (void) osl_getProcessWorkingDir (&(aCwdUrl
.pData
));
291 // Absolute file url.
292 (void) osl_getAbsoluteFileURL (aCwdUrl
.pData
, aFileUrl
.pData
, &(aFileUrl
.pData
));
296 oslFileError result
= osl_openFile (aFileUrl
.pData
, &m_handle
, nFlags
);
297 if (result
== osl_File_E_EXIST
)
299 // Already existing (O_CREAT | O_EXCL).
300 result
= osl_openFile (aFileUrl
.pData
, &m_handle
, osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
301 if ((result
== osl_File_E_None
) && (eAccessMode
== store_AccessCreate
))
303 // Truncate existing file.
304 result
= osl_setFileSize (m_handle
, 0);
307 if (result
!= osl_File_E_None
)
308 return errorFromNative(result
);
312 /** @see FileLockBytes destructor
314 static void closeFile (oslFileHandle hFile
)
316 (void) osl_closeFile (hFile
);
319 /** @see ResourceHolder<T>::destructor_type
323 void operator()(FileHandle
& rFile
) const
326 closeFile (rFile
.m_handle
);
330 typedef CloseFile destructor_type
;
333 class FileLockBytes
:
334 public store::OStoreObject
,
335 public store::ILockBytes
339 oslFileHandle m_hFile
;
341 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
343 storeError
initSize_Impl (sal_uInt32
& rnSize
);
345 /** ILockBytes implementation.
347 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
349 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
350 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
352 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
353 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
);
355 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
356 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
358 virtual storeError
flush_Impl();
362 FileLockBytes (FileLockBytes
const &);
363 FileLockBytes
& operator= (FileLockBytes
const &);
368 explicit FileLockBytes (FileHandle
& rFile
);
370 /** Delegate multiple inherited IReference.
372 virtual oslInterlockedCount SAL_CALL
acquire();
373 virtual oslInterlockedCount SAL_CALL
release();
378 virtual ~FileLockBytes();
383 FileLockBytes::FileLockBytes (FileHandle
& rFile
)
384 : m_hFile (rFile
.m_handle
), m_nSize (SAL_MAX_UINT32
), m_xAllocator()
388 FileLockBytes::~FileLockBytes()
390 FileHandle::closeFile (m_hFile
);
393 oslInterlockedCount SAL_CALL
FileLockBytes::acquire()
395 return OStoreObject::acquire();
398 oslInterlockedCount SAL_CALL
FileLockBytes::release()
400 return OStoreObject::release();
403 storeError
FileLockBytes::initSize_Impl (sal_uInt32
& rnSize
)
405 /* osl_getFileSize() uses slow 'fstat(h, &size)',
406 * instead of fast 'size = lseek(h, 0, SEEK_END)'.
407 * so, init size here, and track changes.
409 sal_uInt64 uSize
= 0;
410 oslFileError result
= osl_getFileSize (m_hFile
, &uSize
);
411 if (result
!= osl_File_E_None
)
412 return FileHandle::errorFromNative(result
);
413 if (uSize
> SAL_MAX_UINT32
)
414 return store_E_CantSeek
;
416 rnSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
420 storeError
FileLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
422 storeError result
= initSize_Impl (m_nSize
);
423 if (result
!= store_E_None
)
426 result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
427 if (result
!= store_E_None
)
430 // @see readPageAt_Impl().
431 m_xAllocator
= rxAllocator
;
435 storeError
FileLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
437 if (m_xAllocator
.is())
439 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
443 if (!m_xAllocator
.is())
444 return store_E_InvalidAccess
;
446 return store_E_OutOfMemory
;
448 PageData
* pagedata
= rPage
.get();
449 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
452 storeError
FileLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
454 PageData
const * pagedata
= rPage
.get();
455 OSL_PRECOND(pagedata
!= 0, "contract violation");
456 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
459 storeError
FileLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
461 sal_uInt64 nDone
= 0;
462 oslFileError result
= osl_readFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
463 if (result
!= osl_File_E_None
)
464 return FileHandle::errorFromNative(result
);
466 return (nDone
!= 0) ? store_E_CantRead
: store_E_NotExists
;
470 storeError
FileLockBytes::writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
472 sal_uInt64 nDone
= 0;
473 oslFileError result
= osl_writeFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
474 if (result
!= osl_File_E_None
)
475 return FileHandle::errorFromNative(result
);
477 return store_E_CantWrite
;
479 sal_uInt64
const uSize
= nOffset
+ nBytes
;
480 OSL_PRECOND(uSize
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
482 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
486 storeError
FileLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
492 storeError
FileLockBytes::setSize_Impl (sal_uInt32 nSize
)
494 oslFileError result
= osl_setFileSize (m_hFile
, nSize
);
495 if (result
!= osl_File_E_None
)
496 return FileHandle::errorFromNative(result
);
502 storeError
FileLockBytes::flush_Impl()
504 oslFileError result
= osl_syncFile (m_hFile
);
505 if (result
!= osl_File_E_None
)
506 return FileHandle::errorFromNative(result
);
510 /*========================================================================
512 * MappedLockBytes implementation.
514 *======================================================================*/
523 FileMapping() : m_pAddr(0), m_nSize(0) {}
525 bool operator != (FileMapping
const & rhs
) const
527 return ((m_pAddr
!= rhs
.m_pAddr
) || (m_nSize
!= rhs
.m_nSize
));
530 oslFileError
initialize (oslFileHandle hFile
)
532 // Determine mapping size.
533 sal_uInt64 uSize
= 0;
534 oslFileError result
= osl_getFileSize (hFile
, &uSize
);
535 if (result
!= osl_File_E_None
)
538 // [SECURITY:IntOver]
539 if (uSize
> SAL_MAX_UINT32
)
540 return osl_File_E_OVERFLOW
;
541 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
544 return osl_mapFile (hFile
, reinterpret_cast<void**>(&m_pAddr
), m_nSize
, 0, osl_File_MapFlag_RandomAccess
);
547 /** @see MappedLockBytes::destructor.
549 static void unmapFile (sal_uInt8
* pAddr
, sal_uInt32 nSize
)
551 (void) osl_unmapFile (pAddr
, nSize
);
554 /** @see ResourceHolder<T>::destructor_type
558 void operator ()(FileMapping
& rMapping
) const
561 unmapFile (rMapping
.m_pAddr
, rMapping
.m_nSize
);
562 rMapping
.m_pAddr
= 0, rMapping
.m_nSize
= 0;
565 typedef UnmapFile destructor_type
;
568 class MappedLockBytes
:
569 public store::OStoreObject
,
570 public store::PageData::Allocator
,
571 public store::ILockBytes
577 sal_uInt16 m_nPageSize
;
579 /** PageData::Allocator implementation.
581 virtual void allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
);
582 virtual void deallocate_Impl (void * pPage
);
584 /** ILockBytes implementation.
586 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
588 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
589 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
591 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
592 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
);
594 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
595 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
597 virtual storeError
flush_Impl();
601 MappedLockBytes (MappedLockBytes
const &);
602 MappedLockBytes
& operator= (MappedLockBytes
const &);
607 explicit MappedLockBytes (FileMapping
& rMapping
);
609 /** Delegate multiple inherited IReference.
611 virtual oslInterlockedCount SAL_CALL
acquire();
612 virtual oslInterlockedCount SAL_CALL
release();
617 virtual ~MappedLockBytes();
622 MappedLockBytes::MappedLockBytes (FileMapping
& rMapping
)
623 : m_pData (rMapping
.m_pAddr
), m_nSize (rMapping
.m_nSize
), m_nPageSize(0)
627 MappedLockBytes::~MappedLockBytes()
629 FileMapping::unmapFile (m_pData
, m_nSize
);
632 oslInterlockedCount SAL_CALL
MappedLockBytes::acquire()
634 return OStoreObject::acquire();
637 oslInterlockedCount SAL_CALL
MappedLockBytes::release()
639 return OStoreObject::release();
642 void MappedLockBytes::allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
)
644 OSL_PRECOND((ppPage
!= 0) && (pnSize
!= 0), "contract violation");
645 *ppPage
= 0, *pnSize
= m_nPageSize
;
648 void MappedLockBytes::deallocate_Impl (void * pPage
)
650 OSL_PRECOND((m_pData
<= pPage
) && (pPage
< m_pData
+ m_nSize
), "contract violation");
651 (void)pPage
; // UNUSED
654 storeError
MappedLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
657 m_nPageSize
= nPageSize
;
661 storeError
MappedLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
663 sal_uInt8
* src_lo
= m_pData
+ nOffset
;
664 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
665 return store_E_NotExists
;
667 sal_uInt8
* src_hi
= src_lo
+ m_nPageSize
;
668 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
669 return store_E_CantRead
;
671 PageHolder
page (reinterpret_cast< PageData
* >(src_lo
), static_cast< PageData::Allocator
* >(this));
677 storeError
MappedLockBytes::writePageAt_Impl (PageHolder
const & /*rPage*/, sal_uInt32
/*nOffset*/)
679 return store_E_AccessViolation
;
682 storeError
MappedLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
684 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
685 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
686 return store_E_NotExists
;
688 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
689 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
690 return store_E_CantRead
;
692 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
696 storeError
MappedLockBytes::writeAt_Impl (sal_uInt32
/*nOffset*/, void const * /*pBuffer*/, sal_uInt32
/*nBytes*/)
698 return store_E_AccessViolation
;
701 storeError
MappedLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
707 storeError
MappedLockBytes::setSize_Impl (sal_uInt32
/*nSize*/)
709 return store_E_AccessViolation
;
712 storeError
MappedLockBytes::flush_Impl()
717 /*========================================================================
719 * MemoryLockBytes implementation.
721 *======================================================================*/
725 class MemoryLockBytes
:
726 public store::OStoreObject
,
727 public store::ILockBytes
733 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
735 /** ILockBytes implementation.
737 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
739 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
740 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
742 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
743 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
);
745 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
746 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
748 virtual storeError
flush_Impl();
752 MemoryLockBytes (MemoryLockBytes
const &);
753 MemoryLockBytes
& operator= (MemoryLockBytes
const &);
760 /** Delegate multiple inherited IReference.
762 virtual oslInterlockedCount SAL_CALL
acquire();
763 virtual oslInterlockedCount SAL_CALL
release();
768 virtual ~MemoryLockBytes();
773 MemoryLockBytes::MemoryLockBytes()
774 : m_pData (0), m_nSize (0), m_xAllocator()
777 MemoryLockBytes::~MemoryLockBytes()
779 rtl_freeMemory (m_pData
);
782 oslInterlockedCount SAL_CALL
MemoryLockBytes::acquire (void)
784 return OStoreObject::acquire();
787 oslInterlockedCount SAL_CALL
MemoryLockBytes::release (void)
789 return OStoreObject::release();
792 storeError
MemoryLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
794 storeError result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
795 if (result
== store_E_None
)
797 // @see readPageAt_Impl().
798 m_xAllocator
= rxAllocator
;
803 storeError
MemoryLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
805 if (m_xAllocator
.is())
807 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
811 if (!m_xAllocator
.is())
812 return store_E_InvalidAccess
;
814 return store_E_OutOfMemory
;
816 PageData
* pagedata
= rPage
.get();
817 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
820 storeError
MemoryLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
822 PageData
const * pagedata
= rPage
.get();
823 OSL_PRECOND(!(pagedata
== 0), "contract violation");
824 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
827 storeError
MemoryLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
829 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
830 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
831 return store_E_NotExists
;
833 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
834 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
835 return store_E_CantRead
;
837 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
841 storeError
MemoryLockBytes::writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
)
843 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
844 OSL_PRECOND(dst_size
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
845 if (dst_size
> m_nSize
)
847 storeError eErrCode
= setSize_Impl (sal::static_int_cast
<sal_uInt32
>(dst_size
));
848 if (eErrCode
!= store_E_None
)
851 OSL_POSTCOND(dst_size
<= m_nSize
, "store::MemoryLockBytes::setSize_Impl() contract violation");
853 sal_uInt8
* dst_lo
= m_pData
+ nOffset
;
854 if (dst_lo
>= m_pData
+ m_nSize
)
855 return store_E_CantSeek
;
857 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
858 if (dst_hi
> m_pData
+ m_nSize
)
859 return store_E_CantWrite
;
861 memcpy (dst_lo
, pBuffer
, (dst_hi
- dst_lo
));
865 storeError
MemoryLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
871 storeError
MemoryLockBytes::setSize_Impl (sal_uInt32 nSize
)
873 if (nSize
!= m_nSize
)
875 sal_uInt8
* pData
= reinterpret_cast<sal_uInt8
*>(rtl_reallocateMemory (m_pData
, nSize
));
879 memset (pData
+ m_nSize
, 0, sal::static_int_cast
<size_t>(nSize
- m_nSize
));
884 return store_E_OutOfMemory
;
886 m_pData
= pData
, m_nSize
= nSize
;
891 storeError
MemoryLockBytes::flush_Impl()
896 /*========================================================================
898 * ILockBytes factory implementations.
900 *======================================================================*/
904 template< class T
> struct ResourceHolder
906 typedef typename
T::destructor_type destructor_type
;
910 explicit ResourceHolder (T
const & value
= T()) : m_value (value
) {}
911 ~ResourceHolder() { reset(); }
913 T
& get() { return m_value
; }
914 T
const & get() const { return m_value
; }
916 void set (T
const & value
) { m_value
= value
; }
917 void reset (T
const & value
= T())
921 destructor_type()(tmp
);
931 ResourceHolder (ResourceHolder
& rhs
)
935 ResourceHolder
& operator= (ResourceHolder
& rhs
)
937 reset (rhs
.release());
943 FileLockBytes_createInstance (
944 rtl::Reference
< ILockBytes
> & rxLockBytes
,
945 rtl_uString
* pFilename
,
946 storeAccessMode eAccessMode
949 // Acquire file handle.
950 ResourceHolder
<FileHandle
> xFile
;
951 storeError result
= xFile
.get().initialize (pFilename
, eAccessMode
);
952 if (result
!= store_E_None
)
955 if (eAccessMode
== store_AccessReadOnly
)
957 ResourceHolder
<FileMapping
> xMapping
;
958 if (xMapping
.get().initialize (xFile
.get().m_handle
) == osl_File_E_None
)
960 rxLockBytes
= new MappedLockBytes (xMapping
.get());
961 if (!rxLockBytes
.is())
962 return store_E_OutOfMemory
;
963 (void) xMapping
.release();
966 if (!rxLockBytes
.is())
968 rxLockBytes
= new FileLockBytes (xFile
.get());
969 if (!rxLockBytes
.is())
970 return store_E_OutOfMemory
;
971 (void) xFile
.release();
978 MemoryLockBytes_createInstance (
979 rtl::Reference
< ILockBytes
> & rxLockBytes
982 rxLockBytes
= new MemoryLockBytes();
983 if (!rxLockBytes
.is())
984 return store_E_OutOfMemory
;