1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "stordata.hxx"
23 #include "sal/types.h"
24 #include "osl/diagnose.h"
26 #include "store/types.h"
27 #include "storbase.hxx"
28 #include "storbios.hxx"
30 using namespace store
;
32 /*========================================================================
34 * OStoreDataPageObject implementation.
36 *======================================================================*/
40 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
42 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
48 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
50 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
53 /*========================================================================
55 * OStoreIndirectionPageObject implementation.
57 *======================================================================*/
59 * store_truncate_Impl (single indirect page).
61 static storeError
store_truncate_Impl (
64 OStorePageBIOS
&rBIOS
)
66 if (nAddr
!= STORE_PAGE_NULL
)
68 // Load single indirect page.
69 OStoreIndirectionPageObject aSingle
;
70 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
71 if (eErrCode
== store_E_None
)
73 // Truncate to 'nSingle' direct pages.
74 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
75 if (eErrCode
!= store_E_None
)
80 if (eErrCode
!= store_E_InvalidChecksum
)
84 // Check for complete truncation.
87 // Free single indirect page.
88 eErrCode
= rBIOS
.free (nAddr
);
89 if (eErrCode
!= store_E_None
)
97 * store_truncate_Impl (double indirect page).
99 static storeError
store_truncate_Impl (
103 OStorePageBIOS
&rBIOS
)
105 if (nAddr
!= STORE_PAGE_NULL
)
107 // Load double indirect page.
108 OStoreIndirectionPageObject aDouble
;
109 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
110 if (eErrCode
== store_E_None
)
112 // Truncate to 'nDouble', 'nSingle' pages.
113 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
114 if (eErrCode
!= store_E_None
)
119 if (eErrCode
!= store_E_InvalidChecksum
)
123 // Check for complete truncation.
124 if ((nDouble
+ nSingle
) == 0)
126 // Free double indirect page.
127 eErrCode
= rBIOS
.free (nAddr
);
128 if (eErrCode
!= store_E_None
)
136 * store_truncate_Impl (triple indirect page).
138 static storeError
store_truncate_Impl (
143 OStorePageBIOS
&rBIOS
)
145 if (nAddr
!= STORE_PAGE_NULL
)
147 // Load triple indirect page.
148 OStoreIndirectionPageObject aTriple
;
149 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
150 if (eErrCode
!= store_E_None
)
153 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
154 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
155 if (eErrCode
!= store_E_None
)
158 // Check for complete truncation.
159 if ((nTriple
+ nDouble
+ nSingle
) == 0)
161 // Free triple indirect page.
162 eErrCode
= rBIOS
.free (nAddr
);
163 if (eErrCode
!= store_E_None
)
173 storeError
OStoreIndirectionPageObject::loadOrCreate (
175 OStorePageBIOS
& rBIOS
)
177 if (nAddr
== STORE_PAGE_NULL
)
179 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
180 if (eErrCode
!= store_E_None
)
183 eErrCode
= rBIOS
.allocate (*this);
184 if (eErrCode
!= store_E_None
)
187 // Save location pending at caller.
188 return store_E_Pending
;
190 return rBIOS
.loadObjectAt (*this, nAddr
);
196 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
198 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
204 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
206 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
210 * read (single indirect).
212 storeError
OStoreIndirectionPageObject::read (
214 OStoreDataPageObject
&rData
,
215 OStorePageBIOS
&rBIOS
)
217 PageHolderObject
< page
> xImpl (m_xPage
);
218 page
const & rPage
= (*xImpl
);
221 sal_uInt16
const nLimit
= rPage
.capacityCount();
222 if (!(nSingle
< nLimit
))
223 return store_E_InvalidAccess
;
225 // Obtain data page location.
226 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
227 if (nAddr
== STORE_PAGE_NULL
)
228 return store_E_NotExists
;
230 // Load data page and leave.
231 return rBIOS
.loadObjectAt (rData
, nAddr
);
235 * read (double indirect).
237 storeError
OStoreIndirectionPageObject::read (
240 OStoreDataPageObject
&rData
,
241 OStorePageBIOS
&rBIOS
)
243 PageHolderObject
< page
> xImpl (m_xPage
);
244 page
const & rPage
= (*xImpl
);
247 sal_uInt16
const nLimit
= rPage
.capacityCount();
248 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
249 return store_E_InvalidAccess
;
251 // Check single indirect page location.
252 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
253 if (nAddr
== STORE_PAGE_NULL
)
254 return store_E_NotExists
;
256 // Load single indirect page.
257 OStoreIndirectionPageObject aSingle
;
258 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
259 if (eErrCode
!= store_E_None
)
262 // Read single indirect and leave.
263 return aSingle
.read (nSingle
, rData
, rBIOS
);
267 * read (triple indirect).
269 storeError
OStoreIndirectionPageObject::read (
273 OStoreDataPageObject
&rData
,
274 OStorePageBIOS
&rBIOS
)
276 PageHolderObject
< page
> xImpl (m_xPage
);
277 page
const & rPage
= (*xImpl
);
280 sal_uInt16
const nLimit
= rPage
.capacityCount();
281 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
282 return store_E_InvalidAccess
;
284 // Check double indirect page location.
285 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
286 if (nAddr
== STORE_PAGE_NULL
)
287 return store_E_NotExists
;
289 // Load double indirect page.
290 OStoreIndirectionPageObject aDouble
;
291 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
292 if (eErrCode
!= store_E_None
)
295 // Read double indirect and leave.
296 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
300 * write (single indirect).
302 storeError
OStoreIndirectionPageObject::write (
304 OStoreDataPageObject
&rData
,
305 OStorePageBIOS
&rBIOS
)
307 PageHolderObject
< page
> xImpl (m_xPage
);
308 page
& rPage
= (*xImpl
);
311 sal_uInt16
const nLimit
= rPage
.capacityCount();
312 if (!(nSingle
< nLimit
))
313 return store_E_InvalidAccess
;
315 // Obtain data page location.
316 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
317 if (nAddr
== STORE_PAGE_NULL
)
319 // Allocate data page.
320 storeError eErrCode
= rBIOS
.allocate (rData
);
321 if (eErrCode
!= store_E_None
)
324 // Store data page location.
325 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
328 return rBIOS
.saveObjectAt (*this, location());
333 return rBIOS
.saveObjectAt (rData
, nAddr
);
338 * write (double indirect).
340 storeError
OStoreIndirectionPageObject::write (
343 OStoreDataPageObject
&rData
,
344 OStorePageBIOS
&rBIOS
)
346 PageHolderObject
< page
> xImpl (m_xPage
);
347 page
& rPage
= (*xImpl
);
350 sal_uInt16
const nLimit
= rPage
.capacityCount();
351 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
352 return store_E_InvalidAccess
;
354 // Load or create single indirect page.
355 OStoreIndirectionPageObject aSingle
;
356 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
357 if (eErrCode
!= store_E_None
)
359 if (eErrCode
!= store_E_Pending
)
361 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
363 eErrCode
= rBIOS
.saveObjectAt (*this, location());
364 if (eErrCode
!= store_E_None
)
368 // Write single indirect and leave.
369 return aSingle
.write (nSingle
, rData
, rBIOS
);
373 * write (triple indirect).
375 storeError
OStoreIndirectionPageObject::write (
379 OStoreDataPageObject
&rData
,
380 OStorePageBIOS
&rBIOS
)
382 PageHolderObject
< page
> xImpl (m_xPage
);
383 page
& rPage
= (*xImpl
);
386 sal_uInt16
const nLimit
= rPage
.capacityCount();
387 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
388 return store_E_InvalidAccess
;
390 // Load or create double indirect page.
391 OStoreIndirectionPageObject aDouble
;
392 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
393 if (eErrCode
!= store_E_None
)
395 if (eErrCode
!= store_E_Pending
)
397 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
399 eErrCode
= rBIOS
.saveObjectAt (*this, location());
400 if (eErrCode
!= store_E_None
)
404 // Write double indirect and leave.
405 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
409 * truncate (single indirect).
411 storeError
OStoreIndirectionPageObject::truncate (
413 OStorePageBIOS
& rBIOS
)
415 PageHolderObject
< page
> xImpl (m_xPage
);
416 page
& rPage
= (*xImpl
);
419 sal_uInt16
const nLimit
= rPage
.capacityCount();
420 if (!(nSingle
< nLimit
))
421 return store_E_InvalidAccess
;
424 storeError eErrCode
= store_E_None
;
425 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
427 // Obtain data page location.
428 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
429 if (nAddr
!= STORE_PAGE_NULL
)
432 eErrCode
= rBIOS
.free (nAddr
);
433 if (eErrCode
!= store_E_None
)
436 // Clear pointer to data page.
437 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
442 // Check for modified page.
446 eErrCode
= rBIOS
.saveObjectAt (*this, location());
454 * truncate (double indirect).
456 storeError
OStoreIndirectionPageObject::truncate (
459 OStorePageBIOS
&rBIOS
)
461 PageHolderObject
< page
> xImpl (m_xPage
);
462 page
& rPage
= (*xImpl
);
465 sal_uInt16
const nLimit
= rPage
.capacityCount();
466 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
467 return store_E_InvalidAccess
;
470 storeError eErrCode
= store_E_None
;
471 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
473 // Truncate single indirect page to zero direct pages.
474 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
475 if (eErrCode
!= store_E_None
)
478 // Clear pointer to single indirect page.
479 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
483 // Truncate last single indirect page to 'nSingle' direct pages.
484 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
485 if (eErrCode
!= store_E_None
)
488 // Check for complete truncation.
491 // Clear pointer to last single indirect page.
492 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
496 // Check for modified page.
500 eErrCode
= rBIOS
.saveObjectAt (*this, location());
508 * truncate (triple indirect).
510 storeError
OStoreIndirectionPageObject::truncate (
514 OStorePageBIOS
&rBIOS
)
516 PageHolderObject
< page
> xImpl (m_xPage
);
517 page
& rPage
= (*xImpl
);
520 sal_uInt16
const nLimit
= rPage
.capacityCount();
521 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
522 return store_E_InvalidAccess
;
525 storeError eErrCode
= store_E_None
;
526 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
528 // Truncate double indirect page to zero single indirect pages.
529 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
530 if (eErrCode
!= store_E_None
)
533 // Clear pointer to double indirect page.
534 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
538 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
539 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
540 if (eErrCode
!= store_E_None
)
543 // Check for complete truncation.
544 if ((nDouble
+ nSingle
) == 0)
546 // Clear pointer to last double indirect page.
547 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
551 // Check for modified page.
555 eErrCode
= rBIOS
.saveObjectAt (*this, location());
562 /*========================================================================
564 * OStoreDirectoryPageObject implementation.
566 *======================================================================*/
570 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
572 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
578 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
580 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
581 // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
585 * scope (external data page; private).
587 OStoreDirectoryPageData::ChunkScope
588 OStoreDirectoryPageObject::scope (
590 page::DataBlock::LinkDescriptor
&rDescr
) const
592 page
const & rPage
= PAGE();
593 OStoreDirectoryDataBlock
const & rDataBlock
= rPage
.m_aDataBlock
;
595 sal_uInt32 index0
, index1
, index2
, index3
;
598 sal_uInt32 nCount
= rDataBlock
.directCount();
599 sal_uInt32 nLimit
= nCount
;
602 // Page to index reduction.
605 // Setup LinkDescriptor indices.
606 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
609 return page::SCOPE_DIRECT
;
614 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
615 nCount
= rDataBlock
.singleCount();
616 nLimit
= nCount
* nCapacity
;
619 // Page to index reduction.
620 sal_uInt32 n
= nPage
;
622 // Reduce to single indirect i(1), direct n = i(0).
623 index1
= n
/ nCapacity
;
624 index0
= n
% nCapacity
;
627 n
= index1
* nCapacity
+ index0
;
628 OSL_POSTCOND(n
== nPage
, "wrong math on indirect indices");
630 return page::SCOPE_UNKNOWN
;
632 // Setup LinkDescriptor indices.
633 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
634 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
637 return page::SCOPE_SINGLE
;
642 nCount
= rDataBlock
.doubleCount();
643 nLimit
= nCount
* nCapacity
* nCapacity
;
646 // Page to index reduction.
647 sal_uInt32 n
= nPage
;
649 // Reduce to double indirect i(2), single indirect n = i(0).
650 index2
= n
/ (nCapacity
* nCapacity
);
651 n
= n
% (nCapacity
* nCapacity
);
653 // Reduce to single indirect i(1), direct n = i(0).
654 index1
= n
/ nCapacity
;
655 index0
= n
% nCapacity
;
658 n
= index2
* nCapacity
* nCapacity
+
659 index1
* nCapacity
+ index0
;
660 OSL_POSTCOND(n
== nPage
, "wrong math on double indirect indices");
662 return page::SCOPE_UNKNOWN
;
664 // Setup LinkDescriptor indices.
665 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
666 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
667 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
670 return page::SCOPE_DOUBLE
;
675 nCount
= rDataBlock
.tripleCount();
676 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
679 // Page to index reduction.
680 sal_uInt32 n
= nPage
;
682 // Reduce to triple indirect i(3), double indirect n.
683 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
684 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
686 // Reduce to double indirect i(2), single indirect n.
687 index2
= n
/ (nCapacity
* nCapacity
);
688 n
= n
% (nCapacity
* nCapacity
);
690 // Reduce to single indirect i(1), direct n = i(0).
691 index1
= n
/ nCapacity
;
692 index0
= n
% nCapacity
;
695 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
696 index2
* nCapacity
* nCapacity
+
697 index1
* nCapacity
+ index0
;
698 OSL_POSTCOND(n
== nPage
, "wrong math on triple indirect indices");
700 return page::SCOPE_UNKNOWN
;
702 // Setup LinkDescriptor indices.
703 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
704 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
705 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
706 rDescr
.m_nIndex3
= (sal_uInt16
)(index3
& 0xffff);
709 return page::SCOPE_TRIPLE
;
712 // Unreachable (more than triple indirect).
713 return page::SCOPE_UNREACHABLE
;
717 * read (external data page).
719 storeError
OStoreDirectoryPageObject::read (
721 OStoreDataPageObject
&rData
,
722 OStorePageBIOS
&rBIOS
)
724 // Determine scope and link indices.
725 page::DataBlock::LinkDescriptor aLink
;
726 page::ChunkScope eScope
= scope (nPage
, aLink
);
728 storeError eErrCode
= store_E_None
;
729 if (eScope
== page::SCOPE_DIRECT
)
731 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
732 if (nAddr
== STORE_PAGE_NULL
)
733 return store_E_NotExists
;
735 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
737 else if (eScope
== page::SCOPE_SINGLE
)
739 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
740 if (nAddr
== STORE_PAGE_NULL
)
741 return store_E_NotExists
;
743 OStoreIndirectionPageObject aSingle
;
744 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
745 if (eErrCode
!= store_E_None
)
748 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
750 else if (eScope
== page::SCOPE_DOUBLE
)
752 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
753 if (nAddr
== STORE_PAGE_NULL
)
754 return store_E_NotExists
;
756 OStoreIndirectionPageObject aDouble
;
757 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
758 if (eErrCode
!= store_E_None
)
761 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
763 else if (eScope
== page::SCOPE_TRIPLE
)
765 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
766 if (nAddr
== STORE_PAGE_NULL
)
767 return store_E_NotExists
;
769 OStoreIndirectionPageObject aTriple
;
770 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
771 if (eErrCode
!= store_E_None
)
774 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
776 else if (eScope
== page::SCOPE_UNREACHABLE
)
779 eErrCode
= store_E_CantSeek
;
784 OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
785 eErrCode
= store_E_Unknown
;
793 * write (external data page).
795 storeError
OStoreDirectoryPageObject::write (
797 OStoreDataPageObject
&rData
,
798 OStorePageBIOS
&rBIOS
)
800 // Determine scope and link indices.
801 page::DataBlock::LinkDescriptor aLink
;
802 page::ChunkScope eScope
= scope (nPage
, aLink
);
804 storeError eErrCode
= store_E_None
;
805 if (eScope
== page::SCOPE_DIRECT
)
807 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
808 if (nAddr
== STORE_PAGE_NULL
)
810 // Allocate data page.
811 eErrCode
= rBIOS
.allocate (rData
);
812 if (eErrCode
!= store_E_None
)
815 // Store data page location.
816 directLink (aLink
.m_nIndex0
, rData
.location());
821 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
824 else if (eScope
== page::SCOPE_SINGLE
)
826 OStoreIndirectionPageObject aSingle
;
827 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
828 if (eErrCode
!= store_E_None
)
830 if (eErrCode
!= store_E_Pending
)
832 singleLink (aLink
.m_nIndex1
, aSingle
.location());
835 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
837 else if (eScope
== page::SCOPE_DOUBLE
)
839 OStoreIndirectionPageObject aDouble
;
840 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
841 if (eErrCode
!= store_E_None
)
843 if (eErrCode
!= store_E_Pending
)
845 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
848 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
850 else if (eScope
== page::SCOPE_TRIPLE
)
852 OStoreIndirectionPageObject aTriple
;
853 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
854 if (eErrCode
!= store_E_None
)
856 if (eErrCode
!= store_E_Pending
)
858 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
861 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
863 else if (eScope
== page::SCOPE_UNREACHABLE
)
866 eErrCode
= store_E_CantSeek
;
871 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
872 eErrCode
= store_E_Unknown
;
880 * truncate (external data page).
882 storeError
OStoreDirectoryPageObject::truncate (
884 OStorePageBIOS
&rBIOS
)
886 // Determine scope and link indices.
887 page::DataBlock::LinkDescriptor aLink
;
888 page::ChunkScope eScope
= scope (nPage
, aLink
);
890 storeError eErrCode
= store_E_None
;
891 if (eScope
== page::SCOPE_DIRECT
)
893 // Truncate all triple indirect pages.
894 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
895 if (eErrCode
!= store_E_None
)
898 // Truncate all double indirect pages.
899 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
900 if (eErrCode
!= store_E_None
)
903 // Truncate all single indirect pages.
904 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
905 if (eErrCode
!= store_E_None
)
908 // Truncate direct pages, including 'aLink.m_nIndex0'.
909 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
911 else if (eScope
== page::SCOPE_SINGLE
)
913 // Truncate all triple indirect pages.
914 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
915 if (eErrCode
!= store_E_None
)
918 // Truncate all double indirect pages.
919 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
920 if (eErrCode
!= store_E_None
)
923 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
924 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
925 if (eErrCode
!= store_E_None
)
928 // Truncate last single indirect page to ... pages.
929 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
930 if (eErrCode
!= store_E_None
)
933 // Check for complete truncation.
934 if (aLink
.m_nIndex0
== 0)
936 // Clear pointer to last single indirect page.
937 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
940 else if (eScope
== page::SCOPE_DOUBLE
)
942 // Truncate all triple indirect pages.
943 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
944 if (eErrCode
!= store_E_None
)
947 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
948 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
949 if (eErrCode
!= store_E_None
)
952 // Truncate last double indirect page to ... pages.
953 eErrCode
= store_truncate_Impl (
954 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
955 if (eErrCode
!= store_E_None
)
958 // Check for complete truncation.
959 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
961 // Clear pointer to last double indirect page.
962 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
965 else if (eScope
== page::SCOPE_TRIPLE
)
967 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
968 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
969 if (eErrCode
!= store_E_None
)
972 // Truncate last triple indirect page to ... pages.
973 eErrCode
= store_truncate_Impl (
974 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
975 if (eErrCode
!= store_E_None
)
978 // Check for complete truncation.
979 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
981 // Clear pointer to last triple indirect page.
982 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
985 else if (eScope
== page::SCOPE_UNREACHABLE
)
988 eErrCode
= store_E_CantSeek
;
993 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
994 eErrCode
= store_E_Unknown
;
1002 * truncate (external data page scope; private).
1004 storeError
OStoreDirectoryPageObject::truncate (
1005 page::ChunkScope eScope
,
1007 OStorePageBIOS
&rBIOS
)
1009 OStoreDirectoryDataBlock
const & rDataBlock
= PAGE().m_aDataBlock
;
1012 storeError eErrCode
= store_E_None
;
1013 if (eScope
== page::SCOPE_DIRECT
)
1015 // Truncate direct data pages.
1016 sal_uInt16 i
, n
= rDataBlock
.directCount();
1017 for (i
= n
; i
> nRemain
; i
--)
1019 // Obtain data page location.
1020 sal_uInt32 nAddr
= directLink (i
- 1);
1021 if (nAddr
== STORE_PAGE_NULL
) continue;
1024 eErrCode
= rBIOS
.free (nAddr
);
1025 if (eErrCode
!= store_E_None
)
1028 // Clear pointer to data page.
1029 directLink (i
- 1, STORE_PAGE_NULL
);
1036 if (eScope
== page::SCOPE_SINGLE
)
1038 // Truncate single indirect pages.
1039 sal_uInt16 i
, n
= rDataBlock
.singleCount();
1040 for (i
= n
; i
> nRemain
; i
--)
1042 // Truncate single indirect page to zero data pages.
1043 eErrCode
= store_truncate_Impl (singleLink (i
- 1), 0, rBIOS
);
1044 if (eErrCode
!= store_E_None
)
1047 // Clear pointer to single indirect page.
1048 singleLink (i
- 1, STORE_PAGE_NULL
);
1055 if (eScope
== page::SCOPE_DOUBLE
)
1057 // Truncate double indirect pages.
1058 sal_uInt16 i
, n
= rDataBlock
.doubleCount();
1059 for (i
= n
; i
> nRemain
; i
--)
1061 // Truncate double indirect page to zero single indirect pages.
1062 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1063 if (eErrCode
!= store_E_None
)
1066 // Clear pointer to double indirect page.
1067 doubleLink (i
- 1, STORE_PAGE_NULL
);
1074 if (eScope
== page::SCOPE_TRIPLE
)
1076 // Truncate triple indirect pages.
1077 sal_uInt16 i
, n
= rDataBlock
.tripleCount();
1078 for (i
= n
; i
> nRemain
; i
--)
1080 // Truncate to zero double indirect pages.
1081 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1082 if (eErrCode
!= store_E_None
)
1085 // Clear pointer to triple indirect page.
1086 tripleLink (i
- 1, STORE_PAGE_NULL
);
1094 return store_E_InvalidAccess
;
1097 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */