xref: /aoo41x/main/store/source/stordata.cxx (revision 73d9b18a)
1*73d9b18aSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*73d9b18aSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*73d9b18aSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*73d9b18aSAndrew Rist  * distributed with this work for additional information
6*73d9b18aSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*73d9b18aSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*73d9b18aSAndrew Rist  * "License"); you may not use this file except in compliance
9*73d9b18aSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*73d9b18aSAndrew Rist  *
11*73d9b18aSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*73d9b18aSAndrew Rist  *
13*73d9b18aSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*73d9b18aSAndrew Rist  * software distributed under the License is distributed on an
15*73d9b18aSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*73d9b18aSAndrew Rist  * KIND, either express or implied.  See the License for the
17*73d9b18aSAndrew Rist  * specific language governing permissions and limitations
18*73d9b18aSAndrew Rist  * under the License.
19*73d9b18aSAndrew Rist  *
20*73d9b18aSAndrew Rist  *************************************************************/
21*73d9b18aSAndrew Rist 
22*73d9b18aSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_store.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "stordata.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "sal/types.h"
30cdf0e10cSrcweir #include "osl/diagnose.h"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "store/types.h"
33cdf0e10cSrcweir #include "storbase.hxx"
34cdf0e10cSrcweir #include "storbios.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace store;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir /*========================================================================
39cdf0e10cSrcweir  *
40cdf0e10cSrcweir  * OStoreDataPageObject implementation.
41cdf0e10cSrcweir  *
42cdf0e10cSrcweir  *======================================================================*/
43cdf0e10cSrcweir /*
44cdf0e10cSrcweir  * guard.
45cdf0e10cSrcweir  */
guard(sal_uInt32 nAddr)46cdf0e10cSrcweir storeError OStoreDataPageObject::guard (sal_uInt32 nAddr)
47cdf0e10cSrcweir {
48cdf0e10cSrcweir     return PageHolderObject< page >::guard (m_xPage, nAddr);
49cdf0e10cSrcweir }
50cdf0e10cSrcweir 
51cdf0e10cSrcweir /*
52cdf0e10cSrcweir  * verify.
53cdf0e10cSrcweir  */
verify(sal_uInt32 nAddr) const54cdf0e10cSrcweir storeError OStoreDataPageObject::verify (sal_uInt32 nAddr) const
55cdf0e10cSrcweir {
56cdf0e10cSrcweir     return PageHolderObject< page >::verify (m_xPage, nAddr);
57cdf0e10cSrcweir }
58cdf0e10cSrcweir 
59cdf0e10cSrcweir /*========================================================================
60cdf0e10cSrcweir  *
61cdf0e10cSrcweir  * OStoreIndirectionPageObject implementation.
62cdf0e10cSrcweir  *
63cdf0e10cSrcweir  *======================================================================*/
64cdf0e10cSrcweir /*
65cdf0e10cSrcweir   * store_truncate_Impl (single indirect page).
66cdf0e10cSrcweir   */
store_truncate_Impl(sal_uInt32 nAddr,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)67cdf0e10cSrcweir static storeError store_truncate_Impl (
68cdf0e10cSrcweir     sal_uInt32      nAddr,
69cdf0e10cSrcweir     sal_uInt16      nSingle,
70cdf0e10cSrcweir     OStorePageBIOS &rBIOS)
71cdf0e10cSrcweir {
72cdf0e10cSrcweir 	if (nAddr != STORE_PAGE_NULL)
73cdf0e10cSrcweir 	{
74cdf0e10cSrcweir 		// Load single indirect page.
75cdf0e10cSrcweir 		OStoreIndirectionPageObject aSingle;
76cdf0e10cSrcweir 		storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
77cdf0e10cSrcweir 		if (eErrCode == store_E_None)
78cdf0e10cSrcweir 		{
79cdf0e10cSrcweir 			// Truncate to 'nSingle' direct pages.
80cdf0e10cSrcweir 			eErrCode = aSingle.truncate (nSingle, rBIOS);
81cdf0e10cSrcweir 			if (eErrCode != store_E_None)
82cdf0e10cSrcweir 				return eErrCode;
83cdf0e10cSrcweir 		}
84cdf0e10cSrcweir 		else
85cdf0e10cSrcweir 		{
86cdf0e10cSrcweir 			if (eErrCode != store_E_InvalidChecksum)
87cdf0e10cSrcweir 				return eErrCode;
88cdf0e10cSrcweir 		}
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 		// Check for complete truncation.
91cdf0e10cSrcweir 		if (nSingle == 0)
92cdf0e10cSrcweir 		{
93cdf0e10cSrcweir 			// Free single indirect page.
94cdf0e10cSrcweir 			eErrCode = rBIOS.free (nAddr);
95cdf0e10cSrcweir 			if (eErrCode != store_E_None)
96cdf0e10cSrcweir 				return eErrCode;
97cdf0e10cSrcweir 		}
98cdf0e10cSrcweir 	}
99cdf0e10cSrcweir     return store_E_None;
100cdf0e10cSrcweir }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir /*
103cdf0e10cSrcweir  * store_truncate_Impl (double indirect page).
104cdf0e10cSrcweir  */
store_truncate_Impl(sal_uInt32 nAddr,sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)105cdf0e10cSrcweir static storeError store_truncate_Impl (
106cdf0e10cSrcweir     sal_uInt32       nAddr,
107cdf0e10cSrcweir     sal_uInt16       nDouble,
108cdf0e10cSrcweir     sal_uInt16       nSingle,
109cdf0e10cSrcweir     OStorePageBIOS  &rBIOS)
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     if (nAddr != STORE_PAGE_NULL)
112cdf0e10cSrcweir     {
113cdf0e10cSrcweir 		// Load double indirect page.
114cdf0e10cSrcweir 		OStoreIndirectionPageObject aDouble;
115cdf0e10cSrcweir 		storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
116cdf0e10cSrcweir 		if (eErrCode == store_E_None)
117cdf0e10cSrcweir 		{
118cdf0e10cSrcweir 			// Truncate to 'nDouble', 'nSingle' pages.
119cdf0e10cSrcweir 			eErrCode = aDouble.truncate (nDouble, nSingle, rBIOS);
120cdf0e10cSrcweir 			if (eErrCode != store_E_None)
121cdf0e10cSrcweir 				return eErrCode;
122cdf0e10cSrcweir 		}
123cdf0e10cSrcweir 		else
124cdf0e10cSrcweir 		{
125cdf0e10cSrcweir 			if (eErrCode != store_E_InvalidChecksum)
126cdf0e10cSrcweir 				return eErrCode;
127cdf0e10cSrcweir 		}
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 		// Check for complete truncation.
130cdf0e10cSrcweir 		if ((nDouble + nSingle) == 0)
131cdf0e10cSrcweir 		{
132cdf0e10cSrcweir 			// Free double indirect page.
133cdf0e10cSrcweir 			eErrCode = rBIOS.free (nAddr);
134cdf0e10cSrcweir 			if (eErrCode != store_E_None)
135cdf0e10cSrcweir 				return eErrCode;
136cdf0e10cSrcweir 		}
137cdf0e10cSrcweir     }
138cdf0e10cSrcweir     return store_E_None;
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir /*
142cdf0e10cSrcweir  * store_truncate_Impl (triple indirect page).
143cdf0e10cSrcweir  */
store_truncate_Impl(sal_uInt32 nAddr,sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)144cdf0e10cSrcweir static storeError store_truncate_Impl (
145cdf0e10cSrcweir     sal_uInt32       nAddr,
146cdf0e10cSrcweir     sal_uInt16       nTriple,
147cdf0e10cSrcweir     sal_uInt16       nDouble,
148cdf0e10cSrcweir     sal_uInt16       nSingle,
149cdf0e10cSrcweir     OStorePageBIOS  &rBIOS)
150cdf0e10cSrcweir {
151cdf0e10cSrcweir     if (nAddr != STORE_PAGE_NULL)
152cdf0e10cSrcweir     {
153cdf0e10cSrcweir         // Load triple indirect page.
154cdf0e10cSrcweir         OStoreIndirectionPageObject aTriple;
155cdf0e10cSrcweir         storeError eErrCode = rBIOS.loadObjectAt (aTriple, nAddr);
156cdf0e10cSrcweir         if (eErrCode != store_E_None)
157cdf0e10cSrcweir             return eErrCode;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir         // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
160cdf0e10cSrcweir         eErrCode = aTriple.truncate (nTriple, nDouble, nSingle, rBIOS);
161cdf0e10cSrcweir         if (eErrCode != store_E_None)
162cdf0e10cSrcweir             return eErrCode;
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         // Check for complete truncation.
165cdf0e10cSrcweir         if ((nTriple + nDouble + nSingle) == 0)
166cdf0e10cSrcweir         {
167cdf0e10cSrcweir             // Free triple indirect page.
168cdf0e10cSrcweir 			eErrCode = rBIOS.free (nAddr);
169cdf0e10cSrcweir             if (eErrCode != store_E_None)
170cdf0e10cSrcweir                 return eErrCode;
171cdf0e10cSrcweir         }
172cdf0e10cSrcweir     }
173cdf0e10cSrcweir     return store_E_None;
174cdf0e10cSrcweir }
175cdf0e10cSrcweir 
176cdf0e10cSrcweir /*
177cdf0e10cSrcweir  * loadOrCreate.
178cdf0e10cSrcweir  */
loadOrCreate(sal_uInt32 nAddr,OStorePageBIOS & rBIOS)179cdf0e10cSrcweir storeError OStoreIndirectionPageObject::loadOrCreate (
180cdf0e10cSrcweir     sal_uInt32       nAddr,
181cdf0e10cSrcweir     OStorePageBIOS & rBIOS)
182cdf0e10cSrcweir {
183cdf0e10cSrcweir     if (nAddr == STORE_PAGE_NULL)
184cdf0e10cSrcweir     {
185cdf0e10cSrcweir         storeError eErrCode = construct<page>(rBIOS.allocator());
186cdf0e10cSrcweir         if (eErrCode != store_E_None)
187cdf0e10cSrcweir             return eErrCode;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir         eErrCode = rBIOS.allocate (*this);
190cdf0e10cSrcweir         if (eErrCode != store_E_None)
191cdf0e10cSrcweir             return eErrCode;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir         // Save location pending at caller.
194cdf0e10cSrcweir         return store_E_Pending;
195cdf0e10cSrcweir     }
196cdf0e10cSrcweir     return rBIOS.loadObjectAt (*this, nAddr);
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir /*
200cdf0e10cSrcweir  * guard.
201cdf0e10cSrcweir  */
guard(sal_uInt32 nAddr)202cdf0e10cSrcweir storeError OStoreIndirectionPageObject::guard (sal_uInt32 nAddr)
203cdf0e10cSrcweir {
204cdf0e10cSrcweir     return PageHolderObject< page >::guard (m_xPage, nAddr);
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir /*
208cdf0e10cSrcweir  * verify.
209cdf0e10cSrcweir  */
verify(sal_uInt32 nAddr) const210cdf0e10cSrcweir storeError OStoreIndirectionPageObject::verify (sal_uInt32 nAddr) const
211cdf0e10cSrcweir {
212cdf0e10cSrcweir     return PageHolderObject< page >::verify (m_xPage, nAddr);
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir /*
216cdf0e10cSrcweir  * read (single indirect).
217cdf0e10cSrcweir  */
read(sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)218cdf0e10cSrcweir storeError OStoreIndirectionPageObject::read (
219cdf0e10cSrcweir 	sal_uInt16             nSingle,
220cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
221cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
222cdf0e10cSrcweir {
223cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
224cdf0e10cSrcweir     page const & rPage = (*xImpl);
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	// Check arguments.
227cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
228cdf0e10cSrcweir 	if (!(nSingle < nLimit))
229cdf0e10cSrcweir 		return store_E_InvalidAccess;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 	// Obtain data page location.
232cdf0e10cSrcweir 	sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]);
233cdf0e10cSrcweir 	if (nAddr == STORE_PAGE_NULL)
234cdf0e10cSrcweir 		return store_E_NotExists;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 	// Load data page and leave.
237cdf0e10cSrcweir     return rBIOS.loadObjectAt (rData, nAddr);
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir /*
241cdf0e10cSrcweir  * read (double indirect).
242cdf0e10cSrcweir  */
read(sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)243cdf0e10cSrcweir storeError OStoreIndirectionPageObject::read (
244cdf0e10cSrcweir 	sal_uInt16             nDouble,
245cdf0e10cSrcweir 	sal_uInt16             nSingle,
246cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
247cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
250cdf0e10cSrcweir     page const & rPage = (*xImpl);
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	// Check arguments.
253cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
254cdf0e10cSrcweir 	if (!((nDouble < nLimit) && (nSingle < nLimit)))
255cdf0e10cSrcweir 		return store_E_InvalidAccess;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	// Check single indirect page location.
258cdf0e10cSrcweir     sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nDouble]);
259cdf0e10cSrcweir 	if (nAddr == STORE_PAGE_NULL)
260cdf0e10cSrcweir 		return store_E_NotExists;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	// Load single indirect page.
263cdf0e10cSrcweir 	OStoreIndirectionPageObject aSingle;
264cdf0e10cSrcweir 	storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
265cdf0e10cSrcweir 	if (eErrCode != store_E_None)
266cdf0e10cSrcweir 		return eErrCode;
267cdf0e10cSrcweir 
268cdf0e10cSrcweir 	// Read single indirect and leave.
269cdf0e10cSrcweir 	return aSingle.read (nSingle, rData, rBIOS);
270cdf0e10cSrcweir }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir /*
273cdf0e10cSrcweir  * read (triple indirect).
274cdf0e10cSrcweir  */
read(sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)275cdf0e10cSrcweir storeError OStoreIndirectionPageObject::read (
276cdf0e10cSrcweir 	sal_uInt16             nTriple,
277cdf0e10cSrcweir 	sal_uInt16             nDouble,
278cdf0e10cSrcweir 	sal_uInt16             nSingle,
279cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
280cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
281cdf0e10cSrcweir {
282cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
283cdf0e10cSrcweir     page const & rPage = (*xImpl);
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	// Check arguments.
286cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
287cdf0e10cSrcweir 	if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
288cdf0e10cSrcweir 		return store_E_InvalidAccess;
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 	// Check double indirect page location.
291cdf0e10cSrcweir     sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nTriple]);
292cdf0e10cSrcweir 	if (nAddr == STORE_PAGE_NULL)
293cdf0e10cSrcweir 		return store_E_NotExists;
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 	// Load double indirect page.
296cdf0e10cSrcweir 	OStoreIndirectionPageObject aDouble;
297cdf0e10cSrcweir 	storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
298cdf0e10cSrcweir 	if (eErrCode != store_E_None)
299cdf0e10cSrcweir 		return eErrCode;
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	// Read double indirect and leave.
302cdf0e10cSrcweir 	return aDouble.read (nDouble, nSingle, rData, rBIOS);
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir /*
306cdf0e10cSrcweir  * write (single indirect).
307cdf0e10cSrcweir  */
write(sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)308cdf0e10cSrcweir storeError OStoreIndirectionPageObject::write (
309cdf0e10cSrcweir 	sal_uInt16             nSingle,
310cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
311cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
312cdf0e10cSrcweir {
313cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
314cdf0e10cSrcweir     page & rPage = (*xImpl);
315cdf0e10cSrcweir 
316cdf0e10cSrcweir 	// Check arguments.
317cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
318cdf0e10cSrcweir 	if (!(nSingle < nLimit))
319cdf0e10cSrcweir 		return store_E_InvalidAccess;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 	// Obtain data page location.
322cdf0e10cSrcweir 	sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]);
323cdf0e10cSrcweir 	if (nAddr == STORE_PAGE_NULL)
324cdf0e10cSrcweir 	{
325cdf0e10cSrcweir         // Allocate data page.
326cdf0e10cSrcweir         storeError eErrCode = rBIOS.allocate (rData);
327cdf0e10cSrcweir         if (eErrCode != store_E_None)
328cdf0e10cSrcweir             return eErrCode;
329cdf0e10cSrcweir 
330cdf0e10cSrcweir         // Store data page location.
331cdf0e10cSrcweir         rPage.m_pData[nSingle] = store::htonl(rData.location());
332cdf0e10cSrcweir 
333cdf0e10cSrcweir         // Save this page.
334cdf0e10cSrcweir         return rBIOS.saveObjectAt (*this, location());
335cdf0e10cSrcweir 	}
336cdf0e10cSrcweir 	else
337cdf0e10cSrcweir 	{
338cdf0e10cSrcweir 		// Save data page.
339cdf0e10cSrcweir         return rBIOS.saveObjectAt (rData, nAddr);
340cdf0e10cSrcweir 	}
341cdf0e10cSrcweir }
342cdf0e10cSrcweir 
343cdf0e10cSrcweir /*
344cdf0e10cSrcweir  * write (double indirect).
345cdf0e10cSrcweir  */
write(sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)346cdf0e10cSrcweir storeError OStoreIndirectionPageObject::write (
347cdf0e10cSrcweir 	sal_uInt16             nDouble,
348cdf0e10cSrcweir 	sal_uInt16             nSingle,
349cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
350cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
353cdf0e10cSrcweir     page & rPage = (*xImpl);
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 	// Check arguments.
356cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
357cdf0e10cSrcweir 	if (!((nDouble < nLimit) && (nSingle < nLimit)))
358cdf0e10cSrcweir 		return store_E_InvalidAccess;
359cdf0e10cSrcweir 
360cdf0e10cSrcweir     // Load or create single indirect page.
361cdf0e10cSrcweir 	OStoreIndirectionPageObject aSingle;
362cdf0e10cSrcweir     storeError eErrCode = aSingle.loadOrCreate (store::ntohl(rPage.m_pData[nDouble]), rBIOS);
363cdf0e10cSrcweir     if (eErrCode != store_E_None)
364cdf0e10cSrcweir     {
365cdf0e10cSrcweir         if (eErrCode != store_E_Pending)
366cdf0e10cSrcweir             return eErrCode;
367cdf0e10cSrcweir         rPage.m_pData[nDouble] = store::htonl(aSingle.location());
368cdf0e10cSrcweir 
369cdf0e10cSrcweir         eErrCode = rBIOS.saveObjectAt (*this, location());
370cdf0e10cSrcweir         if (eErrCode != store_E_None)
371cdf0e10cSrcweir             return eErrCode;
372cdf0e10cSrcweir     }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir 	// Write single indirect and leave.
375cdf0e10cSrcweir 	return aSingle.write (nSingle, rData, rBIOS);
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir /*
379cdf0e10cSrcweir  * write (triple indirect).
380cdf0e10cSrcweir  */
write(sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)381cdf0e10cSrcweir storeError OStoreIndirectionPageObject::write (
382cdf0e10cSrcweir 	sal_uInt16             nTriple,
383cdf0e10cSrcweir 	sal_uInt16             nDouble,
384cdf0e10cSrcweir 	sal_uInt16             nSingle,
385cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
386cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
387cdf0e10cSrcweir {
388cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
389cdf0e10cSrcweir     page & rPage = (*xImpl);
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 	// Check arguments.
392cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
393cdf0e10cSrcweir 	if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
394cdf0e10cSrcweir 		return store_E_InvalidAccess;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     // Load or create double indirect page.
397cdf0e10cSrcweir 	OStoreIndirectionPageObject aDouble;
398cdf0e10cSrcweir 	storeError eErrCode = aDouble.loadOrCreate (store::ntohl(rPage.m_pData[nTriple]), rBIOS);
399cdf0e10cSrcweir     if (eErrCode != store_E_None)
400cdf0e10cSrcweir     {
401cdf0e10cSrcweir         if (eErrCode != store_E_Pending)
402cdf0e10cSrcweir             return eErrCode;
403cdf0e10cSrcweir         rPage.m_pData[nTriple] = store::htonl(aDouble.location());
404cdf0e10cSrcweir 
405cdf0e10cSrcweir         eErrCode = rBIOS.saveObjectAt (*this, location());
406cdf0e10cSrcweir         if (eErrCode != store_E_None)
407cdf0e10cSrcweir             return eErrCode;
408cdf0e10cSrcweir     }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 	// Write double indirect and leave.
411cdf0e10cSrcweir 	return aDouble.write (nDouble, nSingle, rData, rBIOS);
412cdf0e10cSrcweir }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir /*
415cdf0e10cSrcweir  * truncate (single indirect).
416cdf0e10cSrcweir  */
truncate(sal_uInt16 nSingle,OStorePageBIOS & rBIOS)417cdf0e10cSrcweir storeError OStoreIndirectionPageObject::truncate (
418cdf0e10cSrcweir 	sal_uInt16       nSingle,
419cdf0e10cSrcweir 	OStorePageBIOS & rBIOS)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
422cdf0e10cSrcweir     page & rPage = (*xImpl);
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 	// Check arguments.
425cdf0e10cSrcweir 	sal_uInt16 const nLimit = rPage.capacityCount();
426cdf0e10cSrcweir 	if (!(nSingle < nLimit))
427cdf0e10cSrcweir 		return store_E_InvalidAccess;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 	// Truncate.
430cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
431cdf0e10cSrcweir 	for (sal_uInt16 i = nLimit; i > nSingle; i--)
432cdf0e10cSrcweir 	{
433cdf0e10cSrcweir 		// Obtain data page location.
434cdf0e10cSrcweir 		sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[i - 1]);
435cdf0e10cSrcweir 		if (nAddr != STORE_PAGE_NULL)
436cdf0e10cSrcweir         {
437cdf0e10cSrcweir             // Free data page.
438cdf0e10cSrcweir             eErrCode = rBIOS.free (nAddr);
439cdf0e10cSrcweir             if (eErrCode != store_E_None)
440cdf0e10cSrcweir                 return eErrCode;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir             // Clear pointer to data page.
443cdf0e10cSrcweir             rPage.m_pData[i - 1] = STORE_PAGE_NULL;
444cdf0e10cSrcweir             touch();
445cdf0e10cSrcweir         }
446cdf0e10cSrcweir 	}
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	// Check for modified page.
449cdf0e10cSrcweir 	if (dirty())
450cdf0e10cSrcweir 	{
451cdf0e10cSrcweir 		// Save this page.
452cdf0e10cSrcweir         eErrCode = rBIOS.saveObjectAt (*this, location());
453cdf0e10cSrcweir 	}
454cdf0e10cSrcweir 
455cdf0e10cSrcweir     // Done.
456cdf0e10cSrcweir     return eErrCode;
457cdf0e10cSrcweir }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir /*
460cdf0e10cSrcweir  * truncate (double indirect).
461cdf0e10cSrcweir  */
truncate(sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)462cdf0e10cSrcweir storeError OStoreIndirectionPageObject::truncate (
463cdf0e10cSrcweir 	sal_uInt16             nDouble,
464cdf0e10cSrcweir 	sal_uInt16             nSingle,
465cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
466cdf0e10cSrcweir {
467cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
468cdf0e10cSrcweir     page & rPage = (*xImpl);
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	// Check arguments.
471cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
472cdf0e10cSrcweir 	if (!((nDouble < nLimit) && (nSingle < nLimit)))
473cdf0e10cSrcweir 		return store_E_InvalidAccess;
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	// Truncate.
476cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
477cdf0e10cSrcweir 	for (sal_uInt16 i = nLimit; i > nDouble + 1; i--)
478cdf0e10cSrcweir 	{
479cdf0e10cSrcweir         // Truncate single indirect page to zero direct pages.
480cdf0e10cSrcweir         eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, rBIOS);
481cdf0e10cSrcweir         if (eErrCode != store_E_None)
482cdf0e10cSrcweir             return eErrCode;
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 		// Clear pointer to single indirect page.
485cdf0e10cSrcweir 		rPage.m_pData[i - 1] = STORE_PAGE_NULL;
486cdf0e10cSrcweir 		touch();
487cdf0e10cSrcweir 	}
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 	// Truncate last single indirect page to 'nSingle' direct pages.
490cdf0e10cSrcweir     eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nDouble]), nSingle, rBIOS);
491cdf0e10cSrcweir     if (eErrCode != store_E_None)
492cdf0e10cSrcweir         return eErrCode;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir     // Check for complete truncation.
495cdf0e10cSrcweir     if (nSingle == 0)
496cdf0e10cSrcweir     {
497cdf0e10cSrcweir         // Clear pointer to last single indirect page.
498cdf0e10cSrcweir         rPage.m_pData[nDouble] = STORE_PAGE_NULL;
499cdf0e10cSrcweir         touch();
500cdf0e10cSrcweir     }
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 	// Check for modified page.
503cdf0e10cSrcweir 	if (dirty())
504cdf0e10cSrcweir 	{
505cdf0e10cSrcweir 		// Save this page.
506cdf0e10cSrcweir         eErrCode = rBIOS.saveObjectAt (*this, location());
507cdf0e10cSrcweir 	}
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 	// Done.
510cdf0e10cSrcweir 	return eErrCode;
511cdf0e10cSrcweir }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir /*
514cdf0e10cSrcweir  * truncate (triple indirect).
515cdf0e10cSrcweir  */
truncate(sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)516cdf0e10cSrcweir storeError OStoreIndirectionPageObject::truncate (
517cdf0e10cSrcweir 	sal_uInt16             nTriple,
518cdf0e10cSrcweir 	sal_uInt16             nDouble,
519cdf0e10cSrcweir 	sal_uInt16             nSingle,
520cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
521cdf0e10cSrcweir {
522cdf0e10cSrcweir     PageHolderObject< page > xImpl (m_xPage);
523cdf0e10cSrcweir     page & rPage = (*xImpl);
524cdf0e10cSrcweir 
525cdf0e10cSrcweir 	// Check arguments.
526cdf0e10cSrcweir     sal_uInt16 const nLimit = rPage.capacityCount();
527cdf0e10cSrcweir 	if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
528cdf0e10cSrcweir 		return store_E_InvalidAccess;
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	// Truncate.
531cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
532cdf0e10cSrcweir 	for (sal_uInt16 i = nLimit; i > nTriple + 1; i--)
533cdf0e10cSrcweir 	{
534cdf0e10cSrcweir         // Truncate double indirect page to zero single indirect pages.
535cdf0e10cSrcweir         eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, 0, rBIOS);
536cdf0e10cSrcweir 		if (eErrCode != store_E_None)
537cdf0e10cSrcweir             return eErrCode;
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 		// Clear pointer to double indirect page.
540cdf0e10cSrcweir 		rPage.m_pData[i - 1] = STORE_PAGE_NULL;
541cdf0e10cSrcweir 		touch();
542cdf0e10cSrcweir 	}
543cdf0e10cSrcweir 
544cdf0e10cSrcweir     // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
545cdf0e10cSrcweir     eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nTriple]), nDouble, nSingle, rBIOS);
546cdf0e10cSrcweir     if (eErrCode != store_E_None)
547cdf0e10cSrcweir         return eErrCode;
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     // Check for complete truncation.
550cdf0e10cSrcweir     if ((nDouble + nSingle) == 0)
551cdf0e10cSrcweir     {
552cdf0e10cSrcweir         // Clear pointer to last double indirect page.
553cdf0e10cSrcweir         rPage.m_pData[nTriple] = STORE_PAGE_NULL;
554cdf0e10cSrcweir         touch();
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 	// Check for modified page.
558cdf0e10cSrcweir 	if (dirty())
559cdf0e10cSrcweir 	{
560cdf0e10cSrcweir 		// Save this page.
561cdf0e10cSrcweir         eErrCode = rBIOS.saveObjectAt (*this, location());
562cdf0e10cSrcweir 	}
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 	// Done.
565cdf0e10cSrcweir 	return eErrCode;
566cdf0e10cSrcweir }
567cdf0e10cSrcweir 
568cdf0e10cSrcweir /*========================================================================
569cdf0e10cSrcweir  *
570cdf0e10cSrcweir  * OStoreDirectoryPageObject implementation.
571cdf0e10cSrcweir  *
572cdf0e10cSrcweir  *======================================================================*/
573cdf0e10cSrcweir /*
574cdf0e10cSrcweir  * guard.
575cdf0e10cSrcweir  */
guard(sal_uInt32 nAddr)576cdf0e10cSrcweir storeError OStoreDirectoryPageObject::guard (sal_uInt32 nAddr)
577cdf0e10cSrcweir {
578cdf0e10cSrcweir     return PageHolderObject< page >::guard (m_xPage, nAddr);
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir /*
582cdf0e10cSrcweir  * verify.
583cdf0e10cSrcweir  */
verify(sal_uInt32 nAddr) const584cdf0e10cSrcweir storeError OStoreDirectoryPageObject::verify (sal_uInt32 nAddr) const
585cdf0e10cSrcweir {
586cdf0e10cSrcweir 	return PageHolderObject< page >::verify (m_xPage, nAddr);
587cdf0e10cSrcweir 	// OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
588cdf0e10cSrcweir }
589cdf0e10cSrcweir 
590cdf0e10cSrcweir /*
591cdf0e10cSrcweir  * scope (external data page; private).
592cdf0e10cSrcweir  */
593cdf0e10cSrcweir OStoreDirectoryPageData::ChunkScope
scope(sal_uInt32 nPage,page::DataBlock::LinkDescriptor & rDescr) const594cdf0e10cSrcweir OStoreDirectoryPageObject::scope (
595cdf0e10cSrcweir 	sal_uInt32                       nPage,
596cdf0e10cSrcweir 	page::DataBlock::LinkDescriptor &rDescr) const
597cdf0e10cSrcweir {
598cdf0e10cSrcweir     page const & rPage = PAGE();
599cdf0e10cSrcweir     OStoreDirectoryDataBlock const & rDataBlock = rPage.m_aDataBlock;
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 	sal_uInt32 index0, index1, index2, index3;
602cdf0e10cSrcweir 
603cdf0e10cSrcweir 	// direct.
604cdf0e10cSrcweir 	sal_uInt32 nCount = rDataBlock.directCount();
605cdf0e10cSrcweir 	sal_uInt32 nLimit = nCount;
606cdf0e10cSrcweir 	if (nPage < nLimit)
607cdf0e10cSrcweir 	{
608cdf0e10cSrcweir 		// Page to index reduction.
609cdf0e10cSrcweir 		index0 = nPage;
610cdf0e10cSrcweir 
611cdf0e10cSrcweir 		// Setup LinkDescriptor indices.
612cdf0e10cSrcweir 		rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 		// Done.
615cdf0e10cSrcweir 		return page::SCOPE_DIRECT;
616cdf0e10cSrcweir 	}
617cdf0e10cSrcweir 	nPage -= nLimit;
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 	// single indirect.
620cdf0e10cSrcweir 	sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr);
621cdf0e10cSrcweir 	nCount = rDataBlock.singleCount();
622cdf0e10cSrcweir 	nLimit = nCount * nCapacity;
623cdf0e10cSrcweir 	if (nPage < nLimit)
624cdf0e10cSrcweir 	{
625cdf0e10cSrcweir 		// Page to index reduction.
626cdf0e10cSrcweir 		sal_uInt32 n = nPage;
627cdf0e10cSrcweir 
628cdf0e10cSrcweir 		// Reduce to single indirect i(1), direct n = i(0).
629cdf0e10cSrcweir 		index1 = n / nCapacity;
630cdf0e10cSrcweir 		index0 = n % nCapacity;
631cdf0e10cSrcweir 
632cdf0e10cSrcweir 		// Verify reduction.
633cdf0e10cSrcweir 		n = index1 * nCapacity + index0;
634cdf0e10cSrcweir 		OSL_POSTCOND(n == nPage, "wrong math on indirect indices");
635cdf0e10cSrcweir 		if (n != nPage)
636cdf0e10cSrcweir 			return page::SCOPE_UNKNOWN;
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 		// Setup LinkDescriptor indices.
639cdf0e10cSrcweir 		rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
640cdf0e10cSrcweir 		rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 		// Done.
643cdf0e10cSrcweir 		return page::SCOPE_SINGLE;
644cdf0e10cSrcweir 	}
645cdf0e10cSrcweir 	nPage -= nLimit;
646cdf0e10cSrcweir 
647cdf0e10cSrcweir 	// double indirect.
648cdf0e10cSrcweir 	nCount = rDataBlock.doubleCount();
649cdf0e10cSrcweir 	nLimit = nCount * nCapacity * nCapacity;
650cdf0e10cSrcweir 	if (nPage < nLimit)
651cdf0e10cSrcweir 	{
652cdf0e10cSrcweir 		// Page to index reduction.
653cdf0e10cSrcweir 		sal_uInt32 n = nPage;
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 		// Reduce to double indirect i(2), single indirect n = i(0).
656cdf0e10cSrcweir 		index2 = n / (nCapacity * nCapacity);
657cdf0e10cSrcweir 		n      = n % (nCapacity * nCapacity);
658cdf0e10cSrcweir 
659cdf0e10cSrcweir 		// Reduce to single indirect i(1), direct n = i(0).
660cdf0e10cSrcweir 		index1 = n / nCapacity;
661cdf0e10cSrcweir 		index0 = n % nCapacity;
662cdf0e10cSrcweir 
663cdf0e10cSrcweir 		// Verify reduction.
664cdf0e10cSrcweir 		n = index2 * nCapacity * nCapacity +
665cdf0e10cSrcweir 			index1 * nCapacity + index0;
666cdf0e10cSrcweir 		OSL_POSTCOND(n == nPage, "wrong math on double indirect indices");
667cdf0e10cSrcweir 		if (n != nPage)
668cdf0e10cSrcweir 			return page::SCOPE_UNKNOWN;
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 		// Setup LinkDescriptor indices.
671cdf0e10cSrcweir 		rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
672cdf0e10cSrcweir 		rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
673cdf0e10cSrcweir 		rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
674cdf0e10cSrcweir 
675cdf0e10cSrcweir 		// Done.
676cdf0e10cSrcweir 		return page::SCOPE_DOUBLE;
677cdf0e10cSrcweir 	}
678cdf0e10cSrcweir 	nPage -= nLimit;
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 	// triple indirect.
681cdf0e10cSrcweir 	nCount = rDataBlock.tripleCount();
682cdf0e10cSrcweir 	nLimit = nCount * nCapacity * nCapacity * nCapacity;
683cdf0e10cSrcweir 	if (nPage < nLimit)
684cdf0e10cSrcweir 	{
685cdf0e10cSrcweir 		// Page to index reduction.
686cdf0e10cSrcweir 		sal_uInt32 n = nPage;
687cdf0e10cSrcweir 
688cdf0e10cSrcweir 		// Reduce to triple indirect i(3), double indirect n.
689cdf0e10cSrcweir 		index3 = n / (nCapacity * nCapacity * nCapacity);
690cdf0e10cSrcweir 		n      = n % (nCapacity * nCapacity * nCapacity);
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 		// Reduce to double indirect i(2), single indirect n.
693cdf0e10cSrcweir 		index2 = n / (nCapacity * nCapacity);
694cdf0e10cSrcweir 		n      = n % (nCapacity * nCapacity);
695cdf0e10cSrcweir 
696cdf0e10cSrcweir 		// Reduce to single indirect i(1), direct n = i(0).
697cdf0e10cSrcweir 		index1 = n / nCapacity;
698cdf0e10cSrcweir 		index0 = n % nCapacity;
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 		// Verify reduction.
701cdf0e10cSrcweir 		n = index3 * nCapacity * nCapacity * nCapacity +
702cdf0e10cSrcweir 			index2 * nCapacity * nCapacity +
703cdf0e10cSrcweir 			index1 * nCapacity + index0;
704cdf0e10cSrcweir 		OSL_POSTCOND(n == nPage, "wrong math on triple indirect indices");
705cdf0e10cSrcweir 		if (n != nPage)
706cdf0e10cSrcweir 			return page::SCOPE_UNKNOWN;
707cdf0e10cSrcweir 
708cdf0e10cSrcweir 		// Setup LinkDescriptor indices.
709cdf0e10cSrcweir 		rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
710cdf0e10cSrcweir 		rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
711cdf0e10cSrcweir 		rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
712cdf0e10cSrcweir 		rDescr.m_nIndex3 = (sal_uInt16)(index3 & 0xffff);
713cdf0e10cSrcweir 
714cdf0e10cSrcweir 		// Done.
715cdf0e10cSrcweir 		return page::SCOPE_TRIPLE;
716cdf0e10cSrcweir 	}
717cdf0e10cSrcweir 
718cdf0e10cSrcweir 	// Unreachable (more than triple indirect).
719cdf0e10cSrcweir 	return page::SCOPE_UNREACHABLE;
720cdf0e10cSrcweir }
721cdf0e10cSrcweir 
722cdf0e10cSrcweir #if 0  /* NYI */
723cdf0e10cSrcweir /*
724cdf0e10cSrcweir  * chunk (external data page).
725cdf0e10cSrcweir  */
726cdf0e10cSrcweir inode::ChunkDescriptor OStoreDirectoryPageObject::chunk (sal_uInt32 nOffset)
727cdf0e10cSrcweir {
728cdf0e10cSrcweir     // @@@ INSUFFICIENT: NEED SCOPE AS WELL @@@
729cdf0e10cSrcweir     sal_uInt32 nCapacity = m_rPage.capacity();
730cdf0e10cSrcweir     if (nOffset < nCapacity)
731cdf0e10cSrcweir         // Internal scope (inode page).
732cdf0e10cSrcweir         return inode::ChunkDescriptor (nOffset, nCapacity);
733cdf0e10cSrcweir     else
734cdf0e10cSrcweir         // External scope (data page).
735cdf0e10cSrcweir         return inode::ChunkDescriptor (nOffset - nCapacity, data::capacity(m_rPage.m_aDescr));
736cdf0e10cSrcweir 
737cdf0e10cSrcweir     inode::ChunkScope eScope = m_rPage.scope(nOffset);
738cdf0e10cSrcweir     if (eScope == inode::SCOPE_INTERNAL)
739cdf0e10cSrcweir         // Inode page (internal scope).
740cdf0e10cSrcweir         return inode::ChunkDescriptor (nOffset, m_rPage.capacity());
741cdf0e10cSrcweir     else
742cdf0e10cSrcweir         // Data page (external scope).
743cdf0e10cSrcweir         return inode::ChunkDescriptor (nOffset - m_rPage.capacity(), data::capacity(m_rPage.m_aDescr));
744cdf0e10cSrcweir }
745cdf0e10cSrcweir #endif /* NYI */
746cdf0e10cSrcweir 
747cdf0e10cSrcweir /*
748cdf0e10cSrcweir  * read (external data page).
749cdf0e10cSrcweir  */
read(sal_uInt32 nPage,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)750cdf0e10cSrcweir storeError OStoreDirectoryPageObject::read (
751cdf0e10cSrcweir 	sal_uInt32             nPage,
752cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
753cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
754cdf0e10cSrcweir {
755cdf0e10cSrcweir 	// Determine scope and link indices.
756cdf0e10cSrcweir 	page::DataBlock::LinkDescriptor aLink;
757cdf0e10cSrcweir 	page::ChunkScope eScope = scope (nPage, aLink);
758cdf0e10cSrcweir 
759cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
760cdf0e10cSrcweir 	if (eScope == page::SCOPE_DIRECT)
761cdf0e10cSrcweir 	{
762cdf0e10cSrcweir 		sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
763cdf0e10cSrcweir 		if (nAddr == STORE_PAGE_NULL)
764cdf0e10cSrcweir 			return store_E_NotExists;
765cdf0e10cSrcweir 
766cdf0e10cSrcweir         eErrCode = rBIOS.loadObjectAt (rData, nAddr);
767cdf0e10cSrcweir 	}
768cdf0e10cSrcweir 	else if (eScope == page::SCOPE_SINGLE)
769cdf0e10cSrcweir 	{
770cdf0e10cSrcweir 		sal_uInt32 const nAddr = singleLink (aLink.m_nIndex1);
771cdf0e10cSrcweir 		if (nAddr == STORE_PAGE_NULL)
772cdf0e10cSrcweir 			return store_E_NotExists;
773cdf0e10cSrcweir 
774cdf0e10cSrcweir 		OStoreIndirectionPageObject aSingle;
775cdf0e10cSrcweir 		eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
776cdf0e10cSrcweir 		if (eErrCode != store_E_None)
777cdf0e10cSrcweir 			return eErrCode;
778cdf0e10cSrcweir 
779cdf0e10cSrcweir 		eErrCode = aSingle.read (aLink.m_nIndex0, rData, rBIOS);
780cdf0e10cSrcweir 	}
781cdf0e10cSrcweir 	else if (eScope == page::SCOPE_DOUBLE)
782cdf0e10cSrcweir 	{
783cdf0e10cSrcweir 		sal_uInt32 const nAddr = doubleLink (aLink.m_nIndex2);
784cdf0e10cSrcweir 		if (nAddr == STORE_PAGE_NULL)
785cdf0e10cSrcweir 			return store_E_NotExists;
786cdf0e10cSrcweir 
787cdf0e10cSrcweir 		OStoreIndirectionPageObject aDouble;
788cdf0e10cSrcweir 		eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
789cdf0e10cSrcweir 		if (eErrCode != store_E_None)
790cdf0e10cSrcweir 			return eErrCode;
791cdf0e10cSrcweir 
792cdf0e10cSrcweir 		eErrCode = aDouble.read (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
793cdf0e10cSrcweir 	}
794cdf0e10cSrcweir 	else if (eScope == page::SCOPE_TRIPLE)
795cdf0e10cSrcweir 	{
796cdf0e10cSrcweir 		sal_uInt32 const nAddr = tripleLink (aLink.m_nIndex3);
797cdf0e10cSrcweir 		if (nAddr == STORE_PAGE_NULL)
798cdf0e10cSrcweir 			return store_E_NotExists;
799cdf0e10cSrcweir 
800cdf0e10cSrcweir 		OStoreIndirectionPageObject aTriple;
801cdf0e10cSrcweir 		eErrCode = rBIOS.loadObjectAt (aTriple, nAddr);
802cdf0e10cSrcweir 		if (eErrCode != store_E_None)
803cdf0e10cSrcweir 			return eErrCode;
804cdf0e10cSrcweir 
805cdf0e10cSrcweir 		eErrCode = aTriple.read (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
806cdf0e10cSrcweir 	}
807cdf0e10cSrcweir 	else if (eScope == page::SCOPE_UNREACHABLE)
808cdf0e10cSrcweir 	{
809cdf0e10cSrcweir 		// Out of scope.
810cdf0e10cSrcweir 		eErrCode = store_E_CantSeek;
811cdf0e10cSrcweir 	}
812cdf0e10cSrcweir 	else
813cdf0e10cSrcweir 	{
814cdf0e10cSrcweir 		// Unknown scope.
815cdf0e10cSrcweir 		OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
816cdf0e10cSrcweir 		eErrCode = store_E_Unknown;
817cdf0e10cSrcweir 	}
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 	// Leave.
820cdf0e10cSrcweir 	return eErrCode;
821cdf0e10cSrcweir }
822cdf0e10cSrcweir 
823cdf0e10cSrcweir /*
824cdf0e10cSrcweir  * write (external data page).
825cdf0e10cSrcweir  */
write(sal_uInt32 nPage,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)826cdf0e10cSrcweir storeError OStoreDirectoryPageObject::write (
827cdf0e10cSrcweir 	sal_uInt32             nPage,
828cdf0e10cSrcweir 	OStoreDataPageObject  &rData,
829cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
830cdf0e10cSrcweir {
831cdf0e10cSrcweir 	// Determine scope and link indices.
832cdf0e10cSrcweir 	page::DataBlock::LinkDescriptor aLink;
833cdf0e10cSrcweir 	page::ChunkScope eScope = scope (nPage, aLink);
834cdf0e10cSrcweir 
835cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
836cdf0e10cSrcweir 	if (eScope == page::SCOPE_DIRECT)
837cdf0e10cSrcweir 	{
838cdf0e10cSrcweir         sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
839cdf0e10cSrcweir 		if (nAddr == STORE_PAGE_NULL)
840cdf0e10cSrcweir 		{
841cdf0e10cSrcweir             // Allocate data page.
842cdf0e10cSrcweir 			eErrCode = rBIOS.allocate (rData);
843cdf0e10cSrcweir 			if (eErrCode != store_E_None)
844cdf0e10cSrcweir 				return eErrCode;
845cdf0e10cSrcweir 
846cdf0e10cSrcweir             // Store data page location.
847cdf0e10cSrcweir 			directLink (aLink.m_nIndex0, rData.location());
848cdf0e10cSrcweir 		}
849cdf0e10cSrcweir 		else
850cdf0e10cSrcweir 		{
851cdf0e10cSrcweir             // Save data page.
852cdf0e10cSrcweir             eErrCode = rBIOS.saveObjectAt (rData, nAddr);
853cdf0e10cSrcweir 		}
854cdf0e10cSrcweir 	}
855cdf0e10cSrcweir 	else if (eScope == page::SCOPE_SINGLE)
856cdf0e10cSrcweir 	{
857cdf0e10cSrcweir 		OStoreIndirectionPageObject aSingle;
858cdf0e10cSrcweir         eErrCode = aSingle.loadOrCreate (singleLink (aLink.m_nIndex1), rBIOS);
859cdf0e10cSrcweir         if (eErrCode != store_E_None)
860cdf0e10cSrcweir         {
861cdf0e10cSrcweir             if (eErrCode != store_E_Pending)
862cdf0e10cSrcweir                 return eErrCode;
863cdf0e10cSrcweir 			singleLink (aLink.m_nIndex1, aSingle.location());
864cdf0e10cSrcweir         }
865cdf0e10cSrcweir 
866cdf0e10cSrcweir 		eErrCode = aSingle.write (aLink.m_nIndex0, rData, rBIOS);
867cdf0e10cSrcweir 	}
868cdf0e10cSrcweir 	else if (eScope == page::SCOPE_DOUBLE)
869cdf0e10cSrcweir 	{
870cdf0e10cSrcweir 		OStoreIndirectionPageObject aDouble;
871cdf0e10cSrcweir 		eErrCode = aDouble.loadOrCreate (doubleLink (aLink.m_nIndex2), rBIOS);
872cdf0e10cSrcweir         if (eErrCode != store_E_None)
873cdf0e10cSrcweir         {
874cdf0e10cSrcweir             if (eErrCode != store_E_Pending)
875cdf0e10cSrcweir 				return eErrCode;
876cdf0e10cSrcweir 			doubleLink (aLink.m_nIndex2, aDouble.location());
877cdf0e10cSrcweir 		}
878cdf0e10cSrcweir 
879cdf0e10cSrcweir 		eErrCode = aDouble.write (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
880cdf0e10cSrcweir 	}
881cdf0e10cSrcweir 	else if (eScope == page::SCOPE_TRIPLE)
882cdf0e10cSrcweir 	{
883cdf0e10cSrcweir 		OStoreIndirectionPageObject aTriple;
884cdf0e10cSrcweir 		eErrCode = aTriple.loadOrCreate (tripleLink (aLink.m_nIndex3), rBIOS);
885cdf0e10cSrcweir         if (eErrCode != store_E_None)
886cdf0e10cSrcweir         {
887cdf0e10cSrcweir             if (eErrCode != store_E_Pending)
888cdf0e10cSrcweir 				return eErrCode;
889cdf0e10cSrcweir 			tripleLink (aLink.m_nIndex3, aTriple.location());
890cdf0e10cSrcweir 		}
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 		eErrCode = aTriple.write (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
893cdf0e10cSrcweir 	}
894cdf0e10cSrcweir 	else if (eScope == page::SCOPE_UNREACHABLE)
895cdf0e10cSrcweir 	{
896cdf0e10cSrcweir 		// Out of scope.
897cdf0e10cSrcweir 		eErrCode = store_E_CantSeek;
898cdf0e10cSrcweir 	}
899cdf0e10cSrcweir 	else
900cdf0e10cSrcweir 	{
901cdf0e10cSrcweir 		// Unknown scope.
902cdf0e10cSrcweir 		OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
903cdf0e10cSrcweir 		eErrCode = store_E_Unknown;
904cdf0e10cSrcweir 	}
905cdf0e10cSrcweir 
906cdf0e10cSrcweir 	// Leave.
907cdf0e10cSrcweir 	return eErrCode;
908cdf0e10cSrcweir }
909cdf0e10cSrcweir 
910cdf0e10cSrcweir /*
911cdf0e10cSrcweir  * truncate (external data page).
912cdf0e10cSrcweir  */
truncate(sal_uInt32 nPage,OStorePageBIOS & rBIOS)913cdf0e10cSrcweir storeError OStoreDirectoryPageObject::truncate (
914cdf0e10cSrcweir 	sal_uInt32             nPage,
915cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
916cdf0e10cSrcweir {
917cdf0e10cSrcweir 	// Determine scope and link indices.
918cdf0e10cSrcweir 	page::DataBlock::LinkDescriptor aLink;
919cdf0e10cSrcweir 	page::ChunkScope eScope = scope (nPage, aLink);
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
922cdf0e10cSrcweir 	if (eScope == page::SCOPE_DIRECT)
923cdf0e10cSrcweir 	{
924cdf0e10cSrcweir 		// Truncate all triple indirect pages.
925cdf0e10cSrcweir 		eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
926cdf0e10cSrcweir 		if (eErrCode != store_E_None)
927cdf0e10cSrcweir 			return eErrCode;
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 		// Truncate all double indirect pages.
930cdf0e10cSrcweir 		eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
931cdf0e10cSrcweir 		if (eErrCode != store_E_None)
932cdf0e10cSrcweir 			return eErrCode;
933cdf0e10cSrcweir 
934cdf0e10cSrcweir 		// Truncate all single indirect pages.
935cdf0e10cSrcweir 		eErrCode = truncate (page::SCOPE_SINGLE, 0, rBIOS);
936cdf0e10cSrcweir 		if (eErrCode != store_E_None)
937cdf0e10cSrcweir 			return eErrCode;
938cdf0e10cSrcweir 
939cdf0e10cSrcweir 		// Truncate direct pages, including 'aLink.m_nIndex0'.
940cdf0e10cSrcweir 		eErrCode = truncate (eScope, aLink.m_nIndex0, rBIOS);
941cdf0e10cSrcweir 	}
942cdf0e10cSrcweir 	else if (eScope == page::SCOPE_SINGLE)
943cdf0e10cSrcweir 	{
944cdf0e10cSrcweir 		// Truncate all triple indirect pages.
945cdf0e10cSrcweir 		eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
946cdf0e10cSrcweir 		if (eErrCode != store_E_None)
947cdf0e10cSrcweir 			return eErrCode;
948cdf0e10cSrcweir 
949cdf0e10cSrcweir 		// Truncate all double indirect pages.
950cdf0e10cSrcweir 		eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
951cdf0e10cSrcweir 		if (eErrCode != store_E_None)
952cdf0e10cSrcweir 			return eErrCode;
953cdf0e10cSrcweir 
954cdf0e10cSrcweir 		// Truncate single indirect pages, downto 'aLink.m_nIndex1'.
955cdf0e10cSrcweir 		eErrCode = truncate (eScope, aLink.m_nIndex1 + 1, rBIOS);
956cdf0e10cSrcweir 		if (eErrCode != store_E_None)
957cdf0e10cSrcweir 			return eErrCode;
958cdf0e10cSrcweir 
959cdf0e10cSrcweir         // Truncate last single indirect page to ... pages.
960cdf0e10cSrcweir         eErrCode = store_truncate_Impl (singleLink (aLink.m_nIndex1), aLink.m_nIndex0, rBIOS);
961cdf0e10cSrcweir 		if (eErrCode != store_E_None)
962cdf0e10cSrcweir 			return eErrCode;
963cdf0e10cSrcweir 
964cdf0e10cSrcweir         // Check for complete truncation.
965cdf0e10cSrcweir         if (aLink.m_nIndex0 == 0)
966cdf0e10cSrcweir         {
967cdf0e10cSrcweir             // Clear pointer to last single indirect page.
968cdf0e10cSrcweir             singleLink (aLink.m_nIndex1, STORE_PAGE_NULL);
969cdf0e10cSrcweir         }
970cdf0e10cSrcweir 	}
971cdf0e10cSrcweir 	else if (eScope == page::SCOPE_DOUBLE)
972cdf0e10cSrcweir 	{
973cdf0e10cSrcweir 		// Truncate all triple indirect pages.
974cdf0e10cSrcweir 		eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
975cdf0e10cSrcweir 		if (eErrCode != store_E_None)
976cdf0e10cSrcweir 			return eErrCode;
977cdf0e10cSrcweir 
978cdf0e10cSrcweir 		// Truncate double indirect pages, downto 'aLink.m_nIndex2'.
979cdf0e10cSrcweir 		eErrCode = truncate (eScope, aLink.m_nIndex2 + 1, rBIOS);
980cdf0e10cSrcweir 		if (eErrCode != store_E_None)
981cdf0e10cSrcweir 			return eErrCode;
982cdf0e10cSrcweir 
983cdf0e10cSrcweir         // Truncate last double indirect page to ... pages.
984cdf0e10cSrcweir         eErrCode = store_truncate_Impl (
985cdf0e10cSrcweir             doubleLink (aLink.m_nIndex2), aLink.m_nIndex1, aLink.m_nIndex0, rBIOS);
986cdf0e10cSrcweir 		if (eErrCode != store_E_None)
987cdf0e10cSrcweir 			return eErrCode;
988cdf0e10cSrcweir 
989cdf0e10cSrcweir         // Check for complete truncation.
990cdf0e10cSrcweir         if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
991cdf0e10cSrcweir         {
992cdf0e10cSrcweir             // Clear pointer to last double indirect page.
993cdf0e10cSrcweir             doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL);
994cdf0e10cSrcweir         }
995cdf0e10cSrcweir 	}
996cdf0e10cSrcweir 	else if (eScope == page::SCOPE_TRIPLE)
997cdf0e10cSrcweir 	{
998cdf0e10cSrcweir 		// Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
999cdf0e10cSrcweir 		eErrCode = truncate (eScope, aLink.m_nIndex3 + 1, rBIOS);
1000cdf0e10cSrcweir 		if (eErrCode != store_E_None)
1001cdf0e10cSrcweir 			return eErrCode;
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir         // Truncate last triple indirect page to ... pages.
1004cdf0e10cSrcweir         eErrCode = store_truncate_Impl (
1005cdf0e10cSrcweir             tripleLink (aLink.m_nIndex3), aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rBIOS);
1006cdf0e10cSrcweir 		if (eErrCode != store_E_None)
1007cdf0e10cSrcweir 			return eErrCode;
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir         // Check for complete truncation.
1010cdf0e10cSrcweir         if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
1011cdf0e10cSrcweir         {
1012cdf0e10cSrcweir             // Clear pointer to last triple indirect page.
1013cdf0e10cSrcweir             tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL);
1014cdf0e10cSrcweir         }
1015cdf0e10cSrcweir 	}
1016cdf0e10cSrcweir 	else if (eScope == page::SCOPE_UNREACHABLE)
1017cdf0e10cSrcweir 	{
1018cdf0e10cSrcweir 		// Out of scope.
1019cdf0e10cSrcweir 		eErrCode = store_E_CantSeek;
1020cdf0e10cSrcweir 	}
1021cdf0e10cSrcweir 	else
1022cdf0e10cSrcweir 	{
1023cdf0e10cSrcweir 		// Unknown scope.
1024cdf0e10cSrcweir 		OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
1025cdf0e10cSrcweir 		eErrCode = store_E_Unknown;
1026cdf0e10cSrcweir 	}
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir 	// Leave.
1029cdf0e10cSrcweir 	return eErrCode;
1030cdf0e10cSrcweir }
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir /*
1033cdf0e10cSrcweir  * truncate (external data page scope; private).
1034cdf0e10cSrcweir  */
truncate(page::ChunkScope eScope,sal_uInt16 nRemain,OStorePageBIOS & rBIOS)1035cdf0e10cSrcweir storeError OStoreDirectoryPageObject::truncate (
1036cdf0e10cSrcweir 	page::ChunkScope       eScope,
1037cdf0e10cSrcweir 	sal_uInt16             nRemain,
1038cdf0e10cSrcweir 	OStorePageBIOS        &rBIOS)
1039cdf0e10cSrcweir {
1040cdf0e10cSrcweir     OStoreDirectoryDataBlock const & rDataBlock = PAGE().m_aDataBlock;
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 	// Enter.
1043cdf0e10cSrcweir 	storeError eErrCode = store_E_None;
1044cdf0e10cSrcweir 	if (eScope == page::SCOPE_DIRECT)
1045cdf0e10cSrcweir 	{
1046cdf0e10cSrcweir 		// Truncate direct data pages.
1047cdf0e10cSrcweir 		sal_uInt16 i, n = rDataBlock.directCount();
1048cdf0e10cSrcweir 		for (i = n; i > nRemain; i--)
1049cdf0e10cSrcweir 		{
1050cdf0e10cSrcweir 			// Obtain data page location.
1051cdf0e10cSrcweir 			sal_uInt32 nAddr = directLink (i - 1);
1052cdf0e10cSrcweir 			if (nAddr == STORE_PAGE_NULL) continue;
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir 			// Free data page.
1055cdf0e10cSrcweir 			eErrCode = rBIOS.free (nAddr);
1056cdf0e10cSrcweir 			if (eErrCode != store_E_None)
1057cdf0e10cSrcweir 				break;
1058cdf0e10cSrcweir 
1059cdf0e10cSrcweir 			// Clear pointer to data page.
1060cdf0e10cSrcweir 			directLink (i - 1, STORE_PAGE_NULL);
1061cdf0e10cSrcweir 		}
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 		// Done.
1064cdf0e10cSrcweir 		return eErrCode;
1065cdf0e10cSrcweir 	}
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir 	if (eScope == page::SCOPE_SINGLE)
1068cdf0e10cSrcweir 	{
1069cdf0e10cSrcweir 		// Truncate single indirect pages.
1070cdf0e10cSrcweir 		sal_uInt16 i, n = rDataBlock.singleCount();
1071cdf0e10cSrcweir 		for (i = n; i > nRemain; i--)
1072cdf0e10cSrcweir 		{
1073cdf0e10cSrcweir 			// Truncate single indirect page to zero data pages.
1074cdf0e10cSrcweir             eErrCode = store_truncate_Impl (singleLink (i - 1), 0, rBIOS);
1075cdf0e10cSrcweir 			if (eErrCode != store_E_None)
1076cdf0e10cSrcweir 				break;
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir 			// Clear pointer to single indirect page.
1079cdf0e10cSrcweir 			singleLink (i - 1, STORE_PAGE_NULL);
1080cdf0e10cSrcweir 		}
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir 		// Done.
1083cdf0e10cSrcweir 		return eErrCode;
1084cdf0e10cSrcweir 	}
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir 	if (eScope == page::SCOPE_DOUBLE)
1087cdf0e10cSrcweir 	{
1088cdf0e10cSrcweir 		// Truncate double indirect pages.
1089cdf0e10cSrcweir 		sal_uInt16 i, n = rDataBlock.doubleCount();
1090cdf0e10cSrcweir 		for (i = n; i > nRemain; i--)
1091cdf0e10cSrcweir 		{
1092cdf0e10cSrcweir 			// Truncate double indirect page to zero single indirect pages.
1093cdf0e10cSrcweir             eErrCode = store_truncate_Impl (doubleLink (i - 1), 0, 0, rBIOS);
1094cdf0e10cSrcweir 			if (eErrCode != store_E_None)
1095cdf0e10cSrcweir 				break;
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir 			// Clear pointer to double indirect page.
1098cdf0e10cSrcweir 			doubleLink (i - 1, STORE_PAGE_NULL);
1099cdf0e10cSrcweir 		}
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir 		// Done.
1102cdf0e10cSrcweir 		return eErrCode;
1103cdf0e10cSrcweir 	}
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir 	if (eScope == page::SCOPE_TRIPLE)
1106cdf0e10cSrcweir 	{
1107cdf0e10cSrcweir 		// Truncate triple indirect pages.
1108cdf0e10cSrcweir 		sal_uInt16 i, n = rDataBlock.tripleCount();
1109cdf0e10cSrcweir 		for (i = n; i > nRemain; i--)
1110cdf0e10cSrcweir 		{
1111cdf0e10cSrcweir 			// Truncate to zero double indirect pages.
1112cdf0e10cSrcweir 			eErrCode = store_truncate_Impl (tripleLink (i - 1), 0, 0, 0, rBIOS);
1113cdf0e10cSrcweir 			if (eErrCode != store_E_None)
1114cdf0e10cSrcweir 				break;
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir 			// Clear pointer to triple indirect page.
1117cdf0e10cSrcweir 			tripleLink (i - 1, STORE_PAGE_NULL);
1118cdf0e10cSrcweir 		}
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir 		// Done.
1121cdf0e10cSrcweir 		return eErrCode;
1122cdf0e10cSrcweir 	}
1123cdf0e10cSrcweir 
1124cdf0e10cSrcweir 	// Invalid scope.
1125cdf0e10cSrcweir 	return store_E_InvalidAccess;
1126cdf0e10cSrcweir }
1127