LibreOffice Module store (master) 1
storlckb.cxx
Go to the documentation of this file.
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#include "storlckb.hxx"
21
22#include <sal/types.h>
23#include <rtl/string.h>
24#include <rtl/ref.hxx>
25#include <osl/mutex.hxx>
26
27#include <store/types.h>
28
29#include "storbase.hxx"
30#include "stordata.hxx"
31#include "storpage.hxx"
32
33using namespace store;
34
35const sal_uInt32 OStoreLockBytes::m_nTypeId(0x94190310);
36
37OStoreLockBytes::OStoreLockBytes()
38 : m_bWriteable (false)
39{
40}
41
43{
44 if (m_xManager.is() && m_xNode.is())
45 {
46 m_xManager->releasePage(m_xNode->m_aDescr);
47 }
48}
49
50bool OStoreLockBytes::isKindOf (sal_uInt32 nTypeId)
51{
52 return (nTypeId == m_nTypeId);
53}
54
56 OStorePageManager *pManager,
57 rtl_String const *pPath,
58 rtl_String const *pName,
59 storeAccessMode eMode)
60{
61 rtl::Reference<OStorePageManager> xManager (pManager);
62 if (!xManager.is())
64
65 if (!(pPath && pName))
67
69 storeError eErrCode = xManager->iget (
71 pPath, pName, eMode);
72 if (eErrCode != store_E_None)
73 return eErrCode;
74
75 if (!(aPage.attrib() & STORE_ATTRIB_ISFILE))
76 {
77 // No ISFILE in older versions (backward compatibility).
78 if (aPage.attrib() & STORE_ATTRIB_ISLINK)
79 return store_E_NotFile;
80 }
81
82 inode_holder_type xNode (aPage.get());
84 eErrCode = xManager->acquirePage (xNode->m_aDescr, storeAccessMode::ReadWrite);
85 else
86 eErrCode = xManager->acquirePage (xNode->m_aDescr, storeAccessMode::ReadOnly);
87 if (eErrCode != store_E_None)
88 return eErrCode;
89
90 m_xManager = xManager;
91 m_xNode = xNode;
93
94 // Check for truncation.
96 {
97 // Truncate to zero length.
98 eErrCode = setSize(0);
99 }
100 return eErrCode;
101}
102
104 sal_uInt32 nOffset,
105 void *pBuffer,
106 sal_uInt32 nBytes,
107 sal_uInt32 &rnDone)
108{
109 rnDone = 0;
110
111 if (!m_xManager.is())
113
114 if (!pBuffer)
116 if (!nBytes)
117 return store_E_None;
118
119 // Acquire exclusive access.
120 osl::MutexGuard aGuard (*m_xManager);
121
122 // Determine data length.
124
125 sal_uInt32 nDataLen = aPage.dataLength();
126 if ((nOffset + nBytes) > nDataLen)
127 nBytes = nDataLen - nOffset;
128
129 // Read data.
131 sal_uInt8 *pData = static_cast<sal_uInt8*>(pBuffer);
132 while ((0 < nBytes) && (nOffset < nDataLen))
133 {
134 // Determine 'Offset' scope.
135 inode::ChunkScope eScope = m_xNode->scope (nOffset);
136 if (eScope == inode::SCOPE_INTERNAL)
137 {
138 // Read from inode page (internal scope).
140 nOffset, m_xNode->capacity());
141
142 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
143 if(nLength > nBytes)
144 {
145 nLength = nBytes;
146 }
147 memcpy (
148 &pData[rnDone],
149 &m_xNode->m_pData[aDescr.m_nOffset],
150 nLength);
151
152 // Adjust counters.
153 rnDone += nLength;
154 nOffset += nLength;
155 nBytes -= nLength;
156 }
157 else
158 {
159 // Read from data page (external scope).
162
163 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
164 if(nLength > nBytes)
165 {
166 nLength = nBytes;
167 }
168
169 storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
170 if (eErrCode != store_E_None)
171 {
172 if (eErrCode != store_E_NotExists)
173 return eErrCode;
174
175 memset (
176 &pData[rnDone],
177 0,
178 nLength);
179 }
180 else
181 {
182 PageHolderObject< data > xData (aData.makeHolder<data>());
183 memcpy (
184 &pData[rnDone],
185 &xData->m_pData[aDescr.m_nOffset],
186 nLength);
187 }
188
189 // Adjust counters.
190 rnDone += nLength;
191 nOffset += nLength;
192 nBytes -= nLength;
193 }
194 }
195
196 // Done.
197 return store_E_None;
198}
199
201 sal_uInt32 nOffset,
202 const void *pBuffer,
203 sal_uInt32 nBytes,
204 sal_uInt32 &rnDone)
205{
206 rnDone = 0;
207
208 if (!m_xManager.is())
210 if (!m_bWriteable)
212
213 if (!pBuffer)
215 if (!nBytes)
216 return store_E_None;
217
218 // Acquire exclusive access.
219 osl::MutexGuard aGuard (*m_xManager);
220
221 // Write data.
223 const sal_uInt8 *pData = static_cast<const sal_uInt8*>(pBuffer);
224
225 storeError eErrCode = store_E_None;
226 while (nBytes > 0)
227 {
228 // Determine 'Offset' scope.
229 inode::ChunkScope eScope = m_xNode->scope (nOffset);
230 if (eScope == inode::SCOPE_INTERNAL)
231 {
232 // Write to inode page (internal scope).
234 nOffset, m_xNode->capacity());
235
236 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
237 if(nLength > nBytes)
238 {
239 nLength = nBytes;
240 }
241
242 memcpy (
243 &m_xNode->m_pData[aDescr.m_nOffset],
244 &pData[rnDone], nLength);
245
246 // Mark inode dirty.
247 aPage.touch();
248
249 // Adjust counters.
250 rnDone += nLength;
251 nOffset += nLength;
252 nBytes -= nLength;
253
254 // Adjust data length.
255 if (aPage.dataLength() < nOffset)
256 aPage.dataLength (nOffset);
257 }
258 else
259 {
260 // Write to data page (external scope).
262
265
266 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
267 if ((aDescr.m_nOffset > 0) || (nBytes < nLength))
268 {
269 // Unaligned. Need to load/create data page.
270 eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
271 if (eErrCode != store_E_None)
272 {
273 if (eErrCode != store_E_NotExists)
274 return eErrCode;
275
276 eErrCode = aData.construct<data>(m_xManager->allocator());
277 if (eErrCode != store_E_None)
278 return eErrCode;
279 }
280 }
281
282 PageHolderObject< data > xData (aData.makeHolder<data>());
283 if (!xData.is())
284 {
285 eErrCode = aData.construct<data>(m_xManager->allocator());
286 if (eErrCode != store_E_None)
287 return eErrCode;
288 xData = aData.makeHolder<data>();
289 }
290
291 // Modify data page.
292 if(nLength > nBytes)
293 {
294 nLength = nBytes;
295 }
296 memcpy (
297 &xData->m_pData[aDescr.m_nOffset],
298 &pData[rnDone], nLength);
299
300 // Save data page.
301 eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager);
302 if (eErrCode != store_E_None)
303 return eErrCode;
304
305 // Adjust counters.
306 rnDone += nLength;
307 nOffset += nLength;
308 nBytes -= nLength;
309
310 // Adjust data length.
311 if (aPage.dataLength() < nOffset)
312 aPage.dataLength (nOffset);
313 }
314 }
315
316 // Check for modified inode.
317 if (aPage.dirty())
318 return m_xManager->saveObjectAt (aPage, aPage.location());
319 else
320 return store_E_None;
321}
322
324{
325 if (!m_xManager.is())
327 if (!m_bWriteable)
329
330 // Acquire exclusive access.
331 osl::MutexGuard aGuard (*m_xManager);
332
333 // Determine current length.
335 sal_uInt32 nDataLen = aPage.dataLength();
336
337 if (nSize == nDataLen)
338 return store_E_None;
339
340 if (nSize < nDataLen)
341 {
342 // Truncate.
343 storeError eErrCode = store_E_None;
344
345 // Determine 'Size' scope.
346 inode::ChunkScope eSizeScope = m_xNode->scope (nSize);
347 if (eSizeScope == inode::SCOPE_INTERNAL)
348 {
349 // Internal 'Size' scope. Determine 'Data' scope.
350 inode::ChunkScope eDataScope = m_xNode->scope (nDataLen);
351 if (eDataScope == inode::SCOPE_EXTERNAL)
352 {
353 // External 'Data' scope. Truncate all external data pages.
354 eErrCode = aPage.truncate (0, *m_xManager);
355 if (eErrCode != store_E_None)
356 return eErrCode;
357 }
358
359 // Truncate internal data page.
360 inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity());
361 memset (
362 &(m_xNode->m_pData[aDescr.m_nOffset]),
363 0, aDescr.m_nLength);
364 }
365 else
366 {
367 // External 'Size' scope. Truncate external data pages.
370
371 sal_uInt32 nPage = aDescr.m_nPage;
372 if (aDescr.m_nOffset) nPage += 1;
373
374 eErrCode = aPage.truncate (nPage, *m_xManager);
375 if (eErrCode != store_E_None)
376 return eErrCode;
377 }
378 }
379
380 // Set (extended or truncated) size.
381 aPage.dataLength (nSize);
382
383 // Save modified inode.
384 return m_xManager->saveObjectAt (aPage, aPage.location());
385}
386
387/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char * pName
storeError write(sal_uInt32 nPage, OStoreDataPageObject &rData, OStorePageBIOS &rBIOS)
write (external data page).
Definition: stordata.cxx:750
sal_uInt32 attrib() const
attrib.
Definition: stordata.hxx:608
storeError read(sal_uInt32 nPage, OStoreDataPageObject &rData, OStorePageBIOS &rBIOS) const
read (external data page).
Definition: stordata.cxx:677
sal_uInt32 dataLength() const
dataLength.
Definition: stordata.hxx:638
storeError truncate(sal_uInt32 nPage, OStorePageBIOS &rBIOS)
truncate (external data page).
Definition: stordata.cxx:834
static const sal_uInt32 m_nTypeId
IStoreHandle TypeId.
Definition: storlckb.hxx:97
storeError create(OStorePageManager *pManager, rtl_String const *pPath, rtl_String const *pName, storeAccessMode eAccessMode)
create (two-phase construction).
Definition: storlckb.cxx:55
virtual bool isKindOf(sal_uInt32 nMagic) override
IStoreHandle.
Definition: storlckb.cxx:50
inode_holder_type m_xNode
Definition: storlckb.hxx:110
storeError writeAt(sal_uInt32 nOffset, const void *pBuffer, sal_uInt32 nBytes, sal_uInt32 &rnDone)
Write at Offset from Buffer.
Definition: storlckb.cxx:200
storeError setSize(sal_uInt32 nSize)
setSize.
Definition: storlckb.cxx:323
rtl::Reference< OStorePageManager > m_xManager
Definition: storlckb.hxx:104
virtual ~OStoreLockBytes() override
Definition: storlckb.cxx:42
storeError readAt(sal_uInt32 nOffset, void *pBuffer, sal_uInt32 nBytes, sal_uInt32 &rnDone)
Read at Offset into Buffer.
Definition: storlckb.cxx:103
bool dirty() const
State.
Definition: storbase.hxx:586
sal_uInt32 location() const
Location.
Definition: storbase.hxx:601
std::shared_ptr< PageData > & get()
Definition: storbase.hxx:580
std::shared_ptr< PageData > & get()
Definition: storbase.hxx:454
Mode eMode
std::unique_ptr< sal_Int32[]> pData
constexpr OUStringLiteral aData
Old OStorePageCache implementation.
Definition: lockbyte.cxx:133
sal_uInt16 capacity() const
Definition: stordata.hxx:67
sal_uInt16 capacity() const
capacity.
Definition: stordata.hxx:507
ChunkScope scope(sal_uInt32 nPosition) const
scope (internal).
Definition: stordata.hxx:576
storeAccessMode
Access Mode enumeration.
Definition: types.h:62
unsigned char sal_uInt8
storeError
Error Code enumeration.
Definition: types.h:73
@ store_E_InvalidParameter
Definition: types.h:82
@ store_E_None
Definition: types.h:74
@ store_E_InvalidAccess
Definition: types.h:80
@ store_E_AccessViolation
Definition: types.h:75
@ store_E_NotFile
Definition: types.h:87
@ store_E_NotExists
Definition: types.h:85
constexpr sal_uInt32 STORE_ATTRIB_ISLINK
Attributes (predefined).
Definition: types.h:51
constexpr sal_uInt32 STORE_ATTRIB_ISFILE
Definition: types.h:53
sal_Int32 nLength