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 /*========================================================================
33 * OStoreDataPageObject implementation.
35 *======================================================================*/
39 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
41 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
47 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
49 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
52 /*========================================================================
54 * OStoreIndirectionPageObject implementation.
56 *======================================================================*/
58 * store_truncate_Impl (single indirect page).
60 static storeError
store_truncate_Impl (
63 OStorePageBIOS
&rBIOS
)
65 if (nAddr
!= STORE_PAGE_NULL
)
67 // Load single indirect page.
68 OStoreIndirectionPageObject aSingle
;
69 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
70 if (eErrCode
== store_E_None
)
72 // Truncate to 'nSingle' direct pages.
73 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
74 if (eErrCode
!= store_E_None
)
79 if (eErrCode
!= store_E_InvalidChecksum
)
83 // Check for complete truncation.
86 // Free single indirect page.
87 eErrCode
= rBIOS
.free (nAddr
);
88 if (eErrCode
!= store_E_None
)
96 * store_truncate_Impl (double indirect page).
98 static storeError
store_truncate_Impl (
102 OStorePageBIOS
&rBIOS
)
104 if (nAddr
!= STORE_PAGE_NULL
)
106 // Load double indirect page.
107 OStoreIndirectionPageObject aDouble
;
108 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
109 if (eErrCode
== store_E_None
)
111 // Truncate to 'nDouble', 'nSingle' pages.
112 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
113 if (eErrCode
!= store_E_None
)
118 if (eErrCode
!= store_E_InvalidChecksum
)
122 // Check for complete truncation.
123 if ((nDouble
+ nSingle
) == 0)
125 // Free double indirect page.
126 eErrCode
= rBIOS
.free (nAddr
);
127 if (eErrCode
!= store_E_None
)
135 * store_truncate_Impl (triple indirect page).
137 static storeError
store_truncate_Impl (
142 OStorePageBIOS
&rBIOS
)
144 if (nAddr
!= STORE_PAGE_NULL
)
146 // Load triple indirect page.
147 OStoreIndirectionPageObject aTriple
;
148 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
149 if (eErrCode
!= store_E_None
)
152 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
153 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
154 if (eErrCode
!= store_E_None
)
157 // Check for complete truncation.
158 if ((nTriple
+ nDouble
+ nSingle
) == 0)
160 // Free triple indirect page.
161 eErrCode
= rBIOS
.free (nAddr
);
162 if (eErrCode
!= store_E_None
)
172 storeError
OStoreIndirectionPageObject::loadOrCreate (
174 OStorePageBIOS
& rBIOS
)
176 if (nAddr
== STORE_PAGE_NULL
)
178 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
179 if (eErrCode
!= store_E_None
)
182 eErrCode
= rBIOS
.allocate (*this);
183 if (eErrCode
!= store_E_None
)
186 // Save location pending at caller.
187 return store_E_Pending
;
189 return rBIOS
.loadObjectAt (*this, nAddr
);
195 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
197 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
203 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
205 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
209 * read (single indirect).
211 storeError
OStoreIndirectionPageObject::read (
213 OStoreDataPageObject
&rData
,
214 OStorePageBIOS
&rBIOS
) const
216 PageHolderObject
< page
> xImpl (m_xPage
);
217 page
const & rPage
= *xImpl
;
220 sal_uInt16
const nLimit
= rPage
.capacityCount();
221 if (nSingle
>= nLimit
)
222 return store_E_InvalidAccess
;
224 // Obtain data page location.
225 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
226 if (nAddr
== STORE_PAGE_NULL
)
227 return store_E_NotExists
;
229 // Load data page and leave.
230 return rBIOS
.loadObjectAt (rData
, nAddr
);
234 * read (double indirect).
236 storeError
OStoreIndirectionPageObject::read (
239 OStoreDataPageObject
&rData
,
240 OStorePageBIOS
&rBIOS
) const
242 PageHolderObject
< page
> xImpl (m_xPage
);
243 page
const & rPage
= *xImpl
;
246 sal_uInt16
const nLimit
= rPage
.capacityCount();
247 if ((nDouble
>= nLimit
) || (nSingle
>= nLimit
))
248 return store_E_InvalidAccess
;
250 // Check single indirect page location.
251 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
252 if (nAddr
== STORE_PAGE_NULL
)
253 return store_E_NotExists
;
255 // Load single indirect page.
256 OStoreIndirectionPageObject aSingle
;
257 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
258 if (eErrCode
!= store_E_None
)
261 // Read single indirect and leave.
262 return aSingle
.read (nSingle
, rData
, rBIOS
);
266 * read (triple indirect).
268 storeError
OStoreIndirectionPageObject::read (
272 OStoreDataPageObject
&rData
,
273 OStorePageBIOS
&rBIOS
) const
275 PageHolderObject
< page
> xImpl (m_xPage
);
276 page
const & rPage
= *xImpl
;
279 sal_uInt16
const nLimit
= rPage
.capacityCount();
280 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
281 return store_E_InvalidAccess
;
283 // Check double indirect page location.
284 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
285 if (nAddr
== STORE_PAGE_NULL
)
286 return store_E_NotExists
;
288 // Load double indirect page.
289 OStoreIndirectionPageObject aDouble
;
290 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
291 if (eErrCode
!= store_E_None
)
294 // Read double indirect and leave.
295 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
299 * write (single indirect).
301 storeError
OStoreIndirectionPageObject::write (
303 OStoreDataPageObject
&rData
,
304 OStorePageBIOS
&rBIOS
)
306 PageHolderObject
< page
> xImpl (m_xPage
);
307 page
& rPage
= *xImpl
;
310 sal_uInt16
const nLimit
= rPage
.capacityCount();
311 if (nSingle
>= nLimit
)
312 return store_E_InvalidAccess
;
314 // Obtain data page location.
315 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
316 if (nAddr
== STORE_PAGE_NULL
)
318 // Allocate data page.
319 storeError eErrCode
= rBIOS
.allocate (rData
);
320 if (eErrCode
!= store_E_None
)
323 // Store data page location.
324 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
327 return rBIOS
.saveObjectAt (*this, location());
332 return rBIOS
.saveObjectAt (rData
, nAddr
);
337 * write (double indirect).
339 storeError
OStoreIndirectionPageObject::write (
342 OStoreDataPageObject
&rData
,
343 OStorePageBIOS
&rBIOS
)
345 PageHolderObject
< page
> xImpl (m_xPage
);
346 page
& rPage
= *xImpl
;
349 sal_uInt16
const nLimit
= rPage
.capacityCount();
350 if ((nDouble
>= nLimit
) || (nSingle
>= nLimit
))
351 return store_E_InvalidAccess
;
353 // Load or create single indirect page.
354 OStoreIndirectionPageObject aSingle
;
355 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
356 if (eErrCode
!= store_E_None
)
358 if (eErrCode
!= store_E_Pending
)
360 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
362 eErrCode
= rBIOS
.saveObjectAt (*this, location());
363 if (eErrCode
!= store_E_None
)
367 // Write single indirect and leave.
368 return aSingle
.write (nSingle
, rData
, rBIOS
);
372 * write (triple indirect).
374 storeError
OStoreIndirectionPageObject::write (
378 OStoreDataPageObject
&rData
,
379 OStorePageBIOS
&rBIOS
)
381 PageHolderObject
< page
> xImpl (m_xPage
);
382 page
& rPage
= *xImpl
;
385 sal_uInt16
const nLimit
= rPage
.capacityCount();
386 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
387 return store_E_InvalidAccess
;
389 // Load or create double indirect page.
390 OStoreIndirectionPageObject aDouble
;
391 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
392 if (eErrCode
!= store_E_None
)
394 if (eErrCode
!= store_E_Pending
)
396 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
398 eErrCode
= rBIOS
.saveObjectAt (*this, location());
399 if (eErrCode
!= store_E_None
)
403 // Write double indirect and leave.
404 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
408 * truncate (single indirect).
410 storeError
OStoreIndirectionPageObject::truncate (
412 OStorePageBIOS
& rBIOS
)
414 PageHolderObject
< page
> xImpl (m_xPage
);
415 page
& rPage
= *xImpl
;
418 sal_uInt16
const nLimit
= rPage
.capacityCount();
419 if (nSingle
>= nLimit
)
420 return store_E_InvalidAccess
;
423 storeError eErrCode
= store_E_None
;
424 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
426 // Obtain data page location.
427 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
428 if (nAddr
!= STORE_PAGE_NULL
)
431 eErrCode
= rBIOS
.free (nAddr
);
432 if (eErrCode
!= store_E_None
)
435 // Clear pointer to data page.
436 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
441 // Check for modified page.
445 eErrCode
= rBIOS
.saveObjectAt (*this, location());
453 * truncate (double indirect).
455 storeError
OStoreIndirectionPageObject::truncate (
458 OStorePageBIOS
&rBIOS
)
460 PageHolderObject
< page
> xImpl (m_xPage
);
461 page
& rPage
= *xImpl
;
464 sal_uInt16
const nLimit
= rPage
.capacityCount();
465 if ((nDouble
>= nLimit
) || (nSingle
>= nLimit
))
466 return store_E_InvalidAccess
;
469 storeError eErrCode
= store_E_None
;
470 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
472 // Truncate single indirect page to zero direct pages.
473 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
474 if (eErrCode
!= store_E_None
)
477 // Clear pointer to single indirect page.
478 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
482 // Truncate last single indirect page to 'nSingle' direct pages.
483 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
484 if (eErrCode
!= store_E_None
)
487 // Check for complete truncation.
490 // Clear pointer to last single indirect page.
491 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
495 // Check for modified page.
499 eErrCode
= rBIOS
.saveObjectAt (*this, location());
507 * truncate (triple indirect).
509 storeError
OStoreIndirectionPageObject::truncate (
513 OStorePageBIOS
&rBIOS
)
515 PageHolderObject
< page
> xImpl (m_xPage
);
516 page
& rPage
= *xImpl
;
519 sal_uInt16
const nLimit
= rPage
.capacityCount();
520 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
521 return store_E_InvalidAccess
;
524 storeError eErrCode
= store_E_None
;
525 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
527 // Truncate double indirect page to zero single indirect pages.
528 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
529 if (eErrCode
!= store_E_None
)
532 // Clear pointer to double indirect page.
533 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
537 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
538 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
539 if (eErrCode
!= store_E_None
)
542 // Check for complete truncation.
543 if ((nDouble
+ nSingle
) == 0)
545 // Clear pointer to last double indirect page.
546 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
550 // Check for modified page.
554 eErrCode
= rBIOS
.saveObjectAt (*this, location());
561 /*========================================================================
563 * OStoreDirectoryPageObject implementation.
565 *======================================================================*/
569 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
571 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
577 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
579 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
580 // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
584 * scope (external data page; private).
586 OStoreDirectoryPageData::ChunkScope
587 OStoreDirectoryPageObject::scope (
589 page::DataBlock::LinkDescriptor
&rDescr
) const
591 page
const & rPage
= PAGE();
593 sal_uInt32 index0
, index1
, index2
;
596 sal_uInt32 nCount
= OStoreDirectoryDataBlock::directCount
;
597 sal_uInt32 nLimit
= nCount
;
600 // Page to index reduction.
603 // Setup LinkDescriptor indices.
604 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
607 return page::SCOPE_DIRECT
;
612 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
613 nCount
= OStoreDirectoryDataBlock::singleCount
;
614 nLimit
= nCount
* nCapacity
;
617 // Page to index reduction.
618 sal_uInt32 n
= nPage
;
620 // Reduce to single indirect i(1), direct n = i(0).
621 index1
= n
/ nCapacity
;
622 index0
= n
% nCapacity
;
625 n
= index1
* nCapacity
+ index0
;
628 SAL_WARN("store", "wrong math on indirect indices");
629 return page::SCOPE_UNKNOWN
;
632 // Setup LinkDescriptor indices.
633 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
634 rDescr
.m_nIndex1
= static_cast<sal_uInt16
>(index1
& 0xffff);
637 return page::SCOPE_SINGLE
;
642 nCount
= OStoreDirectoryDataBlock::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
;
662 SAL_WARN("store", "wrong math on double indirect indices");
663 return page::SCOPE_UNKNOWN
;
666 // Setup LinkDescriptor indices.
667 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
668 rDescr
.m_nIndex1
= static_cast<sal_uInt16
>(index1
& 0xffff);
669 rDescr
.m_nIndex2
= static_cast<sal_uInt16
>(index2
& 0xffff);
672 return page::SCOPE_DOUBLE
;
677 nCount
= OStoreDirectoryDataBlock::tripleCount
;
678 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
681 // Page to index reduction.
682 sal_uInt32 n
= nPage
;
684 // Reduce to triple indirect i(3), double indirect n.
685 sal_uInt32 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
686 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
688 // Reduce to double indirect i(2), single indirect n.
689 index2
= n
/ (nCapacity
* nCapacity
);
690 n
= n
% (nCapacity
* nCapacity
);
692 // Reduce to single indirect i(1), direct n = i(0).
693 index1
= n
/ nCapacity
;
694 index0
= n
% nCapacity
;
697 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
698 index2
* nCapacity
* nCapacity
+
699 index1
* nCapacity
+ index0
;
702 SAL_WARN("store", "wrong math on triple indirect indices");
703 return page::SCOPE_UNKNOWN
;
706 // Setup LinkDescriptor indices.
707 rDescr
.m_nIndex0
= static_cast<sal_uInt16
>(index0
& 0xffff);
708 rDescr
.m_nIndex1
= static_cast<sal_uInt16
>(index1
& 0xffff);
709 rDescr
.m_nIndex2
= static_cast<sal_uInt16
>(index2
& 0xffff);
710 rDescr
.m_nIndex3
= static_cast<sal_uInt16
>(index3
& 0xffff);
713 return page::SCOPE_TRIPLE
;
716 // Unreachable (more than triple indirect).
717 return page::SCOPE_UNREACHABLE
;
721 * read (external data page).
723 storeError
OStoreDirectoryPageObject::read (
725 OStoreDataPageObject
&rData
,
726 OStorePageBIOS
&rBIOS
) const
728 // Determine scope and link indices.
729 page::DataBlock::LinkDescriptor aLink
;
730 page::ChunkScope eScope
= scope (nPage
, aLink
);
732 storeError eErrCode
= store_E_None
;
733 if (eScope
== page::SCOPE_DIRECT
)
735 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
736 if (nAddr
== STORE_PAGE_NULL
)
737 return store_E_NotExists
;
739 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
741 else if (eScope
== page::SCOPE_SINGLE
)
743 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
744 if (nAddr
== STORE_PAGE_NULL
)
745 return store_E_NotExists
;
747 OStoreIndirectionPageObject aSingle
;
748 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
749 if (eErrCode
!= store_E_None
)
752 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
754 else if (eScope
== page::SCOPE_DOUBLE
)
756 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
757 if (nAddr
== STORE_PAGE_NULL
)
758 return store_E_NotExists
;
760 OStoreIndirectionPageObject aDouble
;
761 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
762 if (eErrCode
!= store_E_None
)
765 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
767 else if (eScope
== page::SCOPE_TRIPLE
)
769 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
770 if (nAddr
== STORE_PAGE_NULL
)
771 return store_E_NotExists
;
773 OStoreIndirectionPageObject aTriple
;
774 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
775 if (eErrCode
!= store_E_None
)
778 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
780 else if (eScope
== page::SCOPE_UNREACHABLE
)
783 eErrCode
= store_E_CantSeek
;
788 SAL_WARN("store", "OStoreDirectoryPageObject::get(): scope failed");
789 eErrCode
= store_E_Unknown
;
797 * write (external data page).
799 storeError
OStoreDirectoryPageObject::write (
801 OStoreDataPageObject
&rData
,
802 OStorePageBIOS
&rBIOS
)
804 // Determine scope and link indices.
805 page::DataBlock::LinkDescriptor aLink
;
806 page::ChunkScope eScope
= scope (nPage
, aLink
);
808 storeError eErrCode
= store_E_None
;
809 if (eScope
== page::SCOPE_DIRECT
)
811 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
812 if (nAddr
== STORE_PAGE_NULL
)
814 // Allocate data page.
815 eErrCode
= rBIOS
.allocate (rData
);
816 if (eErrCode
!= store_E_None
)
819 // Store data page location.
820 directLink (aLink
.m_nIndex0
, rData
.location());
825 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
828 else if (eScope
== page::SCOPE_SINGLE
)
830 OStoreIndirectionPageObject aSingle
;
831 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
832 if (eErrCode
!= store_E_None
)
834 if (eErrCode
!= store_E_Pending
)
836 singleLink (aLink
.m_nIndex1
, aSingle
.location());
839 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
841 else if (eScope
== page::SCOPE_DOUBLE
)
843 OStoreIndirectionPageObject aDouble
;
844 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
845 if (eErrCode
!= store_E_None
)
847 if (eErrCode
!= store_E_Pending
)
849 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
852 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
854 else if (eScope
== page::SCOPE_TRIPLE
)
856 OStoreIndirectionPageObject aTriple
;
857 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
858 if (eErrCode
!= store_E_None
)
860 if (eErrCode
!= store_E_Pending
)
862 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
865 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
867 else if (eScope
== page::SCOPE_UNREACHABLE
)
870 eErrCode
= store_E_CantSeek
;
875 SAL_WARN("store", "OStoreDirectoryPageObject::put(): scope failed");
876 eErrCode
= store_E_Unknown
;
884 * truncate (external data page).
886 storeError
OStoreDirectoryPageObject::truncate (
888 OStorePageBIOS
&rBIOS
)
890 // Determine scope and link indices.
891 page::DataBlock::LinkDescriptor aLink
;
892 page::ChunkScope eScope
= scope (nPage
, aLink
);
894 storeError eErrCode
= store_E_None
;
895 if (eScope
== page::SCOPE_DIRECT
)
897 // Truncate all triple indirect pages.
898 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
899 if (eErrCode
!= store_E_None
)
902 // Truncate all double indirect pages.
903 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
904 if (eErrCode
!= store_E_None
)
907 // Truncate all single indirect pages.
908 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
909 if (eErrCode
!= store_E_None
)
912 // Truncate direct pages, including 'aLink.m_nIndex0'.
913 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
915 else if (eScope
== page::SCOPE_SINGLE
)
917 // Truncate all triple indirect pages.
918 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
919 if (eErrCode
!= store_E_None
)
922 // Truncate all double indirect pages.
923 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
924 if (eErrCode
!= store_E_None
)
927 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
928 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
929 if (eErrCode
!= store_E_None
)
932 // Truncate last single indirect page to ... pages.
933 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
934 if (eErrCode
!= store_E_None
)
937 // Check for complete truncation.
938 if (aLink
.m_nIndex0
== 0)
940 // Clear pointer to last single indirect page.
941 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
944 else if (eScope
== page::SCOPE_DOUBLE
)
946 // Truncate all triple indirect pages.
947 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
948 if (eErrCode
!= store_E_None
)
951 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
952 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
953 if (eErrCode
!= store_E_None
)
956 // Truncate last double indirect page to ... pages.
957 eErrCode
= store_truncate_Impl (
958 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
959 if (eErrCode
!= store_E_None
)
962 // Check for complete truncation.
963 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
965 // Clear pointer to last double indirect page.
966 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
969 else if (eScope
== page::SCOPE_TRIPLE
)
971 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
972 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
973 if (eErrCode
!= store_E_None
)
976 // Truncate last triple indirect page to ... pages.
977 eErrCode
= store_truncate_Impl (
978 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
979 if (eErrCode
!= store_E_None
)
982 // Check for complete truncation.
983 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
985 // Clear pointer to last triple indirect page.
986 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
989 else if (eScope
== page::SCOPE_UNREACHABLE
)
992 eErrCode
= store_E_CantSeek
;
997 SAL_WARN("store", "OStoreDirectoryPageObject::put(): scope failed");
998 eErrCode
= store_E_Unknown
;
1006 * truncate (external data page scope; private).
1008 storeError
OStoreDirectoryPageObject::truncate (
1009 page::ChunkScope eScope
,
1011 OStorePageBIOS
&rBIOS
)
1014 storeError eErrCode
= store_E_None
;
1015 if (eScope
== page::SCOPE_DIRECT
)
1017 // Truncate direct data pages.
1018 for (sal_uInt16 i
= OStoreDirectoryDataBlock::directCount
; i
> nRemain
; i
--)
1020 // Obtain data page location.
1021 sal_uInt32 nAddr
= directLink (i
- 1);
1022 if (nAddr
== STORE_PAGE_NULL
) continue;
1025 eErrCode
= rBIOS
.free (nAddr
);
1026 if (eErrCode
!= store_E_None
)
1029 // Clear pointer to data page.
1030 directLink (i
- 1, STORE_PAGE_NULL
);
1037 if (eScope
== page::SCOPE_SINGLE
)
1039 // Truncate single indirect pages.
1040 for (sal_uInt16 i
= OStoreDirectoryDataBlock::singleCount
; 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 for (sal_uInt16 i
= OStoreDirectoryDataBlock::doubleCount
; i
> nRemain
; i
--)
1060 // Truncate double indirect page to zero single indirect pages.
1061 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1062 if (eErrCode
!= store_E_None
)
1065 // Clear pointer to double indirect page.
1066 doubleLink (i
- 1, STORE_PAGE_NULL
);
1073 if (eScope
== page::SCOPE_TRIPLE
)
1075 // Truncate triple indirect pages.
1076 for (sal_uInt16 i
= OStoreDirectoryDataBlock::tripleCount
; i
> nRemain
; i
--)
1078 // Truncate to zero double indirect pages.
1079 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1080 if (eErrCode
!= store_E_None
)
1083 // Clear pointer to triple indirect page.
1084 tripleLink (i
- 1, STORE_PAGE_NULL
);
1092 return store_E_InvalidAccess
;
1095 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */