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"
24 #include "osl/diagnose.h"
26 #include "store/types.h"
27 #include "storbase.hxx"
28 #include "storbios.hxx"
30 using namespace store
;
32 /*========================================================================
34 * OStoreDataPageObject implementation.
36 *======================================================================*/
40 storeError
OStoreDataPageObject::guard (sal_uInt32 nAddr
)
42 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
48 storeError
OStoreDataPageObject::verify (sal_uInt32 nAddr
) const
50 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
53 /*========================================================================
55 * OStoreIndirectionPageObject implementation.
57 *======================================================================*/
59 * store_truncate_Impl (single indirect page).
61 static storeError
store_truncate_Impl (
64 OStorePageBIOS
&rBIOS
)
66 if (nAddr
!= STORE_PAGE_NULL
)
68 // Load single indirect page.
69 OStoreIndirectionPageObject aSingle
;
70 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
71 if (eErrCode
== store_E_None
)
73 // Truncate to 'nSingle' direct pages.
74 eErrCode
= aSingle
.truncate (nSingle
, rBIOS
);
75 if (eErrCode
!= store_E_None
)
80 if (eErrCode
!= store_E_InvalidChecksum
)
84 // Check for complete truncation.
87 // Free single indirect page.
88 eErrCode
= rBIOS
.free (nAddr
);
89 if (eErrCode
!= store_E_None
)
97 * store_truncate_Impl (double indirect page).
99 static storeError
store_truncate_Impl (
103 OStorePageBIOS
&rBIOS
)
105 if (nAddr
!= STORE_PAGE_NULL
)
107 // Load double indirect page.
108 OStoreIndirectionPageObject aDouble
;
109 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
110 if (eErrCode
== store_E_None
)
112 // Truncate to 'nDouble', 'nSingle' pages.
113 eErrCode
= aDouble
.truncate (nDouble
, nSingle
, rBIOS
);
114 if (eErrCode
!= store_E_None
)
119 if (eErrCode
!= store_E_InvalidChecksum
)
123 // Check for complete truncation.
124 if ((nDouble
+ nSingle
) == 0)
126 // Free double indirect page.
127 eErrCode
= rBIOS
.free (nAddr
);
128 if (eErrCode
!= store_E_None
)
136 * store_truncate_Impl (triple indirect page).
138 static storeError
store_truncate_Impl (
143 OStorePageBIOS
&rBIOS
)
145 if (nAddr
!= STORE_PAGE_NULL
)
147 // Load triple indirect page.
148 OStoreIndirectionPageObject aTriple
;
149 storeError eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
150 if (eErrCode
!= store_E_None
)
153 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
154 eErrCode
= aTriple
.truncate (nTriple
, nDouble
, nSingle
, rBIOS
);
155 if (eErrCode
!= store_E_None
)
158 // Check for complete truncation.
159 if ((nTriple
+ nDouble
+ nSingle
) == 0)
161 // Free triple indirect page.
162 eErrCode
= rBIOS
.free (nAddr
);
163 if (eErrCode
!= store_E_None
)
173 storeError
OStoreIndirectionPageObject::loadOrCreate (
175 OStorePageBIOS
& rBIOS
)
177 if (nAddr
== STORE_PAGE_NULL
)
179 storeError eErrCode
= construct
<page
>(rBIOS
.allocator());
180 if (eErrCode
!= store_E_None
)
183 eErrCode
= rBIOS
.allocate (*this);
184 if (eErrCode
!= store_E_None
)
187 // Save location pending at caller.
188 return store_E_Pending
;
190 return rBIOS
.loadObjectAt (*this, nAddr
);
196 storeError
OStoreIndirectionPageObject::guard (sal_uInt32 nAddr
)
198 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
204 storeError
OStoreIndirectionPageObject::verify (sal_uInt32 nAddr
) const
206 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
210 * read (single indirect).
212 storeError
OStoreIndirectionPageObject::read (
214 OStoreDataPageObject
&rData
,
215 OStorePageBIOS
&rBIOS
)
217 PageHolderObject
< page
> xImpl (m_xPage
);
218 page
const & rPage
= (*xImpl
);
221 sal_uInt16
const nLimit
= rPage
.capacityCount();
222 if (!(nSingle
< nLimit
))
223 return store_E_InvalidAccess
;
225 // Obtain data page location.
226 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
227 if (nAddr
== STORE_PAGE_NULL
)
228 return store_E_NotExists
;
230 // Load data page and leave.
231 return rBIOS
.loadObjectAt (rData
, nAddr
);
235 * read (double indirect).
237 storeError
OStoreIndirectionPageObject::read (
240 OStoreDataPageObject
&rData
,
241 OStorePageBIOS
&rBIOS
)
243 PageHolderObject
< page
> xImpl (m_xPage
);
244 page
const & rPage
= (*xImpl
);
247 sal_uInt16
const nLimit
= rPage
.capacityCount();
248 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
249 return store_E_InvalidAccess
;
251 // Check single indirect page location.
252 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nDouble
]);
253 if (nAddr
== STORE_PAGE_NULL
)
254 return store_E_NotExists
;
256 // Load single indirect page.
257 OStoreIndirectionPageObject aSingle
;
258 storeError eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
259 if (eErrCode
!= store_E_None
)
262 // Read single indirect and leave.
263 return aSingle
.read (nSingle
, rData
, rBIOS
);
267 * read (triple indirect).
269 storeError
OStoreIndirectionPageObject::read (
273 OStoreDataPageObject
&rData
,
274 OStorePageBIOS
&rBIOS
)
276 PageHolderObject
< page
> xImpl (m_xPage
);
277 page
const & rPage
= (*xImpl
);
280 sal_uInt16
const nLimit
= rPage
.capacityCount();
281 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
282 return store_E_InvalidAccess
;
284 // Check double indirect page location.
285 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nTriple
]);
286 if (nAddr
== STORE_PAGE_NULL
)
287 return store_E_NotExists
;
289 // Load double indirect page.
290 OStoreIndirectionPageObject aDouble
;
291 storeError eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
292 if (eErrCode
!= store_E_None
)
295 // Read double indirect and leave.
296 return aDouble
.read (nDouble
, nSingle
, rData
, rBIOS
);
300 * write (single indirect).
302 storeError
OStoreIndirectionPageObject::write (
304 OStoreDataPageObject
&rData
,
305 OStorePageBIOS
&rBIOS
)
307 PageHolderObject
< page
> xImpl (m_xPage
);
308 page
& rPage
= (*xImpl
);
311 sal_uInt16
const nLimit
= rPage
.capacityCount();
312 if (!(nSingle
< nLimit
))
313 return store_E_InvalidAccess
;
315 // Obtain data page location.
316 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[nSingle
]);
317 if (nAddr
== STORE_PAGE_NULL
)
319 // Allocate data page.
320 storeError eErrCode
= rBIOS
.allocate (rData
);
321 if (eErrCode
!= store_E_None
)
324 // Store data page location.
325 rPage
.m_pData
[nSingle
] = store::htonl(rData
.location());
328 return rBIOS
.saveObjectAt (*this, location());
333 return rBIOS
.saveObjectAt (rData
, nAddr
);
338 * write (double indirect).
340 storeError
OStoreIndirectionPageObject::write (
343 OStoreDataPageObject
&rData
,
344 OStorePageBIOS
&rBIOS
)
346 PageHolderObject
< page
> xImpl (m_xPage
);
347 page
& rPage
= (*xImpl
);
350 sal_uInt16
const nLimit
= rPage
.capacityCount();
351 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
352 return store_E_InvalidAccess
;
354 // Load or create single indirect page.
355 OStoreIndirectionPageObject aSingle
;
356 storeError eErrCode
= aSingle
.loadOrCreate (store::ntohl(rPage
.m_pData
[nDouble
]), rBIOS
);
357 if (eErrCode
!= store_E_None
)
359 if (eErrCode
!= store_E_Pending
)
361 rPage
.m_pData
[nDouble
] = store::htonl(aSingle
.location());
363 eErrCode
= rBIOS
.saveObjectAt (*this, location());
364 if (eErrCode
!= store_E_None
)
368 // Write single indirect and leave.
369 return aSingle
.write (nSingle
, rData
, rBIOS
);
373 * write (triple indirect).
375 storeError
OStoreIndirectionPageObject::write (
379 OStoreDataPageObject
&rData
,
380 OStorePageBIOS
&rBIOS
)
382 PageHolderObject
< page
> xImpl (m_xPage
);
383 page
& rPage
= (*xImpl
);
386 sal_uInt16
const nLimit
= rPage
.capacityCount();
387 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
388 return store_E_InvalidAccess
;
390 // Load or create double indirect page.
391 OStoreIndirectionPageObject aDouble
;
392 storeError eErrCode
= aDouble
.loadOrCreate (store::ntohl(rPage
.m_pData
[nTriple
]), rBIOS
);
393 if (eErrCode
!= store_E_None
)
395 if (eErrCode
!= store_E_Pending
)
397 rPage
.m_pData
[nTriple
] = store::htonl(aDouble
.location());
399 eErrCode
= rBIOS
.saveObjectAt (*this, location());
400 if (eErrCode
!= store_E_None
)
404 // Write double indirect and leave.
405 return aDouble
.write (nDouble
, nSingle
, rData
, rBIOS
);
409 * truncate (single indirect).
411 storeError
OStoreIndirectionPageObject::truncate (
413 OStorePageBIOS
& rBIOS
)
415 PageHolderObject
< page
> xImpl (m_xPage
);
416 page
& rPage
= (*xImpl
);
419 sal_uInt16
const nLimit
= rPage
.capacityCount();
420 if (!(nSingle
< nLimit
))
421 return store_E_InvalidAccess
;
424 storeError eErrCode
= store_E_None
;
425 for (sal_uInt16 i
= nLimit
; i
> nSingle
; i
--)
427 // Obtain data page location.
428 sal_uInt32
const nAddr
= store::ntohl(rPage
.m_pData
[i
- 1]);
429 if (nAddr
!= STORE_PAGE_NULL
)
432 eErrCode
= rBIOS
.free (nAddr
);
433 if (eErrCode
!= store_E_None
)
436 // Clear pointer to data page.
437 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
442 // Check for modified page.
446 eErrCode
= rBIOS
.saveObjectAt (*this, location());
454 * truncate (double indirect).
456 storeError
OStoreIndirectionPageObject::truncate (
459 OStorePageBIOS
&rBIOS
)
461 PageHolderObject
< page
> xImpl (m_xPage
);
462 page
& rPage
= (*xImpl
);
465 sal_uInt16
const nLimit
= rPage
.capacityCount();
466 if (!((nDouble
< nLimit
) && (nSingle
< nLimit
)))
467 return store_E_InvalidAccess
;
470 storeError eErrCode
= store_E_None
;
471 for (sal_uInt16 i
= nLimit
; i
> nDouble
+ 1; i
--)
473 // Truncate single indirect page to zero direct pages.
474 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, rBIOS
);
475 if (eErrCode
!= store_E_None
)
478 // Clear pointer to single indirect page.
479 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
483 // Truncate last single indirect page to 'nSingle' direct pages.
484 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nDouble
]), nSingle
, rBIOS
);
485 if (eErrCode
!= store_E_None
)
488 // Check for complete truncation.
491 // Clear pointer to last single indirect page.
492 rPage
.m_pData
[nDouble
] = STORE_PAGE_NULL
;
496 // Check for modified page.
500 eErrCode
= rBIOS
.saveObjectAt (*this, location());
508 * truncate (triple indirect).
510 storeError
OStoreIndirectionPageObject::truncate (
514 OStorePageBIOS
&rBIOS
)
516 PageHolderObject
< page
> xImpl (m_xPage
);
517 page
& rPage
= (*xImpl
);
520 sal_uInt16
const nLimit
= rPage
.capacityCount();
521 if (!((nTriple
< nLimit
) && (nDouble
< nLimit
) && (nSingle
< nLimit
)))
522 return store_E_InvalidAccess
;
525 storeError eErrCode
= store_E_None
;
526 for (sal_uInt16 i
= nLimit
; i
> nTriple
+ 1; i
--)
528 // Truncate double indirect page to zero single indirect pages.
529 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[i
- 1]), 0, 0, rBIOS
);
530 if (eErrCode
!= store_E_None
)
533 // Clear pointer to double indirect page.
534 rPage
.m_pData
[i
- 1] = STORE_PAGE_NULL
;
538 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
539 eErrCode
= store_truncate_Impl (store::ntohl(rPage
.m_pData
[nTriple
]), nDouble
, nSingle
, rBIOS
);
540 if (eErrCode
!= store_E_None
)
543 // Check for complete truncation.
544 if ((nDouble
+ nSingle
) == 0)
546 // Clear pointer to last double indirect page.
547 rPage
.m_pData
[nTriple
] = STORE_PAGE_NULL
;
551 // Check for modified page.
555 eErrCode
= rBIOS
.saveObjectAt (*this, location());
562 /*========================================================================
564 * OStoreDirectoryPageObject implementation.
566 *======================================================================*/
570 storeError
OStoreDirectoryPageObject::guard (sal_uInt32 nAddr
)
572 return PageHolderObject
< page
>::guard (m_xPage
, nAddr
);
578 storeError
OStoreDirectoryPageObject::verify (sal_uInt32 nAddr
) const
580 return PageHolderObject
< page
>::verify (m_xPage
, nAddr
);
581 // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
585 * scope (external data page; private).
587 OStoreDirectoryPageData::ChunkScope
588 OStoreDirectoryPageObject::scope (
590 page::DataBlock::LinkDescriptor
&rDescr
) const
592 page
const & rPage
= PAGE();
594 sal_uInt32 index0
, index1
, index2
, index3
;
597 sal_uInt32 nCount
= OStoreDirectoryDataBlock::directCount
;
598 sal_uInt32 nLimit
= nCount
;
601 // Page to index reduction.
604 // Setup LinkDescriptor indices.
605 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
608 return page::SCOPE_DIRECT
;
613 sal_uInt32
const nCapacity
= indirect::capacityCount(rPage
.m_aDescr
);
614 nCount
= OStoreDirectoryDataBlock::singleCount
;
615 nLimit
= nCount
* nCapacity
;
618 // Page to index reduction.
619 sal_uInt32 n
= nPage
;
621 // Reduce to single indirect i(1), direct n = i(0).
622 index1
= n
/ nCapacity
;
623 index0
= n
% nCapacity
;
626 n
= index1
* nCapacity
+ index0
;
629 SAL_WARN("store", "wrong math on indirect indices");
630 return page::SCOPE_UNKNOWN
;
633 // Setup LinkDescriptor indices.
634 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
635 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
638 return page::SCOPE_SINGLE
;
643 nCount
= OStoreDirectoryDataBlock::doubleCount
;
644 nLimit
= nCount
* nCapacity
* nCapacity
;
647 // Page to index reduction.
648 sal_uInt32 n
= nPage
;
650 // Reduce to double indirect i(2), single indirect n = i(0).
651 index2
= n
/ (nCapacity
* nCapacity
);
652 n
= n
% (nCapacity
* nCapacity
);
654 // Reduce to single indirect i(1), direct n = i(0).
655 index1
= n
/ nCapacity
;
656 index0
= n
% nCapacity
;
659 n
= index2
* nCapacity
* nCapacity
+
660 index1
* nCapacity
+ index0
;
663 SAL_WARN("store", "wrong math on double indirect indices");
664 return page::SCOPE_UNKNOWN
;
667 // Setup LinkDescriptor indices.
668 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
669 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
670 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
673 return page::SCOPE_DOUBLE
;
678 nCount
= OStoreDirectoryDataBlock::tripleCount
;
679 nLimit
= nCount
* nCapacity
* nCapacity
* nCapacity
;
682 // Page to index reduction.
683 sal_uInt32 n
= nPage
;
685 // Reduce to triple indirect i(3), double indirect n.
686 index3
= n
/ (nCapacity
* nCapacity
* nCapacity
);
687 n
= n
% (nCapacity
* nCapacity
* nCapacity
);
689 // Reduce to double indirect i(2), single indirect n.
690 index2
= n
/ (nCapacity
* nCapacity
);
691 n
= n
% (nCapacity
* nCapacity
);
693 // Reduce to single indirect i(1), direct n = i(0).
694 index1
= n
/ nCapacity
;
695 index0
= n
% nCapacity
;
698 n
= index3
* nCapacity
* nCapacity
* nCapacity
+
699 index2
* nCapacity
* nCapacity
+
700 index1
* nCapacity
+ index0
;
703 SAL_WARN("store", "wrong math on triple indirect indices");
704 return page::SCOPE_UNKNOWN
;
707 // Setup LinkDescriptor indices.
708 rDescr
.m_nIndex0
= (sal_uInt16
)(index0
& 0xffff);
709 rDescr
.m_nIndex1
= (sal_uInt16
)(index1
& 0xffff);
710 rDescr
.m_nIndex2
= (sal_uInt16
)(index2
& 0xffff);
711 rDescr
.m_nIndex3
= (sal_uInt16
)(index3
& 0xffff);
714 return page::SCOPE_TRIPLE
;
717 // Unreachable (more than triple indirect).
718 return page::SCOPE_UNREACHABLE
;
722 * read (external data page).
724 storeError
OStoreDirectoryPageObject::read (
726 OStoreDataPageObject
&rData
,
727 OStorePageBIOS
&rBIOS
)
729 // Determine scope and link indices.
730 page::DataBlock::LinkDescriptor aLink
;
731 page::ChunkScope eScope
= scope (nPage
, aLink
);
733 storeError eErrCode
= store_E_None
;
734 if (eScope
== page::SCOPE_DIRECT
)
736 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
737 if (nAddr
== STORE_PAGE_NULL
)
738 return store_E_NotExists
;
740 eErrCode
= rBIOS
.loadObjectAt (rData
, nAddr
);
742 else if (eScope
== page::SCOPE_SINGLE
)
744 sal_uInt32
const nAddr
= singleLink (aLink
.m_nIndex1
);
745 if (nAddr
== STORE_PAGE_NULL
)
746 return store_E_NotExists
;
748 OStoreIndirectionPageObject aSingle
;
749 eErrCode
= rBIOS
.loadObjectAt (aSingle
, nAddr
);
750 if (eErrCode
!= store_E_None
)
753 eErrCode
= aSingle
.read (aLink
.m_nIndex0
, rData
, rBIOS
);
755 else if (eScope
== page::SCOPE_DOUBLE
)
757 sal_uInt32
const nAddr
= doubleLink (aLink
.m_nIndex2
);
758 if (nAddr
== STORE_PAGE_NULL
)
759 return store_E_NotExists
;
761 OStoreIndirectionPageObject aDouble
;
762 eErrCode
= rBIOS
.loadObjectAt (aDouble
, nAddr
);
763 if (eErrCode
!= store_E_None
)
766 eErrCode
= aDouble
.read (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
768 else if (eScope
== page::SCOPE_TRIPLE
)
770 sal_uInt32
const nAddr
= tripleLink (aLink
.m_nIndex3
);
771 if (nAddr
== STORE_PAGE_NULL
)
772 return store_E_NotExists
;
774 OStoreIndirectionPageObject aTriple
;
775 eErrCode
= rBIOS
.loadObjectAt (aTriple
, nAddr
);
776 if (eErrCode
!= store_E_None
)
779 eErrCode
= aTriple
.read (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
781 else if (eScope
== page::SCOPE_UNREACHABLE
)
784 eErrCode
= store_E_CantSeek
;
789 OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
790 eErrCode
= store_E_Unknown
;
798 * write (external data page).
800 storeError
OStoreDirectoryPageObject::write (
802 OStoreDataPageObject
&rData
,
803 OStorePageBIOS
&rBIOS
)
805 // Determine scope and link indices.
806 page::DataBlock::LinkDescriptor aLink
;
807 page::ChunkScope eScope
= scope (nPage
, aLink
);
809 storeError eErrCode
= store_E_None
;
810 if (eScope
== page::SCOPE_DIRECT
)
812 sal_uInt32
const nAddr
= directLink (aLink
.m_nIndex0
);
813 if (nAddr
== STORE_PAGE_NULL
)
815 // Allocate data page.
816 eErrCode
= rBIOS
.allocate (rData
);
817 if (eErrCode
!= store_E_None
)
820 // Store data page location.
821 directLink (aLink
.m_nIndex0
, rData
.location());
826 eErrCode
= rBIOS
.saveObjectAt (rData
, nAddr
);
829 else if (eScope
== page::SCOPE_SINGLE
)
831 OStoreIndirectionPageObject aSingle
;
832 eErrCode
= aSingle
.loadOrCreate (singleLink (aLink
.m_nIndex1
), rBIOS
);
833 if (eErrCode
!= store_E_None
)
835 if (eErrCode
!= store_E_Pending
)
837 singleLink (aLink
.m_nIndex1
, aSingle
.location());
840 eErrCode
= aSingle
.write (aLink
.m_nIndex0
, rData
, rBIOS
);
842 else if (eScope
== page::SCOPE_DOUBLE
)
844 OStoreIndirectionPageObject aDouble
;
845 eErrCode
= aDouble
.loadOrCreate (doubleLink (aLink
.m_nIndex2
), rBIOS
);
846 if (eErrCode
!= store_E_None
)
848 if (eErrCode
!= store_E_Pending
)
850 doubleLink (aLink
.m_nIndex2
, aDouble
.location());
853 eErrCode
= aDouble
.write (aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
855 else if (eScope
== page::SCOPE_TRIPLE
)
857 OStoreIndirectionPageObject aTriple
;
858 eErrCode
= aTriple
.loadOrCreate (tripleLink (aLink
.m_nIndex3
), rBIOS
);
859 if (eErrCode
!= store_E_None
)
861 if (eErrCode
!= store_E_Pending
)
863 tripleLink (aLink
.m_nIndex3
, aTriple
.location());
866 eErrCode
= aTriple
.write (aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rData
, rBIOS
);
868 else if (eScope
== page::SCOPE_UNREACHABLE
)
871 eErrCode
= store_E_CantSeek
;
876 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
877 eErrCode
= store_E_Unknown
;
885 * truncate (external data page).
887 storeError
OStoreDirectoryPageObject::truncate (
889 OStorePageBIOS
&rBIOS
)
891 // Determine scope and link indices.
892 page::DataBlock::LinkDescriptor aLink
;
893 page::ChunkScope eScope
= scope (nPage
, aLink
);
895 storeError eErrCode
= store_E_None
;
896 if (eScope
== page::SCOPE_DIRECT
)
898 // Truncate all triple indirect pages.
899 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
900 if (eErrCode
!= store_E_None
)
903 // Truncate all double indirect pages.
904 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
905 if (eErrCode
!= store_E_None
)
908 // Truncate all single indirect pages.
909 eErrCode
= truncate (page::SCOPE_SINGLE
, 0, rBIOS
);
910 if (eErrCode
!= store_E_None
)
913 // Truncate direct pages, including 'aLink.m_nIndex0'.
914 eErrCode
= truncate (eScope
, aLink
.m_nIndex0
, rBIOS
);
916 else if (eScope
== page::SCOPE_SINGLE
)
918 // Truncate all triple indirect pages.
919 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
920 if (eErrCode
!= store_E_None
)
923 // Truncate all double indirect pages.
924 eErrCode
= truncate (page::SCOPE_DOUBLE
, 0, rBIOS
);
925 if (eErrCode
!= store_E_None
)
928 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
929 eErrCode
= truncate (eScope
, aLink
.m_nIndex1
+ 1, rBIOS
);
930 if (eErrCode
!= store_E_None
)
933 // Truncate last single indirect page to ... pages.
934 eErrCode
= store_truncate_Impl (singleLink (aLink
.m_nIndex1
), aLink
.m_nIndex0
, rBIOS
);
935 if (eErrCode
!= store_E_None
)
938 // Check for complete truncation.
939 if (aLink
.m_nIndex0
== 0)
941 // Clear pointer to last single indirect page.
942 singleLink (aLink
.m_nIndex1
, STORE_PAGE_NULL
);
945 else if (eScope
== page::SCOPE_DOUBLE
)
947 // Truncate all triple indirect pages.
948 eErrCode
= truncate (page::SCOPE_TRIPLE
, 0, rBIOS
);
949 if (eErrCode
!= store_E_None
)
952 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
953 eErrCode
= truncate (eScope
, aLink
.m_nIndex2
+ 1, rBIOS
);
954 if (eErrCode
!= store_E_None
)
957 // Truncate last double indirect page to ... pages.
958 eErrCode
= store_truncate_Impl (
959 doubleLink (aLink
.m_nIndex2
), aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
960 if (eErrCode
!= store_E_None
)
963 // Check for complete truncation.
964 if ((aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
966 // Clear pointer to last double indirect page.
967 doubleLink (aLink
.m_nIndex2
, STORE_PAGE_NULL
);
970 else if (eScope
== page::SCOPE_TRIPLE
)
972 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
973 eErrCode
= truncate (eScope
, aLink
.m_nIndex3
+ 1, rBIOS
);
974 if (eErrCode
!= store_E_None
)
977 // Truncate last triple indirect page to ... pages.
978 eErrCode
= store_truncate_Impl (
979 tripleLink (aLink
.m_nIndex3
), aLink
.m_nIndex2
, aLink
.m_nIndex1
, aLink
.m_nIndex0
, rBIOS
);
980 if (eErrCode
!= store_E_None
)
983 // Check for complete truncation.
984 if ((aLink
.m_nIndex2
+ aLink
.m_nIndex1
+ aLink
.m_nIndex0
) == 0)
986 // Clear pointer to last triple indirect page.
987 tripleLink (aLink
.m_nIndex3
, STORE_PAGE_NULL
);
990 else if (eScope
== page::SCOPE_UNREACHABLE
)
993 eErrCode
= store_E_CantSeek
;
998 OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
999 eErrCode
= store_E_Unknown
;
1007 * truncate (external data page scope; private).
1009 storeError
OStoreDirectoryPageObject::truncate (
1010 page::ChunkScope eScope
,
1012 OStorePageBIOS
&rBIOS
)
1015 storeError eErrCode
= store_E_None
;
1016 if (eScope
== page::SCOPE_DIRECT
)
1018 // Truncate direct data pages.
1019 sal_uInt16 i
, n
= OStoreDirectoryDataBlock::directCount
;
1020 for (i
= n
; i
> nRemain
; i
--)
1022 // Obtain data page location.
1023 sal_uInt32 nAddr
= directLink (i
- 1);
1024 if (nAddr
== STORE_PAGE_NULL
) continue;
1027 eErrCode
= rBIOS
.free (nAddr
);
1028 if (eErrCode
!= store_E_None
)
1031 // Clear pointer to data page.
1032 directLink (i
- 1, STORE_PAGE_NULL
);
1039 if (eScope
== page::SCOPE_SINGLE
)
1041 // Truncate single indirect pages.
1042 sal_uInt16 i
, n
= OStoreDirectoryDataBlock::singleCount
;
1043 for (i
= n
; i
> nRemain
; i
--)
1045 // Truncate single indirect page to zero data pages.
1046 eErrCode
= store_truncate_Impl (singleLink (i
- 1), 0, rBIOS
);
1047 if (eErrCode
!= store_E_None
)
1050 // Clear pointer to single indirect page.
1051 singleLink (i
- 1, STORE_PAGE_NULL
);
1058 if (eScope
== page::SCOPE_DOUBLE
)
1060 // Truncate double indirect pages.
1061 sal_uInt16 i
, n
= OStoreDirectoryDataBlock::doubleCount
;
1062 for (i
= n
; i
> nRemain
; i
--)
1064 // Truncate double indirect page to zero single indirect pages.
1065 eErrCode
= store_truncate_Impl (doubleLink (i
- 1), 0, 0, rBIOS
);
1066 if (eErrCode
!= store_E_None
)
1069 // Clear pointer to double indirect page.
1070 doubleLink (i
- 1, STORE_PAGE_NULL
);
1077 if (eScope
== page::SCOPE_TRIPLE
)
1079 // Truncate triple indirect pages.
1080 sal_uInt16 i
, n
= OStoreDirectoryDataBlock::tripleCount
;
1081 for (i
= n
; i
> nRemain
; i
--)
1083 // Truncate to zero double indirect pages.
1084 eErrCode
= store_truncate_Impl (tripleLink (i
- 1), 0, 0, 0, rBIOS
);
1085 if (eErrCode
!= store_E_None
)
1088 // Clear pointer to triple indirect page.
1089 tripleLink (i
- 1, STORE_PAGE_NULL
);
1097 return store_E_InvalidAccess
;
1100 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */