1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_store.hxx"
32 #include "stordata.hxx"
34 #include "sal/types.h"
35 #include "osl/diagnose.h"
37 #include "store/types.h"
38 #include "storbase.hxx"
39 #include "storbios.hxx"
41 using namespace store
;
43 /*========================================================================
45 * OStoreDataPageObject implementation.
47 *======================================================================*/
51 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
53 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
59 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
61 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
64 /*========================================================================
66 * OStoreIndirectionPageObject implementation.
68 *======================================================================*/
70 * store_truncate_Impl (single indirect page).
72 static storeError
store_truncate_Impl (
75 OStorePageBIOS
&rBIOS
)
77 if (nAddr
!= STORE_PAGE_NULL
)
79 // Load single indirect page.
80 OStoreIndirectionPageObject aSingle
;
81 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
82 if (eErrCode
== store_E_None
)
84 // Truncate to 'nSingle' direct pages.
85 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
86 if (eErrCode
!= store_E_None
)
91 if (eErrCode
!= store_E_InvalidChecksum
)
95 // Check for complete truncation.
98 // Free single indirect page.
99 eErrCode
= rBIOS
.free (nAddr
);
100 if (eErrCode
!= store_E_None
)
108 * store_truncate_Impl (double indirect page).
110 static storeError
store_truncate_Impl (
114 OStorePageBIOS
&rBIOS
)
116 if (nAddr
!= STORE_PAGE_NULL
)
118 // Load double indirect page.
119 OStoreIndirectionPageObject aDouble
;
120 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
121 if (eErrCode
== store_E_None
)
123 // Truncate to 'nDouble', 'nSingle' pages.
124 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
125 if (eErrCode
!= store_E_None
)
130 if (eErrCode
!= store_E_InvalidChecksum
)
134 // Check for complete truncation.
135 if ((nDouble
+ nSingle
) == 0)
137 // Free double indirect page.
138 eErrCode
= rBIOS
.free (nAddr
);
139 if (eErrCode
!= store_E_None
)
147 * store_truncate_Impl (triple indirect page).
149 static storeError
store_truncate_Impl (
154 OStorePageBIOS
&rBIOS
)
156 if (nAddr
!= STORE_PAGE_NULL
)
158 // Load triple indirect page.
159 OStoreIndirectionPageObject aTriple
;
160 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
161 if (eErrCode
!= store_E_None
)
164 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
165 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
166 if (eErrCode
!= store_E_None
)
169 // Check for complete truncation.
170 if ((nTriple
+ nDouble
+ nSingle
) == 0)
172 // Free triple indirect page.
173 eErrCode
= rBIOS
.free (nAddr
);
174 if (eErrCode
!= store_E_None
)
184 storeError
OStoreIndirectionPageObject::loadOrCreate (
186 OStorePageBIOS
& rBIOS
)
188 if (nAddr
== STORE_PAGE_NULL
)
190 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
191 if (eErrCode
!= store_E_None
)
194 eErrCode
= rBIOS
.allocate (*this);
195 if (eErrCode
!= store_E_None
)
198 // Save location pending at caller.
199 return store_E_Pending
;
201 return rBIOS
.loadObjectAt (*this, nAddr
);
207 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
209 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
215 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
217 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
221 * read (single indirect).
223 storeError
OStoreIndirectionPageObject::read (
225 OStoreDataPageObject
&rData
,
226 OStorePageBIOS
&rBIOS
)
228 PageHolderObject
< page
> xImpl (m_xPage
);
229 page
const & rPage
= (*xImpl
);
232 sal_uInt16
const nLimit
= rPage
.capacityCount();
233 if (!(nSingle
< nLimit
))
234 return store_E_InvalidAccess
;
236 // Obtain data page location.
237 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
238 if (nAddr
== STORE_PAGE_NULL
)
239 return store_E_NotExists
;
241 // Load data page and leave.
242 return rBIOS
.loadObjectAt (rData
, nAddr
);
246 * read (double indirect).
248 storeError
OStoreIndirectionPageObject::read (
251 OStoreDataPageObject
&rData
,
252 OStorePageBIOS
&rBIOS
)
254 PageHolderObject
< page
> xImpl (m_xPage
);
255 page
const & rPage
= (*xImpl
);
258 sal_uInt16
const nLimit
= rPage
.capacityCount();
259 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
260 return store_E_InvalidAccess
;
262 // Check single indirect page location.
263 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
264 if (nAddr
== STORE_PAGE_NULL
)
265 return store_E_NotExists
;
267 // Load single indirect page.
268 OStoreIndirectionPageObject aSingle
;
269 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
270 if (eErrCode
!= store_E_None
)
273 // Read single indirect and leave.
274 return aSingle
.read (nSingle
, rData
, rBIOS
);
278 * read (triple indirect).
280 storeError
OStoreIndirectionPageObject::read (
284 OStoreDataPageObject
&rData
,
285 OStorePageBIOS
&rBIOS
)
287 PageHolderObject
< page
> xImpl (m_xPage
);
288 page
const & rPage
= (*xImpl
);
291 sal_uInt16
const nLimit
= rPage
.capacityCount();
292 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
293 return store_E_InvalidAccess
;
295 // Check double indirect page location.
296 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
297 if (nAddr
== STORE_PAGE_NULL
)
298 return store_E_NotExists
;
300 // Load double indirect page.
301 OStoreIndirectionPageObject aDouble
;
302 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
303 if (eErrCode
!= store_E_None
)
306 // Read double indirect and leave.
307 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
311 * write (single indirect).
313 storeError
OStoreIndirectionPageObject::write (
315 OStoreDataPageObject
&rData
,
316 OStorePageBIOS
&rBIOS
)
318 PageHolderObject
< page
> xImpl (m_xPage
);
319 page
& rPage
= (*xImpl
);
322 sal_uInt16
const nLimit
= rPage
.capacityCount();
323 if (!(nSingle
< nLimit
))
324 return store_E_InvalidAccess
;
326 // Obtain data page location.
327 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
328 if (nAddr
== STORE_PAGE_NULL
)
330 // Allocate data page.
331 storeError eErrCode
= rBIOS
.allocate (rData
);
332 if (eErrCode
!= store_E_None
)
335 // Store data page location.
336 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
339 return rBIOS
.saveObjectAt (*this, location());
344 return rBIOS
.saveObjectAt (rData
, nAddr
);
349 * write (double indirect).
351 storeError
OStoreIndirectionPageObject::write (
354 OStoreDataPageObject
&rData
,
355 OStorePageBIOS
&rBIOS
)
357 PageHolderObject
< page
> xImpl (m_xPage
);
358 page
& rPage
= (*xImpl
);
361 sal_uInt16
const nLimit
= rPage
.capacityCount();
362 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
363 return store_E_InvalidAccess
;
365 // Load or create single indirect page.
366 OStoreIndirectionPageObject aSingle
;
367 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
368 if (eErrCode
!= store_E_None
)
370 if (eErrCode
!= store_E_Pending
)
372 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
374 eErrCode
= rBIOS
.saveObjectAt (*this, location());
375 if (eErrCode
!= store_E_None
)
379 // Write single indirect and leave.
380 return aSingle
.write (nSingle
, rData
, rBIOS
);
384 * write (triple indirect).
386 storeError
OStoreIndirectionPageObject::write (
390 OStoreDataPageObject
&rData
,
391 OStorePageBIOS
&rBIOS
)
393 PageHolderObject
< page
> xImpl (m_xPage
);
394 page
& rPage
= (*xImpl
);
397 sal_uInt16
const nLimit
= rPage
.capacityCount();
398 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
399 return store_E_InvalidAccess
;
401 // Load or create double indirect page.
402 OStoreIndirectionPageObject aDouble
;
403 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
404 if (eErrCode
!= store_E_None
)
406 if (eErrCode
!= store_E_Pending
)
408 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
410 eErrCode
= rBIOS
.saveObjectAt (*this, location());
411 if (eErrCode
!= store_E_None
)
415 // Write double indirect and leave.
416 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
420 * truncate (single indirect).
422 storeError
OStoreIndirectionPageObject::truncate (
424 OStorePageBIOS
& rBIOS
)
426 PageHolderObject
< page
> xImpl (m_xPage
);
427 page
& rPage
= (*xImpl
);
430 sal_uInt16
const nLimit
= rPage
.capacityCount();
431 if (!(nSingle
< nLimit
))
432 return store_E_InvalidAccess
;
435 storeError eErrCode
= store_E_None
;
436 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
438 // Obtain data page location.
439 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
440 if (nAddr
!= STORE_PAGE_NULL
)
443 eErrCode
= rBIOS
.free (nAddr
);
444 if (eErrCode
!= store_E_None
)
447 // Clear pointer to data page.
448 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
453 // Check for modified page.
457 eErrCode
= rBIOS
.saveObjectAt (*this, location());
465 * truncate (double indirect).
467 storeError
OStoreIndirectionPageObject::truncate (
470 OStorePageBIOS
&rBIOS
)
472 PageHolderObject
< page
> xImpl (m_xPage
);
473 page
& rPage
= (*xImpl
);
476 sal_uInt16
const nLimit
= rPage
.capacityCount();
477 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
478 return store_E_InvalidAccess
;
481 storeError eErrCode
= store_E_None
;
482 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
484 // Truncate single indirect page to zero direct pages.
485 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
486 if (eErrCode
!= store_E_None
)
489 // Clear pointer to single indirect page.
490 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
494 // Truncate last single indirect page to 'nSingle' direct pages.
495 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
496 if (eErrCode
!= store_E_None
)
499 // Check for complete truncation.
502 // Clear pointer to last single indirect page.
503 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
507 // Check for modified page.
511 eErrCode
= rBIOS
.saveObjectAt (*this, location());
519 * truncate (triple indirect).
521 storeError
OStoreIndirectionPageObject::truncate (
525 OStorePageBIOS
&rBIOS
)
527 PageHolderObject
< page
> xImpl (m_xPage
);
528 page
& rPage
= (*xImpl
);
531 sal_uInt16
const nLimit
= rPage
.capacityCount();
532 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
533 return store_E_InvalidAccess
;
536 storeError eErrCode
= store_E_None
;
537 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
539 // Truncate double indirect page to zero single indirect pages.
540 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
541 if (eErrCode
!= store_E_None
)
544 // Clear pointer to double indirect page.
545 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
549 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
550 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
551 if (eErrCode
!= store_E_None
)
554 // Check for complete truncation.
555 if ((nDouble
+ nSingle
) == 0)
557 // Clear pointer to last double indirect page.
558 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
562 // Check for modified page.
566 eErrCode
= rBIOS
.saveObjectAt (*this, location());
573 /*========================================================================
575 * OStoreDirectoryPageObject implementation.
577 *======================================================================*/
581 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
583 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
589 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
591 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
592 // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
596 * scope (external data page; private).
598 OStoreDirectoryPageData::ChunkScope
599 OStoreDirectoryPageObject::scope (
601 page::DataBlock::LinkDescriptor
&rDescr
) const
603 page
const & rPage
= PAGE();
604 OStoreDirectoryDataBlock
const & rDataBlock
= rPage
.m_aDataBlock
;
606 sal_uInt32 index0
, index1
, index2
, index3
;
609 sal_uInt32 nCount
= rDataBlock
.directCount();
610 sal_uInt32 nLimit
= nCount
;
613 // Page to index reduction.
616 // Setup LinkDescriptor indices.
617 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
620 return page::SCOPE_DIRECT
;
625 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
626 nCount
= rDataBlock
.singleCount();
627 nLimit
= nCount
* nCapacity
;
630 // Page to index reduction.
631 sal_uInt32 n
= nPage
;
633 // Reduce to single indirect i(1), direct n = i(0).
634 index1
= n
/ nCapacity
;
635 index0
= n
% nCapacity
;
638 n
= index1
* nCapacity
+ index0
;
639 OSL_POSTCOND(n
== nPage
, "wrong math on indirect indices");
641 return page::SCOPE_UNKNOWN
;
643 // Setup LinkDescriptor indices.
644 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
645 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
648 return page::SCOPE_SINGLE
;
653 nCount
= rDataBlock
.doubleCount();
654 nLimit
= nCount
* nCapacity
* nCapacity
;
657 // Page to index reduction.
658 sal_uInt32 n
= nPage
;
660 // Reduce to double indirect i(2), single indirect n = i(0).
661 index2
= n
/ (nCapacity
* nCapacity
);
662 n
= n
% (nCapacity
* nCapacity
);
664 // Reduce to single indirect i(1), direct n = i(0).
665 index1
= n
/ nCapacity
;
666 index0
= n
% nCapacity
;
669 n
= index2
* nCapacity
* nCapacity
+
670 index1
* nCapacity
+ index0
;
671 OSL_POSTCOND(n
== nPage
, "wrong math on double indirect indices");
673 return page::SCOPE_UNKNOWN
;
675 // Setup LinkDescriptor indices.
676 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
677 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
678 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
681 return page::SCOPE_DOUBLE
;
686 nCount
= rDataBlock
.tripleCount();
687 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
690 // Page to index reduction.
691 sal_uInt32 n
= nPage
;
693 // Reduce to triple indirect i(3), double indirect n.
694 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
695 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
697 // Reduce to double indirect i(2), single indirect n.
698 index2
= n
/ (nCapacity
* nCapacity
);
699 n
= n
% (nCapacity
* nCapacity
);
701 // Reduce to single indirect i(1), direct n = i(0).
702 index1
= n
/ nCapacity
;
703 index0
= n
% nCapacity
;
706 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
707 index2
* nCapacity
* nCapacity
+
708 index1
* nCapacity
+ index0
;
709 OSL_POSTCOND(n
== nPage
, "wrong math on triple indirect indices");
711 return page::SCOPE_UNKNOWN
;
713 // Setup LinkDescriptor indices.
714 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
715 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
716 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
717 rDescr
.m_nIndex3
= (sal_uInt16
)(index3
& 0xffff);
720 return page::SCOPE_TRIPLE
;
723 // Unreachable (more than triple indirect).
724 return page::SCOPE_UNREACHABLE
;
728 * read (external data page).
730 storeError
OStoreDirectoryPageObject::read (
732 OStoreDataPageObject
&rData
,
733 OStorePageBIOS
&rBIOS
)
735 // Determine scope and link indices.
736 page::DataBlock::LinkDescriptor aLink
;
737 page::ChunkScope eScope
= scope (nPage
, aLink
);
739 storeError eErrCode
= store_E_None
;
740 if (eScope
== page::SCOPE_DIRECT
)
742 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
743 if (nAddr
== STORE_PAGE_NULL
)
744 return store_E_NotExists
;
746 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
748 else if (eScope
== page::SCOPE_SINGLE
)
750 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
751 if (nAddr
== STORE_PAGE_NULL
)
752 return store_E_NotExists
;
754 OStoreIndirectionPageObject aSingle
;
755 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
756 if (eErrCode
!= store_E_None
)
759 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
761 else if (eScope
== page::SCOPE_DOUBLE
)
763 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
764 if (nAddr
== STORE_PAGE_NULL
)
765 return store_E_NotExists
;
767 OStoreIndirectionPageObject aDouble
;
768 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
769 if (eErrCode
!= store_E_None
)
772 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
774 else if (eScope
== page::SCOPE_TRIPLE
)
776 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
777 if (nAddr
== STORE_PAGE_NULL
)
778 return store_E_NotExists
;
780 OStoreIndirectionPageObject aTriple
;
781 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
782 if (eErrCode
!= store_E_None
)
785 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
787 else if (eScope
== page::SCOPE_UNREACHABLE
)
790 eErrCode
= store_E_CantSeek
;
795 OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
796 eErrCode
= store_E_Unknown
;
804 * write (external data page).
806 storeError
OStoreDirectoryPageObject::write (
808 OStoreDataPageObject
&rData
,
809 OStorePageBIOS
&rBIOS
)
811 // Determine scope and link indices.
812 page::DataBlock::LinkDescriptor aLink
;
813 page::ChunkScope eScope
= scope (nPage
, aLink
);
815 storeError eErrCode
= store_E_None
;
816 if (eScope
== page::SCOPE_DIRECT
)
818 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
819 if (nAddr
== STORE_PAGE_NULL
)
821 // Allocate data page.
822 eErrCode
= rBIOS
.allocate (rData
);
823 if (eErrCode
!= store_E_None
)
826 // Store data page location.
827 directLink (aLink
.m_nIndex0
, rData
.location());
832 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
835 else if (eScope
== page::SCOPE_SINGLE
)
837 OStoreIndirectionPageObject aSingle
;
838 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
839 if (eErrCode
!= store_E_None
)
841 if (eErrCode
!= store_E_Pending
)
843 singleLink (aLink
.m_nIndex1
, aSingle
.location());
846 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
848 else if (eScope
== page::SCOPE_DOUBLE
)
850 OStoreIndirectionPageObject aDouble
;
851 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
852 if (eErrCode
!= store_E_None
)
854 if (eErrCode
!= store_E_Pending
)
856 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
859 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
861 else if (eScope
== page::SCOPE_TRIPLE
)
863 OStoreIndirectionPageObject aTriple
;
864 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
865 if (eErrCode
!= store_E_None
)
867 if (eErrCode
!= store_E_Pending
)
869 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
872 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
874 else if (eScope
== page::SCOPE_UNREACHABLE
)
877 eErrCode
= store_E_CantSeek
;
882 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
883 eErrCode
= store_E_Unknown
;
891 * truncate (external data page).
893 storeError
OStoreDirectoryPageObject::truncate (
895 OStorePageBIOS
&rBIOS
)
897 // Determine scope and link indices.
898 page::DataBlock::LinkDescriptor aLink
;
899 page::ChunkScope eScope
= scope (nPage
, aLink
);
901 storeError eErrCode
= store_E_None
;
902 if (eScope
== page::SCOPE_DIRECT
)
904 // Truncate all triple indirect pages.
905 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
906 if (eErrCode
!= store_E_None
)
909 // Truncate all double indirect pages.
910 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
911 if (eErrCode
!= store_E_None
)
914 // Truncate all single indirect pages.
915 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
916 if (eErrCode
!= store_E_None
)
919 // Truncate direct pages, including 'aLink.m_nIndex0'.
920 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
922 else if (eScope
== page::SCOPE_SINGLE
)
924 // Truncate all triple indirect pages.
925 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
926 if (eErrCode
!= store_E_None
)
929 // Truncate all double indirect pages.
930 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
931 if (eErrCode
!= store_E_None
)
934 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
935 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
936 if (eErrCode
!= store_E_None
)
939 // Truncate last single indirect page to ... pages.
940 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
941 if (eErrCode
!= store_E_None
)
944 // Check for complete truncation.
945 if (aLink
.m_nIndex0
== 0)
947 // Clear pointer to last single indirect page.
948 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
951 else if (eScope
== page::SCOPE_DOUBLE
)
953 // Truncate all triple indirect pages.
954 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
955 if (eErrCode
!= store_E_None
)
958 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
959 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
960 if (eErrCode
!= store_E_None
)
963 // Truncate last double indirect page to ... pages.
964 eErrCode
= store_truncate_Impl (
965 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
966 if (eErrCode
!= store_E_None
)
969 // Check for complete truncation.
970 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
972 // Clear pointer to last double indirect page.
973 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
976 else if (eScope
== page::SCOPE_TRIPLE
)
978 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
979 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
980 if (eErrCode
!= store_E_None
)
983 // Truncate last triple indirect page to ... pages.
984 eErrCode
= store_truncate_Impl (
985 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
986 if (eErrCode
!= store_E_None
)
989 // Check for complete truncation.
990 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
992 // Clear pointer to last triple indirect page.
993 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
996 else if (eScope
== page::SCOPE_UNREACHABLE
)
999 eErrCode
= store_E_CantSeek
;
1004 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
1005 eErrCode
= store_E_Unknown
;
1013 * truncate (external data page scope; private).
1015 storeError
OStoreDirectoryPageObject::truncate (
1016 page::ChunkScope eScope
,
1018 OStorePageBIOS
&rBIOS
)
1020 OStoreDirectoryDataBlock
const & rDataBlock
= PAGE().m_aDataBlock
;
1023 storeError eErrCode
= store_E_None
;
1024 if (eScope
== page::SCOPE_DIRECT
)
1026 // Truncate direct data pages.
1027 sal_uInt16 i
, n
= rDataBlock
.directCount();
1028 for (i
= n
; i
> nRemain
; i
--)
1030 // Obtain data page location.
1031 sal_uInt32 nAddr
= directLink (i
- 1);
1032 if (nAddr
== STORE_PAGE_NULL
) continue;
1035 eErrCode
= rBIOS
.free (nAddr
);
1036 if (eErrCode
!= store_E_None
)
1039 // Clear pointer to data page.
1040 directLink (i
- 1, STORE_PAGE_NULL
);
1047 if (eScope
== page::SCOPE_SINGLE
)
1049 // Truncate single indirect pages.
1050 sal_uInt16 i
, n
= rDataBlock
.singleCount();
1051 for (i
= n
; i
> nRemain
; i
--)
1053 // Truncate single indirect page to zero data pages.
1054 eErrCode
= store_truncate_Impl (singleLink (i
- 1), 0, rBIOS
);
1055 if (eErrCode
!= store_E_None
)
1058 // Clear pointer to single indirect page.
1059 singleLink (i
- 1, STORE_PAGE_NULL
);
1066 if (eScope
== page::SCOPE_DOUBLE
)
1068 // Truncate double indirect pages.
1069 sal_uInt16 i
, n
= rDataBlock
.doubleCount();
1070 for (i
= n
; i
> nRemain
; i
--)
1072 // Truncate double indirect page to zero single indirect pages.
1073 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1074 if (eErrCode
!= store_E_None
)
1077 // Clear pointer to double indirect page.
1078 doubleLink (i
- 1, STORE_PAGE_NULL
);
1085 if (eScope
== page::SCOPE_TRIPLE
)
1087 // Truncate triple indirect pages.
1088 sal_uInt16 i
, n
= rDataBlock
.tripleCount();
1089 for (i
= n
; i
> nRemain
; i
--)
1091 // Truncate to zero double indirect pages.
1092 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1093 if (eErrCode
!= store_E_None
)
1096 // Clear pointer to triple indirect page.
1097 tripleLink (i
- 1, STORE_PAGE_NULL
);
1105 return store_E_InvalidAccess
;
1108 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */