1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "lockbyte.hxx"
32 #include "sal/types.h"
33 #include "osl/diagnose.h"
35 #include "osl/process.h"
36 #include "rtl/alloc.h"
37 #include "rtl/ustring.hxx"
40 #include "storbase.hxx"
42 #ifndef INCLUDED_STRING_H
44 #define INCLUDED_STRING_H
47 using namespace store
;
49 /*========================================================================
51 * ILockBytes (non-virtual interface) implementation.
53 *======================================================================*/
55 storeError
ILockBytes::initialize (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
57 OSL_PRECOND((STORE_MINIMUM_PAGESIZE
<= nPageSize
) && (nPageSize
<= STORE_MAXIMUM_PAGESIZE
), "invalid PageSize");
58 return initialize_Impl (rxAllocator
, nPageSize
);
61 storeError
ILockBytes::readPageAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
63 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readPageAt(): invalid Offset");
64 if (nOffset
== STORE_PAGE_NULL
)
65 return store_E_CantSeek
;
67 return readPageAt_Impl (rPage
, nOffset
);
70 storeError
ILockBytes::writePageAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
72 // [SECURITY:ValInput]
73 PageData
const * pagedata
= rPage
.get();
74 OSL_PRECOND(!(pagedata
== 0), "store::ILockBytes::writePageAt(): invalid Page");
76 return store_E_InvalidParameter
;
78 sal_uInt32
const offset
= pagedata
->location();
79 OSL_PRECOND(!(nOffset
!= offset
), "store::ILockBytes::writePageAt(): inconsistent Offset");
80 if (nOffset
!= offset
)
81 return store_E_InvalidParameter
;
83 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writePageAt(): invalid Offset");
84 if (nOffset
== STORE_PAGE_NULL
)
85 return store_E_CantSeek
;
87 return writePageAt_Impl (rPage
, nOffset
);
90 storeError
ILockBytes::readAt (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
92 // [SECURITY:ValInput]
93 sal_uInt8
* dst_lo
= static_cast<sal_uInt8
*>(pBuffer
);
95 return store_E_InvalidParameter
;
97 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
98 if (!(dst_lo
< dst_hi
))
99 return (dst_lo
> dst_hi
) ? store_E_InvalidParameter
: store_E_None
;
101 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readAt(): invalid Offset");
102 if (nOffset
== STORE_PAGE_NULL
)
103 return store_E_CantSeek
;
105 sal_uInt64
const src_size
= nOffset
+ nBytes
;
106 if (src_size
> SAL_MAX_UINT32
)
107 return store_E_CantSeek
;
109 return readAt_Impl (nOffset
, dst_lo
, (dst_hi
- dst_lo
));
112 storeError
ILockBytes::writeAt (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
114 // [SECURITY:ValInput]
115 sal_uInt8
const * src_lo
= static_cast<sal_uInt8
const*>(pBuffer
);
117 return store_E_InvalidParameter
;
119 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
120 if (!(src_lo
< src_hi
))
121 return (src_lo
> src_hi
) ? store_E_InvalidParameter
: store_E_None
;
123 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writeAt(): invalid Offset");
124 if (nOffset
== STORE_PAGE_NULL
)
125 return store_E_CantSeek
;
127 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
128 if (dst_size
> SAL_MAX_UINT32
)
129 return store_E_CantSeek
;
131 return writeAt_Impl (nOffset
, src_lo
, (src_hi
- src_lo
));
134 storeError
ILockBytes::getSize (sal_uInt32
& rnSize
)
137 return getSize_Impl (rnSize
);
140 storeError
ILockBytes::setSize (sal_uInt32 nSize
)
142 return setSize_Impl (nSize
);
145 storeError
ILockBytes::flush()
150 /*========================================================================
152 * FileLockBytes implementation.
154 *======================================================================*/
160 oslFileHandle m_handle
;
162 FileHandle() : m_handle(0) {}
164 bool operator != (FileHandle
const & rhs
)
166 return (m_handle
!= rhs
.m_handle
);
169 static storeError
errorFromNative (oslFileError eErrno
)
173 case osl_File_E_None
:
176 case osl_File_E_NOENT
:
177 return store_E_NotExists
;
179 case osl_File_E_ACCES
:
180 case osl_File_E_PERM
:
181 return store_E_AccessViolation
;
183 case osl_File_E_AGAIN
:
184 case osl_File_E_DEADLK
:
185 return store_E_LockingViolation
;
187 case osl_File_E_BADF
:
188 return store_E_InvalidHandle
;
190 case osl_File_E_INVAL
:
191 return store_E_InvalidParameter
;
193 case osl_File_E_NOMEM
:
194 return store_E_OutOfMemory
;
196 case osl_File_E_NOSPC
:
197 return store_E_OutOfSpace
;
199 case osl_File_E_OVERFLOW
:
200 return store_E_CantSeek
;
203 return store_E_Unknown
;
207 static sal_uInt32
modeToNative (storeAccessMode eAccessMode
)
209 sal_uInt32 nFlags
= 0;
212 case store_AccessCreate
:
213 case store_AccessReadCreate
:
214 nFlags
|= osl_File_OpenFlag_Create
;
216 case store_AccessReadWrite
:
217 nFlags
|= osl_File_OpenFlag_Write
;
219 case store_AccessReadOnly
:
220 nFlags
|= osl_File_OpenFlag_Read
;
223 OSL_PRECOND(0, "store::FileHandle: unknown storeAccessMode");
228 storeError
initialize (rtl_uString
* pFilename
, storeAccessMode eAccessMode
)
231 sal_uInt32 nFlags
= modeToNative (eAccessMode
);
232 if (!pFilename
|| !nFlags
)
233 return store_E_InvalidParameter
;
235 // Convert into FileUrl.
236 rtl::OUString aFileUrl
;
237 if (osl_getFileURLFromSystemPath (pFilename
, &(aFileUrl
.pData
)) != osl_File_E_None
)
239 // Not system path. Assume file url.
240 rtl_uString_assign (&(aFileUrl
.pData
), pFilename
);
242 if (aFileUrl
.compareToAscii("file://", 7) != 0)
244 // Not file url. Assume relative path.
245 rtl::OUString aCwdUrl
;
246 (void) osl_getProcessWorkingDir (&(aCwdUrl
.pData
));
248 // Absolute file url.
249 (void) osl_getAbsoluteFileURL (aCwdUrl
.pData
, aFileUrl
.pData
, &(aFileUrl
.pData
));
253 oslFileError result
= osl_openFile (aFileUrl
.pData
, &m_handle
, nFlags
);
254 if (result
== osl_File_E_EXIST
)
256 // Already existing (O_CREAT | O_EXCL).
257 result
= osl_openFile (aFileUrl
.pData
, &m_handle
, osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
258 if ((result
== osl_File_E_None
) && (eAccessMode
== store_AccessCreate
))
260 // Truncate existing file.
261 result
= osl_setFileSize (m_handle
, 0);
264 if (result
!= osl_File_E_None
)
265 return errorFromNative(result
);
269 /** @see FileLockBytes destructor
271 static void closeFile (oslFileHandle hFile
)
273 (void) osl_closeFile (hFile
);
276 /** @see ResourceHolder<T>::destructor_type
280 void operator()(FileHandle
& rFile
) const
283 closeFile (rFile
.m_handle
);
287 typedef CloseFile destructor_type
;
290 class FileLockBytes
:
291 public store::OStoreObject
,
292 public store::ILockBytes
296 oslFileHandle m_hFile
;
298 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
300 storeError
initSize_Impl (sal_uInt32
& rnSize
);
302 /** ILockBytes implementation.
304 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
306 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
307 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
309 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
310 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
);
312 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
313 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
315 virtual storeError
flush_Impl();
319 FileLockBytes (FileLockBytes
const &);
320 FileLockBytes
& operator= (FileLockBytes
const &);
325 explicit FileLockBytes (FileHandle
& rFile
);
327 /** Delegate multiple inherited IReference.
329 virtual oslInterlockedCount SAL_CALL
acquire();
330 virtual oslInterlockedCount SAL_CALL
release();
335 virtual ~FileLockBytes();
340 FileLockBytes::FileLockBytes (FileHandle
& rFile
)
341 : m_hFile (rFile
.m_handle
), m_nSize (SAL_MAX_UINT32
), m_xAllocator()
345 FileLockBytes::~FileLockBytes()
347 FileHandle::closeFile (m_hFile
);
350 oslInterlockedCount SAL_CALL
FileLockBytes::acquire()
352 return OStoreObject::acquire();
355 oslInterlockedCount SAL_CALL
FileLockBytes::release()
357 return OStoreObject::release();
360 storeError
FileLockBytes::initSize_Impl (sal_uInt32
& rnSize
)
362 /* osl_getFileSize() uses slow 'fstat(h, &size)',
363 * instead of fast 'size = lseek(h, 0, SEEK_END)'.
364 * so, init size here, and track changes.
366 sal_uInt64 uSize
= 0;
367 oslFileError result
= osl_getFileSize (m_hFile
, &uSize
);
368 if (result
!= osl_File_E_None
)
369 return FileHandle::errorFromNative(result
);
370 if (uSize
> SAL_MAX_UINT32
)
371 return store_E_CantSeek
;
373 rnSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
377 storeError
FileLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
379 storeError result
= initSize_Impl (m_nSize
);
380 if (result
!= store_E_None
)
383 result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
384 if (result
!= store_E_None
)
387 // @see readPageAt_Impl().
388 m_xAllocator
= rxAllocator
;
392 storeError
FileLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
394 if (m_xAllocator
.is())
396 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
400 if (!m_xAllocator
.is())
401 return store_E_InvalidAccess
;
403 return store_E_OutOfMemory
;
405 PageData
* pagedata
= rPage
.get();
406 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
409 storeError
FileLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
411 PageData
const * pagedata
= rPage
.get();
412 OSL_PRECOND(pagedata
!= 0, "contract violation");
413 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
416 storeError
FileLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
418 sal_uInt64 nDone
= 0;
419 oslFileError result
= osl_readFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
420 if (result
!= osl_File_E_None
)
421 return FileHandle::errorFromNative(result
);
423 return (nDone
!= 0) ? store_E_CantRead
: store_E_NotExists
;
427 storeError
FileLockBytes::writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
429 sal_uInt64 nDone
= 0;
430 oslFileError result
= osl_writeFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
431 if (result
!= osl_File_E_None
)
432 return FileHandle::errorFromNative(result
);
434 return store_E_CantWrite
;
436 sal_uInt64
const uSize
= nOffset
+ nBytes
;
437 OSL_PRECOND(uSize
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
439 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
443 storeError
FileLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
449 storeError
FileLockBytes::setSize_Impl (sal_uInt32 nSize
)
451 oslFileError result
= osl_setFileSize (m_hFile
, nSize
);
452 if (result
!= osl_File_E_None
)
453 return FileHandle::errorFromNative(result
);
459 storeError
FileLockBytes::flush_Impl()
461 oslFileError result
= osl_syncFile (m_hFile
);
462 if (result
!= osl_File_E_None
)
463 return FileHandle::errorFromNative(result
);
467 /*========================================================================
469 * MappedLockBytes implementation.
471 *======================================================================*/
479 oslFileHandle m_hFile
;
481 FileMapping() : m_pAddr(0), m_nSize(0), m_hFile(0) {}
483 bool operator != (FileMapping
const & rhs
) const
485 return ((m_pAddr
!= rhs
.m_pAddr
) || (m_nSize
!= rhs
.m_nSize
));
488 oslFileError
initialize (oslFileHandle hFile
)
490 // Determine mapping size.
491 sal_uInt64 uSize
= 0;
492 oslFileError result
= osl_getFileSize (hFile
, &uSize
);
493 if (result
!= osl_File_E_None
)
496 // [SECURITY:IntOver]
497 if (uSize
> SAL_MAX_UINT32
)
498 return osl_File_E_OVERFLOW
;
499 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
504 return osl_mapFile (hFile
, reinterpret_cast<void**>(&m_pAddr
), m_nSize
, 0, osl_File_MapFlag_RandomAccess
);
507 /** @see MappedLockBytes::destructor.
509 static void unmapFile (oslFileHandle hFile
, sal_uInt8
* pAddr
, sal_uInt32 nSize
)
511 (void) osl_unmapMappedFile (hFile
, pAddr
, nSize
);
512 (void) osl_closeFile (hFile
);
515 /** @see ResourceHolder<T>::destructor_type
519 void operator ()(FileMapping
& rMapping
) const
522 unmapFile (rMapping
.m_hFile
, rMapping
.m_pAddr
, rMapping
.m_nSize
);
523 rMapping
.m_pAddr
= 0, rMapping
.m_nSize
= 0;
526 typedef UnmapFile destructor_type
;
529 class MappedLockBytes
:
530 public store::OStoreObject
,
531 public store::PageData::Allocator
,
532 public store::ILockBytes
538 sal_uInt16 m_nPageSize
;
539 oslFileHandle m_hFile
;
541 /** PageData::Allocator implementation.
543 virtual void allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
);
544 virtual void deallocate_Impl (void * pPage
);
546 /** ILockBytes implementation.
548 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
550 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
551 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
553 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
554 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
);
556 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
557 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
559 virtual storeError
flush_Impl();
563 MappedLockBytes (MappedLockBytes
const &);
564 MappedLockBytes
& operator= (MappedLockBytes
const &);
569 explicit MappedLockBytes (FileMapping
& rMapping
);
571 /** Delegate multiple inherited IReference.
573 virtual oslInterlockedCount SAL_CALL
acquire();
574 virtual oslInterlockedCount SAL_CALL
release();
579 virtual ~MappedLockBytes();
584 MappedLockBytes::MappedLockBytes (FileMapping
& rMapping
)
585 : m_pData (rMapping
.m_pAddr
), m_nSize (rMapping
.m_nSize
), m_nPageSize(0), m_hFile (rMapping
.m_hFile
)
589 MappedLockBytes::~MappedLockBytes()
591 FileMapping::unmapFile (m_hFile
, m_pData
, m_nSize
);
594 oslInterlockedCount SAL_CALL
MappedLockBytes::acquire()
596 return OStoreObject::acquire();
599 oslInterlockedCount SAL_CALL
MappedLockBytes::release()
601 return OStoreObject::release();
604 void MappedLockBytes::allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
)
606 OSL_PRECOND((ppPage
!= 0) && (pnSize
!= 0), "contract violation");
607 if ((ppPage
!= 0) && (pnSize
!= 0))
608 *ppPage
= 0, *pnSize
= m_nPageSize
;
611 void MappedLockBytes::deallocate_Impl (void * pPage
)
613 OSL_PRECOND((m_pData
<= pPage
) && (pPage
< m_pData
+ m_nSize
), "contract violation");
614 (void)pPage
; // UNUSED
617 storeError
MappedLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
620 m_nPageSize
= nPageSize
;
624 storeError
MappedLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
626 sal_uInt8
* src_lo
= m_pData
+ nOffset
;
627 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
628 return store_E_NotExists
;
630 sal_uInt8
* src_hi
= src_lo
+ m_nPageSize
;
631 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
632 return store_E_CantRead
;
634 PageHolder
page (reinterpret_cast< PageData
* >(src_lo
), static_cast< PageData::Allocator
* >(this));
640 storeError
MappedLockBytes::writePageAt_Impl (PageHolder
const & /*rPage*/, sal_uInt32
/*nOffset*/)
642 return store_E_AccessViolation
;
645 storeError
MappedLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
647 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
648 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
649 return store_E_NotExists
;
651 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
652 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
653 return store_E_CantRead
;
655 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
659 storeError
MappedLockBytes::writeAt_Impl (sal_uInt32
/*nOffset*/, void const * /*pBuffer*/, sal_uInt32
/*nBytes*/)
661 return store_E_AccessViolation
;
664 storeError
MappedLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
670 storeError
MappedLockBytes::setSize_Impl (sal_uInt32
/*nSize*/)
672 return store_E_AccessViolation
;
675 storeError
MappedLockBytes::flush_Impl()
680 /*========================================================================
682 * MemoryLockBytes implementation.
684 *======================================================================*/
688 class MemoryLockBytes
:
689 public store::OStoreObject
,
690 public store::ILockBytes
696 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
698 /** ILockBytes implementation.
700 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
702 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
703 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
705 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
706 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
);
708 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
709 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
711 virtual storeError
flush_Impl();
715 MemoryLockBytes (MemoryLockBytes
const &);
716 MemoryLockBytes
& operator= (MemoryLockBytes
const &);
723 /** Delegate multiple inherited IReference.
725 virtual oslInterlockedCount SAL_CALL
acquire();
726 virtual oslInterlockedCount SAL_CALL
release();
731 virtual ~MemoryLockBytes();
736 MemoryLockBytes::MemoryLockBytes()
737 : m_pData (0), m_nSize (0), m_xAllocator()
740 MemoryLockBytes::~MemoryLockBytes()
742 rtl_freeMemory (m_pData
);
745 oslInterlockedCount SAL_CALL
MemoryLockBytes::acquire (void)
747 return OStoreObject::acquire();
750 oslInterlockedCount SAL_CALL
MemoryLockBytes::release (void)
752 return OStoreObject::release();
755 storeError
MemoryLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
757 storeError result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
758 if (result
== store_E_None
)
760 // @see readPageAt_Impl().
761 m_xAllocator
= rxAllocator
;
766 storeError
MemoryLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
768 if (m_xAllocator
.is())
770 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
774 if (!m_xAllocator
.is())
775 return store_E_InvalidAccess
;
777 return store_E_OutOfMemory
;
779 PageData
* pagedata
= rPage
.get();
780 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
783 storeError
MemoryLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
785 PageData
const * pagedata
= rPage
.get();
786 OSL_PRECOND(!(pagedata
== 0), "contract violation");
787 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
790 storeError
MemoryLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
792 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
793 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
794 return store_E_NotExists
;
796 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
797 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
798 return store_E_CantRead
;
800 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
804 storeError
MemoryLockBytes::writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
)
806 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
807 OSL_PRECOND(dst_size
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
808 if (dst_size
> m_nSize
)
810 storeError eErrCode
= setSize_Impl (sal::static_int_cast
<sal_uInt32
>(dst_size
));
811 if (eErrCode
!= store_E_None
)
814 OSL_POSTCOND(dst_size
<= m_nSize
, "store::MemoryLockBytes::setSize_Impl() contract violation");
816 sal_uInt8
* dst_lo
= m_pData
+ nOffset
;
817 if (dst_lo
>= m_pData
+ m_nSize
)
818 return store_E_CantSeek
;
820 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
821 if (dst_hi
> m_pData
+ m_nSize
)
822 return store_E_CantWrite
;
824 memcpy (dst_lo
, pBuffer
, (dst_hi
- dst_lo
));
828 storeError
MemoryLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
834 storeError
MemoryLockBytes::setSize_Impl (sal_uInt32 nSize
)
836 if (nSize
!= m_nSize
)
838 sal_uInt8
* pData
= reinterpret_cast<sal_uInt8
*>(rtl_reallocateMemory (m_pData
, nSize
));
842 memset (pData
+ m_nSize
, 0, sal::static_int_cast
<size_t>(nSize
- m_nSize
));
847 return store_E_OutOfMemory
;
849 m_pData
= pData
, m_nSize
= nSize
;
854 storeError
MemoryLockBytes::flush_Impl()
859 /*========================================================================
861 * ILockBytes factory implementations.
863 *======================================================================*/
867 template< class T
> struct ResourceHolder
869 typedef typename
T::destructor_type destructor_type
;
873 explicit ResourceHolder (T
const & value
= T()) : m_value (value
) {}
874 ~ResourceHolder() { reset(); }
876 T
& get() { return m_value
; }
877 T
const & get() const { return m_value
; }
879 void set (T
const & value
) { m_value
= value
; }
880 void reset (T
const & value
= T())
884 destructor_type()(tmp
);
894 ResourceHolder (ResourceHolder
& rhs
)
898 ResourceHolder
& operator= (ResourceHolder
& rhs
)
900 reset (rhs
.release());
906 FileLockBytes_createInstance (
907 rtl::Reference
< ILockBytes
> & rxLockBytes
,
908 rtl_uString
* pFilename
,
909 storeAccessMode eAccessMode
912 // Acquire file handle.
913 ResourceHolder
<FileHandle
> xFile
;
914 storeError result
= xFile
.get().initialize (pFilename
, eAccessMode
);
915 if (result
!= store_E_None
)
918 if (eAccessMode
== store_AccessReadOnly
)
920 ResourceHolder
<FileMapping
> xMapping
;
921 if (xMapping
.get().initialize (xFile
.get().m_handle
) == osl_File_E_None
)
923 rxLockBytes
= new MappedLockBytes (xMapping
.get());
924 if (!rxLockBytes
.is())
925 return store_E_OutOfMemory
;
926 (void) xFile
.release();
927 (void) xMapping
.release();
930 if (!rxLockBytes
.is())
932 rxLockBytes
= new FileLockBytes (xFile
.get());
933 if (!rxLockBytes
.is())
934 return store_E_OutOfMemory
;
935 (void) xFile
.release();
942 MemoryLockBytes_createInstance (
943 rtl::Reference
< ILockBytes
> & rxLockBytes
946 rxLockBytes
= new MemoryLockBytes();
947 if (!rxLockBytes
.is())
948 return store_E_OutOfMemory
;
955 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */