Bug Summary

File:store/source/lockbyte.cxx
Location:line 401, column 45
Description:Called C++ object pointer is null

Annotated Source Code

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