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 .
20 #include "stordata.hxx"
22 #include <sal/types.h>
23 #include <sal/log.hxx>
25 #include <store/types.h>
26 #include "storbase.hxx"
27 #include "storbios.hxx"
29 using namespace store
;
31 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
33 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
36 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
38 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
42 store_truncate_Impl (single indirect page).
44 static storeError
store_truncate_Impl (
47 OStorePageBIOS
&rBIOS
)
49 if (nAddr
!= STORE_PAGE_NULL
)
51 // Load single indirect page.
52 OStoreIndirectionPageObject aSingle
;
53 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
54 if (eErrCode
== store_E_None
)
56 // Truncate to 'nSingle' direct pages.
57 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
58 if (eErrCode
!= store_E_None
)
63 if (eErrCode
!= store_E_InvalidChecksum
)
67 // Check for complete truncation.
70 // Free single indirect page.
71 eErrCode
= rBIOS
.free (nAddr
);
72 if (eErrCode
!= store_E_None
)
80 * store_truncate_Impl (double indirect page).
82 static storeError
store_truncate_Impl (
86 OStorePageBIOS
&rBIOS
)
88 if (nAddr
!= STORE_PAGE_NULL
)
90 // Load double indirect page.
91 OStoreIndirectionPageObject aDouble
;
92 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
93 if (eErrCode
== store_E_None
)
95 // Truncate to 'nDouble', 'nSingle' pages.
96 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
97 if (eErrCode
!= store_E_None
)
102 if (eErrCode
!= store_E_InvalidChecksum
)
106 // Check for complete truncation.
107 if ((nDouble
+ nSingle
) == 0)
109 // Free double indirect page.
110 eErrCode
= rBIOS
.free (nAddr
);
111 if (eErrCode
!= store_E_None
)
119 * store_truncate_Impl (triple indirect page).
121 static storeError
store_truncate_Impl (
126 OStorePageBIOS
&rBIOS
)
128 if (nAddr
!= STORE_PAGE_NULL
)
130 // Load triple indirect page.
131 OStoreIndirectionPageObject aTriple
;
132 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
133 if (eErrCode
!= store_E_None
)
136 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
137 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
138 if (eErrCode
!= store_E_None
)
141 // Check for complete truncation.
142 if ((nTriple
+ nDouble
+ nSingle
) == 0)
144 // Free triple indirect page.
145 eErrCode
= rBIOS
.free (nAddr
);
146 if (eErrCode
!= store_E_None
)
153 storeError
OStoreIndirectionPageObject::loadOrCreate (
155 OStorePageBIOS
& rBIOS
)
157 if (nAddr
== STORE_PAGE_NULL
)
159 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
160 if (eErrCode
!= store_E_None
)
163 eErrCode
= rBIOS
.allocate (*this);
164 if (eErrCode
!= store_E_None
)
167 // Save location pending at caller.
168 return store_E_Pending
;
170 return rBIOS
.loadObjectAt (*this, nAddr
);
173 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
175 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
178 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
180 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
183 storeError
OStoreIndirectionPageObject::read (
185 OStoreDataPageObject
&rData
,
186 OStorePageBIOS
&rBIOS
) const
188 PageHolderObject
< page
> xImpl (m_xPage
);
189 page
const & rPage
= *xImpl
;
192 sal_uInt16
const nLimit
= rPage
.capacityCount();
193 if (nSingle
>= nLimit
)
194 return store_E_InvalidAccess
;
196 // Obtain data page location.
197 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
198 if (nAddr
== STORE_PAGE_NULL
)
199 return store_E_NotExists
;
201 // Load data page and leave.
202 return rBIOS
.loadObjectAt (rData
, nAddr
);
206 * read (double indirect).
208 storeError
OStoreIndirectionPageObject::read (
211 OStoreDataPageObject
&rData
,
212 OStorePageBIOS
&rBIOS
) const
214 PageHolderObject
< page
> xImpl (m_xPage
);
215 page
const & rPage
= *xImpl
;
218 sal_uInt16
const nLimit
= rPage
.capacityCount();
219 if ((nDouble
>= nLimit
) || (nSingle
>= nLimit
))
220 return store_E_InvalidAccess
;
222 // Check single indirect page location.
223 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
224 if (nAddr
== STORE_PAGE_NULL
)
225 return store_E_NotExists
;
227 // Load single indirect page.
228 OStoreIndirectionPageObject aSingle
;
229 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
230 if (eErrCode
!= store_E_None
)
233 // Read single indirect and leave.
234 return aSingle
.read (nSingle
, rData
, rBIOS
);
238 * read (triple indirect).
240 storeError
OStoreIndirectionPageObject::read (
244 OStoreDataPageObject
&rData
,
245 OStorePageBIOS
&rBIOS
) const
247 PageHolderObject
< page
> xImpl (m_xPage
);
248 page
const & rPage
= *xImpl
;
251 sal_uInt16
const nLimit
= rPage
.capacityCount();
252 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
253 return store_E_InvalidAccess
;
255 // Check double indirect page location.
256 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
257 if (nAddr
== STORE_PAGE_NULL
)
258 return store_E_NotExists
;
260 // Load double indirect page.
261 OStoreIndirectionPageObject aDouble
;
262 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
263 if (eErrCode
!= store_E_None
)
266 // Read double indirect and leave.
267 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
271 * write (single indirect).
273 storeError
OStoreIndirectionPageObject::write (
275 OStoreDataPageObject
&rData
,
276 OStorePageBIOS
&rBIOS
)
278 PageHolderObject
< page
> xImpl (m_xPage
);
279 page
& rPage
= *xImpl
;
282 sal_uInt16
const nLimit
= rPage
.capacityCount();
283 if (nSingle
>= nLimit
)
284 return store_E_InvalidAccess
;
286 // Obtain data page location.
287 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
288 if (nAddr
== STORE_PAGE_NULL
)
290 // Allocate data page.
291 storeError eErrCode
= rBIOS
.allocate (rData
);
292 if (eErrCode
!= store_E_None
)
295 // Store data page location.
296 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
299 return rBIOS
.saveObjectAt (*this, location());
304 return rBIOS
.saveObjectAt (rData
, nAddr
);
309 * write (double indirect).
311 storeError
OStoreIndirectionPageObject::write (
314 OStoreDataPageObject
&rData
,
315 OStorePageBIOS
&rBIOS
)
317 PageHolderObject
< page
> xImpl (m_xPage
);
318 page
& rPage
= *xImpl
;
321 sal_uInt16
const nLimit
= rPage
.capacityCount();
322 if ((nDouble
>= nLimit
) || (nSingle
>= nLimit
))
323 return store_E_InvalidAccess
;
325 // Load or create single indirect page.
326 OStoreIndirectionPageObject aSingle
;
327 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
328 if (eErrCode
!= store_E_None
)
330 if (eErrCode
!= store_E_Pending
)
332 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
334 eErrCode
= rBIOS
.saveObjectAt (*this, location());
335 if (eErrCode
!= store_E_None
)
339 // Write single indirect and leave.
340 return aSingle
.write (nSingle
, rData
, rBIOS
);
344 * write (triple indirect).
346 storeError
OStoreIndirectionPageObject::write (
350 OStoreDataPageObject
&rData
,
351 OStorePageBIOS
&rBIOS
)
353 PageHolderObject
< page
> xImpl (m_xPage
);
354 page
& rPage
= *xImpl
;
357 sal_uInt16
const nLimit
= rPage
.capacityCount();
358 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
359 return store_E_InvalidAccess
;
361 // Load or create double indirect page.
362 OStoreIndirectionPageObject aDouble
;
363 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
364 if (eErrCode
!= store_E_None
)
366 if (eErrCode
!= store_E_Pending
)
368 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
370 eErrCode
= rBIOS
.saveObjectAt (*this, location());
371 if (eErrCode
!= store_E_None
)
375 // Write double indirect and leave.
376 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
380 * truncate (single indirect).
382 storeError
OStoreIndirectionPageObject::truncate (
384 OStorePageBIOS
& rBIOS
)
386 PageHolderObject
< page
> xImpl (m_xPage
);
387 page
& rPage
= *xImpl
;
390 sal_uInt16
const nLimit
= rPage
.capacityCount();
391 if (nSingle
>= nLimit
)
392 return store_E_InvalidAccess
;
395 storeError eErrCode
= store_E_None
;
396 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
398 // Obtain data page location.
399 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
400 if (nAddr
!= STORE_PAGE_NULL
)
403 eErrCode
= rBIOS
.free (nAddr
);
404 if (eErrCode
!= store_E_None
)
407 // Clear pointer to data page.
408 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
413 // Check for modified page.
417 eErrCode
= rBIOS
.saveObjectAt (*this, location());
425 * truncate (double indirect).
427 storeError
OStoreIndirectionPageObject::truncate (
430 OStorePageBIOS
&rBIOS
)
432 PageHolderObject
< page
> xImpl (m_xPage
);
433 page
& rPage
= *xImpl
;
436 sal_uInt16
const nLimit
= rPage
.capacityCount();
437 if ((nDouble
>= nLimit
) || (nSingle
>= nLimit
))
438 return store_E_InvalidAccess
;
441 storeError eErrCode
= store_E_None
;
442 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
444 // Truncate single indirect page to zero direct pages.
445 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
446 if (eErrCode
!= store_E_None
)
449 // Clear pointer to single indirect page.
450 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
454 // Truncate last single indirect page to 'nSingle' direct pages.
455 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
456 if (eErrCode
!= store_E_None
)
459 // Check for complete truncation.
462 // Clear pointer to last single indirect page.
463 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
467 // Check for modified page.
471 eErrCode
= rBIOS
.saveObjectAt (*this, location());
479 * truncate (triple indirect).
481 storeError
OStoreIndirectionPageObject::truncate (
485 OStorePageBIOS
&rBIOS
)
487 PageHolderObject
< page
> xImpl (m_xPage
);
488 page
& rPage
= *xImpl
;
491 sal_uInt16
const nLimit
= rPage
.capacityCount();
492 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
493 return store_E_InvalidAccess
;
496 storeError eErrCode
= store_E_None
;
497 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
499 // Truncate double indirect page to zero single indirect pages.
500 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
501 if (eErrCode
!= store_E_None
)
504 // Clear pointer to double indirect page.
505 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
509 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
510 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
511 if (eErrCode
!= store_E_None
)
514 // Check for complete truncation.
515 if ((nDouble
+ nSingle
) == 0)
517 // Clear pointer to last double indirect page.
518 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
522 // Check for modified page.
526 eErrCode
= rBIOS
.saveObjectAt (*this, location());
533 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
535 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
538 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
540 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
543 OStoreDirectoryPageData::ChunkScope
544 OStoreDirectoryPageObject::scope (
546 page::DataBlock::LinkDescriptor
&rDescr
) const
548 page
const & rPage
= PAGE();
550 sal_uInt32 index0
, index1
, index2
;
553 sal_uInt32 nCount
= OStoreDirectoryDataBlock::directCount
;
554 sal_uInt32 nLimit
= nCount
;
557 // Page to index reduction.
560 // Setup LinkDescriptor indices.
561 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
564 return page::SCOPE_DIRECT
;
569 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
570 nCount
= OStoreDirectoryDataBlock::singleCount
;
571 nLimit
= nCount
* nCapacity
;
574 // Page to index reduction.
575 sal_uInt32 n
= nPage
;
577 // Reduce to single indirect i(1), direct n = i(0).
578 index1
= n
/ nCapacity
;
579 index0
= n
% nCapacity
;
582 n
= index1
* nCapacity
+ index0
;
585 SAL_WARN("store", "wrong math on indirect indices");
586 return page::SCOPE_UNKNOWN
;
589 // Setup LinkDescriptor indices.
590 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
591 rDescr
.m_nIndex1
= static_cast<sal_uInt16
>(index1
& 0xffff);
594 return page::SCOPE_SINGLE
;
599 nCount
= OStoreDirectoryDataBlock::doubleCount
;
600 nLimit
= nCount
* nCapacity
* nCapacity
;
603 // Page to index reduction.
604 sal_uInt32 n
= nPage
;
606 // Reduce to double indirect i(2), single indirect n = i(0).
607 index2
= n
/ (nCapacity
* nCapacity
);
608 n
= n
% (nCapacity
* nCapacity
);
610 // Reduce to single indirect i(1), direct n = i(0).
611 index1
= n
/ nCapacity
;
612 index0
= n
% nCapacity
;
615 n
= index2
* nCapacity
* nCapacity
+
616 index1
* nCapacity
+ index0
;
619 SAL_WARN("store", "wrong math on double indirect indices");
620 return page::SCOPE_UNKNOWN
;
623 // Setup LinkDescriptor indices.
624 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
625 rDescr
.m_nIndex1
= static_cast<sal_uInt16
>(index1
& 0xffff);
626 rDescr
.m_nIndex2
= static_cast<sal_uInt16
>(index2
& 0xffff);
629 return page::SCOPE_DOUBLE
;
634 nCount
= OStoreDirectoryDataBlock::tripleCount
;
635 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
638 // Page to index reduction.
639 sal_uInt32 n
= nPage
;
641 // Reduce to triple indirect i(3), double indirect n.
642 sal_uInt32 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
643 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
645 // Reduce to double indirect i(2), single indirect n.
646 index2
= n
/ (nCapacity
* nCapacity
);
647 n
= n
% (nCapacity
* nCapacity
);
649 // Reduce to single indirect i(1), direct n = i(0).
650 index1
= n
/ nCapacity
;
651 index0
= n
% nCapacity
;
654 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
655 index2
* nCapacity
* nCapacity
+
656 index1
* nCapacity
+ index0
;
659 SAL_WARN("store", "wrong math on triple indirect indices");
660 return page::SCOPE_UNKNOWN
;
663 // Setup LinkDescriptor indices.
664 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
665 rDescr
.m_nIndex1
= static_cast<sal_uInt16
>(index1
& 0xffff);
666 rDescr
.m_nIndex2
= static_cast<sal_uInt16
>(index2
& 0xffff);
667 rDescr
.m_nIndex3
= static_cast<sal_uInt16
>(index3
& 0xffff);
670 return page::SCOPE_TRIPLE
;
673 // Unreachable (more than triple indirect).
674 return page::SCOPE_UNREACHABLE
;
677 storeError
OStoreDirectoryPageObject::read (
679 OStoreDataPageObject
&rData
,
680 OStorePageBIOS
&rBIOS
) const
682 // Determine scope and link indices.
683 page::DataBlock::LinkDescriptor aLink
;
684 page::ChunkScope eScope
= scope (nPage
, aLink
);
686 storeError eErrCode
= store_E_None
;
687 if (eScope
== page::SCOPE_DIRECT
)
689 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
690 if (nAddr
== STORE_PAGE_NULL
)
691 return store_E_NotExists
;
693 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
695 else if (eScope
== page::SCOPE_SINGLE
)
697 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
698 if (nAddr
== STORE_PAGE_NULL
)
699 return store_E_NotExists
;
701 OStoreIndirectionPageObject aSingle
;
702 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
703 if (eErrCode
!= store_E_None
)
706 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
708 else if (eScope
== page::SCOPE_DOUBLE
)
710 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
711 if (nAddr
== STORE_PAGE_NULL
)
712 return store_E_NotExists
;
714 OStoreIndirectionPageObject aDouble
;
715 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
716 if (eErrCode
!= store_E_None
)
719 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
721 else if (eScope
== page::SCOPE_TRIPLE
)
723 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
724 if (nAddr
== STORE_PAGE_NULL
)
725 return store_E_NotExists
;
727 OStoreIndirectionPageObject aTriple
;
728 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
729 if (eErrCode
!= store_E_None
)
732 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
734 else if (eScope
== page::SCOPE_UNREACHABLE
)
737 eErrCode
= store_E_CantSeek
;
742 SAL_WARN("store", "OStoreDirectoryPageObject::get(): scope failed");
743 eErrCode
= store_E_Unknown
;
750 storeError
OStoreDirectoryPageObject::write (
752 OStoreDataPageObject
&rData
,
753 OStorePageBIOS
&rBIOS
)
755 // Determine scope and link indices.
756 page::DataBlock::LinkDescriptor aLink
;
757 page::ChunkScope eScope
= scope (nPage
, aLink
);
759 storeError eErrCode
= store_E_None
;
760 if (eScope
== page::SCOPE_DIRECT
)
762 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
763 if (nAddr
== STORE_PAGE_NULL
)
765 // Allocate data page.
766 eErrCode
= rBIOS
.allocate (rData
);
767 if (eErrCode
!= store_E_None
)
770 // Store data page location.
771 directLink (aLink
.m_nIndex0
, rData
.location());
776 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
779 else if (eScope
== page::SCOPE_SINGLE
)
781 OStoreIndirectionPageObject aSingle
;
782 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
783 if (eErrCode
!= store_E_None
)
785 if (eErrCode
!= store_E_Pending
)
787 singleLink (aLink
.m_nIndex1
, aSingle
.location());
790 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
792 else if (eScope
== page::SCOPE_DOUBLE
)
794 OStoreIndirectionPageObject aDouble
;
795 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
796 if (eErrCode
!= store_E_None
)
798 if (eErrCode
!= store_E_Pending
)
800 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
803 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
805 else if (eScope
== page::SCOPE_TRIPLE
)
807 OStoreIndirectionPageObject aTriple
;
808 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
809 if (eErrCode
!= store_E_None
)
811 if (eErrCode
!= store_E_Pending
)
813 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
816 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
818 else if (eScope
== page::SCOPE_UNREACHABLE
)
821 eErrCode
= store_E_CantSeek
;
826 SAL_WARN("store", "OStoreDirectoryPageObject::put(): scope failed");
827 eErrCode
= store_E_Unknown
;
834 storeError
OStoreDirectoryPageObject::truncate (
836 OStorePageBIOS
&rBIOS
)
838 // Determine scope and link indices.
839 page::DataBlock::LinkDescriptor aLink
;
840 page::ChunkScope eScope
= scope (nPage
, aLink
);
842 storeError eErrCode
= store_E_None
;
843 if (eScope
== page::SCOPE_DIRECT
)
845 // Truncate all triple indirect pages.
846 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
847 if (eErrCode
!= store_E_None
)
850 // Truncate all double indirect pages.
851 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
852 if (eErrCode
!= store_E_None
)
855 // Truncate all single indirect pages.
856 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
857 if (eErrCode
!= store_E_None
)
860 // Truncate direct pages, including 'aLink.m_nIndex0'.
861 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
863 else if (eScope
== page::SCOPE_SINGLE
)
865 // Truncate all triple indirect pages.
866 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
867 if (eErrCode
!= store_E_None
)
870 // Truncate all double indirect pages.
871 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
872 if (eErrCode
!= store_E_None
)
875 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
876 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
877 if (eErrCode
!= store_E_None
)
880 // Truncate last single indirect page to ... pages.
881 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
882 if (eErrCode
!= store_E_None
)
885 // Check for complete truncation.
886 if (aLink
.m_nIndex0
== 0)
888 // Clear pointer to last single indirect page.
889 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
892 else if (eScope
== page::SCOPE_DOUBLE
)
894 // Truncate all triple indirect pages.
895 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
896 if (eErrCode
!= store_E_None
)
899 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
900 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
901 if (eErrCode
!= store_E_None
)
904 // Truncate last double indirect page to ... pages.
905 eErrCode
= store_truncate_Impl (
906 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
907 if (eErrCode
!= store_E_None
)
910 // Check for complete truncation.
911 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
913 // Clear pointer to last double indirect page.
914 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
917 else if (eScope
== page::SCOPE_TRIPLE
)
919 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
920 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
921 if (eErrCode
!= store_E_None
)
924 // Truncate last triple indirect page to ... pages.
925 eErrCode
= store_truncate_Impl (
926 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
927 if (eErrCode
!= store_E_None
)
930 // Check for complete truncation.
931 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
933 // Clear pointer to last triple indirect page.
934 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
937 else if (eScope
== page::SCOPE_UNREACHABLE
)
940 eErrCode
= store_E_CantSeek
;
945 SAL_WARN("store", "OStoreDirectoryPageObject::put(): scope failed");
946 eErrCode
= store_E_Unknown
;
954 * truncate (external data page scope; private).
956 storeError
OStoreDirectoryPageObject::truncate (
957 page::ChunkScope eScope
,
959 OStorePageBIOS
&rBIOS
)
962 storeError eErrCode
= store_E_None
;
963 if (eScope
== page::SCOPE_DIRECT
)
965 // Truncate direct data pages.
966 for (sal_uInt16 i
= OStoreDirectoryDataBlock::directCount
; i
> nRemain
; i
--)
968 // Obtain data page location.
969 sal_uInt32 nAddr
= directLink (i
- 1);
970 if (nAddr
== STORE_PAGE_NULL
) continue;
973 eErrCode
= rBIOS
.free (nAddr
);
974 if (eErrCode
!= store_E_None
)
977 // Clear pointer to data page.
978 directLink (i
- 1, STORE_PAGE_NULL
);
985 if (eScope
== page::SCOPE_SINGLE
)
987 // Truncate single indirect pages.
988 for (sal_uInt16 i
= OStoreDirectoryDataBlock::singleCount
; i
> nRemain
; i
--)
990 // Truncate single indirect page to zero data pages.
991 eErrCode
= store_truncate_Impl (singleLink (i
- 1), 0, rBIOS
);
992 if (eErrCode
!= store_E_None
)
995 // Clear pointer to single indirect page.
996 singleLink (i
- 1, STORE_PAGE_NULL
);
1003 if (eScope
== page::SCOPE_DOUBLE
)
1005 // Truncate double indirect pages.
1006 for (sal_uInt16 i
= OStoreDirectoryDataBlock::doubleCount
; i
> nRemain
; i
--)
1008 // Truncate double indirect page to zero single indirect pages.
1009 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1010 if (eErrCode
!= store_E_None
)
1013 // Clear pointer to double indirect page.
1014 doubleLink (i
- 1, STORE_PAGE_NULL
);
1021 if (eScope
== page::SCOPE_TRIPLE
)
1023 // Truncate triple indirect pages.
1024 for (sal_uInt16 i
= OStoreDirectoryDataBlock::tripleCount
; i
> nRemain
; i
--)
1026 // Truncate to zero double indirect pages.
1027 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1028 if (eErrCode
!= store_E_None
)
1031 // Clear pointer to triple indirect page.
1032 tripleLink (i
- 1, STORE_PAGE_NULL
);
1040 return store_E_InvalidAccess
;
1043 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */