1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "lockbyte.hxx"
23 #include "sal/types.h"
24 #include "osl/diagnose.h"
26 #include "osl/process.h"
27 #include "rtl/alloc.h"
28 #include "rtl/ustring.hxx"
31 #include "storbase.hxx"
35 using namespace store
;
37 /*========================================================================
39 * ILockBytes (non-virtual interface) implementation.
41 *======================================================================*/
43 storeError
ILockBytes::initialize (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
45 OSL_PRECOND((STORE_MINIMUM_PAGESIZE
<= nPageSize
) && (nPageSize
<= STORE_MAXIMUM_PAGESIZE
), "invalid PageSize");
46 return initialize_Impl (rxAllocator
, nPageSize
);
49 storeError
ILockBytes::readPageAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
51 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readPageAt(): invalid Offset");
52 if (nOffset
== STORE_PAGE_NULL
)
53 return store_E_CantSeek
;
55 return readPageAt_Impl (rPage
, nOffset
);
58 storeError
ILockBytes::writePageAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
60 // [SECURITY:ValInput]
61 PageData
const * pagedata
= rPage
.get();
62 OSL_PRECOND(!(pagedata
== 0), "store::ILockBytes::writePageAt(): invalid Page");
64 return store_E_InvalidParameter
;
66 sal_uInt32
const offset
= pagedata
->location();
67 OSL_PRECOND(!(nOffset
!= offset
), "store::ILockBytes::writePageAt(): inconsistent Offset");
68 if (nOffset
!= offset
)
69 return store_E_InvalidParameter
;
71 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writePageAt(): invalid Offset");
72 if (nOffset
== STORE_PAGE_NULL
)
73 return store_E_CantSeek
;
75 return writePageAt_Impl (rPage
, nOffset
);
78 storeError
ILockBytes::readAt (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
80 // [SECURITY:ValInput]
81 sal_uInt8
* dst_lo
= static_cast<sal_uInt8
*>(pBuffer
);
83 return store_E_InvalidParameter
;
85 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
86 if (!(dst_lo
< dst_hi
))
87 return (dst_lo
> dst_hi
) ? store_E_InvalidParameter
: store_E_None
;
89 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readAt(): invalid Offset");
90 if (nOffset
== STORE_PAGE_NULL
)
91 return store_E_CantSeek
;
93 sal_uInt64
const src_size
= nOffset
+ nBytes
;
94 if (src_size
> SAL_MAX_UINT32
)
95 return store_E_CantSeek
;
97 return readAt_Impl (nOffset
, dst_lo
, (dst_hi
- dst_lo
));
100 storeError
ILockBytes::writeAt (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
102 // [SECURITY:ValInput]
103 sal_uInt8
const * src_lo
= static_cast<sal_uInt8
const*>(pBuffer
);
105 return store_E_InvalidParameter
;
107 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
108 if (!(src_lo
< src_hi
))
109 return (src_lo
> src_hi
) ? store_E_InvalidParameter
: store_E_None
;
111 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writeAt(): invalid Offset");
112 if (nOffset
== STORE_PAGE_NULL
)
113 return store_E_CantSeek
;
115 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
116 if (dst_size
> SAL_MAX_UINT32
)
117 return store_E_CantSeek
;
119 return writeAt_Impl (nOffset
, src_lo
, (src_hi
- src_lo
));
122 storeError
ILockBytes::getSize (sal_uInt32
& rnSize
)
125 return getSize_Impl (rnSize
);
128 storeError
ILockBytes::setSize (sal_uInt32 nSize
)
130 return setSize_Impl (nSize
);
133 storeError
ILockBytes::flush()
138 /*========================================================================
140 * FileLockBytes implementation.
142 *======================================================================*/
148 oslFileHandle m_handle
;
150 FileHandle() : m_handle(0) {}
152 bool operator != (FileHandle
const & rhs
)
154 return (m_handle
!= rhs
.m_handle
);
157 static storeError
errorFromNative (oslFileError eErrno
)
161 case osl_File_E_None
:
164 case osl_File_E_NOENT
:
165 return store_E_NotExists
;
167 case osl_File_E_ACCES
:
168 case osl_File_E_PERM
:
169 return store_E_AccessViolation
;
171 case osl_File_E_AGAIN
:
172 case osl_File_E_DEADLK
:
173 return store_E_LockingViolation
;
175 case osl_File_E_BADF
:
176 return store_E_InvalidHandle
;
178 case osl_File_E_INVAL
:
179 return store_E_InvalidParameter
;
181 case osl_File_E_NOMEM
:
182 return store_E_OutOfMemory
;
184 case osl_File_E_NOSPC
:
185 return store_E_OutOfSpace
;
187 case osl_File_E_OVERFLOW
:
188 return store_E_CantSeek
;
191 return store_E_Unknown
;
195 static sal_uInt32
modeToNative (storeAccessMode eAccessMode
)
197 sal_uInt32 nFlags
= 0;
200 case store_AccessCreate
:
201 case store_AccessReadCreate
:
202 nFlags
|= osl_File_OpenFlag_Create
;
204 case store_AccessReadWrite
:
205 nFlags
|= osl_File_OpenFlag_Write
;
207 case store_AccessReadOnly
:
208 nFlags
|= osl_File_OpenFlag_Read
;
211 OSL_PRECOND(0, "store::FileHandle: unknown storeAccessMode");
216 storeError
initialize (rtl_uString
* pFilename
, storeAccessMode eAccessMode
)
219 sal_uInt32 nFlags
= modeToNative (eAccessMode
);
220 if (!pFilename
|| !nFlags
)
221 return store_E_InvalidParameter
;
223 // Convert into FileUrl.
225 if (osl_getFileURLFromSystemPath (pFilename
, &(aFileUrl
.pData
)) != osl_File_E_None
)
227 // Not system path. Assume file url.
228 rtl_uString_assign (&(aFileUrl
.pData
), pFilename
);
230 if (!aFileUrl
.startsWith("file://"))
232 // Not file url. Assume relative path.
234 (void) osl_getProcessWorkingDir (&(aCwdUrl
.pData
));
236 // Absolute file url.
237 (void) osl_getAbsoluteFileURL (aCwdUrl
.pData
, aFileUrl
.pData
, &(aFileUrl
.pData
));
241 oslFileError result
= osl_openFile (aFileUrl
.pData
, &m_handle
, nFlags
);
242 if (result
== osl_File_E_EXIST
)
244 // Already existing (O_CREAT | O_EXCL).
245 result
= osl_openFile (aFileUrl
.pData
, &m_handle
, osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
246 if ((result
== osl_File_E_None
) && (eAccessMode
== store_AccessCreate
))
248 // Truncate existing file.
249 result
= osl_setFileSize (m_handle
, 0);
252 if (result
!= osl_File_E_None
)
253 return errorFromNative(result
);
257 /** @see FileLockBytes destructor
259 static void closeFile (oslFileHandle hFile
)
261 (void) osl_closeFile (hFile
);
264 /** @see ResourceHolder<T>::destructor_type
268 void operator()(FileHandle
& rFile
) const
271 closeFile (rFile
.m_handle
);
275 typedef CloseFile destructor_type
;
278 class FileLockBytes
:
279 public store::OStoreObject
,
280 public store::ILockBytes
284 oslFileHandle m_hFile
;
286 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
288 storeError
initSize_Impl (sal_uInt32
& rnSize
);
290 /** ILockBytes implementation.
292 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
294 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
295 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
297 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
298 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
);
300 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
301 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
303 virtual storeError
flush_Impl();
307 FileLockBytes (FileLockBytes
const &);
308 FileLockBytes
& operator= (FileLockBytes
const &);
313 explicit FileLockBytes (FileHandle
& rFile
);
315 /** Delegate multiple inherited IReference.
317 virtual oslInterlockedCount SAL_CALL
acquire();
318 virtual oslInterlockedCount SAL_CALL
release();
323 virtual ~FileLockBytes();
328 FileLockBytes::FileLockBytes (FileHandle
& rFile
)
329 : m_hFile (rFile
.m_handle
), m_nSize (SAL_MAX_UINT32
), m_xAllocator()
333 FileLockBytes::~FileLockBytes()
335 FileHandle::closeFile (m_hFile
);
338 oslInterlockedCount SAL_CALL
FileLockBytes::acquire()
340 return OStoreObject::acquire();
343 oslInterlockedCount SAL_CALL
FileLockBytes::release()
345 return OStoreObject::release();
348 storeError
FileLockBytes::initSize_Impl (sal_uInt32
& rnSize
)
350 /* osl_getFileSize() uses slow 'fstat(h, &size)',
351 * instead of fast 'size = lseek(h, 0, SEEK_END)'.
352 * so, init size here, and track changes.
354 sal_uInt64 uSize
= 0;
355 oslFileError result
= osl_getFileSize (m_hFile
, &uSize
);
356 if (result
!= osl_File_E_None
)
357 return FileHandle::errorFromNative(result
);
358 if (uSize
> SAL_MAX_UINT32
)
359 return store_E_CantSeek
;
361 rnSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
365 storeError
FileLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
367 storeError result
= initSize_Impl (m_nSize
);
368 if (result
!= store_E_None
)
371 result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
372 if (result
!= store_E_None
)
375 // @see readPageAt_Impl().
376 m_xAllocator
= rxAllocator
;
380 storeError
FileLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
382 if (m_xAllocator
.is())
384 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
388 if (!m_xAllocator
.is())
389 return store_E_InvalidAccess
;
391 return store_E_OutOfMemory
;
393 PageData
* pagedata
= rPage
.get();
394 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
397 storeError
FileLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
399 PageData
const * pagedata
= rPage
.get();
400 OSL_PRECOND(pagedata
!= 0, "contract violation");
401 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
404 storeError
FileLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
406 sal_uInt64 nDone
= 0;
407 oslFileError result
= osl_readFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
408 if (result
!= osl_File_E_None
)
409 return FileHandle::errorFromNative(result
);
411 return (nDone
!= 0) ? store_E_CantRead
: store_E_NotExists
;
415 storeError
FileLockBytes::writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
417 sal_uInt64 nDone
= 0;
418 oslFileError result
= osl_writeFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
419 if (result
!= osl_File_E_None
)
420 return FileHandle::errorFromNative(result
);
422 return store_E_CantWrite
;
424 sal_uInt64
const uSize
= nOffset
+ nBytes
;
425 OSL_PRECOND(uSize
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
427 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
431 storeError
FileLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
437 storeError
FileLockBytes::setSize_Impl (sal_uInt32 nSize
)
439 oslFileError result
= osl_setFileSize (m_hFile
, nSize
);
440 if (result
!= osl_File_E_None
)
441 return FileHandle::errorFromNative(result
);
447 storeError
FileLockBytes::flush_Impl()
449 oslFileError result
= osl_syncFile (m_hFile
);
450 if (result
!= osl_File_E_None
)
451 return FileHandle::errorFromNative(result
);
455 /*========================================================================
457 * MappedLockBytes implementation.
459 *======================================================================*/
467 oslFileHandle m_hFile
;
469 FileMapping() : m_pAddr(0), m_nSize(0), m_hFile(0) {}
471 bool operator != (FileMapping
const & rhs
) const
473 return ((m_pAddr
!= rhs
.m_pAddr
) || (m_nSize
!= rhs
.m_nSize
));
476 oslFileError
initialize (oslFileHandle hFile
)
478 // Determine mapping size.
479 sal_uInt64 uSize
= 0;
480 oslFileError result
= osl_getFileSize (hFile
, &uSize
);
481 if (result
!= osl_File_E_None
)
484 // [SECURITY:IntOver]
485 if (uSize
> SAL_MAX_UINT32
)
486 return osl_File_E_OVERFLOW
;
487 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
492 return osl_mapFile (hFile
, reinterpret_cast<void**>(&m_pAddr
), m_nSize
, 0, osl_File_MapFlag_RandomAccess
);
495 /** @see MappedLockBytes::destructor.
497 static void unmapFile (oslFileHandle hFile
, sal_uInt8
* pAddr
, sal_uInt32 nSize
)
499 (void) osl_unmapMappedFile (hFile
, pAddr
, nSize
);
500 (void) osl_closeFile (hFile
);
503 /** @see ResourceHolder<T>::destructor_type
507 void operator ()(FileMapping
& rMapping
) const
510 unmapFile (rMapping
.m_hFile
, rMapping
.m_pAddr
, rMapping
.m_nSize
);
511 rMapping
.m_pAddr
= 0, rMapping
.m_nSize
= 0;
514 typedef UnmapFile destructor_type
;
517 class MappedLockBytes
:
518 public store::OStoreObject
,
519 public store::PageData::Allocator
,
520 public store::ILockBytes
526 sal_uInt16 m_nPageSize
;
527 oslFileHandle m_hFile
;
529 /** PageData::Allocator implementation.
531 virtual void allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
);
532 virtual void deallocate_Impl (void * pPage
);
534 /** ILockBytes implementation.
536 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
538 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
539 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
541 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
542 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
);
544 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
545 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
547 virtual storeError
flush_Impl();
551 MappedLockBytes (MappedLockBytes
const &);
552 MappedLockBytes
& operator= (MappedLockBytes
const &);
557 explicit MappedLockBytes (FileMapping
& rMapping
);
559 /** Delegate multiple inherited IReference.
561 virtual oslInterlockedCount SAL_CALL
acquire();
562 virtual oslInterlockedCount SAL_CALL
release();
567 virtual ~MappedLockBytes();
572 MappedLockBytes::MappedLockBytes (FileMapping
& rMapping
)
573 : m_pData (rMapping
.m_pAddr
), m_nSize (rMapping
.m_nSize
), m_nPageSize(0), m_hFile (rMapping
.m_hFile
)
577 MappedLockBytes::~MappedLockBytes()
579 FileMapping::unmapFile (m_hFile
, m_pData
, m_nSize
);
582 oslInterlockedCount SAL_CALL
MappedLockBytes::acquire()
584 return OStoreObject::acquire();
587 oslInterlockedCount SAL_CALL
MappedLockBytes::release()
589 return OStoreObject::release();
592 void MappedLockBytes::allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
)
594 OSL_PRECOND((ppPage
!= 0) && (pnSize
!= 0), "contract violation");
595 if ((ppPage
!= 0) && (pnSize
!= 0))
596 *ppPage
= 0, *pnSize
= m_nPageSize
;
599 void MappedLockBytes::deallocate_Impl (void * pPage
)
601 OSL_PRECOND((m_pData
<= pPage
) && (pPage
< m_pData
+ m_nSize
), "contract violation");
602 (void)pPage
; // UNUSED
605 storeError
MappedLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
608 m_nPageSize
= nPageSize
;
612 storeError
MappedLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
614 sal_uInt8
* src_lo
= m_pData
+ nOffset
;
615 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
616 return store_E_NotExists
;
618 sal_uInt8
* src_hi
= src_lo
+ m_nPageSize
;
619 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
620 return store_E_CantRead
;
622 PageHolder
page (reinterpret_cast< PageData
* >(src_lo
), static_cast< PageData::Allocator
* >(this));
628 storeError
MappedLockBytes::writePageAt_Impl (PageHolder
const & /*rPage*/, sal_uInt32
/*nOffset*/)
630 return store_E_AccessViolation
;
633 storeError
MappedLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
635 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
636 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
637 return store_E_NotExists
;
639 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
640 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
641 return store_E_CantRead
;
643 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
647 storeError
MappedLockBytes::writeAt_Impl (sal_uInt32
/*nOffset*/, void const * /*pBuffer*/, sal_uInt32
/*nBytes*/)
649 return store_E_AccessViolation
;
652 storeError
MappedLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
658 storeError
MappedLockBytes::setSize_Impl (sal_uInt32
/*nSize*/)
660 return store_E_AccessViolation
;
663 storeError
MappedLockBytes::flush_Impl()
668 /*========================================================================
670 * MemoryLockBytes implementation.
672 *======================================================================*/
676 class MemoryLockBytes
:
677 public store::OStoreObject
,
678 public store::ILockBytes
684 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
686 /** ILockBytes implementation.
688 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
);
690 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
691 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
693 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
694 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
);
696 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
697 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
699 virtual storeError
flush_Impl();
703 MemoryLockBytes (MemoryLockBytes
const &);
704 MemoryLockBytes
& operator= (MemoryLockBytes
const &);
711 /** Delegate multiple inherited IReference.
713 virtual oslInterlockedCount SAL_CALL
acquire();
714 virtual oslInterlockedCount SAL_CALL
release();
719 virtual ~MemoryLockBytes();
724 MemoryLockBytes::MemoryLockBytes()
725 : m_pData (0), m_nSize (0), m_xAllocator()
728 MemoryLockBytes::~MemoryLockBytes()
730 rtl_freeMemory (m_pData
);
733 oslInterlockedCount SAL_CALL
MemoryLockBytes::acquire (void)
735 return OStoreObject::acquire();
738 oslInterlockedCount SAL_CALL
MemoryLockBytes::release (void)
740 return OStoreObject::release();
743 storeError
MemoryLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
745 storeError result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
746 if (result
== store_E_None
)
748 // @see readPageAt_Impl().
749 m_xAllocator
= rxAllocator
;
754 storeError
MemoryLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
756 if (m_xAllocator
.is())
758 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
762 if (!m_xAllocator
.is())
763 return store_E_InvalidAccess
;
765 return store_E_OutOfMemory
;
767 PageData
* pagedata
= rPage
.get();
768 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
771 storeError
MemoryLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
773 PageData
const * pagedata
= rPage
.get();
774 OSL_PRECOND(!(pagedata
== 0), "contract violation");
775 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
778 storeError
MemoryLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
780 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
781 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
782 return store_E_NotExists
;
784 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
785 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
786 return store_E_CantRead
;
788 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
792 storeError
MemoryLockBytes::writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
)
794 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
795 OSL_PRECOND(dst_size
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
796 if (dst_size
> m_nSize
)
798 storeError eErrCode
= setSize_Impl (sal::static_int_cast
<sal_uInt32
>(dst_size
));
799 if (eErrCode
!= store_E_None
)
802 OSL_POSTCOND(dst_size
<= m_nSize
, "store::MemoryLockBytes::setSize_Impl() contract violation");
804 sal_uInt8
* dst_lo
= m_pData
+ nOffset
;
805 if (dst_lo
>= m_pData
+ m_nSize
)
806 return store_E_CantSeek
;
808 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
809 if (dst_hi
> m_pData
+ m_nSize
)
810 return store_E_CantWrite
;
812 memcpy (dst_lo
, pBuffer
, (dst_hi
- dst_lo
));
816 storeError
MemoryLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
822 storeError
MemoryLockBytes::setSize_Impl (sal_uInt32 nSize
)
824 if (nSize
!= m_nSize
)
826 sal_uInt8
* pData
= reinterpret_cast<sal_uInt8
*>(rtl_reallocateMemory (m_pData
, nSize
));
830 memset (pData
+ m_nSize
, 0, sal::static_int_cast
<size_t>(nSize
- m_nSize
));
835 return store_E_OutOfMemory
;
837 m_pData
= pData
, m_nSize
= nSize
;
842 storeError
MemoryLockBytes::flush_Impl()
847 /*========================================================================
849 * ILockBytes factory implementations.
851 *======================================================================*/
855 template< class T
> struct ResourceHolder
857 typedef typename
T::destructor_type destructor_type
;
861 explicit ResourceHolder (T
const & value
= T()) : m_value (value
) {}
862 ~ResourceHolder() { reset(); }
864 T
& get() { return m_value
; }
865 T
const & get() const { return m_value
; }
867 void set (T
const & value
) { m_value
= value
; }
868 void reset (T
const & value
= T())
872 destructor_type()(tmp
);
882 ResourceHolder (ResourceHolder
& rhs
)
886 ResourceHolder
& operator= (ResourceHolder
& rhs
)
888 reset (rhs
.release());
894 FileLockBytes_createInstance (
895 rtl::Reference
< ILockBytes
> & rxLockBytes
,
896 rtl_uString
* pFilename
,
897 storeAccessMode eAccessMode
900 // Acquire file handle.
901 ResourceHolder
<FileHandle
> xFile
;
902 storeError result
= xFile
.get().initialize (pFilename
, eAccessMode
);
903 if (result
!= store_E_None
)
906 if (eAccessMode
== store_AccessReadOnly
)
908 ResourceHolder
<FileMapping
> xMapping
;
909 if (xMapping
.get().initialize (xFile
.get().m_handle
) == osl_File_E_None
)
911 rxLockBytes
= new MappedLockBytes (xMapping
.get());
912 if (!rxLockBytes
.is())
913 return store_E_OutOfMemory
;
914 (void) xFile
.release();
915 (void) xMapping
.release();
918 if (!rxLockBytes
.is())
920 rxLockBytes
= new FileLockBytes (xFile
.get());
921 if (!rxLockBytes
.is())
922 return store_E_OutOfMemory
;
923 (void) xFile
.release();
930 MemoryLockBytes_createInstance (
931 rtl::Reference
< ILockBytes
> & rxLockBytes
934 rxLockBytes
= new MemoryLockBytes();
935 if (!rxLockBytes
.is())
936 return store_E_OutOfMemory
;
943 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */