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