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 .
20 #include "lockbyte.hxx"
22 #include "boost/noncopyable.hpp"
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"
29 #include "sal/log.hxx"
32 #include "storbase.hxx"
36 using namespace store
;
38 /*========================================================================
40 * ILockBytes (non-virtual interface) implementation.
42 *======================================================================*/
44 storeError
ILockBytes::initialize (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
46 OSL_PRECOND((STORE_MINIMUM_PAGESIZE
<= nPageSize
) && (nPageSize
<= STORE_MAXIMUM_PAGESIZE
), "invalid PageSize");
47 return initialize_Impl (rxAllocator
, nPageSize
);
50 storeError
ILockBytes::readPageAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
52 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readPageAt(): invalid Offset");
53 if (nOffset
== STORE_PAGE_NULL
)
54 return store_E_CantSeek
;
56 return readPageAt_Impl (rPage
, nOffset
);
59 storeError
ILockBytes::writePageAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
61 // [SECURITY:ValInput]
62 PageData
const * pagedata
= rPage
.get();
63 OSL_PRECOND(!(pagedata
== 0), "store::ILockBytes::writePageAt(): invalid Page");
65 return store_E_InvalidParameter
;
67 sal_uInt32
const offset
= pagedata
->location();
68 OSL_PRECOND(!(nOffset
!= offset
), "store::ILockBytes::writePageAt(): inconsistent Offset");
69 if (nOffset
!= offset
)
70 return store_E_InvalidParameter
;
72 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writePageAt(): invalid Offset");
73 if (nOffset
== STORE_PAGE_NULL
)
74 return store_E_CantSeek
;
76 return writePageAt_Impl (rPage
, nOffset
);
79 storeError
ILockBytes::readAt (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
81 // [SECURITY:ValInput]
82 sal_uInt8
* dst_lo
= static_cast<sal_uInt8
*>(pBuffer
);
84 return store_E_InvalidParameter
;
86 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
87 if (!(dst_lo
< dst_hi
))
88 return (dst_lo
> dst_hi
) ? store_E_InvalidParameter
: store_E_None
;
90 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::readAt(): invalid Offset");
91 if (nOffset
== STORE_PAGE_NULL
)
92 return store_E_CantSeek
;
94 sal_uInt64
const src_size
= static_cast<sal_uInt64
>(nOffset
) + nBytes
;
95 if (src_size
> SAL_MAX_UINT32
)
96 return store_E_CantSeek
;
98 return readAt_Impl (nOffset
, dst_lo
, (dst_hi
- dst_lo
));
101 storeError
ILockBytes::writeAt (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
103 // [SECURITY:ValInput]
104 sal_uInt8
const * src_lo
= static_cast<sal_uInt8
const*>(pBuffer
);
106 return store_E_InvalidParameter
;
108 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
109 if (!(src_lo
< src_hi
))
110 return (src_lo
> src_hi
) ? store_E_InvalidParameter
: store_E_None
;
112 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::ILockBytes::writeAt(): invalid Offset");
113 if (nOffset
== STORE_PAGE_NULL
)
114 return store_E_CantSeek
;
116 sal_uInt64
const dst_size
= static_cast<sal_uInt64
>(nOffset
) + nBytes
;
117 if (dst_size
> SAL_MAX_UINT32
)
118 return store_E_CantSeek
;
120 return writeAt_Impl (nOffset
, src_lo
, (src_hi
- src_lo
));
123 storeError
ILockBytes::getSize (sal_uInt32
& rnSize
)
126 return getSize_Impl (rnSize
);
129 storeError
ILockBytes::setSize (sal_uInt32 nSize
)
131 return setSize_Impl (nSize
);
134 storeError
ILockBytes::flush()
139 /*========================================================================
141 * FileLockBytes implementation.
143 *======================================================================*/
149 oslFileHandle m_handle
;
151 FileHandle() : m_handle(0) {}
153 bool operator != (FileHandle
const & rhs
)
155 return (m_handle
!= rhs
.m_handle
);
158 static storeError
errorFromNative (oslFileError eErrno
)
162 case osl_File_E_None
:
165 case osl_File_E_NOENT
:
166 return store_E_NotExists
;
168 case osl_File_E_ACCES
:
169 case osl_File_E_PERM
:
170 return store_E_AccessViolation
;
172 case osl_File_E_AGAIN
:
173 case osl_File_E_DEADLK
:
174 return store_E_LockingViolation
;
176 case osl_File_E_BADF
:
177 return store_E_InvalidHandle
;
179 case osl_File_E_INVAL
:
180 return store_E_InvalidParameter
;
182 case osl_File_E_NOMEM
:
183 return store_E_OutOfMemory
;
185 case osl_File_E_NOSPC
:
186 return store_E_OutOfSpace
;
188 case osl_File_E_OVERFLOW
:
189 return store_E_CantSeek
;
192 return store_E_Unknown
;
196 static sal_uInt32
modeToNative (storeAccessMode eAccessMode
)
198 sal_uInt32 nFlags
= 0;
201 case store_AccessCreate
:
202 case store_AccessReadCreate
:
203 nFlags
|= osl_File_OpenFlag_Create
;
205 case store_AccessReadWrite
:
206 nFlags
|= osl_File_OpenFlag_Write
;
208 case store_AccessReadOnly
:
209 nFlags
|= osl_File_OpenFlag_Read
;
212 OSL_PRECOND(false, "store::FileHandle: unknown storeAccessMode");
217 storeError
initialize (rtl_uString
* pFilename
, storeAccessMode eAccessMode
)
220 sal_uInt32 nFlags
= modeToNative (eAccessMode
);
221 if (!pFilename
|| !nFlags
)
222 return store_E_InvalidParameter
;
224 // Convert into FileUrl.
226 if (osl_getFileURLFromSystemPath (pFilename
, &(aFileUrl
.pData
)) != osl_File_E_None
)
228 // Not system path. Assume file url.
229 rtl_uString_assign (&(aFileUrl
.pData
), pFilename
);
231 if (!aFileUrl
.startsWith("file://"))
233 // Not file url. Assume relative path.
235 (void) osl_getProcessWorkingDir (&(aCwdUrl
.pData
));
237 // Absolute file url.
238 (void) osl_getAbsoluteFileURL (aCwdUrl
.pData
, aFileUrl
.pData
, &(aFileUrl
.pData
));
242 oslFileError result
= osl_openFile (aFileUrl
.pData
, &m_handle
, nFlags
);
243 if (result
== osl_File_E_EXIST
)
245 // Already existing (O_CREAT | O_EXCL).
246 result
= osl_openFile (aFileUrl
.pData
, &m_handle
, osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
);
247 if ((result
== osl_File_E_None
) && (eAccessMode
== store_AccessCreate
))
249 // Truncate existing file.
250 result
= osl_setFileSize (m_handle
, 0);
253 if (result
!= osl_File_E_None
)
254 return errorFromNative(result
);
258 /** @see FileLockBytes destructor
260 static void closeFile (oslFileHandle hFile
)
262 (void) osl_closeFile (hFile
);
265 /** @see ResourceHolder<T>::destructor_type
269 void operator()(FileHandle
& rFile
) const
272 closeFile (rFile
.m_handle
);
276 typedef CloseFile destructor_type
;
279 class FileLockBytes
:
280 public store::OStoreObject
,
281 public store::ILockBytes
,
282 private boost::noncopyable
286 oslFileHandle m_hFile
;
288 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
290 storeError
initSize_Impl (sal_uInt32
& rnSize
);
292 /** ILockBytes implementation.
294 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
) SAL_OVERRIDE
;
296 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
) SAL_OVERRIDE
;
297 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
) SAL_OVERRIDE
;
299 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
) SAL_OVERRIDE
;
300 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
) SAL_OVERRIDE
;
302 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
) SAL_OVERRIDE
;
303 virtual storeError
setSize_Impl (sal_uInt32 nSize
) SAL_OVERRIDE
;
305 virtual storeError
flush_Impl() SAL_OVERRIDE
;
310 explicit FileLockBytes (FileHandle
& rFile
);
315 virtual ~FileLockBytes();
320 FileLockBytes::FileLockBytes (FileHandle
& rFile
)
321 : m_hFile (rFile
.m_handle
), m_nSize (SAL_MAX_UINT32
), m_xAllocator()
325 FileLockBytes::~FileLockBytes()
327 FileHandle::closeFile (m_hFile
);
330 storeError
FileLockBytes::initSize_Impl (sal_uInt32
& rnSize
)
332 /* osl_getFileSize() uses slow 'fstat(h, &size)',
333 * instead of fast 'size = lseek(h, 0, SEEK_END)'.
334 * so, init size here, and track changes.
336 sal_uInt64 uSize
= 0;
337 oslFileError result
= osl_getFileSize (m_hFile
, &uSize
);
338 if (result
!= osl_File_E_None
)
339 return FileHandle::errorFromNative(result
);
340 if (uSize
> SAL_MAX_UINT32
)
341 return store_E_CantSeek
;
343 rnSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
347 storeError
FileLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
349 storeError result
= initSize_Impl (m_nSize
);
350 if (result
!= store_E_None
)
353 result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
354 if (result
!= store_E_None
)
357 // @see readPageAt_Impl().
358 m_xAllocator
= rxAllocator
;
362 storeError
FileLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
364 if (m_xAllocator
.is())
366 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
370 if (!m_xAllocator
.is())
371 return store_E_InvalidAccess
;
373 return store_E_OutOfMemory
;
375 PageData
* pagedata
= rPage
.get();
376 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
379 storeError
FileLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
381 PageData
const * pagedata
= rPage
.get();
382 OSL_PRECOND(pagedata
!= 0, "contract violation");
383 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
386 storeError
FileLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
388 sal_uInt64 nDone
= 0;
389 oslFileError result
= osl_readFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
390 if (result
!= osl_File_E_None
)
391 return FileHandle::errorFromNative(result
);
393 return (nDone
!= 0) ? store_E_CantRead
: store_E_NotExists
;
397 storeError
FileLockBytes::writeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
399 sal_uInt64 nDone
= 0;
400 oslFileError result
= osl_writeFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
401 if (result
!= osl_File_E_None
)
402 return FileHandle::errorFromNative(result
);
404 return store_E_CantWrite
;
406 sal_uInt64
const uSize
= nOffset
+ nBytes
;
407 OSL_PRECOND(uSize
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
409 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
413 storeError
FileLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
419 storeError
FileLockBytes::setSize_Impl (sal_uInt32 nSize
)
421 oslFileError result
= osl_setFileSize (m_hFile
, nSize
);
422 if (result
!= osl_File_E_None
)
423 return FileHandle::errorFromNative(result
);
429 storeError
FileLockBytes::flush_Impl()
431 oslFileError result
= osl_syncFile (m_hFile
);
432 if (result
!= osl_File_E_None
)
433 return FileHandle::errorFromNative(result
);
437 /*========================================================================
439 * MappedLockBytes implementation.
441 *======================================================================*/
449 oslFileHandle m_hFile
;
451 FileMapping() : m_pAddr(0), m_nSize(0), m_hFile(0) {}
453 bool operator != (FileMapping
const & rhs
) const
455 return ((m_pAddr
!= rhs
.m_pAddr
) || (m_nSize
!= rhs
.m_nSize
));
458 oslFileError
initialize (oslFileHandle hFile
)
460 // Determine mapping size.
461 sal_uInt64 uSize
= 0;
462 oslFileError result
= osl_getFileSize (hFile
, &uSize
);
463 if (result
!= osl_File_E_None
)
466 // [SECURITY:IntOver]
467 if (uSize
> SAL_MAX_UINT32
)
468 return osl_File_E_OVERFLOW
;
469 m_nSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
474 return osl_mapFile (hFile
, reinterpret_cast<void**>(&m_pAddr
), m_nSize
, 0, osl_File_MapFlag_RandomAccess
);
477 /** @see MappedLockBytes::destructor.
479 static void unmapFile (oslFileHandle hFile
, sal_uInt8
* pAddr
, sal_uInt32 nSize
)
481 (void) osl_unmapMappedFile (hFile
, pAddr
, nSize
);
482 (void) osl_closeFile (hFile
);
485 /** @see ResourceHolder<T>::destructor_type
489 void operator ()(FileMapping
& rMapping
) const
492 unmapFile (rMapping
.m_hFile
, rMapping
.m_pAddr
, rMapping
.m_nSize
);
493 rMapping
.m_pAddr
= 0, rMapping
.m_nSize
= 0;
496 typedef UnmapFile destructor_type
;
499 class MappedLockBytes
:
500 public store::OStoreObject
,
501 public store::PageData::Allocator
,
502 public store::ILockBytes
,
503 private boost::noncopyable
509 sal_uInt16 m_nPageSize
;
510 oslFileHandle m_hFile
;
512 /** PageData::Allocator implementation.
514 virtual void allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
) SAL_OVERRIDE
;
515 virtual void deallocate_Impl (void * pPage
) SAL_OVERRIDE
;
517 /** ILockBytes implementation.
519 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
) SAL_OVERRIDE
;
521 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
) SAL_OVERRIDE
;
522 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
) SAL_OVERRIDE
;
524 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
) SAL_OVERRIDE
;
525 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
) SAL_OVERRIDE
;
527 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
) SAL_OVERRIDE
;
528 virtual storeError
setSize_Impl (sal_uInt32 nSize
) SAL_OVERRIDE
;
530 virtual storeError
flush_Impl() SAL_OVERRIDE
;
535 explicit MappedLockBytes (FileMapping
& rMapping
);
540 virtual ~MappedLockBytes();
545 MappedLockBytes::MappedLockBytes (FileMapping
& rMapping
)
546 : m_pData (rMapping
.m_pAddr
), m_nSize (rMapping
.m_nSize
), m_nPageSize(0), m_hFile (rMapping
.m_hFile
)
550 MappedLockBytes::~MappedLockBytes()
552 FileMapping::unmapFile (m_hFile
, m_pData
, m_nSize
);
555 void MappedLockBytes::allocate_Impl (void ** ppPage
, sal_uInt16
* pnSize
)
557 OSL_PRECOND((ppPage
!= 0) && (pnSize
!= 0), "contract violation");
558 if ((ppPage
!= 0) && (pnSize
!= 0))
559 *ppPage
= 0, *pnSize
= m_nPageSize
;
562 void MappedLockBytes::deallocate_Impl (void * pPage
)
564 OSL_PRECOND((m_pData
<= pPage
) && (pPage
< m_pData
+ m_nSize
), "contract violation");
565 (void)pPage
; // UNUSED
568 storeError
MappedLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
571 m_nPageSize
= nPageSize
;
575 storeError
MappedLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
577 sal_uInt8
* src_lo
= m_pData
+ nOffset
;
578 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
579 return store_E_NotExists
;
581 sal_uInt8
* src_hi
= src_lo
+ m_nPageSize
;
582 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
583 return store_E_CantRead
;
585 PageHolder
page (reinterpret_cast< PageData
* >(src_lo
), static_cast< PageData::Allocator
* >(this));
591 storeError
MappedLockBytes::writePageAt_Impl (PageHolder
const & /*rPage*/, sal_uInt32
/*nOffset*/)
593 return store_E_AccessViolation
;
596 storeError
MappedLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
598 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
599 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
600 return store_E_NotExists
;
602 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
603 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
604 return store_E_CantRead
;
606 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
610 storeError
MappedLockBytes::writeAt_Impl (sal_uInt32
/*nOffset*/, void const * /*pBuffer*/, sal_uInt32
/*nBytes*/)
612 return store_E_AccessViolation
;
615 storeError
MappedLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
621 storeError
MappedLockBytes::setSize_Impl (sal_uInt32
/*nSize*/)
623 return store_E_AccessViolation
;
626 storeError
MappedLockBytes::flush_Impl()
631 /*========================================================================
633 * MemoryLockBytes implementation.
635 *======================================================================*/
639 class MemoryLockBytes
:
640 public store::OStoreObject
,
641 public store::ILockBytes
,
642 private boost::noncopyable
648 rtl::Reference
< PageData::Allocator
> m_xAllocator
;
650 /** ILockBytes implementation.
652 virtual storeError
initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
) SAL_OVERRIDE
;
654 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
) SAL_OVERRIDE
;
655 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
) SAL_OVERRIDE
;
657 virtual storeError
readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
) SAL_OVERRIDE
;
658 virtual storeError
writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
) SAL_OVERRIDE
;
660 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
) SAL_OVERRIDE
;
661 virtual storeError
setSize_Impl (sal_uInt32 nSize
) SAL_OVERRIDE
;
663 virtual storeError
flush_Impl() SAL_OVERRIDE
;
673 virtual ~MemoryLockBytes();
678 MemoryLockBytes::MemoryLockBytes()
679 : m_pData (0), m_nSize (0), m_xAllocator()
682 MemoryLockBytes::~MemoryLockBytes()
684 rtl_freeMemory (m_pData
);
687 storeError
MemoryLockBytes::initialize_Impl (rtl::Reference
< PageData::Allocator
> & rxAllocator
, sal_uInt16 nPageSize
)
689 storeError result
= PageData::Allocator::createInstance (rxAllocator
, nPageSize
);
690 if (result
== store_E_None
)
692 // @see readPageAt_Impl().
693 m_xAllocator
= rxAllocator
;
698 storeError
MemoryLockBytes::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
700 if (m_xAllocator
.is())
702 PageHolder
page (m_xAllocator
->construct
<PageData
>(), m_xAllocator
);
706 if (!m_xAllocator
.is())
707 return store_E_InvalidAccess
;
709 return store_E_OutOfMemory
;
711 PageData
* pagedata
= rPage
.get();
712 return readAt_Impl (nOffset
, pagedata
, pagedata
->size());
715 storeError
MemoryLockBytes::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
717 PageData
const * pagedata
= rPage
.get();
718 OSL_PRECOND(!(pagedata
== 0), "contract violation");
719 return writeAt_Impl (nOffset
, pagedata
, pagedata
->size());
722 storeError
MemoryLockBytes::readAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
724 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
725 if ((m_pData
> src_lo
) || (src_lo
>= m_pData
+ m_nSize
))
726 return store_E_NotExists
;
728 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
729 if ((m_pData
> src_hi
) || (src_hi
> m_pData
+ m_nSize
))
730 return store_E_CantRead
;
732 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
736 storeError
MemoryLockBytes::writeAt_Impl (sal_uInt32 nOffset
, const void * pBuffer
, sal_uInt32 nBytes
)
738 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
739 OSL_PRECOND(dst_size
< SAL_MAX_UINT32
, "store::ILockBytes::writeAt() contract violation");
740 if (dst_size
> m_nSize
)
742 storeError eErrCode
= setSize_Impl (sal::static_int_cast
<sal_uInt32
>(dst_size
));
743 if (eErrCode
!= store_E_None
)
746 SAL_WARN_IF(dst_size
> m_nSize
, "store", "store::MemoryLockBytes::setSize_Impl() contract violation");
748 sal_uInt8
* dst_lo
= m_pData
+ nOffset
;
749 if (dst_lo
>= m_pData
+ m_nSize
)
750 return store_E_CantSeek
;
752 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
753 if (dst_hi
> m_pData
+ m_nSize
)
754 return store_E_CantWrite
;
756 memcpy (dst_lo
, pBuffer
, (dst_hi
- dst_lo
));
760 storeError
MemoryLockBytes::getSize_Impl (sal_uInt32
& rnSize
)
766 storeError
MemoryLockBytes::setSize_Impl (sal_uInt32 nSize
)
768 if (nSize
!= m_nSize
)
770 sal_uInt8
* pData
= static_cast<sal_uInt8
*>(rtl_reallocateMemory (m_pData
, nSize
));
774 memset (pData
+ m_nSize
, 0, sal::static_int_cast
<size_t>(nSize
- m_nSize
));
779 return store_E_OutOfMemory
;
781 m_pData
= pData
, m_nSize
= nSize
;
786 storeError
MemoryLockBytes::flush_Impl()
791 /*========================================================================
793 * ILockBytes factory implementations.
795 *======================================================================*/
799 template< class T
> struct ResourceHolder
801 typedef typename
T::destructor_type destructor_type
;
805 explicit ResourceHolder (T
const & value
= T()) : m_value (value
) {}
806 ~ResourceHolder() { reset(); }
808 T
& get() { return m_value
; }
809 T
const & get() const { return m_value
; }
811 void set (T
const & value
) { m_value
= value
; }
812 void reset (T
const & value
= T())
816 destructor_type()(tmp
);
826 ResourceHolder (ResourceHolder
& rhs
)
830 ResourceHolder
& operator= (ResourceHolder
& rhs
)
832 reset (rhs
.release());
838 FileLockBytes_createInstance (
839 rtl::Reference
< ILockBytes
> & rxLockBytes
,
840 rtl_uString
* pFilename
,
841 storeAccessMode eAccessMode
844 // Acquire file handle.
845 ResourceHolder
<FileHandle
> xFile
;
846 storeError result
= xFile
.get().initialize (pFilename
, eAccessMode
);
847 if (result
!= store_E_None
)
850 if (eAccessMode
== store_AccessReadOnly
)
852 ResourceHolder
<FileMapping
> xMapping
;
853 if (xMapping
.get().initialize (xFile
.get().m_handle
) == osl_File_E_None
)
855 rxLockBytes
= new MappedLockBytes (xMapping
.get());
856 if (!rxLockBytes
.is())
857 return store_E_OutOfMemory
;
858 (void) xFile
.release();
859 (void) xMapping
.release();
862 if (!rxLockBytes
.is())
864 rxLockBytes
= new FileLockBytes (xFile
.get());
865 if (!rxLockBytes
.is())
866 return store_E_OutOfMemory
;
867 (void) xFile
.release();
874 MemoryLockBytes_createInstance (
875 rtl::Reference
< ILockBytes
> & rxLockBytes
878 rxLockBytes
= new MemoryLockBytes();
879 if (!rxLockBytes
.is())
880 return store_E_OutOfMemory
;
887 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */