xref: /aoo42x/main/store/source/storlckb.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_store.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "storlckb.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "sal/types.h"
34*cdf0e10cSrcweir #include "sal/macros.h"
35*cdf0e10cSrcweir #include "rtl/string.h"
36*cdf0e10cSrcweir #include "rtl/ref.hxx"
37*cdf0e10cSrcweir #include "osl/mutex.hxx"
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include "store/types.h"
40*cdf0e10cSrcweir #include "object.hxx"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include "storbase.hxx"
43*cdf0e10cSrcweir #include "stordata.hxx"
44*cdf0e10cSrcweir #include "storpage.hxx"
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir using namespace store;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir /*========================================================================
49*cdf0e10cSrcweir  *
50*cdf0e10cSrcweir  * OStoreLockBytes implementation.
51*cdf0e10cSrcweir  *
52*cdf0e10cSrcweir  *======================================================================*/
53*cdf0e10cSrcweir const sal_uInt32 OStoreLockBytes::m_nTypeId = sal_uInt32(0x94190310);
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir /*
56*cdf0e10cSrcweir  * OStoreLockBytes.
57*cdf0e10cSrcweir  */
58*cdf0e10cSrcweir OStoreLockBytes::OStoreLockBytes (void)
59*cdf0e10cSrcweir 	: m_xManager   (),
60*cdf0e10cSrcweir 	  m_xNode      (),
61*cdf0e10cSrcweir 	  m_bWriteable (false)
62*cdf0e10cSrcweir {
63*cdf0e10cSrcweir }
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir /*
66*cdf0e10cSrcweir  * ~OStoreLockBytes.
67*cdf0e10cSrcweir  */
68*cdf0e10cSrcweir OStoreLockBytes::~OStoreLockBytes (void)
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir 	if (m_xManager.is())
71*cdf0e10cSrcweir 	{
72*cdf0e10cSrcweir 		if (m_xNode.is())
73*cdf0e10cSrcweir 		{
74*cdf0e10cSrcweir 			OStorePageDescriptor aDescr (m_xNode->m_aDescr);
75*cdf0e10cSrcweir 			if (m_bWriteable)
76*cdf0e10cSrcweir                 m_xManager->releasePage (aDescr, store_AccessReadWrite);
77*cdf0e10cSrcweir 			else
78*cdf0e10cSrcweir                 m_xManager->releasePage (aDescr, store_AccessReadOnly);
79*cdf0e10cSrcweir 		}
80*cdf0e10cSrcweir 	}
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir /*
84*cdf0e10cSrcweir  * isKindOf.
85*cdf0e10cSrcweir  */
86*cdf0e10cSrcweir sal_Bool SAL_CALL OStoreLockBytes::isKindOf (sal_uInt32 nTypeId)
87*cdf0e10cSrcweir {
88*cdf0e10cSrcweir 	return (nTypeId == m_nTypeId);
89*cdf0e10cSrcweir }
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir /*
92*cdf0e10cSrcweir  * create.
93*cdf0e10cSrcweir  */
94*cdf0e10cSrcweir storeError OStoreLockBytes::create (
95*cdf0e10cSrcweir 	OStorePageManager *pManager,
96*cdf0e10cSrcweir 	rtl_String        *pPath,
97*cdf0e10cSrcweir 	rtl_String        *pName,
98*cdf0e10cSrcweir 	storeAccessMode    eMode)
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir 	rtl::Reference<OStorePageManager> xManager (pManager);
101*cdf0e10cSrcweir 	if (!xManager.is())
102*cdf0e10cSrcweir 		return store_E_InvalidAccess;
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir 	if (!(pPath && pName))
105*cdf0e10cSrcweir 		return store_E_InvalidParameter;
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir 	OStoreDirectoryPageObject aPage;
108*cdf0e10cSrcweir 	storeError eErrCode = xManager->iget (
109*cdf0e10cSrcweir 		aPage, STORE_ATTRIB_ISFILE,
110*cdf0e10cSrcweir 		pPath, pName, eMode);
111*cdf0e10cSrcweir 	if (eErrCode != store_E_None)
112*cdf0e10cSrcweir 		return eErrCode;
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir 	if (!(aPage.attrib() & STORE_ATTRIB_ISFILE))
115*cdf0e10cSrcweir 	{
116*cdf0e10cSrcweir 		// No ISFILE in older versions (backward compatibility).
117*cdf0e10cSrcweir 		if (aPage.attrib() & STORE_ATTRIB_ISLINK)
118*cdf0e10cSrcweir 			return store_E_NotFile;
119*cdf0e10cSrcweir 	}
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 	// ...
122*cdf0e10cSrcweir     inode_holder_type xNode (aPage.get());
123*cdf0e10cSrcweir 	if (eMode != store_AccessReadOnly)
124*cdf0e10cSrcweir 		eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadWrite);
125*cdf0e10cSrcweir 	else
126*cdf0e10cSrcweir 		eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
127*cdf0e10cSrcweir 	if (eErrCode != store_E_None)
128*cdf0e10cSrcweir 		return eErrCode;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 	// ...
131*cdf0e10cSrcweir 	m_xManager   = xManager;
132*cdf0e10cSrcweir 	m_xNode      = xNode;
133*cdf0e10cSrcweir 	m_bWriteable = (eMode != store_AccessReadOnly);
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 	// Check for truncation.
136*cdf0e10cSrcweir 	if (eMode == store_AccessCreate)
137*cdf0e10cSrcweir 	{
138*cdf0e10cSrcweir 		// Truncate to zero length.
139*cdf0e10cSrcweir 		eErrCode = setSize(0);
140*cdf0e10cSrcweir 	}
141*cdf0e10cSrcweir 	return eErrCode;
142*cdf0e10cSrcweir }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir /*
145*cdf0e10cSrcweir  * readAt.
146*cdf0e10cSrcweir  */
147*cdf0e10cSrcweir storeError OStoreLockBytes::readAt (
148*cdf0e10cSrcweir 	sal_uInt32  nOffset,
149*cdf0e10cSrcweir 	void       *pBuffer,
150*cdf0e10cSrcweir 	sal_uInt32  nBytes,
151*cdf0e10cSrcweir 	sal_uInt32 &rnDone)
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	rnDone = 0;
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 	if (!m_xManager.is())
156*cdf0e10cSrcweir 		return store_E_InvalidAccess;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	if (!pBuffer)
159*cdf0e10cSrcweir 		return store_E_InvalidParameter;
160*cdf0e10cSrcweir 	if (!nBytes)
161*cdf0e10cSrcweir 		return store_E_None;
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir 	// Acquire exclusive access.
164*cdf0e10cSrcweir 	osl::MutexGuard aGuard (*m_xManager);
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 	// Determine data length.
167*cdf0e10cSrcweir 	OStoreDirectoryPageObject aPage (m_xNode.get());
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir 	sal_uInt32 nDataLen = aPage.dataLength();
170*cdf0e10cSrcweir 	if ((nOffset + nBytes) > nDataLen)
171*cdf0e10cSrcweir 		nBytes = nDataLen - nOffset;
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir 	// Read data.
174*cdf0e10cSrcweir     OStoreDataPageObject aData;
175*cdf0e10cSrcweir 	sal_uInt8 *pData = (sal_uInt8*)pBuffer;
176*cdf0e10cSrcweir 	while ((0 < nBytes) && (nOffset < nDataLen))
177*cdf0e10cSrcweir 	{
178*cdf0e10cSrcweir 		// Determine 'Offset' scope.
179*cdf0e10cSrcweir 		inode::ChunkScope eScope = m_xNode->scope (nOffset);
180*cdf0e10cSrcweir 		if (eScope == inode::SCOPE_INTERNAL)
181*cdf0e10cSrcweir 		{
182*cdf0e10cSrcweir 			// Read from inode page (internal scope).
183*cdf0e10cSrcweir 			inode::ChunkDescriptor aDescr (
184*cdf0e10cSrcweir 				nOffset, m_xNode->capacity());
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir 			sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
187*cdf0e10cSrcweir 			nLength = SAL_MIN(nLength, nBytes);
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 			memcpy (
190*cdf0e10cSrcweir 				&pData[rnDone],
191*cdf0e10cSrcweir 				&m_xNode->m_pData[aDescr.m_nOffset],
192*cdf0e10cSrcweir 				nLength);
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 			// Adjust counters.
195*cdf0e10cSrcweir 			rnDone  += nLength;
196*cdf0e10cSrcweir 			nOffset += nLength;
197*cdf0e10cSrcweir 			nBytes  -= nLength;
198*cdf0e10cSrcweir 		}
199*cdf0e10cSrcweir 		else
200*cdf0e10cSrcweir 		{
201*cdf0e10cSrcweir 			// Read from data page (external scope).
202*cdf0e10cSrcweir 			inode::ChunkDescriptor aDescr (
203*cdf0e10cSrcweir 				nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 			sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
206*cdf0e10cSrcweir 			nLength = SAL_MIN(nLength, nBytes);
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 			storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
209*cdf0e10cSrcweir 			if (eErrCode != store_E_None)
210*cdf0e10cSrcweir 			{
211*cdf0e10cSrcweir 				if (eErrCode != store_E_NotExists)
212*cdf0e10cSrcweir 					return eErrCode;
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 				memset (
215*cdf0e10cSrcweir 					&pData[rnDone],
216*cdf0e10cSrcweir                     0,
217*cdf0e10cSrcweir 					nLength);
218*cdf0e10cSrcweir 			}
219*cdf0e10cSrcweir 			else
220*cdf0e10cSrcweir 			{
221*cdf0e10cSrcweir                 PageHolderObject< data > xData (aData.makeHolder<data>());
222*cdf0e10cSrcweir 				memcpy (
223*cdf0e10cSrcweir 					&pData[rnDone],
224*cdf0e10cSrcweir 					&xData->m_pData[aDescr.m_nOffset],
225*cdf0e10cSrcweir 					nLength);
226*cdf0e10cSrcweir 			}
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 			// Adjust counters.
229*cdf0e10cSrcweir 			rnDone  += nLength;
230*cdf0e10cSrcweir 			nOffset += nLength;
231*cdf0e10cSrcweir 			nBytes  -= nLength;
232*cdf0e10cSrcweir 		}
233*cdf0e10cSrcweir 	}
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir 	// Done.
236*cdf0e10cSrcweir 	return store_E_None;
237*cdf0e10cSrcweir }
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir /*
240*cdf0e10cSrcweir  * writeAt.
241*cdf0e10cSrcweir  */
242*cdf0e10cSrcweir storeError OStoreLockBytes::writeAt (
243*cdf0e10cSrcweir 	sal_uInt32  nOffset,
244*cdf0e10cSrcweir 	const void *pBuffer,
245*cdf0e10cSrcweir 	sal_uInt32  nBytes,
246*cdf0e10cSrcweir 	sal_uInt32 &rnDone)
247*cdf0e10cSrcweir {
248*cdf0e10cSrcweir 	rnDone = 0;
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 	if (!m_xManager.is())
251*cdf0e10cSrcweir 		return store_E_InvalidAccess;
252*cdf0e10cSrcweir 	if (!m_bWriteable)
253*cdf0e10cSrcweir 		return store_E_AccessViolation;
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 	if (!pBuffer)
256*cdf0e10cSrcweir 		return store_E_InvalidParameter;
257*cdf0e10cSrcweir 	if (!nBytes)
258*cdf0e10cSrcweir 		return store_E_None;
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 	// Acquire exclusive access.
261*cdf0e10cSrcweir 	osl::MutexGuard aGuard (*m_xManager);
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 	// Write data.
264*cdf0e10cSrcweir 	OStoreDirectoryPageObject aPage (m_xNode.get());
265*cdf0e10cSrcweir 	const sal_uInt8 *pData = (const sal_uInt8*)pBuffer;
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
268*cdf0e10cSrcweir 	while (nBytes > 0)
269*cdf0e10cSrcweir 	{
270*cdf0e10cSrcweir 		// Determine 'Offset' scope.
271*cdf0e10cSrcweir 		inode::ChunkScope eScope = m_xNode->scope (nOffset);
272*cdf0e10cSrcweir 		if (eScope == inode::SCOPE_INTERNAL)
273*cdf0e10cSrcweir 		{
274*cdf0e10cSrcweir 			// Write to inode page (internal scope).
275*cdf0e10cSrcweir 			inode::ChunkDescriptor aDescr (
276*cdf0e10cSrcweir 				nOffset, m_xNode->capacity());
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 			sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
279*cdf0e10cSrcweir 			nLength = SAL_MIN(nLength, nBytes);
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 			memcpy (
282*cdf0e10cSrcweir 				&m_xNode->m_pData[aDescr.m_nOffset],
283*cdf0e10cSrcweir 				&pData[rnDone], nLength);
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 			// Mark inode dirty.
286*cdf0e10cSrcweir 			aPage.touch();
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir 			// Adjust counters.
289*cdf0e10cSrcweir 			rnDone  += nLength;
290*cdf0e10cSrcweir 			nOffset += nLength;
291*cdf0e10cSrcweir 			nBytes  -= nLength;
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 			// Adjust data length.
294*cdf0e10cSrcweir 			if (aPage.dataLength() < nOffset)
295*cdf0e10cSrcweir 				aPage.dataLength (nOffset);
296*cdf0e10cSrcweir 		}
297*cdf0e10cSrcweir 		else
298*cdf0e10cSrcweir 		{
299*cdf0e10cSrcweir 			// Write to data page (external scope).
300*cdf0e10cSrcweir 			OStoreDataPageObject aData;
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir 			inode::ChunkDescriptor aDescr (
303*cdf0e10cSrcweir 				nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir 			sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
306*cdf0e10cSrcweir 			if ((aDescr.m_nOffset > 0) || (nBytes < nLength))
307*cdf0e10cSrcweir 			{
308*cdf0e10cSrcweir 				// Unaligned. Need to load/create data page.
309*cdf0e10cSrcweir // @@@ loadOrCreate()
310*cdf0e10cSrcweir 				eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
311*cdf0e10cSrcweir 				if (eErrCode != store_E_None)
312*cdf0e10cSrcweir 				{
313*cdf0e10cSrcweir 					if (eErrCode != store_E_NotExists)
314*cdf0e10cSrcweir 						return eErrCode;
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir                     eErrCode = aData.construct<data>(m_xManager->allocator());
317*cdf0e10cSrcweir                     if (eErrCode != store_E_None)
318*cdf0e10cSrcweir 						return eErrCode;
319*cdf0e10cSrcweir 				}
320*cdf0e10cSrcweir 			}
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir             PageHolderObject< data > xData (aData.makeHolder<data>());
323*cdf0e10cSrcweir             if (!xData.is())
324*cdf0e10cSrcweir             {
325*cdf0e10cSrcweir                 eErrCode = aData.construct<data>(m_xManager->allocator());
326*cdf0e10cSrcweir                 if (eErrCode != store_E_None)
327*cdf0e10cSrcweir                     return eErrCode;
328*cdf0e10cSrcweir                 xData = aData.makeHolder<data>();
329*cdf0e10cSrcweir             }
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir 			// Modify data page.
332*cdf0e10cSrcweir 			nLength = SAL_MIN(nLength, nBytes);
333*cdf0e10cSrcweir 			memcpy (
334*cdf0e10cSrcweir 				&xData->m_pData[aDescr.m_nOffset],
335*cdf0e10cSrcweir 				&pData[rnDone], nLength);
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir 			// Save data page.
338*cdf0e10cSrcweir 			eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager);
339*cdf0e10cSrcweir 			if (eErrCode != store_E_None)
340*cdf0e10cSrcweir 				return eErrCode;
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir 			// Adjust counters.
343*cdf0e10cSrcweir 			rnDone  += nLength;
344*cdf0e10cSrcweir 			nOffset += nLength;
345*cdf0e10cSrcweir 			nBytes  -= nLength;
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 			// Adjust data length.
348*cdf0e10cSrcweir 			if (aPage.dataLength() < nOffset)
349*cdf0e10cSrcweir 				aPage.dataLength (nOffset);
350*cdf0e10cSrcweir 		}
351*cdf0e10cSrcweir 	}
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir 	// Check for modified inode.
354*cdf0e10cSrcweir 	if (aPage.dirty())
355*cdf0e10cSrcweir 		return m_xManager->saveObjectAt (aPage, aPage.location());
356*cdf0e10cSrcweir 	else
357*cdf0e10cSrcweir 		return store_E_None;
358*cdf0e10cSrcweir }
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir /*
361*cdf0e10cSrcweir  * flush.
362*cdf0e10cSrcweir  */
363*cdf0e10cSrcweir storeError OStoreLockBytes::flush (void)
364*cdf0e10cSrcweir {
365*cdf0e10cSrcweir 	if (!m_xManager.is())
366*cdf0e10cSrcweir 		return store_E_InvalidAccess;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir 	return m_xManager->flush();
369*cdf0e10cSrcweir }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir /*
372*cdf0e10cSrcweir  * setSize.
373*cdf0e10cSrcweir  */
374*cdf0e10cSrcweir storeError OStoreLockBytes::setSize (sal_uInt32 nSize)
375*cdf0e10cSrcweir {
376*cdf0e10cSrcweir 	if (!m_xManager.is())
377*cdf0e10cSrcweir 		return store_E_InvalidAccess;
378*cdf0e10cSrcweir 	if (!m_bWriteable)
379*cdf0e10cSrcweir 		return store_E_AccessViolation;
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir 	// Acquire exclusive access.
382*cdf0e10cSrcweir 	osl::MutexGuard aGuard (*m_xManager);
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir 	// Determine current length.
385*cdf0e10cSrcweir 	OStoreDirectoryPageObject aPage (m_xNode.get());
386*cdf0e10cSrcweir 	sal_uInt32 nDataLen = aPage.dataLength();
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir 	if (nSize == nDataLen)
389*cdf0e10cSrcweir 		return store_E_None;
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir 	if (nSize < nDataLen)
392*cdf0e10cSrcweir 	{
393*cdf0e10cSrcweir 		// Truncate.
394*cdf0e10cSrcweir 		storeError eErrCode = store_E_None;
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir 		// Determine 'Size' scope.
397*cdf0e10cSrcweir 		inode::ChunkScope eSizeScope = m_xNode->scope (nSize);
398*cdf0e10cSrcweir 		if (eSizeScope == inode::SCOPE_INTERNAL)
399*cdf0e10cSrcweir 		{
400*cdf0e10cSrcweir 			// Internal 'Size' scope. Determine 'Data' scope.
401*cdf0e10cSrcweir 			inode::ChunkScope eDataScope = m_xNode->scope (nDataLen);
402*cdf0e10cSrcweir 			if (eDataScope == inode::SCOPE_EXTERNAL)
403*cdf0e10cSrcweir 			{
404*cdf0e10cSrcweir 				// External 'Data' scope. Truncate all external data pages.
405*cdf0e10cSrcweir 				eErrCode = aPage.truncate (0, *m_xManager);
406*cdf0e10cSrcweir 				if (eErrCode != store_E_None)
407*cdf0e10cSrcweir 					return eErrCode;
408*cdf0e10cSrcweir 			}
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 			// Truncate internal data page.
411*cdf0e10cSrcweir 			inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity());
412*cdf0e10cSrcweir 			memset (
413*cdf0e10cSrcweir 				&(m_xNode->m_pData[aDescr.m_nOffset]),
414*cdf0e10cSrcweir 				0, aDescr.m_nLength);
415*cdf0e10cSrcweir 		}
416*cdf0e10cSrcweir 		else
417*cdf0e10cSrcweir 		{
418*cdf0e10cSrcweir 			// External 'Size' scope. Truncate external data pages.
419*cdf0e10cSrcweir 			inode::ChunkDescriptor aDescr (
420*cdf0e10cSrcweir 				nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir 			sal_uInt32 nPage = aDescr.m_nPage;
423*cdf0e10cSrcweir 			if (aDescr.m_nOffset) nPage += 1;
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir 			eErrCode = aPage.truncate (nPage, *m_xManager);
426*cdf0e10cSrcweir 			if (eErrCode != store_E_None)
427*cdf0e10cSrcweir 				return eErrCode;
428*cdf0e10cSrcweir 		}
429*cdf0e10cSrcweir 	}
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir 	// Set (extended or truncated) size.
432*cdf0e10cSrcweir 	aPage.dataLength (nSize);
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir 	// Save modified inode.
435*cdf0e10cSrcweir 	return m_xManager->saveObjectAt (aPage, aPage.location());
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir /*
439*cdf0e10cSrcweir  * stat.
440*cdf0e10cSrcweir  */
441*cdf0e10cSrcweir storeError OStoreLockBytes::stat (sal_uInt32 &rnSize)
442*cdf0e10cSrcweir {
443*cdf0e10cSrcweir 	rnSize = 0;
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir 	if (!m_xManager.is())
446*cdf0e10cSrcweir 		return store_E_InvalidAccess;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir 	OStoreDirectoryPageObject aPage (m_xNode.get());
449*cdf0e10cSrcweir 	rnSize = aPage.dataLength();
450*cdf0e10cSrcweir 	return store_E_None;
451*cdf0e10cSrcweir }
452