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 #ifndef _STORE_STORDATA_HXX_
30 #define _STORE_STORDATA_HXX_
32 #include "sal/types.h"
33 #include "sal/macros.h"
35 #include "store/types.h"
36 #include "storbase.hxx"
41 /*========================================================================
45 *======================================================================*/
46 #define STORE_MAGIC_DATAPAGE sal_uInt32(0x94190310)
48 struct OStoreDataPageData
: public store::OStorePageData
50 typedef OStorePageData base
;
51 typedef OStoreDataPageData self
;
53 typedef OStorePageDescriptor D
;
61 static const sal_uInt32 theTypeId
= STORE_MAGIC_DATAPAGE
;
65 static const size_t theSize
= 0;
66 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
67 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
71 static sal_uInt16
capacity (const D
& rDescr
) // @see inode::ChunkDescriptor
73 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
75 sal_uInt16
capacity() const
77 return self::capacity (base::m_aDescr
);
82 sal_uInt16
usage() const
84 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
89 explicit OStoreDataPageData (sal_uInt16 nPageSize
= self::thePageSize
)
92 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
93 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
94 if (capacity()) memset (m_pData
, 0, capacity());
97 /** guard (external representation).
101 /** verify (external representation).
103 storeError
verify() const { return store_E_None
; }
106 /*========================================================================
108 * OStoreDataPageObject.
110 *======================================================================*/
111 class OStoreDataPageObject
: public store::OStorePageObject
113 typedef OStorePageObject base
;
114 typedef OStoreDataPageData page
;
119 explicit OStoreDataPageObject (PageHolder
const & rxPage
= PageHolder())
120 : OStorePageObject (rxPage
)
123 /** External representation.
125 virtual storeError
guard (sal_uInt32 nAddr
);
126 virtual storeError
verify (sal_uInt32 nAddr
) const;
129 /*========================================================================
131 * OStoreIndirectionPageData.
133 *======================================================================*/
134 #define STORE_MAGIC_INDIRECTPAGE sal_uInt32(0x89191107)
136 struct OStoreIndirectionPageData
: public store::OStorePageData
138 typedef OStorePageData base
;
139 typedef OStoreIndirectionPageData self
;
141 typedef OStorePageGuard G
;
142 typedef OStorePageDescriptor D
;
147 sal_uInt32 m_pData
[1];
151 static const sal_uInt32 theTypeId
= STORE_MAGIC_INDIRECTPAGE
;
155 static const size_t theSize
= sizeof(G
);
156 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
157 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
161 static sal_uInt16
capacity (const D
& rDescr
)
163 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
165 sal_uInt16
capacity() const
167 return self::capacity (base::m_aDescr
);
172 static sal_uInt16
capacityCount (const D
& rDescr
) // @see DirectoryPageObject::scope()
174 return sal_uInt16(capacity(rDescr
) / sizeof(sal_uInt32
));
176 sal_uInt16
capacityCount() const
178 return sal_uInt16(capacity() / sizeof(sal_uInt32
));
183 explicit OStoreIndirectionPageData (sal_uInt16 nPageSize
)
186 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
187 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
188 self::m_aGuard
.m_nMagic
= store::htonl(0);
189 memset (m_pData
, STORE_PAGE_NULL
, capacity());
192 /** guard (external representation).
196 sal_uInt32 nCRC32
= 0;
197 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
198 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
199 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
202 /** verify (external representation).
204 storeError
verify() const
206 sal_uInt32 nCRC32
= 0;
207 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
208 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
209 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
210 return store_E_InvalidChecksum
;
216 /*========================================================================
218 * OStoreIndirectionPageObject.
220 *======================================================================*/
221 class OStoreIndirectionPageObject
: public store::OStorePageObject
223 typedef OStorePageObject base
;
224 typedef OStoreIndirectionPageData page
;
229 explicit OStoreIndirectionPageObject (PageHolder
const & rxPage
= PageHolder())
230 : OStorePageObject (rxPage
)
233 /** External representation.
235 storeError
loadOrCreate (
237 OStorePageBIOS
& rBIOS
);
239 virtual storeError
guard (sal_uInt32 nAddr
);
240 virtual storeError
verify (sal_uInt32 nAddr
) const;
242 /** read (indirect data page).
246 OStoreDataPageObject
&rData
,
247 OStorePageBIOS
&rBIOS
);
252 OStoreDataPageObject
&rData
,
253 OStorePageBIOS
&rBIOS
);
259 OStoreDataPageObject
&rData
,
260 OStorePageBIOS
&rBIOS
);
262 /** write (indirect data page).
266 OStoreDataPageObject
&rData
,
267 OStorePageBIOS
&rBIOS
);
272 OStoreDataPageObject
&rData
,
273 OStorePageBIOS
&rBIOS
);
279 OStoreDataPageObject
&rData
,
280 OStorePageBIOS
&rBIOS
);
282 /** truncate (indirect data page).
284 storeError
truncate (
286 OStorePageBIOS
&rBIOS
);
288 storeError
truncate (
291 OStorePageBIOS
&rBIOS
);
293 storeError
truncate (
297 OStorePageBIOS
&rBIOS
);
300 /*========================================================================
302 * OStorePageNameBlock.
304 *======================================================================*/
305 struct OStorePageNameBlock
307 typedef OStorePageGuard G
;
308 typedef OStorePageKey K
;
314 sal_uInt32 m_nAttrib
;
315 sal_Char m_pData
[STORE_MAXIMUM_NAMESIZE
];
319 static const size_t theSize
= sizeof(G
) + sizeof(K
) + sizeof(sal_uInt32
) + sizeof(sal_Char
[STORE_MAXIMUM_NAMESIZE
]);
323 void initialize (void)
328 memset (m_pData
, 0, sizeof(m_pData
));
333 OStorePageNameBlock (void)
334 : m_aGuard(), m_aKey(), m_nAttrib (0)
336 memset (m_pData
, 0, sizeof(m_pData
));
339 /** guard (external representation).
343 sal_uInt32 nCRC32
= 0;
344 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
345 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
346 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
349 /** verify (external representation).
351 storeError
verify() const
353 sal_uInt32 nCRC32
= 0;
354 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
355 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
356 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
357 return store_E_InvalidChecksum
;
363 /*========================================================================
365 * OStoreDirectoryDataBlock.
367 *======================================================================*/
368 #define STORE_LIMIT_DATAPAGE_DIRECT 16
369 #define STORE_LIMIT_DATAPAGE_SINGLE 8
370 #define STORE_LIMIT_DATAPAGE_DOUBLE 1
371 #define STORE_LIMIT_DATAPAGE_TRIPLE 1
373 struct OStoreDirectoryDataBlock
375 typedef OStorePageGuard G
;
379 struct LinkDescriptor
383 sal_uInt16 m_nIndex0
;
384 sal_uInt16 m_nIndex1
;
385 sal_uInt16 m_nIndex2
;
386 sal_uInt16 m_nIndex3
;
390 LinkDescriptor (void)
391 : m_nIndex0 ((sal_uInt16
)(~0)),
392 m_nIndex1 ((sal_uInt16
)(~0)),
393 m_nIndex2 ((sal_uInt16
)(~0)),
394 m_nIndex3 ((sal_uInt16
)(~0))
404 sal_uInt32 m_pDirect
[STORE_LIMIT_DATAPAGE_DIRECT
];
405 sal_uInt32 m_pSingle
[STORE_LIMIT_DATAPAGE_SINGLE
];
406 sal_uInt32 m_pDouble
[STORE_LIMIT_DATAPAGE_DOUBLE
];
407 sal_uInt32 m_pTriple
[STORE_LIMIT_DATAPAGE_TRIPLE
];
411 void initialize (void)
413 memset(m_pDirect
, STORE_PAGE_NULL
, sizeof(m_pDirect
));
414 memset(m_pSingle
, STORE_PAGE_NULL
, sizeof(m_pSingle
));
415 memset(m_pDouble
, STORE_PAGE_NULL
, sizeof(m_pDouble
));
416 memset(m_pTriple
, STORE_PAGE_NULL
, sizeof(m_pTriple
));
431 sal_uInt32 m_nDataLen
;
435 static const size_t theSize
= sizeof(G
) + sizeof(LinkTable
) + sizeof(sal_uInt32
);
439 void initialize (void)
442 m_aTable
.initialize();
448 OStoreDirectoryDataBlock (void)
449 : m_aGuard(), m_aTable(), m_nDataLen (0)
452 /** guard (external representation).
456 sal_uInt32 nCRC32
= 0;
457 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
458 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
459 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
462 /** verify (external representation).
464 storeError
verify() const
466 sal_uInt32 nCRC32
= 0;
467 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
468 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
469 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
470 return store_E_InvalidChecksum
;
477 static sal_uInt16
directCount (void)
479 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DIRECT
));
481 sal_uInt32
directLink (sal_uInt16 nIndex
) const
483 if (nIndex
< directCount())
484 return store::ntohl(m_aTable
.m_pDirect
[nIndex
]);
486 return STORE_PAGE_NULL
;
488 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
490 if (nIndex
< directCount())
491 m_aTable
.m_pDirect
[nIndex
] = store::htonl(nAddr
);
496 static sal_uInt16
singleCount (void)
498 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_SINGLE
));
500 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
502 if (nIndex
< singleCount())
503 return store::ntohl(m_aTable
.m_pSingle
[nIndex
]);
505 return STORE_PAGE_NULL
;
507 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
509 if (nIndex
< singleCount())
510 m_aTable
.m_pSingle
[nIndex
] = store::htonl(nAddr
);
515 static sal_uInt16
doubleCount (void)
517 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DOUBLE
));
519 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
521 if (nIndex
< doubleCount())
522 return store::ntohl(m_aTable
.m_pDouble
[nIndex
]);
524 return STORE_PAGE_NULL
;
526 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
528 if (nIndex
< doubleCount())
529 m_aTable
.m_pDouble
[nIndex
] = store::htonl(nAddr
);
534 static sal_uInt16
tripleCount (void)
536 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_TRIPLE
));
538 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
540 if (nIndex
< tripleCount())
541 return store::ntohl(m_aTable
.m_pTriple
[nIndex
]);
543 return STORE_PAGE_NULL
;
545 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
547 if (nIndex
< tripleCount())
548 m_aTable
.m_pTriple
[nIndex
] = store::htonl(nAddr
);
552 /*========================================================================
554 * OStoreDirectoryPageData.
556 *======================================================================*/
557 #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
559 struct OStoreDirectoryPageData
: public store::OStorePageData
561 typedef OStorePageData base
;
562 typedef OStoreDirectoryPageData self
;
564 typedef OStorePageDescriptor D
;
565 typedef OStorePageNameBlock NameBlock
;
566 typedef OStoreDirectoryDataBlock DataBlock
;
570 NameBlock m_aNameBlock
;
571 DataBlock m_aDataBlock
;
572 sal_uInt8 m_pData
[1];
576 static const sal_uInt32 theTypeId
= STORE_MAGIC_DIRECTORYPAGE
;
580 static const size_t theSize
= NameBlock::theSize
+ DataBlock::theSize
;
581 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
582 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
586 sal_uInt16
capacity() const
588 return (store::ntohs(base::m_aDescr
.m_nSize
) - self::thePageSize
);
593 sal_uInt16
usage() const
595 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
600 void initialize (void)
602 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
603 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
605 m_aNameBlock
.initialize();
606 m_aDataBlock
.initialize();
608 memset (m_pData
, 0, capacity());
613 explicit OStoreDirectoryPageData (sal_uInt16 nPageSize
)
614 : base (nPageSize
), m_aNameBlock(), m_aDataBlock()
616 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
617 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
618 memset (m_pData
, 0, capacity());
621 /** guard (external representation).
625 m_aNameBlock
.guard();
626 m_aDataBlock
.guard();
629 /** verify (external representation).
631 storeError
verify() const
633 storeError eErrCode
= m_aNameBlock
.verify();
634 if (eErrCode
== store_E_None
)
635 eErrCode
= m_aDataBlock
.verify();
641 struct ChunkDescriptor
646 sal_uInt16 m_nOffset
;
647 sal_uInt16 m_nLength
;
651 ChunkDescriptor (sal_uInt32 nPosition
, sal_uInt16 nCapacity
)
653 m_nPage
= nPosition
/ nCapacity
;
654 m_nOffset
= (sal_uInt16
)((nPosition
% nCapacity
) & 0xffff);
655 m_nLength
= nCapacity
- m_nOffset
;
673 /** scope (internal).
675 ChunkScope
scope (sal_uInt32 nPosition
) const
677 sal_uInt32 nCapacity
= capacity();
678 if (nPosition
< nCapacity
)
679 return SCOPE_INTERNAL
;
681 return SCOPE_EXTERNAL
;
685 /*========================================================================
687 * OStoreDirectoryPageObject.
689 *======================================================================*/
690 class OStoreDirectoryPageObject
: public store::OStorePageObject
692 typedef OStorePageObject base
;
693 typedef OStoreDirectoryPageData page
;
694 typedef OStoreIndirectionPageData indirect
;
696 typedef OStorePageDescriptor D
;
701 explicit OStoreDirectoryPageObject (PageHolder
const & rxPage
= PageHolder())
702 : OStorePageObject (rxPage
)
705 /** External representation.
707 virtual storeError
guard (sal_uInt32 nAddr
);
708 virtual storeError
verify (sal_uInt32 nAddr
) const;
712 sal_uInt32
attrib (void) const
714 return store::ntohl(PAGE().m_aNameBlock
.m_nAttrib
);
716 void attrib (sal_uInt32 nAttrib
)
718 PAGE().m_aNameBlock
.m_nAttrib
= store::htonl(nAttrib
);
724 OStorePageKey
key (void) const
726 return PAGE().m_aNameBlock
.m_aKey
;
728 void key (OStorePageKey
const & rKey
)
730 PAGE().m_aNameBlock
.m_aKey
= rKey
;
736 sal_uInt32
path (void) const
738 page
const & rPage
= PAGE();
739 const sal_Char
* pszName
= rPage
.m_aNameBlock
.m_pData
;
740 sal_uInt32 nPath
= store::ntohl(rPage
.m_aNameBlock
.m_aKey
.m_nHigh
);
741 return rtl_crc32 (nPath
, pszName
, rtl_str_getLength(pszName
));
744 sal_Size
getName (sal_Char
* pBuffer
, sal_Size nBufsiz
) const
746 sal_Char
const * pszName
= PAGE().m_aNameBlock
.m_pData
;
747 sal_Size nLength
= rtl_str_getLength(pszName
);
748 memcpy (pBuffer
, pszName
, SAL_MIN(nLength
, nBufsiz
));
754 sal_uInt32
dataLength (void) const
756 return store::ntohl(PAGE().m_aDataBlock
.m_nDataLen
);
758 void dataLength (sal_uInt32 nLength
)
760 PAGE().m_aDataBlock
.m_nDataLen
= store::htonl(nLength
);
766 sal_uInt32
directLink (sal_uInt16 nIndex
) const
768 return PAGE().m_aDataBlock
.directLink (nIndex
);
770 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
772 PAGE().m_aDataBlock
.directLink (nIndex
, nAddr
);
778 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
780 return PAGE().m_aDataBlock
.singleLink (nIndex
);
782 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
784 PAGE().m_aDataBlock
.singleLink (nIndex
, nAddr
);
790 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
792 return PAGE().m_aDataBlock
.doubleLink (nIndex
);
794 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
796 PAGE().m_aDataBlock
.doubleLink (nIndex
, nAddr
);
802 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
804 return PAGE().m_aDataBlock
.tripleLink (nIndex
);
806 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
808 PAGE().m_aDataBlock
.tripleLink (nIndex
, nAddr
);
812 /** read (external data page).
816 OStoreDataPageObject
&rData
,
817 OStorePageBIOS
&rBIOS
);
819 /** write (external data page).
823 OStoreDataPageObject
&rData
,
824 OStorePageBIOS
&rBIOS
);
826 /** truncate (external data page).
828 storeError
truncate (
830 OStorePageBIOS
&rBIOS
);
837 page
* pImpl
= static_cast<page
*>(m_xPage
.get());
838 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
841 page
const & PAGE() const
843 page
const * pImpl
= static_cast<page
const *>(m_xPage
.get());
844 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
848 /** scope (external data page; private).
850 page::ChunkScope
scope (
852 page::DataBlock::LinkDescriptor
&rDescr
) const;
854 /** truncate (external data page scope; private).
856 storeError
truncate (
857 page::ChunkScope eScope
,
859 OStorePageBIOS
&rBIOS
);
862 /*========================================================================
866 *======================================================================*/
870 #endif /* !_STORE_STORDATA_HXX_ */
872 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */