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.hxx,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 #ifndef _STORE_STORDATA_HXX_
32 #define _STORE_STORDATA_HXX_ "$Revision: 1.6.8.2 $"
34 #include "sal/types.h"
35 #include "sal/macros.h"
37 #include "store/types.h"
38 #include "storbase.hxx"
43 /*========================================================================
47 *======================================================================*/
48 #define STORE_MAGIC_DATAPAGE sal_uInt32(0x94190310)
50 struct OStoreDataPageData
: public store::OStorePageData
52 typedef OStorePageData base
;
53 typedef OStoreDataPageData self
;
55 typedef OStorePageDescriptor D
;
63 static const sal_uInt32 theTypeId
= STORE_MAGIC_DATAPAGE
;
67 static const size_t theSize
= 0;
68 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
69 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
73 static sal_uInt16
capacity (const D
& rDescr
) // @see inode::ChunkDescriptor
75 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
77 sal_uInt16
capacity() const
79 return self::capacity (base::m_aDescr
);
84 sal_uInt16
usage() const
86 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
91 explicit OStoreDataPageData (sal_uInt16 nPageSize
= self::thePageSize
)
94 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
95 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
96 memset (m_pData
, 0, capacity());
99 /** guard (external representation).
103 /** verify (external representation).
105 storeError
verify() const { return store_E_None
; }
108 /*========================================================================
110 * OStoreDataPageObject.
112 *======================================================================*/
113 class OStoreDataPageObject
: public store::OStorePageObject
115 typedef OStorePageObject base
;
116 typedef OStoreDataPageData page
;
121 explicit OStoreDataPageObject (PageHolder
const & rxPage
= PageHolder())
122 : OStorePageObject (rxPage
)
125 /** External representation.
127 virtual storeError
guard (sal_uInt32 nAddr
);
128 virtual storeError
verify (sal_uInt32 nAddr
) const;
131 /*========================================================================
133 * OStoreIndirectionPageData.
135 *======================================================================*/
136 #define STORE_MAGIC_INDIRECTPAGE sal_uInt32(0x89191107)
138 struct OStoreIndirectionPageData
: public store::OStorePageData
140 typedef OStorePageData base
;
141 typedef OStoreIndirectionPageData self
;
143 typedef OStorePageGuard G
;
144 typedef OStorePageDescriptor D
;
149 sal_uInt32 m_pData
[1];
153 static const sal_uInt32 theTypeId
= STORE_MAGIC_INDIRECTPAGE
;
157 static const size_t theSize
= sizeof(G
);
158 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
159 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
163 static sal_uInt16
capacity (const D
& rDescr
)
165 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
167 sal_uInt16
capacity() const
169 return self::capacity (base::m_aDescr
);
174 static sal_uInt16
capacityCount (const D
& rDescr
) // @see DirectoryPageObject::scope()
176 return sal_uInt16(capacity(rDescr
) / sizeof(sal_uInt32
));
178 sal_uInt16
capacityCount() const
180 return sal_uInt16(capacity() / sizeof(sal_uInt32
));
185 explicit OStoreIndirectionPageData (sal_uInt16 nPageSize
)
188 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
189 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
190 self::m_aGuard
.m_nMagic
= store::htonl(0);
191 memset (m_pData
, STORE_PAGE_NULL
, capacity());
194 /** guard (external representation).
198 sal_uInt32 nCRC32
= 0;
199 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
200 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
201 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
204 /** verify (external representation).
206 storeError
verify() const
209 sal_uInt32 nCRC32
= 0;
210 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
211 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
212 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
213 return store_E_InvalidChecksum
;
219 /*========================================================================
221 * OStoreIndirectionPageObject.
223 *======================================================================*/
224 class OStoreIndirectionPageObject
: public store::OStorePageObject
226 typedef OStorePageObject base
;
227 typedef OStoreIndirectionPageData page
;
232 explicit OStoreIndirectionPageObject (PageHolder
const & rxPage
= PageHolder())
233 : OStorePageObject (rxPage
)
236 /** External representation.
238 storeError
loadOrCreate (
240 OStorePageBIOS
& rBIOS
);
242 virtual storeError
guard (sal_uInt32 nAddr
);
243 virtual storeError
verify (sal_uInt32 nAddr
) const;
245 /** read (indirect data page).
249 OStoreDataPageObject
&rData
,
250 OStorePageBIOS
&rBIOS
);
255 OStoreDataPageObject
&rData
,
256 OStorePageBIOS
&rBIOS
);
262 OStoreDataPageObject
&rData
,
263 OStorePageBIOS
&rBIOS
);
265 /** write (indirect data page).
269 OStoreDataPageObject
&rData
,
270 OStorePageBIOS
&rBIOS
);
275 OStoreDataPageObject
&rData
,
276 OStorePageBIOS
&rBIOS
);
282 OStoreDataPageObject
&rData
,
283 OStorePageBIOS
&rBIOS
);
285 /** truncate (indirect data page).
287 storeError
truncate (
289 OStorePageBIOS
&rBIOS
);
291 storeError
truncate (
294 OStorePageBIOS
&rBIOS
);
296 storeError
truncate (
300 OStorePageBIOS
&rBIOS
);
303 /*========================================================================
305 * OStorePageNameBlock.
307 *======================================================================*/
308 struct OStorePageNameBlock
310 typedef OStorePageGuard G
;
311 typedef OStorePageKey K
;
317 sal_uInt32 m_nAttrib
;
318 sal_Char m_pData
[STORE_MAXIMUM_NAMESIZE
];
322 static const size_t theSize
= sizeof(G
) + sizeof(K
) + sizeof(sal_uInt32
) + sizeof(sal_Char
[STORE_MAXIMUM_NAMESIZE
]);
326 void initialize (void)
331 memset (m_pData
, 0, sizeof(m_pData
));
336 OStorePageNameBlock (void)
337 : m_aGuard(), m_aKey(), m_nAttrib (0)
339 memset (m_pData
, 0, sizeof(m_pData
));
342 /** guard (external representation).
346 sal_uInt32 nCRC32
= 0;
347 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
348 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
349 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
352 /** verify (external representation).
354 storeError
verify() const
356 sal_uInt32 nCRC32
= 0;
357 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
358 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
359 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
360 return store_E_InvalidChecksum
;
366 /*========================================================================
368 * OStoreDirectoryDataBlock.
370 *======================================================================*/
371 #define STORE_LIMIT_DATAPAGE_DIRECT 16
372 #define STORE_LIMIT_DATAPAGE_SINGLE 8
373 #define STORE_LIMIT_DATAPAGE_DOUBLE 1
374 #define STORE_LIMIT_DATAPAGE_TRIPLE 1
376 struct OStoreDirectoryDataBlock
378 typedef OStorePageGuard G
;
382 struct LinkDescriptor
386 sal_uInt16 m_nIndex0
;
387 sal_uInt16 m_nIndex1
;
388 sal_uInt16 m_nIndex2
;
389 sal_uInt16 m_nIndex3
;
393 LinkDescriptor (void)
394 : m_nIndex0 ((sal_uInt16
)(~0)),
395 m_nIndex1 ((sal_uInt16
)(~0)),
396 m_nIndex2 ((sal_uInt16
)(~0)),
397 m_nIndex3 ((sal_uInt16
)(~0))
407 sal_uInt32 m_pDirect
[STORE_LIMIT_DATAPAGE_DIRECT
];
408 sal_uInt32 m_pSingle
[STORE_LIMIT_DATAPAGE_SINGLE
];
409 sal_uInt32 m_pDouble
[STORE_LIMIT_DATAPAGE_DOUBLE
];
410 sal_uInt32 m_pTriple
[STORE_LIMIT_DATAPAGE_TRIPLE
];
414 void initialize (void)
416 memset(m_pDirect
, STORE_PAGE_NULL
, sizeof(m_pDirect
));
417 memset(m_pSingle
, STORE_PAGE_NULL
, sizeof(m_pSingle
));
418 memset(m_pDouble
, STORE_PAGE_NULL
, sizeof(m_pDouble
));
419 memset(m_pTriple
, STORE_PAGE_NULL
, sizeof(m_pTriple
));
434 sal_uInt32 m_nDataLen
;
438 static const size_t theSize
= sizeof(G
) + sizeof(LinkTable
) + sizeof(sal_uInt32
);
442 void initialize (void)
445 m_aTable
.initialize();
451 OStoreDirectoryDataBlock (void)
452 : m_aGuard(), m_aTable(), m_nDataLen (0)
455 /** guard (external representation).
459 sal_uInt32 nCRC32
= 0;
460 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
461 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
462 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
465 /** verify (external representation).
467 storeError
verify() const
469 sal_uInt32 nCRC32
= 0;
470 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
471 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
472 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
473 return store_E_InvalidChecksum
;
480 static sal_uInt16
directCount (void)
482 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DIRECT
));
484 sal_uInt32
directLink (sal_uInt16 nIndex
) const
486 if (nIndex
< directCount())
487 return store::ntohl(m_aTable
.m_pDirect
[nIndex
]);
489 return STORE_PAGE_NULL
;
491 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
493 if (nIndex
< directCount())
494 m_aTable
.m_pDirect
[nIndex
] = store::htonl(nAddr
);
499 static sal_uInt16
singleCount (void)
501 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_SINGLE
));
503 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
505 if (nIndex
< singleCount())
506 return store::ntohl(m_aTable
.m_pSingle
[nIndex
]);
508 return STORE_PAGE_NULL
;
510 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
512 if (nIndex
< singleCount())
513 m_aTable
.m_pSingle
[nIndex
] = store::htonl(nAddr
);
518 static sal_uInt16
doubleCount (void)
520 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DOUBLE
));
522 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
524 if (nIndex
< doubleCount())
525 return store::ntohl(m_aTable
.m_pDouble
[nIndex
]);
527 return STORE_PAGE_NULL
;
529 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
531 if (nIndex
< doubleCount())
532 m_aTable
.m_pDouble
[nIndex
] = store::htonl(nAddr
);
537 static sal_uInt16
tripleCount (void)
539 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_TRIPLE
));
541 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
543 if (nIndex
< tripleCount())
544 return store::ntohl(m_aTable
.m_pTriple
[nIndex
]);
546 return STORE_PAGE_NULL
;
548 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
550 if (nIndex
< tripleCount())
551 m_aTable
.m_pTriple
[nIndex
] = store::htonl(nAddr
);
555 /*========================================================================
557 * OStoreDirectoryPageData.
559 *======================================================================*/
560 #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
562 struct OStoreDirectoryPageData
: public store::OStorePageData
564 typedef OStorePageData base
;
565 typedef OStoreDirectoryPageData self
;
567 typedef OStorePageDescriptor D
;
568 typedef OStorePageNameBlock NameBlock
;
569 typedef OStoreDirectoryDataBlock DataBlock
;
573 NameBlock m_aNameBlock
;
574 DataBlock m_aDataBlock
;
575 sal_uInt8 m_pData
[1];
579 static const sal_uInt32 theTypeId
= STORE_MAGIC_DIRECTORYPAGE
;
583 static const size_t theSize
= NameBlock::theSize
+ DataBlock::theSize
;
584 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
585 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
589 sal_uInt16
capacity() const
591 return (store::ntohs(base::m_aDescr
.m_nSize
) - self::thePageSize
);
596 sal_uInt16
usage() const
598 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
603 void initialize (void)
605 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
606 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
608 m_aNameBlock
.initialize();
609 m_aDataBlock
.initialize();
611 memset (m_pData
, 0, capacity());
616 explicit OStoreDirectoryPageData (sal_uInt16 nPageSize
)
617 : base (nPageSize
), m_aNameBlock(), m_aDataBlock()
619 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
620 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
621 memset (m_pData
, 0, capacity());
624 /** guard (external representation).
628 m_aNameBlock
.guard();
629 m_aDataBlock
.guard();
632 /** verify (external representation).
634 storeError
verify() const
636 storeError eErrCode
= m_aNameBlock
.verify();
637 if (eErrCode
== store_E_None
)
638 eErrCode
= m_aDataBlock
.verify();
644 struct ChunkDescriptor
649 sal_uInt16 m_nOffset
;
650 sal_uInt16 m_nLength
;
654 ChunkDescriptor (sal_uInt32 nPosition
, sal_uInt16 nCapacity
)
656 m_nPage
= nPosition
/ nCapacity
;
657 m_nOffset
= (sal_uInt16
)((nPosition
% nCapacity
) & 0xffff);
658 m_nLength
= nCapacity
- m_nOffset
;
676 /** scope (internal).
678 ChunkScope
scope (sal_uInt32 nPosition
) const
680 sal_uInt32 nCapacity
= capacity();
681 if (nPosition
< nCapacity
)
682 return SCOPE_INTERNAL
;
684 return SCOPE_EXTERNAL
;
688 /*========================================================================
690 * OStoreDirectoryPageObject.
692 *======================================================================*/
693 class OStoreDirectoryPageObject
: public store::OStorePageObject
695 typedef OStorePageObject base
;
696 typedef OStoreDirectoryPageData page
;
697 typedef OStoreIndirectionPageData indirect
;
699 typedef OStorePageDescriptor D
;
704 explicit OStoreDirectoryPageObject (PageHolder
const & rxPage
= PageHolder())
705 : OStorePageObject (rxPage
)
708 /** External representation.
710 virtual storeError
guard (sal_uInt32 nAddr
);
711 virtual storeError
verify (sal_uInt32 nAddr
) const;
715 sal_uInt32
attrib (void) const
717 return store::ntohl(PAGE().m_aNameBlock
.m_nAttrib
);
719 void attrib (sal_uInt32 nAttrib
)
721 PAGE().m_aNameBlock
.m_nAttrib
= store::htonl(nAttrib
);
727 OStorePageKey
key (void) const
729 return PAGE().m_aNameBlock
.m_aKey
;
731 void key (OStorePageKey
const & rKey
)
733 PAGE().m_aNameBlock
.m_aKey
= rKey
;
739 sal_uInt32
path (void) const
741 page
const & rPage
= PAGE();
742 const sal_Char
* pszName
= rPage
.m_aNameBlock
.m_pData
;
743 sal_uInt32 nPath
= store::ntohl(rPage
.m_aNameBlock
.m_aKey
.m_nHigh
);
744 return rtl_crc32 (nPath
, pszName
, rtl_str_getLength(pszName
));
747 sal_Size
getName (sal_Char
* pBuffer
, sal_Size nBufsiz
) const
749 sal_Char
const * pszName
= PAGE().m_aNameBlock
.m_pData
;
750 sal_Size nLength
= rtl_str_getLength(pszName
);
751 memcpy (pBuffer
, pszName
, SAL_MIN(nLength
, nBufsiz
));
757 sal_uInt32
dataLength (void) const
759 return store::ntohl(PAGE().m_aDataBlock
.m_nDataLen
);
761 void dataLength (sal_uInt32 nLength
)
763 PAGE().m_aDataBlock
.m_nDataLen
= store::htonl(nLength
);
769 sal_uInt32
directLink (sal_uInt16 nIndex
) const
771 return PAGE().m_aDataBlock
.directLink (nIndex
);
773 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
775 PAGE().m_aDataBlock
.directLink (nIndex
, nAddr
);
781 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
783 return PAGE().m_aDataBlock
.singleLink (nIndex
);
785 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
787 PAGE().m_aDataBlock
.singleLink (nIndex
, nAddr
);
793 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
795 return PAGE().m_aDataBlock
.doubleLink (nIndex
);
797 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
799 PAGE().m_aDataBlock
.doubleLink (nIndex
, nAddr
);
805 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
807 return PAGE().m_aDataBlock
.tripleLink (nIndex
);
809 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
811 PAGE().m_aDataBlock
.tripleLink (nIndex
, nAddr
);
815 /** read (external data page).
819 OStoreDataPageObject
&rData
,
820 OStorePageBIOS
&rBIOS
);
822 /** write (external data page).
826 OStoreDataPageObject
&rData
,
827 OStorePageBIOS
&rBIOS
);
829 /** truncate (external data page).
831 storeError
truncate (
833 OStorePageBIOS
&rBIOS
);
840 page
* pImpl
= static_cast<page
*>(m_xPage
.get());
841 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
844 page
const & PAGE() const
846 page
const * pImpl
= static_cast<page
const *>(m_xPage
.get());
847 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
851 /** scope (external data page; private).
853 page::ChunkScope
scope (
855 page::DataBlock::LinkDescriptor
&rDescr
) const;
857 /** truncate (external data page scope; private).
859 storeError
truncate (
860 page::ChunkScope eScope
,
862 OStorePageBIOS
&rBIOS
);
865 /*========================================================================
869 *======================================================================*/
873 #endif /* !_STORE_STORDATA_HXX_ */