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>
27 #include <sal/types.h>
28 #include <rtl/string.h>
30 #include <store/types.h>
31 #include "storbase.hxx"
39 constexpr sal_uInt32
STORE_MAGIC_DATAPAGE(0x94190310);
41 struct OStoreDataPageData
: public store::PageData
43 typedef PageData 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 static_cast<sal_uInt16
>(store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
68 sal_uInt16
capacity() const
70 return self::capacity (base::m_aDescr
);
75 explicit OStoreDataPageData (sal_uInt16 nPageSize
)
78 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
79 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
80 if (capacity()) memset (m_pData
, 0, capacity());
83 /** guard (external representation).
85 void guard() const { (void) this; /* loplugin:staticmethods */ }
87 /** verify (external representation).
89 storeError
verify() const {
90 (void) this; // loplugin:staticmethods
95 class OStoreDataPageObject
: public store::OStorePageObject
97 typedef OStorePageObject base
;
98 typedef OStoreDataPageData page
;
103 explicit OStoreDataPageObject (std::shared_ptr
<PageData
> const & rxPage
= std::shared_ptr
<PageData
>())
104 : OStorePageObject (rxPage
)
107 /** External representation.
109 virtual storeError
guard (sal_uInt32 nAddr
) override
;
110 virtual storeError
verify (sal_uInt32 nAddr
) const override
;
113 constexpr sal_uInt32
STORE_MAGIC_INDIRECTPAGE(0x89191107);
115 struct OStoreIndirectionPageData
: public store::PageData
117 typedef PageData base
;
118 typedef OStoreIndirectionPageData self
;
120 typedef OStorePageGuard G
;
121 typedef OStorePageDescriptor D
;
126 sal_uInt32 m_pData
[1];
130 static const sal_uInt32 theTypeId
= STORE_MAGIC_INDIRECTPAGE
;
134 static const size_t theSize
= sizeof(G
);
135 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
136 static_assert(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
, "got to be at least equal in size");
140 static sal_uInt16
capacity (const D
& rDescr
)
142 return static_cast<sal_uInt16
>(store::ntohs(rDescr
.m_nSize
) - self::thePageSize
);
144 sal_uInt16
capacity() const
146 return self::capacity (base::m_aDescr
);
151 static sal_uInt16
capacityCount (const D
& rDescr
) // @see DirectoryPageObject::scope()
153 return sal_uInt16(capacity(rDescr
) / sizeof(sal_uInt32
));
155 sal_uInt16
capacityCount() const
157 return sal_uInt16(capacity() / sizeof(sal_uInt32
));
162 explicit OStoreIndirectionPageData (sal_uInt16 nPageSize
)
165 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
166 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
167 self::m_aGuard
.m_nMagic
= store::htonl(0);
168 memset (m_pData
, STORE_PAGE_NULL
, capacity());
171 /** guard (external representation).
175 sal_uInt32 nCRC32
= rtl_crc32 (0, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
176 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
177 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
180 /** verify (external representation).
182 storeError
verify() const
184 sal_uInt32 nCRC32
= rtl_crc32 (0, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
185 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
186 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
187 return store_E_InvalidChecksum
;
193 class OStoreIndirectionPageObject
: public store::OStorePageObject
195 typedef OStorePageObject base
;
196 typedef OStoreIndirectionPageData page
;
201 explicit OStoreIndirectionPageObject (std::shared_ptr
<PageData
> const & rxPage
= std::shared_ptr
<PageData
>())
202 : OStorePageObject (rxPage
)
205 /** External representation.
207 storeError
loadOrCreate (
209 OStorePageBIOS
& rBIOS
);
211 virtual storeError
guard (sal_uInt32 nAddr
) override
;
212 virtual storeError
verify (sal_uInt32 nAddr
) const override
;
214 /** read (indirect data page).
218 OStoreDataPageObject
&rData
,
219 OStorePageBIOS
&rBIOS
) const;
224 OStoreDataPageObject
&rData
,
225 OStorePageBIOS
&rBIOS
) const;
231 OStoreDataPageObject
&rData
,
232 OStorePageBIOS
&rBIOS
) const;
234 /** write (indirect data page).
238 OStoreDataPageObject
&rData
,
239 OStorePageBIOS
&rBIOS
);
244 OStoreDataPageObject
&rData
,
245 OStorePageBIOS
&rBIOS
);
251 OStoreDataPageObject
&rData
,
252 OStorePageBIOS
&rBIOS
);
254 /** truncate (indirect data page).
256 storeError
truncate (
258 OStorePageBIOS
&rBIOS
);
260 storeError
truncate (
263 OStorePageBIOS
&rBIOS
);
265 storeError
truncate (
269 OStorePageBIOS
&rBIOS
);
272 struct OStorePageNameBlock
274 typedef OStorePageGuard G
;
275 typedef OStorePageKey K
;
281 sal_uInt32 m_nAttrib
= 0;
282 char m_pData
[STORE_MAXIMUM_NAMESIZE
] = {};
286 static const size_t theSize
= sizeof(G
) + sizeof(K
) + sizeof(sal_uInt32
) + sizeof(char[STORE_MAXIMUM_NAMESIZE
]);
290 OStorePageNameBlock() = default;
292 /** guard (external representation).
296 sal_uInt32 nCRC32
= rtl_crc32 (0, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
297 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, static_cast<sal_uInt32
>(theSize
- sizeof(G
)));
298 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
301 /** verify (external representation).
303 storeError
verify() const
305 sal_uInt32 nCRC32
= rtl_crc32 (0, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
306 nCRC32
= rtl_crc32 (nCRC32
, &m_aKey
, static_cast<sal_uInt32
>(theSize
- sizeof(G
)));
307 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
308 return store_E_InvalidChecksum
;
314 #define STORE_LIMIT_DATAPAGE_DIRECT 16
315 #define STORE_LIMIT_DATAPAGE_SINGLE 8
316 #define STORE_LIMIT_DATAPAGE_DOUBLE 1
317 #define STORE_LIMIT_DATAPAGE_TRIPLE 1
319 struct OStoreDirectoryDataBlock
321 typedef OStorePageGuard G
;
325 struct LinkDescriptor
329 sal_uInt16 m_nIndex0
;
330 sal_uInt16 m_nIndex1
;
331 sal_uInt16 m_nIndex2
;
332 sal_uInt16 m_nIndex3
;
337 : m_nIndex0 (sal_uInt16(~0)),
338 m_nIndex1 (sal_uInt16(~0)),
339 m_nIndex2 (sal_uInt16(~0)),
340 m_nIndex3 (sal_uInt16(~0))
350 sal_uInt32 m_pDirect
[STORE_LIMIT_DATAPAGE_DIRECT
];
351 sal_uInt32 m_pSingle
[STORE_LIMIT_DATAPAGE_SINGLE
];
352 sal_uInt32 m_pDouble
[STORE_LIMIT_DATAPAGE_DOUBLE
];
353 sal_uInt32 m_pTriple
[STORE_LIMIT_DATAPAGE_TRIPLE
];
359 memset(m_pDirect
, STORE_PAGE_NULL
, sizeof(m_pDirect
));
360 memset(m_pSingle
, STORE_PAGE_NULL
, sizeof(m_pSingle
));
361 memset(m_pDouble
, STORE_PAGE_NULL
, sizeof(m_pDouble
));
362 memset(m_pTriple
, STORE_PAGE_NULL
, sizeof(m_pTriple
));
377 sal_uInt32 m_nDataLen
;
381 static const size_t theSize
= sizeof(G
) + sizeof(LinkTable
) + sizeof(sal_uInt32
);
385 OStoreDirectoryDataBlock()
386 : m_aGuard(), m_aTable(), m_nDataLen (0)
389 /** guard (external representation).
393 sal_uInt32 nCRC32
= rtl_crc32 (0, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
394 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, static_cast<sal_uInt32
>(theSize
- sizeof(G
)));
395 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
398 /** verify (external representation).
400 storeError
verify() const
402 sal_uInt32 nCRC32
= rtl_crc32 (0, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
403 nCRC32
= rtl_crc32 (nCRC32
, &m_aTable
, static_cast<sal_uInt32
>(theSize
- sizeof(G
)));
404 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
405 return store_E_InvalidChecksum
;
412 static const sal_uInt16 directCount
= sal_uInt16(STORE_LIMIT_DATAPAGE_DIRECT
);
414 sal_uInt32
directLink (sal_uInt16 nIndex
) const
416 if (nIndex
< directCount
)
417 return store::ntohl(m_aTable
.m_pDirect
[nIndex
]);
419 return STORE_PAGE_NULL
;
421 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
423 if (nIndex
< directCount
)
424 m_aTable
.m_pDirect
[nIndex
] = store::htonl(nAddr
);
429 static const sal_uInt16 singleCount
= sal_uInt16(STORE_LIMIT_DATAPAGE_SINGLE
);
431 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
433 if (nIndex
< singleCount
)
434 return store::ntohl(m_aTable
.m_pSingle
[nIndex
]);
436 return STORE_PAGE_NULL
;
438 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
440 if (nIndex
< singleCount
)
441 m_aTable
.m_pSingle
[nIndex
] = store::htonl(nAddr
);
446 static const sal_uInt16 doubleCount
= sal_uInt16(STORE_LIMIT_DATAPAGE_DOUBLE
);
448 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
450 if (nIndex
< doubleCount
)
451 return store::ntohl(m_aTable
.m_pDouble
[nIndex
]);
453 return STORE_PAGE_NULL
;
455 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
457 if (nIndex
< doubleCount
)
458 m_aTable
.m_pDouble
[nIndex
] = store::htonl(nAddr
);
463 static const sal_uInt16 tripleCount
= sal_uInt16(STORE_LIMIT_DATAPAGE_TRIPLE
);
465 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
467 if (nIndex
< tripleCount
)
468 return store::ntohl(m_aTable
.m_pTriple
[nIndex
]);
470 return STORE_PAGE_NULL
;
472 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
474 if (nIndex
< tripleCount
)
475 m_aTable
.m_pTriple
[nIndex
] = store::htonl(nAddr
);
479 #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
481 struct OStoreDirectoryPageData
: public store::PageData
483 typedef PageData base
;
484 typedef OStoreDirectoryPageData self
;
486 typedef OStorePageDescriptor D
;
487 typedef OStorePageNameBlock NameBlock
;
488 typedef OStoreDirectoryDataBlock DataBlock
;
492 NameBlock m_aNameBlock
;
493 DataBlock m_aDataBlock
;
494 sal_uInt8 m_pData
[1];
498 static const sal_uInt32 theTypeId
= STORE_MAGIC_DIRECTORYPAGE
;
502 static const size_t theSize
= NameBlock::theSize
+ DataBlock::theSize
;
503 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
504 static_assert(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
, "got to be at least equal in size");
508 sal_uInt16
capacity() const
510 return static_cast<sal_uInt16
>(store::ntohs(base::m_aDescr
.m_nSize
) - self::thePageSize
);
515 explicit OStoreDirectoryPageData (sal_uInt16 nPageSize
)
516 : base (nPageSize
), m_aNameBlock(), m_aDataBlock()
518 base::m_aGuard
.m_nMagic
= store::htonl(self::theTypeId
);
519 base::m_aDescr
.m_nUsed
= store::htons(self::thePageSize
);
520 memset (m_pData
, 0, capacity());
523 /** guard (external representation).
527 m_aNameBlock
.guard();
528 m_aDataBlock
.guard();
531 /** verify (external representation).
533 storeError
verify() const
535 storeError eErrCode
= m_aNameBlock
.verify();
536 if (eErrCode
== store_E_None
)
537 eErrCode
= m_aDataBlock
.verify();
543 struct ChunkDescriptor
548 sal_uInt16 m_nOffset
;
549 sal_uInt16 m_nLength
;
553 ChunkDescriptor (sal_uInt32 nPosition
, sal_uInt16 nCapacity
)
554 : m_nPage(nPosition
/ nCapacity
),
555 m_nOffset(static_cast<sal_uInt16
>((nPosition
% nCapacity
) & 0xffff)),
556 m_nLength(nCapacity
- m_nOffset
)
575 /** scope (internal).
577 ChunkScope
scope (sal_uInt32 nPosition
) const
579 sal_uInt32 nCapacity
= capacity();
580 if (nPosition
< nCapacity
)
581 return SCOPE_INTERNAL
;
583 return SCOPE_EXTERNAL
;
587 class OStoreDirectoryPageObject
: public store::OStorePageObject
589 typedef OStorePageObject base
;
590 typedef OStoreDirectoryPageData page
;
591 typedef OStoreIndirectionPageData indirect
;
593 typedef OStorePageDescriptor D
;
598 explicit OStoreDirectoryPageObject (std::shared_ptr
<PageData
> const & rxPage
= std::shared_ptr
<PageData
>())
599 : OStorePageObject (rxPage
)
602 /** External representation.
604 virtual storeError
guard (sal_uInt32 nAddr
) override
;
605 virtual storeError
verify (sal_uInt32 nAddr
) const override
;
609 sal_uInt32
attrib() const
611 return store::ntohl(PAGE().m_aNameBlock
.m_nAttrib
);
613 void attrib (sal_uInt32 nAttrib
)
615 PAGE().m_aNameBlock
.m_nAttrib
= store::htonl(nAttrib
);
621 void key (OStorePageKey
const & rKey
)
623 PAGE().m_aNameBlock
.m_aKey
= rKey
;
629 sal_uInt32
path() const
631 page
const & rPage
= PAGE();
632 const char * pszName
= rPage
.m_aNameBlock
.m_pData
;
633 sal_uInt32 nPath
= store::ntohl(rPage
.m_aNameBlock
.m_aKey
.m_nHigh
);
634 return rtl_crc32 (nPath
, pszName
, rtl_str_getLength(pszName
));
639 sal_uInt32
dataLength() const
641 return store::ntohl(PAGE().m_aDataBlock
.m_nDataLen
);
643 void dataLength (sal_uInt32 nLength
)
645 PAGE().m_aDataBlock
.m_nDataLen
= store::htonl(nLength
);
651 sal_uInt32
directLink (sal_uInt16 nIndex
) const
653 return PAGE().m_aDataBlock
.directLink (nIndex
);
655 void directLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
657 PAGE().m_aDataBlock
.directLink (nIndex
, nAddr
);
663 sal_uInt32
singleLink (sal_uInt16 nIndex
) const
665 return PAGE().m_aDataBlock
.singleLink (nIndex
);
667 void singleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
669 PAGE().m_aDataBlock
.singleLink (nIndex
, nAddr
);
675 sal_uInt32
doubleLink (sal_uInt16 nIndex
) const
677 return PAGE().m_aDataBlock
.doubleLink (nIndex
);
679 void doubleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
681 PAGE().m_aDataBlock
.doubleLink (nIndex
, nAddr
);
687 sal_uInt32
tripleLink (sal_uInt16 nIndex
) const
689 return PAGE().m_aDataBlock
.tripleLink (nIndex
);
691 void tripleLink (sal_uInt16 nIndex
, sal_uInt32 nAddr
)
693 PAGE().m_aDataBlock
.tripleLink (nIndex
, nAddr
);
697 /** read (external data page).
701 OStoreDataPageObject
&rData
,
702 OStorePageBIOS
&rBIOS
) const;
704 /** write (external data page).
708 OStoreDataPageObject
&rData
,
709 OStorePageBIOS
&rBIOS
);
711 /** truncate (external data page).
713 storeError
truncate (
715 OStorePageBIOS
&rBIOS
);
722 page
* pImpl
= static_cast<page
*>(m_xPage
.get());
723 OSL_PRECOND(pImpl
!= nullptr, "OStoreDirectoryPageObject::PAGE(): Null pointer");
726 page
const & PAGE() const
728 page
const * pImpl
= static_cast<page
const *>(m_xPage
.get());
729 OSL_PRECOND(pImpl
!= nullptr, "OStoreDirectoryPageObject::PAGE(): Null pointer");
733 /** scope (external data page; private).
735 page::ChunkScope
scope (
737 page::DataBlock::LinkDescriptor
&rDescr
) const;
739 /** truncate (external data page scope; private).
741 storeError
truncate (
742 page::ChunkScope eScope
,
744 OStorePageBIOS
&rBIOS
);
749 #endif // INCLUDED_STORE_SOURCE_STORDATA_HXX
751 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */