1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: stordata.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_store.hxx"
34 #include "stordata.hxx"
36 #include "sal/types.h"
37 #include "osl/diagnose.h"
39 #include "store/types.h"
40 #include "storbase.hxx"
41 #include "storbios.hxx"
43 using namespace store
;
45 /*========================================================================
47 * OStoreDataPageObject implementation.
49 *======================================================================*/
53 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
55 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
61 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
63 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
66 /*========================================================================
68 * OStoreIndirectionPageObject implementation.
70 *======================================================================*/
72 * store_truncate_Impl (single indirect page).
74 static storeError
store_truncate_Impl (
77 OStorePageBIOS
&rBIOS
)
79 if (nAddr
!= STORE_PAGE_NULL
)
81 // Load single indirect page.
82 OStoreIndirectionPageObject aSingle
;
83 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
84 if (eErrCode
== store_E_None
)
86 // Truncate to 'nSingle' direct pages.
87 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
88 if (eErrCode
!= store_E_None
)
93 if (eErrCode
!= store_E_InvalidChecksum
)
97 // Check for complete truncation.
100 // Free single indirect page.
101 OStorePageData aPageHead
;
102 eErrCode
= rBIOS
.free (aPageHead
, nAddr
);
103 if (eErrCode
!= store_E_None
)
111 * store_truncate_Impl (double indirect page).
113 static storeError
store_truncate_Impl (
117 OStorePageBIOS
&rBIOS
)
119 if (nAddr
!= STORE_PAGE_NULL
)
121 // Load double indirect page.
122 OStoreIndirectionPageObject aDouble
;
123 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
124 if (eErrCode
== store_E_None
)
126 // Truncate to 'nDouble', 'nSingle' pages.
127 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
128 if (eErrCode
!= store_E_None
)
133 if (eErrCode
!= store_E_InvalidChecksum
)
137 // Check for complete truncation.
138 if ((nDouble
+ nSingle
) == 0)
140 // Free double indirect page.
141 OStorePageData aPageHead
;
142 eErrCode
= rBIOS
.free (aPageHead
, nAddr
);
143 if (eErrCode
!= store_E_None
)
151 * store_truncate_Impl (triple indirect page).
153 static storeError
store_truncate_Impl (
158 OStorePageBIOS
&rBIOS
)
160 if (nAddr
!= STORE_PAGE_NULL
)
162 // Load triple indirect page.
163 OStoreIndirectionPageObject aTriple
;
164 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
165 if (eErrCode
!= store_E_None
)
168 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
169 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
170 if (eErrCode
!= store_E_None
)
173 // Check for complete truncation.
174 if ((nTriple
+ nDouble
+ nSingle
) == 0)
176 // Free triple indirect page.
177 OStorePageData aPageHead
;
178 eErrCode
= rBIOS
.free (aPageHead
, nAddr
);
179 if (eErrCode
!= store_E_None
)
189 storeError
OStoreIndirectionPageObject::loadOrCreate (
191 OStorePageBIOS
& rBIOS
)
193 if (nAddr
== STORE_PAGE_NULL
)
195 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
196 if (eErrCode
!= store_E_None
)
199 eErrCode
= rBIOS
.allocate (*this);
200 if (eErrCode
!= store_E_None
)
203 // Save location pending at caller.
204 return store_E_Pending
;
206 return rBIOS
.loadObjectAt (*this, nAddr
);
212 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
214 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
220 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
222 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
226 * read (single indirect).
228 storeError
OStoreIndirectionPageObject::read (
230 OStoreDataPageObject
&rData
,
231 OStorePageBIOS
&rBIOS
)
233 PageHolderObject
< page
> xImpl (m_xPage
);
234 page
const & rPage
= (*xImpl
);
237 sal_uInt16
const nLimit
= rPage
.capacityCount();
238 if (!(nSingle
< nLimit
))
239 return store_E_InvalidAccess
;
241 // Obtain data page location.
242 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
243 if (nAddr
== STORE_PAGE_NULL
)
244 return store_E_NotExists
;
246 // Load data page and leave.
247 return rBIOS
.loadObjectAt (rData
, nAddr
);
251 * read (double indirect).
253 storeError
OStoreIndirectionPageObject::read (
256 OStoreDataPageObject
&rData
,
257 OStorePageBIOS
&rBIOS
)
259 PageHolderObject
< page
> xImpl (m_xPage
);
260 page
const & rPage
= (*xImpl
);
263 sal_uInt16
const nLimit
= rPage
.capacityCount();
264 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
265 return store_E_InvalidAccess
;
267 // Check single indirect page location.
268 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
269 if (nAddr
== STORE_PAGE_NULL
)
270 return store_E_NotExists
;
272 // Load single indirect page.
273 OStoreIndirectionPageObject aSingle
;
274 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
275 if (eErrCode
!= store_E_None
)
278 // Read single indirect and leave.
279 return aSingle
.read (nSingle
, rData
, rBIOS
);
283 * read (triple indirect).
285 storeError
OStoreIndirectionPageObject::read (
289 OStoreDataPageObject
&rData
,
290 OStorePageBIOS
&rBIOS
)
292 PageHolderObject
< page
> xImpl (m_xPage
);
293 page
const & rPage
= (*xImpl
);
296 sal_uInt16
const nLimit
= rPage
.capacityCount();
297 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
298 return store_E_InvalidAccess
;
300 // Check double indirect page location.
301 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
302 if (nAddr
== STORE_PAGE_NULL
)
303 return store_E_NotExists
;
305 // Load double indirect page.
306 OStoreIndirectionPageObject aDouble
;
307 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
308 if (eErrCode
!= store_E_None
)
311 // Read double indirect and leave.
312 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
316 * write (single indirect).
318 storeError
OStoreIndirectionPageObject::write (
320 OStoreDataPageObject
&rData
,
321 OStorePageBIOS
&rBIOS
)
323 PageHolderObject
< page
> xImpl (m_xPage
);
324 page
& rPage
= (*xImpl
);
327 sal_uInt16
const nLimit
= rPage
.capacityCount();
328 if (!(nSingle
< nLimit
))
329 return store_E_InvalidAccess
;
331 // Obtain data page location.
332 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
333 if (nAddr
== STORE_PAGE_NULL
)
335 // Allocate data page.
336 storeError eErrCode
= rBIOS
.allocate (rData
);
337 if (eErrCode
!= store_E_None
)
340 // Store data page location.
341 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
344 return rBIOS
.saveObjectAt (*this, location());
349 return rBIOS
.saveObjectAt (rData
, nAddr
);
354 * write (double indirect).
356 storeError
OStoreIndirectionPageObject::write (
359 OStoreDataPageObject
&rData
,
360 OStorePageBIOS
&rBIOS
)
362 PageHolderObject
< page
> xImpl (m_xPage
);
363 page
& rPage
= (*xImpl
);
366 sal_uInt16
const nLimit
= rPage
.capacityCount();
367 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
368 return store_E_InvalidAccess
;
370 // Load or create single indirect page.
371 OStoreIndirectionPageObject aSingle
;
372 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
373 if (eErrCode
!= store_E_None
)
375 if (eErrCode
!= store_E_Pending
)
377 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
379 eErrCode
= rBIOS
.saveObjectAt (*this, location());
380 if (eErrCode
!= store_E_None
)
384 // Write single indirect and leave.
385 return aSingle
.write (nSingle
, rData
, rBIOS
);
389 * write (triple indirect).
391 storeError
OStoreIndirectionPageObject::write (
395 OStoreDataPageObject
&rData
,
396 OStorePageBIOS
&rBIOS
)
398 PageHolderObject
< page
> xImpl (m_xPage
);
399 page
& rPage
= (*xImpl
);
402 sal_uInt16
const nLimit
= rPage
.capacityCount();
403 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
404 return store_E_InvalidAccess
;
406 // Load or create double indirect page.
407 OStoreIndirectionPageObject aDouble
;
408 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
409 if (eErrCode
!= store_E_None
)
411 if (eErrCode
!= store_E_Pending
)
413 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
415 eErrCode
= rBIOS
.saveObjectAt (*this, location());
416 if (eErrCode
!= store_E_None
)
420 // Write double indirect and leave.
421 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
425 * truncate (single indirect).
427 storeError
OStoreIndirectionPageObject::truncate (
429 OStorePageBIOS
& rBIOS
)
431 PageHolderObject
< page
> xImpl (m_xPage
);
432 page
& rPage
= (*xImpl
);
435 sal_uInt16
const nLimit
= rPage
.capacityCount();
436 if (!(nSingle
< nLimit
))
437 return store_E_InvalidAccess
;
439 // Save PageDescriptor.
440 OStorePageDescriptor
aDescr (rPage
.m_aDescr
);
441 aDescr
.m_nAddr
= store::ntohl(aDescr
.m_nAddr
);
442 aDescr
.m_nSize
= store::ntohs(aDescr
.m_nSize
);
445 storeError eErrCode
= rBIOS
.acquireLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
446 if (eErrCode
!= store_E_None
)
450 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
452 // Obtain data page location.
453 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
454 if (nAddr
!= STORE_PAGE_NULL
)
457 OStorePageData aPageHead
;
458 eErrCode
= rBIOS
.free (aPageHead
, nAddr
);
459 if (eErrCode
!= store_E_None
)
461 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
465 // Clear pointer to data page.
466 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
471 // Check for modified page.
475 eErrCode
= rBIOS
.saveObjectAt (*this, location());
476 if (eErrCode
!= store_E_None
)
479 OSL_TRACE("OStoreIndirectionPageObject::truncate(): save failed");
481 // Release Lock and Leave.
482 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
487 // Release Lock and Leave.
488 return rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
492 * truncate (double indirect).
494 storeError
OStoreIndirectionPageObject::truncate (
497 OStorePageBIOS
&rBIOS
)
499 PageHolderObject
< page
> xImpl (m_xPage
);
500 page
& rPage
= (*xImpl
);
503 sal_uInt16
const nLimit
= rPage
.capacityCount();
504 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
505 return store_E_InvalidAccess
;
507 // Save PageDescriptor.
508 OStorePageDescriptor
aDescr (rPage
.m_aDescr
);
509 aDescr
.m_nAddr
= store::ntohl(aDescr
.m_nAddr
);
510 aDescr
.m_nSize
= store::ntohs(aDescr
.m_nSize
);
513 storeError eErrCode
= rBIOS
.acquireLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
514 if (eErrCode
!= store_E_None
)
518 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
520 // Truncate single indirect page to zero direct pages.
521 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
522 if (eErrCode
!= store_E_None
)
524 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
528 // Clear pointer to single indirect page.
529 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
533 // Truncate last single indirect page to 'nSingle' direct pages.
534 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
535 if (eErrCode
!= store_E_None
)
537 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
541 // Check for complete truncation.
544 // Clear pointer to last single indirect page.
545 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
549 // Check for modified page.
553 eErrCode
= rBIOS
.saveObjectAt (*this, location());
554 if (eErrCode
!= store_E_None
)
557 OSL_TRACE("OStoreIndirectionPageObject::truncate(): save failed");
559 // Release Lock and Leave.
560 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
565 // Release Lock and Leave.
566 return rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
570 * truncate (triple indirect).
572 storeError
OStoreIndirectionPageObject::truncate (
576 OStorePageBIOS
&rBIOS
)
578 PageHolderObject
< page
> xImpl (m_xPage
);
579 page
& rPage
= (*xImpl
);
582 sal_uInt16
const nLimit
= rPage
.capacityCount();
583 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
584 return store_E_InvalidAccess
;
586 // Save PageDescriptor.
587 OStorePageDescriptor
aDescr (rPage
.m_aDescr
);
588 aDescr
.m_nAddr
= store::ntohl(aDescr
.m_nAddr
);
589 aDescr
.m_nSize
= store::ntohs(aDescr
.m_nSize
);
592 storeError eErrCode
= rBIOS
.acquireLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
593 if (eErrCode
!= store_E_None
)
597 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
599 // Truncate double indirect page to zero single indirect pages.
600 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
601 if (eErrCode
!= store_E_None
)
603 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
607 // Clear pointer to double indirect page.
608 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
612 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
613 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
614 if (eErrCode
!= store_E_None
)
616 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
620 // Check for complete truncation.
621 if ((nDouble
+ nSingle
) == 0)
623 // Clear pointer to last double indirect page.
624 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
628 // Check for modified page.
632 eErrCode
= rBIOS
.saveObjectAt (*this, location());
633 if (eErrCode
!= store_E_None
)
636 OSL_TRACE("OStoreIndirectionPageObject::truncate(): save failed");
638 // Release Lock and Leave.
639 rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
644 // Release Lock and Leave.
645 return rBIOS
.releaseLock (aDescr
.m_nAddr
, aDescr
.m_nSize
);
648 /*========================================================================
650 * OStoreDirectoryPageObject implementation.
652 *======================================================================*/
656 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
658 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
664 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
666 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
667 // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
671 * scope (external data page; private).
673 OStoreDirectoryPageData::ChunkScope
674 OStoreDirectoryPageObject::scope (
676 page::DataBlock::LinkDescriptor
&rDescr
) const
678 page
const & rPage
= PAGE();
679 OStoreDirectoryDataBlock
const & rDataBlock
= rPage
.m_aDataBlock
;
681 sal_uInt32 index0
, index1
, index2
, index3
;
684 sal_uInt32 nCount
= rDataBlock
.directCount();
685 sal_uInt32 nLimit
= nCount
;
688 // Page to index reduction.
691 // Setup LinkDescriptor indices.
692 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
695 return page::SCOPE_DIRECT
;
700 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
701 nCount
= rDataBlock
.singleCount();
702 nLimit
= nCount
* nCapacity
;
705 // Page to index reduction.
706 sal_uInt32 n
= nPage
;
708 // Reduce to single indirect i(1), direct n = i(0).
709 index1
= n
/ nCapacity
;
710 index0
= n
% nCapacity
;
713 n
= index1
* nCapacity
+ index0
;
714 OSL_POSTCOND(n
== nPage
, "wrong math on indirect indices");
716 return page::SCOPE_UNKNOWN
;
718 // Setup LinkDescriptor indices.
719 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
720 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
723 return page::SCOPE_SINGLE
;
728 nCount
= rDataBlock
.doubleCount();
729 nLimit
= nCount
* nCapacity
* nCapacity
;
732 // Page to index reduction.
733 sal_uInt32 n
= nPage
;
735 // Reduce to double indirect i(2), single indirect n = i(0).
736 index2
= n
/ (nCapacity
* nCapacity
);
737 n
= n
% (nCapacity
* nCapacity
);
739 // Reduce to single indirect i(1), direct n = i(0).
740 index1
= n
/ nCapacity
;
741 index0
= n
% nCapacity
;
744 n
= index2
* nCapacity
* nCapacity
+
745 index1
* nCapacity
+ index0
;
746 OSL_POSTCOND(n
== nPage
, "wrong math on double indirect indices");
748 return page::SCOPE_UNKNOWN
;
750 // Setup LinkDescriptor indices.
751 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
752 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
753 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
756 return page::SCOPE_DOUBLE
;
761 nCount
= rDataBlock
.tripleCount();
762 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
765 // Page to index reduction.
766 sal_uInt32 n
= nPage
;
768 // Reduce to triple indirect i(3), double indirect n.
769 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
770 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
772 // Reduce to double indirect i(2), single indirect n.
773 index2
= n
/ (nCapacity
* nCapacity
);
774 n
= n
% (nCapacity
* nCapacity
);
776 // Reduce to single indirect i(1), direct n = i(0).
777 index1
= n
/ nCapacity
;
778 index0
= n
% nCapacity
;
781 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
782 index2
* nCapacity
* nCapacity
+
783 index1
* nCapacity
+ index0
;
784 OSL_POSTCOND(n
== nPage
, "wrong math on triple indirect indices");
786 return page::SCOPE_UNKNOWN
;
788 // Setup LinkDescriptor indices.
789 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
790 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
791 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
792 rDescr
.m_nIndex3
= (sal_uInt16
)(index3
& 0xffff);
795 return page::SCOPE_TRIPLE
;
798 // Unreachable (more than triple indirect).
799 return page::SCOPE_UNREACHABLE
;
804 * chunk (external data page).
806 inode::ChunkDescriptor
OStoreDirectoryPageObject::chunk (sal_uInt32 nOffset
)
808 // @@@ INSUFFICIENT: NEED SCOPE AS WELL @@@
809 sal_uInt32 nCapacity
= m_rPage
.capacity();
810 if (nOffset
< nCapacity
)
811 // Internal scope (inode page).
812 return inode::ChunkDescriptor (nOffset
, nCapacity
);
814 // External scope (data page).
815 return inode::ChunkDescriptor (nOffset
- nCapacity
, data::capacity(m_rPage
.m_aDescr
));
817 inode::ChunkScope eScope
= m_rPage
.scope(nOffset
);
818 if (eScope
== inode::SCOPE_INTERNAL
)
819 // Inode page (internal scope).
820 return inode::ChunkDescriptor (nOffset
, m_rPage
.capacity());
822 // Data page (external scope).
823 return inode::ChunkDescriptor (nOffset
- m_rPage
.capacity(), data::capacity(m_rPage
.m_aDescr
));
828 * read (external data page).
830 storeError
OStoreDirectoryPageObject::read (
832 OStoreDataPageObject
&rData
,
833 OStorePageBIOS
&rBIOS
)
835 // Determine scope and link indices.
836 page::DataBlock::LinkDescriptor aLink
;
837 page::ChunkScope eScope
= scope (nPage
, aLink
);
839 storeError eErrCode
= store_E_None
;
840 if (eScope
== page::SCOPE_DIRECT
)
842 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
843 if (nAddr
== STORE_PAGE_NULL
)
844 return store_E_NotExists
;
846 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
848 else if (eScope
== page::SCOPE_SINGLE
)
850 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
851 if (nAddr
== STORE_PAGE_NULL
)
852 return store_E_NotExists
;
854 OStoreIndirectionPageObject aSingle
;
855 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
856 if (eErrCode
!= store_E_None
)
859 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
861 else if (eScope
== page::SCOPE_DOUBLE
)
863 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
864 if (nAddr
== STORE_PAGE_NULL
)
865 return store_E_NotExists
;
867 OStoreIndirectionPageObject aDouble
;
868 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
869 if (eErrCode
!= store_E_None
)
872 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
874 else if (eScope
== page::SCOPE_TRIPLE
)
876 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
877 if (nAddr
== STORE_PAGE_NULL
)
878 return store_E_NotExists
;
880 OStoreIndirectionPageObject aTriple
;
881 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
882 if (eErrCode
!= store_E_None
)
885 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
887 else if (eScope
== page::SCOPE_UNREACHABLE
)
890 eErrCode
= store_E_CantSeek
;
895 OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
896 eErrCode
= store_E_Unknown
;
904 * write (external data page).
906 storeError
OStoreDirectoryPageObject::write (
908 OStoreDataPageObject
&rData
,
909 OStorePageBIOS
&rBIOS
)
911 // Determine scope and link indices.
912 page::DataBlock::LinkDescriptor aLink
;
913 page::ChunkScope eScope
= scope (nPage
, aLink
);
915 storeError eErrCode
= store_E_None
;
916 if (eScope
== page::SCOPE_DIRECT
)
918 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
919 if (nAddr
== STORE_PAGE_NULL
)
921 // Allocate data page.
922 eErrCode
= rBIOS
.allocate (rData
);
923 if (eErrCode
!= store_E_None
)
926 // Store data page location.
927 directLink (aLink
.m_nIndex0
, rData
.location());
932 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
935 else if (eScope
== page::SCOPE_SINGLE
)
937 OStoreIndirectionPageObject aSingle
;
938 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
939 if (eErrCode
!= store_E_None
)
941 if (eErrCode
!= store_E_Pending
)
943 singleLink (aLink
.m_nIndex1
, aSingle
.location());
946 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
948 else if (eScope
== page::SCOPE_DOUBLE
)
950 OStoreIndirectionPageObject aDouble
;
951 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
952 if (eErrCode
!= store_E_None
)
954 if (eErrCode
!= store_E_Pending
)
956 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
959 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
961 else if (eScope
== page::SCOPE_TRIPLE
)
963 OStoreIndirectionPageObject aTriple
;
964 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
965 if (eErrCode
!= store_E_None
)
967 if (eErrCode
!= store_E_Pending
)
969 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
972 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
974 else if (eScope
== page::SCOPE_UNREACHABLE
)
977 eErrCode
= store_E_CantSeek
;
982 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
983 eErrCode
= store_E_Unknown
;
991 * truncate (external data page).
993 storeError
OStoreDirectoryPageObject::truncate (
995 OStorePageBIOS
&rBIOS
)
997 // Determine scope and link indices.
998 page::DataBlock::LinkDescriptor aLink
;
999 page::ChunkScope eScope
= scope (nPage
, aLink
);
1001 storeError eErrCode
= store_E_None
;
1002 if (eScope
== page::SCOPE_DIRECT
)
1004 // Truncate all triple indirect pages.
1005 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
1006 if (eErrCode
!= store_E_None
)
1009 // Truncate all double indirect pages.
1010 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
1011 if (eErrCode
!= store_E_None
)
1014 // Truncate all single indirect pages.
1015 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
1016 if (eErrCode
!= store_E_None
)
1019 // Truncate direct pages, including 'aLink.m_nIndex0'.
1020 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
1022 else if (eScope
== page::SCOPE_SINGLE
)
1024 // Truncate all triple indirect pages.
1025 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
1026 if (eErrCode
!= store_E_None
)
1029 // Truncate all double indirect pages.
1030 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
1031 if (eErrCode
!= store_E_None
)
1034 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
1035 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
1036 if (eErrCode
!= store_E_None
)
1039 // Truncate last single indirect page to ... pages.
1040 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
1041 if (eErrCode
!= store_E_None
)
1044 // Check for complete truncation.
1045 if (aLink
.m_nIndex0
== 0)
1047 // Clear pointer to last single indirect page.
1048 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
1051 else if (eScope
== page::SCOPE_DOUBLE
)
1053 // Truncate all triple indirect pages.
1054 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
1055 if (eErrCode
!= store_E_None
)
1058 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
1059 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
1060 if (eErrCode
!= store_E_None
)
1063 // Truncate last double indirect page to ... pages.
1064 eErrCode
= store_truncate_Impl (
1065 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
1066 if (eErrCode
!= store_E_None
)
1069 // Check for complete truncation.
1070 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
1072 // Clear pointer to last double indirect page.
1073 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
1076 else if (eScope
== page::SCOPE_TRIPLE
)
1078 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
1079 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
1080 if (eErrCode
!= store_E_None
)
1083 // Truncate last triple indirect page to ... pages.
1084 eErrCode
= store_truncate_Impl (
1085 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
1086 if (eErrCode
!= store_E_None
)
1089 // Check for complete truncation.
1090 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
1092 // Clear pointer to last triple indirect page.
1093 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
1096 else if (eScope
== page::SCOPE_UNREACHABLE
)
1099 eErrCode
= store_E_CantSeek
;
1104 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
1105 eErrCode
= store_E_Unknown
;
1113 * truncate (external data page scope; private).
1115 storeError
OStoreDirectoryPageObject::truncate (
1116 page::ChunkScope eScope
,
1118 OStorePageBIOS
&rBIOS
)
1120 OStoreDirectoryDataBlock
const & rDataBlock
= PAGE().m_aDataBlock
;
1123 storeError eErrCode
= store_E_None
;
1124 if (eScope
== page::SCOPE_DIRECT
)
1126 // Truncate direct data pages.
1127 sal_uInt16 i
, n
= rDataBlock
.directCount();
1128 for (i
= n
; i
> nRemain
; i
--)
1130 // Obtain data page location.
1131 sal_uInt32 nAddr
= directLink (i
- 1);
1132 if (nAddr
== STORE_PAGE_NULL
) continue;
1135 OStoreDataPageData aData
;
1136 eErrCode
= rBIOS
.free (aData
, nAddr
);
1137 if (eErrCode
!= store_E_None
)
1140 // Clear pointer to data page.
1141 directLink (i
- 1, STORE_PAGE_NULL
);
1148 if (eScope
== page::SCOPE_SINGLE
)
1150 // Truncate single indirect pages.
1151 sal_uInt16 i
, n
= rDataBlock
.singleCount();
1152 for (i
= n
; i
> nRemain
; i
--)
1154 // Truncate single indirect page to zero data pages.
1155 eErrCode
= store_truncate_Impl (singleLink (i
- 1), 0, rBIOS
);
1156 if (eErrCode
!= store_E_None
)
1159 // Clear pointer to single indirect page.
1160 singleLink (i
- 1, STORE_PAGE_NULL
);
1167 if (eScope
== page::SCOPE_DOUBLE
)
1169 // Truncate double indirect pages.
1170 sal_uInt16 i
, n
= rDataBlock
.doubleCount();
1171 for (i
= n
; i
> nRemain
; i
--)
1173 // Truncate double indirect page to zero single indirect pages.
1174 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1175 if (eErrCode
!= store_E_None
)
1178 // Clear pointer to double indirect page.
1179 doubleLink (i
- 1, STORE_PAGE_NULL
);
1186 if (eScope
== page::SCOPE_TRIPLE
)
1188 // Truncate triple indirect pages.
1189 sal_uInt16 i
, n
= rDataBlock
.tripleCount();
1190 for (i
= n
; i
> nRemain
; i
--)
1192 // Truncate to zero double indirect pages.
1193 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1194 if (eErrCode
!= store_E_None
)
1197 // Clear pointer to triple indirect page.
1198 tripleLink (i
- 1, STORE_PAGE_NULL
);
1206 return store_E_InvalidAccess
;