nss: upgrade to release 3.73
[LibreOffice.git] / store / source / stordata.hxx
blob7662bbe3bdbe020619cfb2106b1c849ad096609e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
27 #include <sal/types.h>
28 #include <rtl/string.h>
30 #include <store/types.h>
31 #include "storbase.hxx"
32 #include <string.h>
34 namespace store
37 class OStorePageBIOS;
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;
48 /** Representation.
50 sal_uInt8 m_pData[1];
52 /** type.
54 static const sal_uInt32 theTypeId = STORE_MAGIC_DATAPAGE;
56 /** size.
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");
62 /** capacity.
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);
73 /** Construction.
75 explicit OStoreDataPageData (sal_uInt16 nPageSize)
76 : base (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
91 return store_E_None;
95 class OStoreDataPageObject : public store::OStorePageObject
97 typedef OStorePageObject base;
98 typedef OStoreDataPageData page;
100 public:
101 /** Construction.
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;
123 /** Representation.
125 G m_aGuard;
126 sal_uInt32 m_pData[1];
128 /** type.
130 static const sal_uInt32 theTypeId = STORE_MAGIC_INDIRECTPAGE;
132 /** size.
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");
138 /** capacity.
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);
149 /** capacityCount.
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));
160 /** Construction.
162 explicit OStoreIndirectionPageData (sal_uInt16 nPageSize)
163 : base (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).
173 void guard()
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;
188 else
189 return store_E_None;
193 class OStoreIndirectionPageObject : public store::OStorePageObject
195 typedef OStorePageObject base;
196 typedef OStoreIndirectionPageData page;
198 public:
199 /** Construction.
201 explicit OStoreIndirectionPageObject (std::shared_ptr<PageData> const & rxPage = std::shared_ptr<PageData>())
202 : OStorePageObject (rxPage)
205 /** External representation.
207 storeError loadOrCreate (
208 sal_uInt32 nAddr,
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).
216 storeError read (
217 sal_uInt16 nSingle,
218 OStoreDataPageObject &rData,
219 OStorePageBIOS &rBIOS) const;
221 storeError read (
222 sal_uInt16 nDouble,
223 sal_uInt16 nSingle,
224 OStoreDataPageObject &rData,
225 OStorePageBIOS &rBIOS) const;
227 storeError read (
228 sal_uInt16 nTriple,
229 sal_uInt16 nDouble,
230 sal_uInt16 nSingle,
231 OStoreDataPageObject &rData,
232 OStorePageBIOS &rBIOS) const;
234 /** write (indirect data page).
236 storeError write (
237 sal_uInt16 nSingle,
238 OStoreDataPageObject &rData,
239 OStorePageBIOS &rBIOS);
241 storeError write (
242 sal_uInt16 nDouble,
243 sal_uInt16 nSingle,
244 OStoreDataPageObject &rData,
245 OStorePageBIOS &rBIOS);
247 storeError write (
248 sal_uInt16 nTriple,
249 sal_uInt16 nDouble,
250 sal_uInt16 nSingle,
251 OStoreDataPageObject &rData,
252 OStorePageBIOS &rBIOS);
254 /** truncate (indirect data page).
256 storeError truncate (
257 sal_uInt16 nSingle,
258 OStorePageBIOS &rBIOS);
260 storeError truncate (
261 sal_uInt16 nDouble,
262 sal_uInt16 nSingle,
263 OStorePageBIOS &rBIOS);
265 storeError truncate (
266 sal_uInt16 nTriple,
267 sal_uInt16 nDouble,
268 sal_uInt16 nSingle,
269 OStorePageBIOS &rBIOS);
272 struct OStorePageNameBlock
274 typedef OStorePageGuard G;
275 typedef OStorePageKey K;
277 /** Representation.
279 G m_aGuard;
280 K m_aKey;
281 sal_uInt32 m_nAttrib = 0;
282 char m_pData[STORE_MAXIMUM_NAMESIZE] = {};
284 /** size.
286 static const size_t theSize = sizeof(G) + sizeof(K) + sizeof(sal_uInt32) + sizeof(char[STORE_MAXIMUM_NAMESIZE]);
288 /** Construction.
290 OStorePageNameBlock() = default;
292 /** guard (external representation).
294 void guard()
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;
309 else
310 return store_E_None;
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;
323 /** LinkDescriptor.
325 struct LinkDescriptor
327 /** Representation.
329 sal_uInt16 m_nIndex0;
330 sal_uInt16 m_nIndex1;
331 sal_uInt16 m_nIndex2;
332 sal_uInt16 m_nIndex3;
334 /** Construction.
336 LinkDescriptor()
337 : m_nIndex0 (sal_uInt16(~0)),
338 m_nIndex1 (sal_uInt16(~0)),
339 m_nIndex2 (sal_uInt16(~0)),
340 m_nIndex3 (sal_uInt16(~0))
344 /** LinkTable.
346 struct LinkTable
348 /** Representation.
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];
355 /** initialize.
357 void initialize()
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));
365 /** Construction.
367 LinkTable()
369 initialize();
373 /** Representation.
375 G m_aGuard;
376 LinkTable m_aTable;
377 sal_uInt32 m_nDataLen;
379 /** size.
381 static const size_t theSize = sizeof(G) + sizeof(LinkTable) + sizeof(sal_uInt32);
383 /** Construction.
385 OStoreDirectoryDataBlock()
386 : m_aGuard(), m_aTable(), m_nDataLen (0)
389 /** guard (external representation).
391 void guard()
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;
406 else
407 return store_E_None;
410 /** direct.
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]);
418 else
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);
427 /** single.
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]);
435 else
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);
444 /** double.
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]);
452 else
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);
461 /** triple.
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]);
469 else
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;
490 /** Representation.
492 NameBlock m_aNameBlock;
493 DataBlock m_aDataBlock;
494 sal_uInt8 m_pData[1];
496 /** type.
498 static const sal_uInt32 theTypeId = STORE_MAGIC_DIRECTORYPAGE;
500 /** size.
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");
506 /** capacity.
508 sal_uInt16 capacity() const
510 return static_cast<sal_uInt16>(store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize);
513 /** Construction.
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).
525 void guard()
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();
538 return eErrCode;
541 /** ChunkDescriptor.
543 struct ChunkDescriptor
545 /** Representation.
547 sal_uInt32 m_nPage;
548 sal_uInt16 m_nOffset;
549 sal_uInt16 m_nLength;
551 /** Construction.
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)
561 /** ChunkScope.
563 enum ChunkScope
565 SCOPE_INTERNAL,
566 SCOPE_EXTERNAL,
567 SCOPE_DIRECT,
568 SCOPE_SINGLE,
569 SCOPE_DOUBLE,
570 SCOPE_TRIPLE,
571 SCOPE_UNREACHABLE,
572 SCOPE_UNKNOWN
575 /** scope (internal).
577 ChunkScope scope (sal_uInt32 nPosition) const
579 sal_uInt32 nCapacity = capacity();
580 if (nPosition < nCapacity)
581 return SCOPE_INTERNAL;
582 else
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;
595 public:
596 /** Construction.
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;
607 /** attrib.
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);
616 touch();
619 /** key.
621 void key (OStorePageKey const & rKey)
623 PAGE().m_aNameBlock.m_aKey = rKey;
624 touch();
627 /** path.
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));
637 /** dataLength.
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);
646 touch();
649 /** direct.
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);
658 touch();
661 /** single indirect.
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);
670 touch();
673 /** double indirect.
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);
682 touch();
685 /** triple indirect.
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);
694 touch();
697 /** read (external data page).
699 storeError read (
700 sal_uInt32 nPage,
701 OStoreDataPageObject &rData,
702 OStorePageBIOS &rBIOS) const;
704 /** write (external data page).
706 storeError write (
707 sal_uInt32 nPage,
708 OStoreDataPageObject &rData,
709 OStorePageBIOS &rBIOS);
711 /** truncate (external data page).
713 storeError truncate (
714 sal_uInt32 nPage,
715 OStorePageBIOS &rBIOS);
717 private:
718 /** Representation.
720 page & PAGE()
722 page * pImpl = static_cast<page*>(m_xPage.get());
723 OSL_PRECOND(pImpl != nullptr, "OStoreDirectoryPageObject::PAGE(): Null pointer");
724 return (*pImpl);
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");
730 return (*pImpl);
733 /** scope (external data page; private).
735 page::ChunkScope scope (
736 sal_uInt32 nPage,
737 page::DataBlock::LinkDescriptor &rDescr) const;
739 /** truncate (external data page scope; private).
741 storeError truncate (
742 page::ChunkScope eScope,
743 sal_uInt16 nRemain,
744 OStorePageBIOS &rBIOS);
747 } // namespace store
749 #endif // INCLUDED_STORE_SOURCE_STORDATA_HXX
751 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */