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 INCLUDED_STORE_SOURCE_STORDATA_HXX
21 #define INCLUDED_STORE_SOURCE_STORDATA_HXX
23 #include "sal/config.h"
25 #include "sal/types.h"
26 #include "sal/macros.h"
28 #include "store/types.h"
29 #include "storbase.hxx"
34 /*========================================================================
38 *======================================================================*/
39 #define STORE_MAGIC_DATAPAGE sal_uInt32(0x94190310)
41 struct OStoreDataPageData
: public store::OStorePageData
43 typedef OStorePageData base
;
44 typedef OStoreDataPageData self
;
46 typedef OStorePageDescriptor D
;
54 static const sal_uInt32 theTypeId
= STORE_MAGIC_DATAPAGE
;
58 static const size_t theSize
= 0;
59 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
60 static_assert(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
, "got to be at least equal in size");
64 static sal_uInt16
capacity (const D
& rDescr
) // @see inode::ChunkDescriptor
66 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
68 sal_uInt16
capacity() const
70 return self::capacity (base::m_aDescr
);
75 sal_uInt16
usage() const
77 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
82 explicit OStoreDataPageData (sal_uInt16 nPageSize
= self::thePageSize
)
85 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
86 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
87 if (capacity()) memset (m_pData
, 0, capacity());
90 /** guard (external representation).
92 void guard() { (void) this; /* loplugin:staticmethods */ }
94 /** verify (external representation).
96 storeError
verify() const {
97 (void) this; // loplugin:staticmethods
102 /*========================================================================
104 * OStoreDataPageObject.
106 *======================================================================*/
107 class OStoreDataPageObject
: public store::OStorePageObject
109 typedef OStorePageObject base
;
110 typedef OStoreDataPageData page
;
115 explicit OStoreDataPageObject (PageHolder
const & rxPage
= PageHolder())
116 : OStorePageObject (rxPage
)
119 /** External representation.
121 virtual storeError
guard (sal_uInt32 nAddr
) SAL_OVERRIDE
;
122 virtual storeError
verify (sal_uInt32 nAddr
) const SAL_OVERRIDE
;
125 /*========================================================================
127 * OStoreIndirectionPageData.
129 *======================================================================*/
130 #define STORE_MAGIC_INDIRECTPAGE sal_uInt32(0x89191107)
132 struct OStoreIndirectionPageData
: public store::OStorePageData
134 typedef OStorePageData base
;
135 typedef OStoreIndirectionPageData self
;
137 typedef OStorePageGuard G
;
138 typedef OStorePageDescriptor D
;
143 sal_uInt32 m_pData
[1];
147 static const sal_uInt32 theTypeId
= STORE_MAGIC_INDIRECTPAGE
;
151 static const size_t theSize
= sizeof(G
);
152 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
153 static_assert(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
, "got to be at least equal in size");
157 static sal_uInt16
capacity (const D
& rDescr
)
159 return (store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
161 sal_uInt16
capacity() const
163 return self::capacity (base::m_aDescr
);
168 static sal_uInt16
capacityCount (const D
& rDescr
) // @see DirectoryPageObject::scope()
170 return sal_uInt16(capacity(rDescr
) / sizeof(sal_uInt32
));
172 sal_uInt16
capacityCount() const
174 return sal_uInt16(capacity() / sizeof(sal_uInt32
));
179 explicit OStoreIndirectionPageData (sal_uInt16 nPageSize
)
182 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
183 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
184 self::m_aGuard
.m_nMagic
= store::htonl(0);
185 memset (m_pData
, STORE_PAGE_NULL
, capacity());
188 /** guard (external representation).
192 sal_uInt32 nCRC32
= 0;
193 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
194 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
195 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
198 /** verify (external representation).
200 storeError
verify() const
202 sal_uInt32 nCRC32
= 0;
203 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
204 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
205 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
206 return store_E_InvalidChecksum
;
212 /*========================================================================
214 * OStoreIndirectionPageObject.
216 *======================================================================*/
217 class OStoreIndirectionPageObject
: public store::OStorePageObject
219 typedef OStorePageObject base
;
220 typedef OStoreIndirectionPageData page
;
225 explicit OStoreIndirectionPageObject (PageHolder
const & rxPage
= PageHolder())
226 : OStorePageObject (rxPage
)
229 /** External representation.
231 storeError
loadOrCreate (
233 OStorePageBIOS
& rBIOS
);
235 virtual storeError
guard (sal_uInt32 nAddr
) SAL_OVERRIDE
;
236 virtual storeError
verify (sal_uInt32 nAddr
) const SAL_OVERRIDE
;
238 /** read (indirect data page).
242 OStoreDataPageObject
&rData
,
243 OStorePageBIOS
&rBIOS
);
248 OStoreDataPageObject
&rData
,
249 OStorePageBIOS
&rBIOS
);
255 OStoreDataPageObject
&rData
,
256 OStorePageBIOS
&rBIOS
);
258 /** write (indirect data page).
262 OStoreDataPageObject
&rData
,
263 OStorePageBIOS
&rBIOS
);
268 OStoreDataPageObject
&rData
,
269 OStorePageBIOS
&rBIOS
);
275 OStoreDataPageObject
&rData
,
276 OStorePageBIOS
&rBIOS
);
278 /** truncate (indirect data page).
280 storeError
truncate (
282 OStorePageBIOS
&rBIOS
);
284 storeError
truncate (
287 OStorePageBIOS
&rBIOS
);
289 storeError
truncate (
293 OStorePageBIOS
&rBIOS
);
296 /*========================================================================
298 * OStorePageNameBlock.
300 *======================================================================*/
301 struct OStorePageNameBlock
303 typedef OStorePageGuard G
;
304 typedef OStorePageKey K
;
310 sal_uInt32 m_nAttrib
;
311 sal_Char m_pData
[STORE_MAXIMUM_NAMESIZE
];
315 static const size_t theSize
= sizeof(G
) + sizeof(K
) + sizeof(sal_uInt32
) + sizeof(sal_Char
[STORE_MAXIMUM_NAMESIZE
]);
324 memset (m_pData
, 0, sizeof(m_pData
));
329 OStorePageNameBlock()
330 : m_aGuard(), m_aKey(), m_nAttrib (0)
332 memset (m_pData
, 0, sizeof(m_pData
));
335 /** guard (external representation).
339 sal_uInt32 nCRC32
= 0;
340 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
341 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
342 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
345 /** verify (external representation).
347 storeError
verify() const
349 sal_uInt32 nCRC32
= 0;
350 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
351 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, theSize
- sizeof(G
));
352 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
353 return store_E_InvalidChecksum
;
359 /*========================================================================
361 * OStoreDirectoryDataBlock.
363 *======================================================================*/
364 #define STORE_LIMIT_DATAPAGE_DIRECT 16
365 #define STORE_LIMIT_DATAPAGE_SINGLE 8
366 #define STORE_LIMIT_DATAPAGE_DOUBLE 1
367 #define STORE_LIMIT_DATAPAGE_TRIPLE 1
369 struct OStoreDirectoryDataBlock
371 typedef OStorePageGuard G
;
375 struct LinkDescriptor
379 sal_uInt16 m_nIndex0
;
380 sal_uInt16 m_nIndex1
;
381 sal_uInt16 m_nIndex2
;
382 sal_uInt16 m_nIndex3
;
387 : m_nIndex0 ((sal_uInt16
)(~0)),
388 m_nIndex1 ((sal_uInt16
)(~0)),
389 m_nIndex2 ((sal_uInt16
)(~0)),
390 m_nIndex3 ((sal_uInt16
)(~0))
400 sal_uInt32 m_pDirect
[STORE_LIMIT_DATAPAGE_DIRECT
];
401 sal_uInt32 m_pSingle
[STORE_LIMIT_DATAPAGE_SINGLE
];
402 sal_uInt32 m_pDouble
[STORE_LIMIT_DATAPAGE_DOUBLE
];
403 sal_uInt32 m_pTriple
[STORE_LIMIT_DATAPAGE_TRIPLE
];
409 memset(m_pDirect
, STORE_PAGE_NULL
, sizeof(m_pDirect
));
410 memset(m_pSingle
, STORE_PAGE_NULL
, sizeof(m_pSingle
));
411 memset(m_pDouble
, STORE_PAGE_NULL
, sizeof(m_pDouble
));
412 memset(m_pTriple
, STORE_PAGE_NULL
, sizeof(m_pTriple
));
427 sal_uInt32 m_nDataLen
;
431 static const size_t theSize
= sizeof(G
) + sizeof(LinkTable
) + sizeof(sal_uInt32
);
438 m_aTable
.initialize();
444 OStoreDirectoryDataBlock()
445 : m_aGuard(), m_aTable(), m_nDataLen (0)
448 /** guard (external representation).
452 sal_uInt32 nCRC32
= 0;
453 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
454 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
455 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
458 /** verify (external representation).
460 storeError
verify() const
462 sal_uInt32 nCRC32
= 0;
463 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
464 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, theSize
- sizeof(G
));
465 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
466 return store_E_InvalidChecksum
;
473 static const sal_uInt16 directCount
= ((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 const sal_uInt16 singleCount
= ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_SINGLE
));
492 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
494 if (nIndex
< singleCount
)
495 return store::ntohl(m_aTable
.m_pSingle
[nIndex
]);
497 return STORE_PAGE_NULL
;
499 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
501 if (nIndex
< singleCount
)
502 m_aTable
.m_pSingle
[nIndex
] = store::htonl(nAddr
);
507 static const sal_uInt16 doubleCount
= ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_DOUBLE
));
509 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
511 if (nIndex
< doubleCount
)
512 return store::ntohl(m_aTable
.m_pDouble
[nIndex
]);
514 return STORE_PAGE_NULL
;
516 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
518 if (nIndex
< doubleCount
)
519 m_aTable
.m_pDouble
[nIndex
] = store::htonl(nAddr
);
524 static const sal_uInt16 tripleCount
= ((sal_uInt16
)(STORE_LIMIT_DATAPAGE_TRIPLE
));
526 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
528 if (nIndex
< tripleCount
)
529 return store::ntohl(m_aTable
.m_pTriple
[nIndex
]);
531 return STORE_PAGE_NULL
;
533 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
535 if (nIndex
< tripleCount
)
536 m_aTable
.m_pTriple
[nIndex
] = store::htonl(nAddr
);
540 /*========================================================================
542 * OStoreDirectoryPageData.
544 *======================================================================*/
545 #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
547 struct OStoreDirectoryPageData
: public store::OStorePageData
549 typedef OStorePageData base
;
550 typedef OStoreDirectoryPageData self
;
552 typedef OStorePageDescriptor D
;
553 typedef OStorePageNameBlock NameBlock
;
554 typedef OStoreDirectoryDataBlock DataBlock
;
558 NameBlock m_aNameBlock
;
559 DataBlock m_aDataBlock
;
560 sal_uInt8 m_pData
[1];
564 static const sal_uInt32 theTypeId
= STORE_MAGIC_DIRECTORYPAGE
;
568 static const size_t theSize
= NameBlock::theSize
+ DataBlock::theSize
;
569 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
570 static_assert(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
, "got to be at least equal in size");
574 sal_uInt16
capacity() const
576 return (store::ntohs(base::m_aDescr
.m_nSize
) - self::thePageSize
);
581 sal_uInt16
usage() const
583 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
590 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
591 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
593 m_aNameBlock
.initialize();
594 m_aDataBlock
.initialize();
596 memset (m_pData
, 0, capacity());
601 explicit OStoreDirectoryPageData (sal_uInt16 nPageSize
)
602 : base (nPageSize
), m_aNameBlock(), m_aDataBlock()
604 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
605 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
606 memset (m_pData
, 0, capacity());
609 /** guard (external representation).
613 m_aNameBlock
.guard();
614 m_aDataBlock
.guard();
617 /** verify (external representation).
619 storeError
verify() const
621 storeError eErrCode
= m_aNameBlock
.verify();
622 if (eErrCode
== store_E_None
)
623 eErrCode
= m_aDataBlock
.verify();
629 struct ChunkDescriptor
634 sal_uInt16 m_nOffset
;
635 sal_uInt16 m_nLength
;
639 ChunkDescriptor (sal_uInt32 nPosition
, sal_uInt16 nCapacity
)
641 m_nPage
= nPosition
/ nCapacity
;
642 m_nOffset
= (sal_uInt16
)((nPosition
% nCapacity
) & 0xffff);
643 m_nLength
= nCapacity
- m_nOffset
;
661 /** scope (internal).
663 ChunkScope
scope (sal_uInt32 nPosition
) const
665 sal_uInt32 nCapacity
= capacity();
666 if (nPosition
< nCapacity
)
667 return SCOPE_INTERNAL
;
669 return SCOPE_EXTERNAL
;
673 /*========================================================================
675 * OStoreDirectoryPageObject.
677 *======================================================================*/
678 class OStoreDirectoryPageObject
: public store::OStorePageObject
680 typedef OStorePageObject base
;
681 typedef OStoreDirectoryPageData page
;
682 typedef OStoreIndirectionPageData indirect
;
684 typedef OStorePageDescriptor D
;
689 explicit OStoreDirectoryPageObject (PageHolder
const & rxPage
= PageHolder())
690 : OStorePageObject (rxPage
)
693 /** External representation.
695 virtual storeError
guard (sal_uInt32 nAddr
) SAL_OVERRIDE
;
696 virtual storeError
verify (sal_uInt32 nAddr
) const SAL_OVERRIDE
;
700 sal_uInt32
attrib() const
702 return store::ntohl(PAGE().m_aNameBlock
.m_nAttrib
);
704 void attrib (sal_uInt32 nAttrib
)
706 PAGE().m_aNameBlock
.m_nAttrib
= store::htonl(nAttrib
);
712 OStorePageKey
key() const
714 return PAGE().m_aNameBlock
.m_aKey
;
716 void key (OStorePageKey
const & rKey
)
718 PAGE().m_aNameBlock
.m_aKey
= rKey
;
724 sal_uInt32
path() const
726 page
const & rPage
= PAGE();
727 const sal_Char
* pszName
= rPage
.m_aNameBlock
.m_pData
;
728 sal_uInt32 nPath
= store::ntohl(rPage
.m_aNameBlock
.m_aKey
.m_nHigh
);
729 return rtl_crc32 (nPath
, pszName
, rtl_str_getLength(pszName
));
732 sal_Size
getName (sal_Char
* pBuffer
, sal_Size nBufsize
) const
734 sal_Char
const * pszName
= PAGE().m_aNameBlock
.m_pData
;
735 sal_Size nLength
= rtl_str_getLength(pszName
);
736 memcpy (pBuffer
, pszName
, nLength
< nBufsize
? nLength
: nBufsize
);
742 sal_uInt32
dataLength() const
744 return store::ntohl(PAGE().m_aDataBlock
.m_nDataLen
);
746 void dataLength (sal_uInt32 nLength
)
748 PAGE().m_aDataBlock
.m_nDataLen
= store::htonl(nLength
);
754 sal_uInt32
directLink (sal_uInt16 nIndex
) const
756 return PAGE().m_aDataBlock
.directLink (nIndex
);
758 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
760 PAGE().m_aDataBlock
.directLink (nIndex
, nAddr
);
766 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
768 return PAGE().m_aDataBlock
.singleLink (nIndex
);
770 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
772 PAGE().m_aDataBlock
.singleLink (nIndex
, nAddr
);
778 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
780 return PAGE().m_aDataBlock
.doubleLink (nIndex
);
782 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
784 PAGE().m_aDataBlock
.doubleLink (nIndex
, nAddr
);
790 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
792 return PAGE().m_aDataBlock
.tripleLink (nIndex
);
794 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
796 PAGE().m_aDataBlock
.tripleLink (nIndex
, nAddr
);
800 /** read (external data page).
804 OStoreDataPageObject
&rData
,
805 OStorePageBIOS
&rBIOS
);
807 /** write (external data page).
811 OStoreDataPageObject
&rData
,
812 OStorePageBIOS
&rBIOS
);
814 /** truncate (external data page).
816 storeError
truncate (
818 OStorePageBIOS
&rBIOS
);
825 page
* pImpl
= static_cast<page
*>(m_xPage
.get());
826 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
829 page
const & PAGE() const
831 page
const * pImpl
= static_cast<page
const *>(m_xPage
.get());
832 OSL_PRECOND(pImpl
!= 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
836 /** scope (external data page; private).
838 page::ChunkScope
scope (
840 page::DataBlock::LinkDescriptor
&rDescr
) const;
842 /** truncate (external data page scope; private).
844 storeError
truncate (
845 page::ChunkScope eScope
,
847 OStorePageBIOS
&rBIOS
);
850 /*========================================================================
854 *======================================================================*/
858 #endif // INCLUDED_STORE_SOURCE_STORDATA_HXX
860 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */