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 ************************************************************************/
30 #include "stordata.hxx"
32 #include "sal/types.h"
33 #include "osl/diagnose.h"
35 #include "store/types.h"
36 #include "storbase.hxx"
37 #include "storbios.hxx"
39 using namespace store
;
41 /*========================================================================
43 * OStoreDataPageObject implementation.
45 *======================================================================*/
49 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
51 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
57 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
59 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
62 /*========================================================================
64 * OStoreIndirectionPageObject implementation.
66 *======================================================================*/
68 * store_truncate_Impl (single indirect page).
70 static storeError
store_truncate_Impl (
73 OStorePageBIOS
&rBIOS
)
75 if (nAddr
!= STORE_PAGE_NULL
)
77 // Load single indirect page.
78 OStoreIndirectionPageObject aSingle
;
79 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
80 if (eErrCode
== store_E_None
)
82 // Truncate to 'nSingle' direct pages.
83 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
84 if (eErrCode
!= store_E_None
)
89 if (eErrCode
!= store_E_InvalidChecksum
)
93 // Check for complete truncation.
96 // Free single indirect page.
97 eErrCode
= rBIOS
.free (nAddr
);
98 if (eErrCode
!= store_E_None
)
106 * store_truncate_Impl (double indirect page).
108 static storeError
store_truncate_Impl (
112 OStorePageBIOS
&rBIOS
)
114 if (nAddr
!= STORE_PAGE_NULL
)
116 // Load double indirect page.
117 OStoreIndirectionPageObject aDouble
;
118 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
119 if (eErrCode
== store_E_None
)
121 // Truncate to 'nDouble', 'nSingle' pages.
122 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
123 if (eErrCode
!= store_E_None
)
128 if (eErrCode
!= store_E_InvalidChecksum
)
132 // Check for complete truncation.
133 if ((nDouble
+ nSingle
) == 0)
135 // Free double indirect page.
136 eErrCode
= rBIOS
.free (nAddr
);
137 if (eErrCode
!= store_E_None
)
145 * store_truncate_Impl (triple indirect page).
147 static storeError
store_truncate_Impl (
152 OStorePageBIOS
&rBIOS
)
154 if (nAddr
!= STORE_PAGE_NULL
)
156 // Load triple indirect page.
157 OStoreIndirectionPageObject aTriple
;
158 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
159 if (eErrCode
!= store_E_None
)
162 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
163 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
164 if (eErrCode
!= store_E_None
)
167 // Check for complete truncation.
168 if ((nTriple
+ nDouble
+ nSingle
) == 0)
170 // Free triple indirect page.
171 eErrCode
= rBIOS
.free (nAddr
);
172 if (eErrCode
!= store_E_None
)
182 storeError
OStoreIndirectionPageObject::loadOrCreate (
184 OStorePageBIOS
& rBIOS
)
186 if (nAddr
== STORE_PAGE_NULL
)
188 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
189 if (eErrCode
!= store_E_None
)
192 eErrCode
= rBIOS
.allocate (*this);
193 if (eErrCode
!= store_E_None
)
196 // Save location pending at caller.
197 return store_E_Pending
;
199 return rBIOS
.loadObjectAt (*this, nAddr
);
205 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
207 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
213 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
215 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
219 * read (single indirect).
221 storeError
OStoreIndirectionPageObject::read (
223 OStoreDataPageObject
&rData
,
224 OStorePageBIOS
&rBIOS
)
226 PageHolderObject
< page
> xImpl (m_xPage
);
227 page
const & rPage
= (*xImpl
);
230 sal_uInt16
const nLimit
= rPage
.capacityCount();
231 if (!(nSingle
< nLimit
))
232 return store_E_InvalidAccess
;
234 // Obtain data page location.
235 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
236 if (nAddr
== STORE_PAGE_NULL
)
237 return store_E_NotExists
;
239 // Load data page and leave.
240 return rBIOS
.loadObjectAt (rData
, nAddr
);
244 * read (double indirect).
246 storeError
OStoreIndirectionPageObject::read (
249 OStoreDataPageObject
&rData
,
250 OStorePageBIOS
&rBIOS
)
252 PageHolderObject
< page
> xImpl (m_xPage
);
253 page
const & rPage
= (*xImpl
);
256 sal_uInt16
const nLimit
= rPage
.capacityCount();
257 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
258 return store_E_InvalidAccess
;
260 // Check single indirect page location.
261 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
262 if (nAddr
== STORE_PAGE_NULL
)
263 return store_E_NotExists
;
265 // Load single indirect page.
266 OStoreIndirectionPageObject aSingle
;
267 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
268 if (eErrCode
!= store_E_None
)
271 // Read single indirect and leave.
272 return aSingle
.read (nSingle
, rData
, rBIOS
);
276 * read (triple indirect).
278 storeError
OStoreIndirectionPageObject::read (
282 OStoreDataPageObject
&rData
,
283 OStorePageBIOS
&rBIOS
)
285 PageHolderObject
< page
> xImpl (m_xPage
);
286 page
const & rPage
= (*xImpl
);
289 sal_uInt16
const nLimit
= rPage
.capacityCount();
290 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
291 return store_E_InvalidAccess
;
293 // Check double indirect page location.
294 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
295 if (nAddr
== STORE_PAGE_NULL
)
296 return store_E_NotExists
;
298 // Load double indirect page.
299 OStoreIndirectionPageObject aDouble
;
300 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
301 if (eErrCode
!= store_E_None
)
304 // Read double indirect and leave.
305 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
309 * write (single indirect).
311 storeError
OStoreIndirectionPageObject::write (
313 OStoreDataPageObject
&rData
,
314 OStorePageBIOS
&rBIOS
)
316 PageHolderObject
< page
> xImpl (m_xPage
);
317 page
& rPage
= (*xImpl
);
320 sal_uInt16
const nLimit
= rPage
.capacityCount();
321 if (!(nSingle
< nLimit
))
322 return store_E_InvalidAccess
;
324 // Obtain data page location.
325 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
326 if (nAddr
== STORE_PAGE_NULL
)
328 // Allocate data page.
329 storeError eErrCode
= rBIOS
.allocate (rData
);
330 if (eErrCode
!= store_E_None
)
333 // Store data page location.
334 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
337 return rBIOS
.saveObjectAt (*this, location());
342 return rBIOS
.saveObjectAt (rData
, nAddr
);
347 * write (double indirect).
349 storeError
OStoreIndirectionPageObject::write (
352 OStoreDataPageObject
&rData
,
353 OStorePageBIOS
&rBIOS
)
355 PageHolderObject
< page
> xImpl (m_xPage
);
356 page
& rPage
= (*xImpl
);
359 sal_uInt16
const nLimit
= rPage
.capacityCount();
360 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
361 return store_E_InvalidAccess
;
363 // Load or create single indirect page.
364 OStoreIndirectionPageObject aSingle
;
365 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
366 if (eErrCode
!= store_E_None
)
368 if (eErrCode
!= store_E_Pending
)
370 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
372 eErrCode
= rBIOS
.saveObjectAt (*this, location());
373 if (eErrCode
!= store_E_None
)
377 // Write single indirect and leave.
378 return aSingle
.write (nSingle
, rData
, rBIOS
);
382 * write (triple indirect).
384 storeError
OStoreIndirectionPageObject::write (
388 OStoreDataPageObject
&rData
,
389 OStorePageBIOS
&rBIOS
)
391 PageHolderObject
< page
> xImpl (m_xPage
);
392 page
& rPage
= (*xImpl
);
395 sal_uInt16
const nLimit
= rPage
.capacityCount();
396 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
397 return store_E_InvalidAccess
;
399 // Load or create double indirect page.
400 OStoreIndirectionPageObject aDouble
;
401 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
402 if (eErrCode
!= store_E_None
)
404 if (eErrCode
!= store_E_Pending
)
406 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
408 eErrCode
= rBIOS
.saveObjectAt (*this, location());
409 if (eErrCode
!= store_E_None
)
413 // Write double indirect and leave.
414 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
418 * truncate (single indirect).
420 storeError
OStoreIndirectionPageObject::truncate (
422 OStorePageBIOS
& rBIOS
)
424 PageHolderObject
< page
> xImpl (m_xPage
);
425 page
& rPage
= (*xImpl
);
428 sal_uInt16
const nLimit
= rPage
.capacityCount();
429 if (!(nSingle
< nLimit
))
430 return store_E_InvalidAccess
;
433 storeError eErrCode
= store_E_None
;
434 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
436 // Obtain data page location.
437 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
438 if (nAddr
!= STORE_PAGE_NULL
)
441 eErrCode
= rBIOS
.free (nAddr
);
442 if (eErrCode
!= store_E_None
)
445 // Clear pointer to data page.
446 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
451 // Check for modified page.
455 eErrCode
= rBIOS
.saveObjectAt (*this, location());
463 * truncate (double indirect).
465 storeError
OStoreIndirectionPageObject::truncate (
468 OStorePageBIOS
&rBIOS
)
470 PageHolderObject
< page
> xImpl (m_xPage
);
471 page
& rPage
= (*xImpl
);
474 sal_uInt16
const nLimit
= rPage
.capacityCount();
475 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
476 return store_E_InvalidAccess
;
479 storeError eErrCode
= store_E_None
;
480 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
482 // Truncate single indirect page to zero direct pages.
483 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
484 if (eErrCode
!= store_E_None
)
487 // Clear pointer to single indirect page.
488 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
492 // Truncate last single indirect page to 'nSingle' direct pages.
493 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
494 if (eErrCode
!= store_E_None
)
497 // Check for complete truncation.
500 // Clear pointer to last single indirect page.
501 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
505 // Check for modified page.
509 eErrCode
= rBIOS
.saveObjectAt (*this, location());
517 * truncate (triple indirect).
519 storeError
OStoreIndirectionPageObject::truncate (
523 OStorePageBIOS
&rBIOS
)
525 PageHolderObject
< page
> xImpl (m_xPage
);
526 page
& rPage
= (*xImpl
);
529 sal_uInt16
const nLimit
= rPage
.capacityCount();
530 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
531 return store_E_InvalidAccess
;
534 storeError eErrCode
= store_E_None
;
535 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
537 // Truncate double indirect page to zero single indirect pages.
538 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
539 if (eErrCode
!= store_E_None
)
542 // Clear pointer to double indirect page.
543 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
547 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
548 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
549 if (eErrCode
!= store_E_None
)
552 // Check for complete truncation.
553 if ((nDouble
+ nSingle
) == 0)
555 // Clear pointer to last double indirect page.
556 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
560 // Check for modified page.
564 eErrCode
= rBIOS
.saveObjectAt (*this, location());
571 /*========================================================================
573 * OStoreDirectoryPageObject implementation.
575 *======================================================================*/
579 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
581 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
587 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
589 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
590 // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
594 * scope (external data page; private).
596 OStoreDirectoryPageData::ChunkScope
597 OStoreDirectoryPageObject::scope (
599 page::DataBlock::LinkDescriptor
&rDescr
) const
601 page
const & rPage
= PAGE();
602 OStoreDirectoryDataBlock
const & rDataBlock
= rPage
.m_aDataBlock
;
604 sal_uInt32 index0
, index1
, index2
, index3
;
607 sal_uInt32 nCount
= rDataBlock
.directCount();
608 sal_uInt32 nLimit
= nCount
;
611 // Page to index reduction.
614 // Setup LinkDescriptor indices.
615 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
618 return page::SCOPE_DIRECT
;
623 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
624 nCount
= rDataBlock
.singleCount();
625 nLimit
= nCount
* nCapacity
;
628 // Page to index reduction.
629 sal_uInt32 n
= nPage
;
631 // Reduce to single indirect i(1), direct n = i(0).
632 index1
= n
/ nCapacity
;
633 index0
= n
% nCapacity
;
636 n
= index1
* nCapacity
+ index0
;
637 OSL_POSTCOND(n
== nPage
, "wrong math on indirect indices");
639 return page::SCOPE_UNKNOWN
;
641 // Setup LinkDescriptor indices.
642 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
643 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
646 return page::SCOPE_SINGLE
;
651 nCount
= rDataBlock
.doubleCount();
652 nLimit
= nCount
* nCapacity
* nCapacity
;
655 // Page to index reduction.
656 sal_uInt32 n
= nPage
;
658 // Reduce to double indirect i(2), single indirect n = i(0).
659 index2
= n
/ (nCapacity
* nCapacity
);
660 n
= n
% (nCapacity
* nCapacity
);
662 // Reduce to single indirect i(1), direct n = i(0).
663 index1
= n
/ nCapacity
;
664 index0
= n
% nCapacity
;
667 n
= index2
* nCapacity
* nCapacity
+
668 index1
* nCapacity
+ index0
;
669 OSL_POSTCOND(n
== nPage
, "wrong math on double indirect indices");
671 return page::SCOPE_UNKNOWN
;
673 // Setup LinkDescriptor indices.
674 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
675 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
676 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
679 return page::SCOPE_DOUBLE
;
684 nCount
= rDataBlock
.tripleCount();
685 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
688 // Page to index reduction.
689 sal_uInt32 n
= nPage
;
691 // Reduce to triple indirect i(3), double indirect n.
692 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
693 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
695 // Reduce to double indirect i(2), single indirect n.
696 index2
= n
/ (nCapacity
* nCapacity
);
697 n
= n
% (nCapacity
* nCapacity
);
699 // Reduce to single indirect i(1), direct n = i(0).
700 index1
= n
/ nCapacity
;
701 index0
= n
% nCapacity
;
704 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
705 index2
* nCapacity
* nCapacity
+
706 index1
* nCapacity
+ index0
;
707 OSL_POSTCOND(n
== nPage
, "wrong math on triple indirect indices");
709 return page::SCOPE_UNKNOWN
;
711 // Setup LinkDescriptor indices.
712 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
713 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
714 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
715 rDescr
.m_nIndex3
= (sal_uInt16
)(index3
& 0xffff);
718 return page::SCOPE_TRIPLE
;
721 // Unreachable (more than triple indirect).
722 return page::SCOPE_UNREACHABLE
;
726 * read (external data page).
728 storeError
OStoreDirectoryPageObject::read (
730 OStoreDataPageObject
&rData
,
731 OStorePageBIOS
&rBIOS
)
733 // Determine scope and link indices.
734 page::DataBlock::LinkDescriptor aLink
;
735 page::ChunkScope eScope
= scope (nPage
, aLink
);
737 storeError eErrCode
= store_E_None
;
738 if (eScope
== page::SCOPE_DIRECT
)
740 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
741 if (nAddr
== STORE_PAGE_NULL
)
742 return store_E_NotExists
;
744 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
746 else if (eScope
== page::SCOPE_SINGLE
)
748 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
749 if (nAddr
== STORE_PAGE_NULL
)
750 return store_E_NotExists
;
752 OStoreIndirectionPageObject aSingle
;
753 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
754 if (eErrCode
!= store_E_None
)
757 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
759 else if (eScope
== page::SCOPE_DOUBLE
)
761 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
762 if (nAddr
== STORE_PAGE_NULL
)
763 return store_E_NotExists
;
765 OStoreIndirectionPageObject aDouble
;
766 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
767 if (eErrCode
!= store_E_None
)
770 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
772 else if (eScope
== page::SCOPE_TRIPLE
)
774 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
775 if (nAddr
== STORE_PAGE_NULL
)
776 return store_E_NotExists
;
778 OStoreIndirectionPageObject aTriple
;
779 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
780 if (eErrCode
!= store_E_None
)
783 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
785 else if (eScope
== page::SCOPE_UNREACHABLE
)
788 eErrCode
= store_E_CantSeek
;
793 OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
794 eErrCode
= store_E_Unknown
;
802 * write (external data page).
804 storeError
OStoreDirectoryPageObject::write (
806 OStoreDataPageObject
&rData
,
807 OStorePageBIOS
&rBIOS
)
809 // Determine scope and link indices.
810 page::DataBlock::LinkDescriptor aLink
;
811 page::ChunkScope eScope
= scope (nPage
, aLink
);
813 storeError eErrCode
= store_E_None
;
814 if (eScope
== page::SCOPE_DIRECT
)
816 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
817 if (nAddr
== STORE_PAGE_NULL
)
819 // Allocate data page.
820 eErrCode
= rBIOS
.allocate (rData
);
821 if (eErrCode
!= store_E_None
)
824 // Store data page location.
825 directLink (aLink
.m_nIndex0
, rData
.location());
830 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
833 else if (eScope
== page::SCOPE_SINGLE
)
835 OStoreIndirectionPageObject aSingle
;
836 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
837 if (eErrCode
!= store_E_None
)
839 if (eErrCode
!= store_E_Pending
)
841 singleLink (aLink
.m_nIndex1
, aSingle
.location());
844 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
846 else if (eScope
== page::SCOPE_DOUBLE
)
848 OStoreIndirectionPageObject aDouble
;
849 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
850 if (eErrCode
!= store_E_None
)
852 if (eErrCode
!= store_E_Pending
)
854 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
857 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
859 else if (eScope
== page::SCOPE_TRIPLE
)
861 OStoreIndirectionPageObject aTriple
;
862 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
863 if (eErrCode
!= store_E_None
)
865 if (eErrCode
!= store_E_Pending
)
867 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
870 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
872 else if (eScope
== page::SCOPE_UNREACHABLE
)
875 eErrCode
= store_E_CantSeek
;
880 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
881 eErrCode
= store_E_Unknown
;
889 * truncate (external data page).
891 storeError
OStoreDirectoryPageObject::truncate (
893 OStorePageBIOS
&rBIOS
)
895 // Determine scope and link indices.
896 page::DataBlock::LinkDescriptor aLink
;
897 page::ChunkScope eScope
= scope (nPage
, aLink
);
899 storeError eErrCode
= store_E_None
;
900 if (eScope
== page::SCOPE_DIRECT
)
902 // Truncate all triple indirect pages.
903 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
904 if (eErrCode
!= store_E_None
)
907 // Truncate all double indirect pages.
908 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
909 if (eErrCode
!= store_E_None
)
912 // Truncate all single indirect pages.
913 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
914 if (eErrCode
!= store_E_None
)
917 // Truncate direct pages, including 'aLink.m_nIndex0'.
918 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
920 else if (eScope
== page::SCOPE_SINGLE
)
922 // Truncate all triple indirect pages.
923 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
924 if (eErrCode
!= store_E_None
)
927 // Truncate all double indirect pages.
928 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
929 if (eErrCode
!= store_E_None
)
932 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
933 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
934 if (eErrCode
!= store_E_None
)
937 // Truncate last single indirect page to ... pages.
938 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
939 if (eErrCode
!= store_E_None
)
942 // Check for complete truncation.
943 if (aLink
.m_nIndex0
== 0)
945 // Clear pointer to last single indirect page.
946 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
949 else if (eScope
== page::SCOPE_DOUBLE
)
951 // Truncate all triple indirect pages.
952 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
953 if (eErrCode
!= store_E_None
)
956 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
957 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
958 if (eErrCode
!= store_E_None
)
961 // Truncate last double indirect page to ... pages.
962 eErrCode
= store_truncate_Impl (
963 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
964 if (eErrCode
!= store_E_None
)
967 // Check for complete truncation.
968 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
970 // Clear pointer to last double indirect page.
971 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
974 else if (eScope
== page::SCOPE_TRIPLE
)
976 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
977 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
978 if (eErrCode
!= store_E_None
)
981 // Truncate last triple indirect page to ... pages.
982 eErrCode
= store_truncate_Impl (
983 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
984 if (eErrCode
!= store_E_None
)
987 // Check for complete truncation.
988 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
990 // Clear pointer to last triple indirect page.
991 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
994 else if (eScope
== page::SCOPE_UNREACHABLE
)
997 eErrCode
= store_E_CantSeek
;
1002 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
1003 eErrCode
= store_E_Unknown
;
1011 * truncate (external data page scope; private).
1013 storeError
OStoreDirectoryPageObject::truncate (
1014 page::ChunkScope eScope
,
1016 OStorePageBIOS
&rBIOS
)
1018 OStoreDirectoryDataBlock
const & rDataBlock
= PAGE().m_aDataBlock
;
1021 storeError eErrCode
= store_E_None
;
1022 if (eScope
== page::SCOPE_DIRECT
)
1024 // Truncate direct data pages.
1025 sal_uInt16 i
, n
= rDataBlock
.directCount();
1026 for (i
= n
; i
> nRemain
; i
--)
1028 // Obtain data page location.
1029 sal_uInt32 nAddr
= directLink (i
- 1);
1030 if (nAddr
== STORE_PAGE_NULL
) continue;
1033 eErrCode
= rBIOS
.free (nAddr
);
1034 if (eErrCode
!= store_E_None
)
1037 // Clear pointer to data page.
1038 directLink (i
- 1, STORE_PAGE_NULL
);
1045 if (eScope
== page::SCOPE_SINGLE
)
1047 // Truncate single indirect pages.
1048 sal_uInt16 i
, n
= rDataBlock
.singleCount();
1049 for (i
= n
; i
> nRemain
; i
--)
1051 // Truncate single indirect page to zero data pages.
1052 eErrCode
= store_truncate_Impl (singleLink (i
- 1), 0, rBIOS
);
1053 if (eErrCode
!= store_E_None
)
1056 // Clear pointer to single indirect page.
1057 singleLink (i
- 1, STORE_PAGE_NULL
);
1064 if (eScope
== page::SCOPE_DOUBLE
)
1066 // Truncate double indirect pages.
1067 sal_uInt16 i
, n
= rDataBlock
.doubleCount();
1068 for (i
= n
; i
> nRemain
; i
--)
1070 // Truncate double indirect page to zero single indirect pages.
1071 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1072 if (eErrCode
!= store_E_None
)
1075 // Clear pointer to double indirect page.
1076 doubleLink (i
- 1, STORE_PAGE_NULL
);
1083 if (eScope
== page::SCOPE_TRIPLE
)
1085 // Truncate triple indirect pages.
1086 sal_uInt16 i
, n
= rDataBlock
.tripleCount();
1087 for (i
= n
; i
> nRemain
; i
--)
1089 // Truncate to zero double indirect pages.
1090 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1091 if (eErrCode
!= store_E_None
)
1094 // Clear pointer to triple indirect page.
1095 tripleLink (i
- 1, STORE_PAGE_NULL
);
1103 return store_E_InvalidAccess
;
1106 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */