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 #ifndef _STORE_STORDATA_HXX_
21 #define _STORE_STORDATA_HXX_
23 #include "sal/config.h"
25 #include "boost/static_assert.hpp"
26 #include "sal/types.h"
27 #include "sal/macros.h"
29 #include "store/types.h"
30 #include "storbase.hxx"
35 /*========================================================================
39 *======================================================================*/
40 #define STORE_MAGIC_DATAPAGE sal_uInt32(0x94190310)
42 struct OStoreDataPageData
: public store::OStorePageData
44 typedef OStorePageData base
;
45 typedef OStoreDataPageData self
;
47 typedef OStorePageDescriptor D
;
55 static const sal_uInt32 theTypeId
= STORE_MAGIC_DATAPAGE
;
59 static const size_t theSize
= 0;
60 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
61 BOOST_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
65 static sal_uInt16
capacity (const D
& rDescr
) // @see inode::ChunkDescriptor
67 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
69 sal_uInt16
capacity() const
71 return self::capacity (base::m_aDescr
);
76 sal_uInt16
usage() const
78 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
83 explicit OStoreDataPageData (sal_uInt16 nPageSize
= self::thePageSize
)
86 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
87 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
88 if (capacity()) memset (m_pData
, 0, capacity());
91 /** guard (external representation).
95 /** verify (external representation).
97 storeError
verify() const { return store_E_None
; }
100 /*========================================================================
102 * OStoreDataPageObject.
104 *======================================================================*/
105 class OStoreDataPageObject
: public store::OStorePageObject
107 typedef OStorePageObject base
;
108 typedef OStoreDataPageData page
;
113 explicit OStoreDataPageObject (PageHolder
const & rxPage
= PageHolder())
114 : OStorePageObject (rxPage
)
117 /** External representation.
119 virtual storeError
guard (sal_uInt32 nAddr
);
120 virtual storeError
verify (sal_uInt32 nAddr
) const;
123 /*========================================================================
125 * OStoreIndirectionPageData.
127 *======================================================================*/
128 #define STORE_MAGIC_INDIRECTPAGE sal_uInt32(0x89191107)
130 struct OStoreIndirectionPageData
: public store::OStorePageData
132 typedef OStorePageData base
;
133 typedef OStoreIndirectionPageData self
;
135 typedef OStorePageGuard G
;
136 typedef OStorePageDescriptor D
;
141 sal_uInt32 m_pData
[1];
145 static const sal_uInt32 theTypeId
= STORE_MAGIC_INDIRECTPAGE
;
149 static const size_t theSize
= sizeof(G
);
150 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
151 BOOST_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
155 static sal_uInt16
capacity (const D
& rDescr
)
157 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
159 sal_uInt16
capacity() const
161 return self::capacity (base::m_aDescr
);
166 static sal_uInt16
capacityCount (const D
& rDescr
) // @see DirectoryPageObject::scope()
168 return sal_uInt16(capacity(rDescr
) / sizeof(sal_uInt32
));
170 sal_uInt16
capacityCount() const
172 return sal_uInt16(capacity() / sizeof(sal_uInt32
));
177 explicit OStoreIndirectionPageData (sal_uInt16 nPageSize
)
180 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
181 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
182 self::m_aGuard
.m_nMagic
= store::htonl(0);
183 memset (m_pData
, STORE_PAGE_NULL
, capacity());
186 /** guard (external representation).
190 sal_uInt32 nCRC32
= 0;
191 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
192 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
193 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
196 /** verify (external representation).
198 storeError
verify() const
200 sal_uInt32 nCRC32
= 0;
201 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
202 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
203 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
204 return store_E_InvalidChecksum
;
210 /*========================================================================
212 * OStoreIndirectionPageObject.
214 *======================================================================*/
215 class OStoreIndirectionPageObject
: public store::OStorePageObject
217 typedef OStorePageObject base
;
218 typedef OStoreIndirectionPageData page
;
223 explicit OStoreIndirectionPageObject (PageHolder
const & rxPage
= PageHolder())
224 : OStorePageObject (rxPage
)
227 /** External representation.
229 storeError
loadOrCreate (
231 OStorePageBIOS
& rBIOS
);
233 virtual storeError
guard (sal_uInt32 nAddr
);
234 virtual storeError
verify (sal_uInt32 nAddr
) const;
236 /** read (indirect data page).
240 OStoreDataPageObject
&rData
,
241 OStorePageBIOS
&rBIOS
);
246 OStoreDataPageObject
&rData
,
247 OStorePageBIOS
&rBIOS
);
253 OStoreDataPageObject
&rData
,
254 OStorePageBIOS
&rBIOS
);
256 /** write (indirect data page).
260 OStoreDataPageObject
&rData
,
261 OStorePageBIOS
&rBIOS
);
266 OStoreDataPageObject
&rData
,
267 OStorePageBIOS
&rBIOS
);
273 OStoreDataPageObject
&rData
,
274 OStorePageBIOS
&rBIOS
);
276 /** truncate (indirect data page).
278 storeError
truncate (
280 OStorePageBIOS
&rBIOS
);
282 storeError
truncate (
285 OStorePageBIOS
&rBIOS
);
287 storeError
truncate (
291 OStorePageBIOS
&rBIOS
);
294 /*========================================================================
296 * OStorePageNameBlock.
298 *======================================================================*/
299 struct OStorePageNameBlock
301 typedef OStorePageGuard G
;
302 typedef OStorePageKey K
;
308 sal_uInt32 m_nAttrib
;
309 sal_Char m_pData
[STORE_MAXIMUM_NAMESIZE
];
313 static const size_t theSize
= sizeof(G
) + sizeof(K
) + sizeof(sal_uInt32
) + sizeof(sal_Char
[STORE_MAXIMUM_NAMESIZE
]);
317 void initialize (void)
322 memset (m_pData
, 0, sizeof(m_pData
));
327 OStorePageNameBlock (void)
328 : m_aGuard(), m_aKey(), m_nAttrib (0)
330 memset (m_pData
, 0, sizeof(m_pData
));
333 /** guard (external representation).
337 sal_uInt32 nCRC32
= 0;
338 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
339 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
340 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
343 /** verify (external representation).
345 storeError
verify() const
347 sal_uInt32 nCRC32
= 0;
348 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
349 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
350 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
351 return store_E_InvalidChecksum
;
357 /*========================================================================
359 * OStoreDirectoryDataBlock.
361 *======================================================================*/
362 #define STORE_LIMIT_DATAPAGE_DIRECT 16
363 #define STORE_LIMIT_DATAPAGE_SINGLE 8
364 #define STORE_LIMIT_DATAPAGE_DOUBLE 1
365 #define STORE_LIMIT_DATAPAGE_TRIPLE 1
367 struct OStoreDirectoryDataBlock
369 typedef OStorePageGuard G
;
373 struct LinkDescriptor
377 sal_uInt16 m_nIndex0
;
378 sal_uInt16 m_nIndex1
;
379 sal_uInt16 m_nIndex2
;
380 sal_uInt16 m_nIndex3
;
384 LinkDescriptor (void)
385 : m_nIndex0 ((sal_uInt16
)(~0)),
386 m_nIndex1 ((sal_uInt16
)(~0)),
387 m_nIndex2 ((sal_uInt16
)(~0)),
388 m_nIndex3 ((sal_uInt16
)(~0))
398 sal_uInt32 m_pDirect
[STORE_LIMIT_DATAPAGE_DIRECT
];
399 sal_uInt32 m_pSingle
[STORE_LIMIT_DATAPAGE_SINGLE
];
400 sal_uInt32 m_pDouble
[STORE_LIMIT_DATAPAGE_DOUBLE
];
401 sal_uInt32 m_pTriple
[STORE_LIMIT_DATAPAGE_TRIPLE
];
405 void initialize (void)
407 memset(m_pDirect
, STORE_PAGE_NULL
, sizeof(m_pDirect
));
408 memset(m_pSingle
, STORE_PAGE_NULL
, sizeof(m_pSingle
));
409 memset(m_pDouble
, STORE_PAGE_NULL
, sizeof(m_pDouble
));
410 memset(m_pTriple
, STORE_PAGE_NULL
, sizeof(m_pTriple
));
425 sal_uInt32 m_nDataLen
;
429 static const size_t theSize
= sizeof(G
) + sizeof(LinkTable
) + sizeof(sal_uInt32
);
433 void initialize (void)
436 m_aTable
.initialize();
442 OStoreDirectoryDataBlock (void)
443 : m_aGuard(), m_aTable(), m_nDataLen (0)
446 /** guard (external representation).
450 sal_uInt32 nCRC32
= 0;
451 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
452 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
453 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
456 /** verify (external representation).
458 storeError
verify() const
460 sal_uInt32 nCRC32
= 0;
461 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
462 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
463 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
464 return store_E_InvalidChecksum
;
471 static sal_uInt16
directCount (void)
473 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DIRECT
));
475 sal_uInt32
directLink (sal_uInt16 nIndex
) const
477 if (nIndex
< directCount())
478 return store::ntohl(m_aTable
.m_pDirect
[nIndex
]);
480 return STORE_PAGE_NULL
;
482 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
484 if (nIndex
< directCount())
485 m_aTable
.m_pDirect
[nIndex
] = store::htonl(nAddr
);
490 static sal_uInt16
singleCount (void)
492 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_SINGLE
));
494 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
496 if (nIndex
< singleCount())
497 return store::ntohl(m_aTable
.m_pSingle
[nIndex
]);
499 return STORE_PAGE_NULL
;
501 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
503 if (nIndex
< singleCount())
504 m_aTable
.m_pSingle
[nIndex
] = store::htonl(nAddr
);
509 static sal_uInt16
doubleCount (void)
511 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DOUBLE
));
513 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
515 if (nIndex
< doubleCount())
516 return store::ntohl(m_aTable
.m_pDouble
[nIndex
]);
518 return STORE_PAGE_NULL
;
520 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
522 if (nIndex
< doubleCount())
523 m_aTable
.m_pDouble
[nIndex
] = store::htonl(nAddr
);
528 static sal_uInt16
tripleCount (void)
530 return ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_TRIPLE
));
532 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
534 if (nIndex
< tripleCount())
535 return store::ntohl(m_aTable
.m_pTriple
[nIndex
]);
537 return STORE_PAGE_NULL
;
539 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
541 if (nIndex
< tripleCount())
542 m_aTable
.m_pTriple
[nIndex
] = store::htonl(nAddr
);
546 /*========================================================================
548 * OStoreDirectoryPageData.
550 *======================================================================*/
551 #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
553 struct OStoreDirectoryPageData
: public store::OStorePageData
555 typedef OStorePageData base
;
556 typedef OStoreDirectoryPageData self
;
558 typedef OStorePageDescriptor D
;
559 typedef OStorePageNameBlock NameBlock
;
560 typedef OStoreDirectoryDataBlock DataBlock
;
564 NameBlock m_aNameBlock
;
565 DataBlock m_aDataBlock
;
566 sal_uInt8 m_pData
[1];
570 static const sal_uInt32 theTypeId
= STORE_MAGIC_DIRECTORYPAGE
;
574 static const size_t theSize
= NameBlock::theSize
+ DataBlock::theSize
;
575 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
576 BOOST_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
580 sal_uInt16
capacity() const
582 return (store::ntohs(base::m_aDescr
.m_nSize
) - self::thePageSize
);
587 sal_uInt16
usage() const
589 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
594 void initialize (void)
596 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
597 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
599 m_aNameBlock
.initialize();
600 m_aDataBlock
.initialize();
602 memset (m_pData
, 0, capacity());
607 explicit OStoreDirectoryPageData (sal_uInt16 nPageSize
)
608 : base (nPageSize
), m_aNameBlock(), m_aDataBlock()
610 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
611 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
612 memset (m_pData
, 0, capacity());
615 /** guard (external representation).
619 m_aNameBlock
.guard();
620 m_aDataBlock
.guard();
623 /** verify (external representation).
625 storeError
verify() const
627 storeError eErrCode
= m_aNameBlock
.verify();
628 if (eErrCode
== store_E_None
)
629 eErrCode
= m_aDataBlock
.verify();
635 struct ChunkDescriptor
640 sal_uInt16 m_nOffset
;
641 sal_uInt16 m_nLength
;
645 ChunkDescriptor (sal_uInt32 nPosition
, sal_uInt16 nCapacity
)
647 m_nPage
= nPosition
/ nCapacity
;
648 m_nOffset
= (sal_uInt16
)((nPosition
% nCapacity
) & 0xffff);
649 m_nLength
= nCapacity
- m_nOffset
;
667 /** scope (internal).
669 ChunkScope
scope (sal_uInt32 nPosition
) const
671 sal_uInt32 nCapacity
= capacity();
672 if (nPosition
< nCapacity
)
673 return SCOPE_INTERNAL
;
675 return SCOPE_EXTERNAL
;
679 /*========================================================================
681 * OStoreDirectoryPageObject.
683 *======================================================================*/
684 class OStoreDirectoryPageObject
: public store::OStorePageObject
686 typedef OStorePageObject base
;
687 typedef OStoreDirectoryPageData page
;
688 typedef OStoreIndirectionPageData indirect
;
690 typedef OStorePageDescriptor D
;
695 explicit OStoreDirectoryPageObject (PageHolder
const & rxPage
= PageHolder())
696 : OStorePageObject (rxPage
)
699 /** External representation.
701 virtual storeError
guard (sal_uInt32 nAddr
);
702 virtual storeError
verify (sal_uInt32 nAddr
) const;
706 sal_uInt32
attrib (void) const
708 return store::ntohl(PAGE().m_aNameBlock
.m_nAttrib
);
710 void attrib (sal_uInt32 nAttrib
)
712 PAGE().m_aNameBlock
.m_nAttrib
= store::htonl(nAttrib
);
718 OStorePageKey
key (void) const
720 return PAGE().m_aNameBlock
.m_aKey
;
722 void key (OStorePageKey
const & rKey
)
724 PAGE().m_aNameBlock
.m_aKey
= rKey
;
730 sal_uInt32
path (void) const
732 page
const & rPage
= PAGE();
733 const sal_Char
* pszName
= rPage
.m_aNameBlock
.m_pData
;
734 sal_uInt32 nPath
= store::ntohl(rPage
.m_aNameBlock
.m_aKey
.m_nHigh
);
735 return rtl_crc32 (nPath
, pszName
, rtl_str_getLength(pszName
));
738 sal_Size
getName (sal_Char
* pBuffer
, sal_Size nBufsize
) const
740 sal_Char
const * pszName
= PAGE().m_aNameBlock
.m_pData
;
741 sal_Size nLength
= rtl_str_getLength(pszName
);
742 memcpy (pBuffer
, pszName
, nLength
< nBufsize
? nLength
: nBufsize
);
748 sal_uInt32
dataLength (void) const
750 return store::ntohl(PAGE().m_aDataBlock
.m_nDataLen
);
752 void dataLength (sal_uInt32 nLength
)
754 PAGE().m_aDataBlock
.m_nDataLen
= store::htonl(nLength
);
760 sal_uInt32
directLink (sal_uInt16 nIndex
) const
762 return PAGE().m_aDataBlock
.directLink (nIndex
);
764 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
766 PAGE().m_aDataBlock
.directLink (nIndex
, nAddr
);
772 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
774 return PAGE().m_aDataBlock
.singleLink (nIndex
);
776 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
778 PAGE().m_aDataBlock
.singleLink (nIndex
, nAddr
);
784 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
786 return PAGE().m_aDataBlock
.doubleLink (nIndex
);
788 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
790 PAGE().m_aDataBlock
.doubleLink (nIndex
, nAddr
);
796 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
798 return PAGE().m_aDataBlock
.tripleLink (nIndex
);
800 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
802 PAGE().m_aDataBlock
.tripleLink (nIndex
, nAddr
);
806 /** read (external data page).
810 OStoreDataPageObject
&rData
,
811 OStorePageBIOS
&rBIOS
);
813 /** write (external data page).
817 OStoreDataPageObject
&rData
,
818 OStorePageBIOS
&rBIOS
);
820 /** truncate (external data page).
822 storeError
truncate (
824 OStorePageBIOS
&rBIOS
);
831 page
* pImpl
= static_cast<page
*>(m_xPage
.get());
832 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
835 page
const & PAGE() const
837 page
const * pImpl
= static_cast<page
const *>(m_xPage
.get());
838 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
842 /** scope (external data page; private).
844 page::ChunkScope
scope (
846 page::DataBlock::LinkDescriptor
&rDescr
) const;
848 /** truncate (external data page scope; private).
850 storeError
truncate (
851 page::ChunkScope eScope
,
853 OStorePageBIOS
&rBIOS
);
856 /*========================================================================
860 *======================================================================*/
864 #endif /* !_STORE_STORDATA_HXX_ */
866 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */