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