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