merge the formfield patch from ooo-build
[ooovba.git] / store / source / storlckb.cxx
blob61750643c9f2ec7aa69179810e20f107c6f62a49
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: storlckb.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_store.hxx"
34 #include "storlckb.hxx"
36 #include "sal/types.h"
37 #include "sal/macros.h"
38 #include "rtl/string.h"
39 #include "rtl/ref.hxx"
40 #include "osl/mutex.hxx"
42 #include "store/types.h"
43 #include "object.hxx"
45 #include "storbase.hxx"
46 #include "stordata.hxx"
47 #include "storpage.hxx"
49 using namespace store;
51 /*========================================================================
53 * OStoreLockBytes implementation.
55 *======================================================================*/
56 const sal_uInt32 OStoreLockBytes::m_nTypeId = sal_uInt32(0x94190310);
59 * OStoreLockBytes.
61 OStoreLockBytes::OStoreLockBytes (void)
62 : m_xManager (),
63 m_xNode (),
64 m_bWriteable (false)
69 * ~OStoreLockBytes.
71 OStoreLockBytes::~OStoreLockBytes (void)
73 if (m_xManager.is())
75 if (m_xNode.is())
77 OStorePageDescriptor aDescr (m_xNode->m_aDescr);
78 if (m_bWriteable)
79 m_xManager->releasePage (aDescr, store_AccessReadWrite);
80 else
81 m_xManager->releasePage (aDescr, store_AccessReadOnly);
87 * isKindOf.
89 sal_Bool SAL_CALL OStoreLockBytes::isKindOf (sal_uInt32 nTypeId)
91 return (nTypeId == m_nTypeId);
95 * create.
97 storeError OStoreLockBytes::create (
98 OStorePageManager *pManager,
99 rtl_String *pPath,
100 rtl_String *pName,
101 storeAccessMode eMode)
103 rtl::Reference<OStorePageManager> xManager (pManager);
104 if (!xManager.is())
105 return store_E_InvalidAccess;
107 if (!(pPath && pName))
108 return store_E_InvalidParameter;
110 OStoreDirectoryPageObject aPage;
111 storeError eErrCode = xManager->iget (
112 aPage, STORE_ATTRIB_ISFILE,
113 pPath, pName, eMode);
114 if (eErrCode != store_E_None)
115 return eErrCode;
117 if (!(aPage.attrib() & STORE_ATTRIB_ISFILE))
119 // No ISFILE in older versions (backward compatibility).
120 if (aPage.attrib() & STORE_ATTRIB_ISLINK)
121 return store_E_NotFile;
124 // ...
125 inode_holder_type xNode (aPage.get());
126 if (eMode != store_AccessReadOnly)
127 eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadWrite);
128 else
129 eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
130 if (eErrCode != store_E_None)
131 return eErrCode;
133 // ...
134 m_xManager = xManager;
135 m_xNode = xNode;
136 m_bWriteable = (eMode != store_AccessReadOnly);
138 // Check for truncation.
139 if (eMode == store_AccessCreate)
141 // Truncate to zero length.
142 eErrCode = setSize(0);
144 return eErrCode;
148 * readAt.
150 storeError OStoreLockBytes::readAt (
151 sal_uInt32 nOffset,
152 void *pBuffer,
153 sal_uInt32 nBytes,
154 sal_uInt32 &rnDone)
156 rnDone = 0;
158 if (!m_xManager.is())
159 return store_E_InvalidAccess;
161 if (!pBuffer)
162 return store_E_InvalidParameter;
163 if (!nBytes)
164 return store_E_None;
166 // Acquire exclusive access.
167 osl::MutexGuard aGuard (*m_xManager);
169 // Determine data length.
170 OStoreDirectoryPageObject aPage (m_xNode.get());
172 sal_uInt32 nDataLen = aPage.dataLength();
173 if ((nOffset + nBytes) > nDataLen)
174 nBytes = nDataLen - nOffset;
176 // Read data.
177 OStoreDataPageObject aData;
178 sal_uInt8 *pData = (sal_uInt8*)pBuffer;
179 while ((0 < nBytes) && (nOffset < nDataLen))
181 // Determine 'Offset' scope.
182 inode::ChunkScope eScope = m_xNode->scope (nOffset);
183 if (eScope == inode::SCOPE_INTERNAL)
185 // Read from inode page (internal scope).
186 inode::ChunkDescriptor aDescr (
187 nOffset, m_xNode->capacity());
189 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
190 nLength = SAL_MIN(nLength, nBytes);
192 memcpy (
193 &pData[rnDone],
194 &m_xNode->m_pData[aDescr.m_nOffset],
195 nLength);
197 // Adjust counters.
198 rnDone += nLength;
199 nOffset += nLength;
200 nBytes -= nLength;
202 else
204 // Read from data page (external scope).
205 inode::ChunkDescriptor aDescr (
206 nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
208 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
209 nLength = SAL_MIN(nLength, nBytes);
211 storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
212 if (eErrCode != store_E_None)
214 if (eErrCode != store_E_NotExists)
215 return eErrCode;
217 memset (
218 &pData[rnDone],
220 nLength);
222 else
224 PageHolderObject< data > xData (aData.makeHolder<data>());
225 memcpy (
226 &pData[rnDone],
227 &xData->m_pData[aDescr.m_nOffset],
228 nLength);
231 // Adjust counters.
232 rnDone += nLength;
233 nOffset += nLength;
234 nBytes -= nLength;
238 // Done.
239 return store_E_None;
243 * writeAt.
245 storeError OStoreLockBytes::writeAt (
246 sal_uInt32 nOffset,
247 const void *pBuffer,
248 sal_uInt32 nBytes,
249 sal_uInt32 &rnDone)
251 rnDone = 0;
253 if (!m_xManager.is())
254 return store_E_InvalidAccess;
255 if (!m_bWriteable)
256 return store_E_AccessViolation;
258 if (!pBuffer)
259 return store_E_InvalidParameter;
260 if (!nBytes)
261 return store_E_None;
263 // Acquire exclusive access.
264 osl::MutexGuard aGuard (*m_xManager);
266 // Write data.
267 OStoreDirectoryPageObject aPage (m_xNode.get());
268 const sal_uInt8 *pData = (const sal_uInt8*)pBuffer;
270 storeError eErrCode = store_E_None;
271 while (nBytes > 0)
273 // Determine 'Offset' scope.
274 inode::ChunkScope eScope = m_xNode->scope (nOffset);
275 if (eScope == inode::SCOPE_INTERNAL)
277 // Write to inode page (internal scope).
278 inode::ChunkDescriptor aDescr (
279 nOffset, m_xNode->capacity());
281 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
282 nLength = SAL_MIN(nLength, nBytes);
284 memcpy (
285 &m_xNode->m_pData[aDescr.m_nOffset],
286 &pData[rnDone], nLength);
288 // Mark inode dirty.
289 aPage.touch();
291 // Adjust counters.
292 rnDone += nLength;
293 nOffset += nLength;
294 nBytes -= nLength;
296 // Adjust data length.
297 if (aPage.dataLength() < nOffset)
298 aPage.dataLength (nOffset);
300 else
302 // Write to data page (external scope).
303 OStoreDataPageObject aData;
305 inode::ChunkDescriptor aDescr (
306 nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
308 sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
309 if ((aDescr.m_nOffset > 0) || (nBytes < nLength))
311 // Unaligned. Need to load/create data page.
312 // @@@ loadOrCreate()
313 eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
314 if (eErrCode != store_E_None)
316 if (eErrCode != store_E_NotExists)
317 return eErrCode;
319 eErrCode = aData.construct<data>(m_xManager->allocator());
320 if (eErrCode != store_E_None)
321 return eErrCode;
325 PageHolderObject< data > xData (aData.makeHolder<data>());
326 if (!xData.is())
328 eErrCode = aData.construct<data>(m_xManager->allocator());
329 if (eErrCode != store_E_None)
330 return eErrCode;
331 xData = aData.makeHolder<data>();
334 // Modify data page.
335 nLength = SAL_MIN(nLength, nBytes);
336 memcpy (
337 &xData->m_pData[aDescr.m_nOffset],
338 &pData[rnDone], nLength);
340 // Save data page.
341 eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager);
342 if (eErrCode != store_E_None)
343 return eErrCode;
345 // Adjust counters.
346 rnDone += nLength;
347 nOffset += nLength;
348 nBytes -= nLength;
350 // Adjust data length.
351 if (aPage.dataLength() < nOffset)
352 aPage.dataLength (nOffset);
356 // Check for modified inode.
357 if (aPage.dirty())
358 return m_xManager->saveObjectAt (aPage, aPage.location());
359 else
360 return store_E_None;
364 * flush.
366 storeError OStoreLockBytes::flush (void)
368 if (!m_xManager.is())
369 return store_E_InvalidAccess;
371 return m_xManager->flush();
375 * setSize.
377 storeError OStoreLockBytes::setSize (sal_uInt32 nSize)
379 if (!m_xManager.is())
380 return store_E_InvalidAccess;
381 if (!m_bWriteable)
382 return store_E_AccessViolation;
384 // Acquire exclusive access.
385 osl::MutexGuard aGuard (*m_xManager);
387 // Determine current length.
388 OStoreDirectoryPageObject aPage (m_xNode.get());
389 sal_uInt32 nDataLen = aPage.dataLength();
391 if (nSize == nDataLen)
392 return store_E_None;
394 if (nSize < nDataLen)
396 // Truncate.
397 storeError eErrCode = store_E_None;
399 // Determine 'Size' scope.
400 inode::ChunkScope eSizeScope = m_xNode->scope (nSize);
401 if (eSizeScope == inode::SCOPE_INTERNAL)
403 // Internal 'Size' scope. Determine 'Data' scope.
404 inode::ChunkScope eDataScope = m_xNode->scope (nDataLen);
405 if (eDataScope == inode::SCOPE_EXTERNAL)
407 // External 'Data' scope. Truncate all external data pages.
408 eErrCode = aPage.truncate (0, *m_xManager);
409 if (eErrCode != store_E_None)
410 return eErrCode;
413 // Truncate internal data page.
414 inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity());
415 memset (
416 &(m_xNode->m_pData[aDescr.m_nOffset]),
417 0, aDescr.m_nLength);
419 else
421 // External 'Size' scope. Truncate external data pages.
422 inode::ChunkDescriptor aDescr (
423 nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
425 sal_uInt32 nPage = aDescr.m_nPage;
426 if (aDescr.m_nOffset) nPage += 1;
428 eErrCode = aPage.truncate (nPage, *m_xManager);
429 if (eErrCode != store_E_None)
430 return eErrCode;
434 // Set (extended or truncated) size.
435 aPage.dataLength (nSize);
437 // Save modified inode.
438 return m_xManager->saveObjectAt (aPage, aPage.location());
442 * stat.
444 storeError OStoreLockBytes::stat (sal_uInt32 &rnSize)
446 rnSize = 0;
448 if (!m_xManager.is())
449 return store_E_InvalidAccess;
451 OStoreDirectoryPageObject aPage (m_xNode.get());
452 rnSize = aPage.dataLength();
453 return store_E_None;