Bug Summary

File:store/source/storlckb.cxx
Location:line 259, column 26
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 "storlckb.hxx"
22
23#include "sal/types.h"
24#include "sal/macros.h"
25#include "rtl/string.h"
26#include "rtl/ref.hxx"
27#include "osl/mutex.hxx"
28
29#include "store/types.h"
30#include "object.hxx"
31
32#include "storbase.hxx"
33#include "stordata.hxx"
34#include "storpage.hxx"
35
36using namespace store;
37
38/*========================================================================
39 *
40 * OStoreLockBytes implementation.
41 *
42 *======================================================================*/
43const sal_uInt32 OStoreLockBytes::m_nTypeId = sal_uInt32(0x94190310);
44
45/*
46 * OStoreLockBytes.
47 */
48OStoreLockBytes::OStoreLockBytes (void)
49 : m_xManager (),
50 m_xNode (),
51 m_bWriteable (false)
52{
53}
54
55/*
56 * ~OStoreLockBytes.
57 */
58OStoreLockBytes::~OStoreLockBytes (void)
59{
60 if (m_xManager.is() && m_xNode.is())
61 {
62 m_xManager->releasePage(m_xNode->m_aDescr);
63 }
64}
65
66/*
67 * isKindOf.
68 */
69sal_Bool SAL_CALL OStoreLockBytes::isKindOf (sal_uInt32 nTypeId)
70{
71 return (nTypeId == m_nTypeId);
72}
73
74/*
75 * create.
76 */
77storeError OStoreLockBytes::create (
78 OStorePageManager *pManager,
79 rtl_String *pPath,
80 rtl_String *pName,
81 storeAccessMode eMode)
82{
83 rtl::Reference<OStorePageManager> xManager (pManager);
84 if (!xManager.is())
85 return store_E_InvalidAccess;
86
87 if (!(pPath && pName))
88 return store_E_InvalidParameter;
89
90 OStoreDirectoryPageObject aPage;
91 storeError eErrCode = xManager->iget (
92 aPage, STORE_ATTRIB_ISFILE((sal_uInt32)0x40000000),
93 pPath, pName, eMode);
94 if (eErrCode != store_E_None)
95 return eErrCode;
96
97 if (!(aPage.attrib() & STORE_ATTRIB_ISFILE((sal_uInt32)0x40000000)))
98 {
99 // No ISFILE in older versions (backward compatibility).
100 if (aPage.attrib() & STORE_ATTRIB_ISLINK((sal_uInt32)0x10000000))
101 return store_E_NotFile;
102 }
103
104 // ...
105 inode_holder_type xNode (aPage.get());
106 if (eMode != store_AccessReadOnly)
107 eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadWrite);
108 else
109 eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
110 if (eErrCode != store_E_None)
111 return eErrCode;
112
113 // ...
114 m_xManager = xManager;
115 m_xNode = xNode;
116 m_bWriteable = (eMode != store_AccessReadOnly);
117
118 // Check for truncation.
119 if (eMode == store_AccessCreate)
120 {
121 // Truncate to zero length.
122 eErrCode = setSize(0);
123 }
124 return eErrCode;
125}
126
127/*
128 * readAt.
129 */
130storeError OStoreLockBytes::readAt (
131 sal_uInt32 nOffset,
132 void *pBuffer,
133 sal_uInt32 nBytes,
134 sal_uInt32 &rnDone)
135{
136 rnDone = 0;
137
138 if (!m_xManager.is())
139 return store_E_InvalidAccess;
140
141 if (!pBuffer)
142 return store_E_InvalidParameter;
143 if (!nBytes)
144 return store_E_None;
145
146 // Acquire exclusive access.
147 osl::MutexGuard aGuard (*m_xManager);
148
149 // Determine data length.
150 OStoreDirectoryPageObject aPage (m_xNode.get());
151
152 sal_uInt32 nDataLen = aPage.dataLength();
153 if ((nOffset + nBytes) > nDataLen)
154 nBytes = nDataLen - nOffset;
155
156 // Read data.
157 OStoreDataPageObject aData;
158 sal_uInt8 *pData = (sal_uInt8*)pBuffer;
159 while ((0 < nBytes) && (nOffset < nDataLen))
160 {
161 // Determine 'Offset' scope.
162 inode::ChunkScope eScope = m_xNode->scope (nOffset);
163 if (eScope == inode::SCOPE_INTERNAL)
164 {
165 // Read from inode page (internal scope).
166 inode::ChunkDescriptor aDescr (
167 nOffset, m_xNode->capacity());
168
169 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
170 nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes));
171
172 memcpy (
173 &pData[rnDone],
174 &m_xNode->m_pData[aDescr.m_nOffset],
175 nLength);
176
177 // Adjust counters.
178 rnDone += nLength;
179 nOffset += nLength;
180 nBytes -= nLength;
181 }
182 else
183 {
184 // Read from data page (external scope).
185 inode::ChunkDescriptor aDescr (
186 nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
187
188 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
189 nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes));
190
191 storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
192 if (eErrCode != store_E_None)
193 {
194 if (eErrCode != store_E_NotExists)
195 return eErrCode;
196
197 memset (
198 &pData[rnDone],
199 0,
200 nLength);
201 }
202 else
203 {
204 PageHolderObject< data > xData (aData.makeHolder<data>());
205 memcpy (
206 &pData[rnDone],
207 &xData->m_pData[aDescr.m_nOffset],
208 nLength);
209 }
210
211 // Adjust counters.
212 rnDone += nLength;
213 nOffset += nLength;
214 nBytes -= nLength;
215 }
216 }
217
218 // Done.
219 return store_E_None;
220}
221
222/*
223 * writeAt.
224 */
225storeError OStoreLockBytes::writeAt (
226 sal_uInt32 nOffset,
227 const void *pBuffer,
228 sal_uInt32 nBytes,
229 sal_uInt32 &rnDone)
230{
231 rnDone = 0;
232
233 if (!m_xManager.is())
1
Taking false branch
234 return store_E_InvalidAccess;
235 if (!m_bWriteable)
2
Taking false branch
236 return store_E_AccessViolation;
237
238 if (!pBuffer)
3
Taking false branch
239 return store_E_InvalidParameter;
240 if (!nBytes)
4
Taking false branch
241 return store_E_None;
242
243 // Acquire exclusive access.
244 osl::MutexGuard aGuard (*m_xManager);
245
246 // Write data.
247 OStoreDirectoryPageObject aPage (m_xNode.get());
248 const sal_uInt8 *pData = (const sal_uInt8*)pBuffer;
249
250 storeError eErrCode = store_E_None;
251 while (nBytes > 0)
5
Loop condition is true. Entering loop body
12
Loop condition is true. Entering loop body
252 {
253 // Determine 'Offset' scope.
254 inode::ChunkScope eScope = m_xNode->scope (nOffset);
255 if (eScope == inode::SCOPE_INTERNAL)
6
Taking false branch
13
Taking true branch
256 {
257 // Write to inode page (internal scope).
258 inode::ChunkDescriptor aDescr (
259 nOffset, m_xNode->capacity());
14
Called C++ object pointer is null
260
261 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
262 nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes));
263
264 memcpy (
265 &m_xNode->m_pData[aDescr.m_nOffset],
266 &pData[rnDone], nLength);
267
268 // Mark inode dirty.
269 aPage.touch();
270
271 // Adjust counters.
272 rnDone += nLength;
273 nOffset += nLength;
274 nBytes -= nLength;
275
276 // Adjust data length.
277 if (aPage.dataLength() < nOffset)
278 aPage.dataLength (nOffset);
279 }
280 else
281 {
282 // Write to data page (external scope).
283 OStoreDataPageObject aData;
284
285 inode::ChunkDescriptor aDescr (
286 nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
287
288 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
289 if ((aDescr.m_nOffset > 0) || (nBytes < nLength))
7
Taking false branch
290 {
291 // Unaligned. Need to load/create data page.
292// @@@ loadOrCreate()
293 eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
294 if (eErrCode != store_E_None)
295 {
296 if (eErrCode != store_E_NotExists)
297 return eErrCode;
298
299 eErrCode = aData.construct<data>(m_xManager->allocator());
300 if (eErrCode != store_E_None)
301 return eErrCode;
302 }
303 }
304
305 PageHolderObject< data > xData (aData.makeHolder<data>());
306 if (!xData.is())
8
Taking true branch
307 {
308 eErrCode = aData.construct<data>(m_xManager->allocator());
309 if (eErrCode != store_E_None)
9
Taking false branch
310 return eErrCode;
311 xData = aData.makeHolder<data>();
312 }
313
314 // Modify data page.
315 nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes));
316 memcpy (
317 &xData->m_pData[aDescr.m_nOffset],
318 &pData[rnDone], nLength);
319
320 // Save data page.
321 eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager);
322 if (eErrCode != store_E_None)
10
Taking false branch
323 return eErrCode;
324
325 // Adjust counters.
326 rnDone += nLength;
327 nOffset += nLength;
328 nBytes -= nLength;
329
330 // Adjust data length.
331 if (aPage.dataLength() < nOffset)
11
Taking false branch
332 aPage.dataLength (nOffset);
333 }
334 }
335
336 // Check for modified inode.
337 if (aPage.dirty())
338 return m_xManager->saveObjectAt (aPage, aPage.location());
339 else
340 return store_E_None;
341}
342
343/*
344 * flush.
345 */
346storeError OStoreLockBytes::flush (void)
347{
348 if (!m_xManager.is())
349 return store_E_InvalidAccess;
350
351 return m_xManager->flush();
352}
353
354/*
355 * setSize.
356 */
357storeError OStoreLockBytes::setSize (sal_uInt32 nSize)
358{
359 if (!m_xManager.is())
360 return store_E_InvalidAccess;
361 if (!m_bWriteable)
362 return store_E_AccessViolation;
363
364 // Acquire exclusive access.
365 osl::MutexGuard aGuard (*m_xManager);
366
367 // Determine current length.
368 OStoreDirectoryPageObject aPage (m_xNode.get());
369 sal_uInt32 nDataLen = aPage.dataLength();
370
371 if (nSize == nDataLen)
372 return store_E_None;
373
374 if (nSize < nDataLen)
375 {
376 // Truncate.
377 storeError eErrCode = store_E_None;
378
379 // Determine 'Size' scope.
380 inode::ChunkScope eSizeScope = m_xNode->scope (nSize);
381 if (eSizeScope == inode::SCOPE_INTERNAL)
382 {
383 // Internal 'Size' scope. Determine 'Data' scope.
384 inode::ChunkScope eDataScope = m_xNode->scope (nDataLen);
385 if (eDataScope == inode::SCOPE_EXTERNAL)
386 {
387 // External 'Data' scope. Truncate all external data pages.
388 eErrCode = aPage.truncate (0, *m_xManager);
389 if (eErrCode != store_E_None)
390 return eErrCode;
391 }
392
393 // Truncate internal data page.
394 inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity());
395 memset (
396 &(m_xNode->m_pData[aDescr.m_nOffset]),
397 0, aDescr.m_nLength);
398 }
399 else
400 {
401 // External 'Size' scope. Truncate external data pages.
402 inode::ChunkDescriptor aDescr (
403 nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
404
405 sal_uInt32 nPage = aDescr.m_nPage;
406 if (aDescr.m_nOffset) nPage += 1;
407
408 eErrCode = aPage.truncate (nPage, *m_xManager);
409 if (eErrCode != store_E_None)
410 return eErrCode;
411 }
412 }
413
414 // Set (extended or truncated) size.
415 aPage.dataLength (nSize);
416
417 // Save modified inode.
418 return m_xManager->saveObjectAt (aPage, aPage.location());
419}
420
421/*
422 * stat.
423 */
424storeError OStoreLockBytes::stat (sal_uInt32 &rnSize)
425{
426 rnSize = 0;
427
428 if (!m_xManager.is())
429 return store_E_InvalidAccess;
430
431 OStoreDirectoryPageObject aPage (m_xNode.get());
432 rnSize = aPage.dataLength();
433 return store_E_None;
434}
435
436/* vim:set shiftwidth=4 softtabstop=4 expandtab: */