xref: /trunk/main/store/source/stordata.hxx (revision 1a5fa39b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _STORE_STORDATA_HXX_
25 #define _STORE_STORDATA_HXX_
26 
27 #include "sal/types.h"
28 #include "sal/macros.h"
29 
30 #include "store/types.h"
31 #include "storbase.hxx"
32 
33 namespace store
34 {
35 
36 /*========================================================================
37  *
38  * OStoreDataPageData.
39  *
40  *======================================================================*/
41 #define STORE_MAGIC_DATAPAGE sal_uInt32(0x94190310)
42 
43 struct OStoreDataPageData : public store::OStorePageData
44 {
45 	typedef OStorePageData       base;
46 	typedef OStoreDataPageData   self;
47 
48 	typedef OStorePageDescriptor D;
49 
50 	/** Representation.
51 	*/
52 	sal_uInt8 m_pData[1];
53 
54     /** type.
55      */
56     static const sal_uInt32 theTypeId = STORE_MAGIC_DATAPAGE;
57 
58 	/** size.
59 	*/
60     static const size_t     theSize     = 0;
61     static const sal_uInt16 thePageSize = base::theSize + self::theSize;
62     STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
63 
64 	/** capacity.
65 	*/
capacitystore::OStoreDataPageData66 	static sal_uInt16 capacity (const D& rDescr) // @see inode::ChunkDescriptor
67 	{
68 		return (store::ntohs(rDescr.m_nSize) - self::thePageSize);
69 	}
capacitystore::OStoreDataPageData70 	sal_uInt16 capacity() const
71 	{
72 		return self::capacity (base::m_aDescr);
73 	}
74 
75 	/** usage.
76 	*/
usagestore::OStoreDataPageData77 	sal_uInt16 usage() const
78 	{
79 		return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize);
80 	}
81 
82 	/** Construction.
83 	*/
OStoreDataPageDatastore::OStoreDataPageData84 	explicit OStoreDataPageData (sal_uInt16 nPageSize = self::thePageSize)
85 		: base (nPageSize)
86 	{
87 		base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
88 		base::m_aDescr.m_nUsed  = store::htons(self::thePageSize);
89 		if (capacity()) memset (m_pData, 0, capacity());
90 	}
91 
92 	/** guard (external representation).
93 	*/
guardstore::OStoreDataPageData94 	void guard() {}
95 
96 	/** verify (external representation).
97 	*/
verifystore::OStoreDataPageData98 	storeError verify() const { return store_E_None; }
99 };
100 
101 /*========================================================================
102  *
103  * OStoreDataPageObject.
104  *
105  *======================================================================*/
106 class OStoreDataPageObject : public store::OStorePageObject
107 {
108 	typedef OStorePageObject     base;
109 	typedef OStoreDataPageData   page;
110 
111 public:
112 	/** Construction.
113 	*/
OStoreDataPageObject(PageHolder const & rxPage=PageHolder ())114 	explicit OStoreDataPageObject (PageHolder const & rxPage = PageHolder())
115         : OStorePageObject (rxPage)
116     {}
117 
118 	/** External representation.
119 	 */
120     virtual storeError guard  (sal_uInt32 nAddr);
121     virtual storeError verify (sal_uInt32 nAddr) const;
122 };
123 
124 /*========================================================================
125  *
126  * OStoreIndirectionPageData.
127  *
128  *======================================================================*/
129 #define STORE_MAGIC_INDIRECTPAGE sal_uInt32(0x89191107)
130 
131 struct OStoreIndirectionPageData : public store::OStorePageData
132 {
133 	typedef OStorePageData            base;
134 	typedef OStoreIndirectionPageData self;
135 
136 	typedef OStorePageGuard           G;
137 	typedef OStorePageDescriptor      D;
138 
139 	/** Representation.
140 	*/
141 	G          m_aGuard;
142 	sal_uInt32 m_pData[1];
143 
144     /** type.
145      */
146     static const sal_uInt32 theTypeId = STORE_MAGIC_INDIRECTPAGE;
147 
148 	/** size.
149      */
150     static const size_t     theSize     = sizeof(G);
151     static const sal_uInt16 thePageSize = base::theSize + self::theSize;
152     STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
153 
154 	/** capacity.
155 	*/
capacitystore::OStoreIndirectionPageData156 	static sal_uInt16 capacity (const D& rDescr)
157 	{
158 		return (store::ntohs(rDescr.m_nSize) - self::thePageSize);
159 	}
capacitystore::OStoreIndirectionPageData160 	sal_uInt16 capacity() const
161 	{
162 		return self::capacity (base::m_aDescr);
163 	}
164 
165 	/** capacityCount.
166 	*/
capacityCountstore::OStoreIndirectionPageData167 	static sal_uInt16 capacityCount (const D& rDescr) // @see DirectoryPageObject::scope()
168 	{
169 		return sal_uInt16(capacity(rDescr) / sizeof(sal_uInt32));
170 	}
capacityCountstore::OStoreIndirectionPageData171 	sal_uInt16 capacityCount() const
172 	{
173 		return sal_uInt16(capacity() / sizeof(sal_uInt32));
174 	}
175 
176 	/** Construction.
177 	*/
OStoreIndirectionPageDatastore::OStoreIndirectionPageData178 	explicit OStoreIndirectionPageData (sal_uInt16 nPageSize)
179 		: base (nPageSize)
180 	{
181 		base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
182 		base::m_aDescr.m_nUsed  = store::htons(self::thePageSize);
183 		self::m_aGuard.m_nMagic = store::htonl(0);
184 		memset (m_pData, STORE_PAGE_NULL, capacity());
185 	}
186 
187 	/** guard (external representation).
188 	*/
guardstore::OStoreIndirectionPageData189 	void guard()
190 	{
191 		sal_uInt32 nCRC32 = 0;
192 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
193 		nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
194 		m_aGuard.m_nCRC32 = store::htonl(nCRC32);
195 	}
196 
197 	/** verify (external representation).
198 	*/
verifystore::OStoreIndirectionPageData199 	storeError verify() const
200 	{
201 		sal_uInt32 nCRC32 = 0;
202 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
203 		nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
204 		if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
205 			return store_E_InvalidChecksum;
206 		else
207 			return store_E_None;
208 	}
209 };
210 
211 /*========================================================================
212  *
213  * OStoreIndirectionPageObject.
214  *
215  *======================================================================*/
216 class OStoreIndirectionPageObject : public store::OStorePageObject
217 {
218 	typedef OStorePageObject          base;
219 	typedef OStoreIndirectionPageData page;
220 
221 public:
222 	/** Construction.
223 	*/
OStoreIndirectionPageObject(PageHolder const & rxPage=PageHolder ())224     explicit OStoreIndirectionPageObject (PageHolder const & rxPage = PageHolder())
225         : OStorePageObject (rxPage)
226     {}
227 
228 	/** External representation.
229 	*/
230     storeError loadOrCreate (
231         sal_uInt32       nAddr,
232         OStorePageBIOS & rBIOS);
233 
234     virtual storeError guard  (sal_uInt32 nAddr);
235     virtual storeError verify (sal_uInt32 nAddr) const;
236 
237 	/** read (indirect data page).
238 	*/
239 	storeError read (
240 		sal_uInt16             nSingle,
241 		OStoreDataPageObject  &rData,
242 		OStorePageBIOS        &rBIOS);
243 
244 	storeError read (
245 		sal_uInt16             nDouble,
246 		sal_uInt16             nSingle,
247 		OStoreDataPageObject  &rData,
248 		OStorePageBIOS        &rBIOS);
249 
250 	storeError read (
251 		sal_uInt16             nTriple,
252 		sal_uInt16             nDouble,
253 		sal_uInt16             nSingle,
254 		OStoreDataPageObject  &rData,
255 		OStorePageBIOS        &rBIOS);
256 
257 	/** write (indirect data page).
258 	*/
259 	storeError write (
260 		sal_uInt16             nSingle,
261 		OStoreDataPageObject  &rData,
262 		OStorePageBIOS        &rBIOS);
263 
264 	storeError write (
265 		sal_uInt16             nDouble,
266 		sal_uInt16             nSingle,
267 		OStoreDataPageObject  &rData,
268 		OStorePageBIOS        &rBIOS);
269 
270 	storeError write (
271 		sal_uInt16             nTriple,
272 		sal_uInt16             nDouble,
273 		sal_uInt16             nSingle,
274 		OStoreDataPageObject  &rData,
275 		OStorePageBIOS        &rBIOS);
276 
277 	/** truncate (indirect data page).
278 	*/
279 	storeError truncate (
280 		sal_uInt16             nSingle,
281 		OStorePageBIOS        &rBIOS);
282 
283 	storeError truncate (
284 		sal_uInt16             nDouble,
285 		sal_uInt16             nSingle,
286 		OStorePageBIOS        &rBIOS);
287 
288 	storeError truncate (
289 		sal_uInt16             nTriple,
290 		sal_uInt16             nDouble,
291 		sal_uInt16             nSingle,
292 		OStorePageBIOS        &rBIOS);
293 };
294 
295 /*========================================================================
296  *
297  * OStorePageNameBlock.
298  *
299  *======================================================================*/
300 struct OStorePageNameBlock
301 {
302 	typedef OStorePageGuard G;
303 	typedef OStorePageKey   K;
304 
305 	/** Representation.
306 	*/
307 	G          m_aGuard;
308 	K          m_aKey;
309 	sal_uInt32 m_nAttrib;
310 	sal_Char   m_pData[STORE_MAXIMUM_NAMESIZE];
311 
312 	/** size.
313 	*/
314     static const size_t theSize = sizeof(G) + sizeof(K) + sizeof(sal_uInt32) + sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE]);
315 
316 	/** initialize.
317 	*/
initializestore::OStorePageNameBlock318 	void initialize (void)
319 	{
320 		m_aGuard  = G();
321 		m_aKey    = K();
322 		m_nAttrib = 0;
323 		memset (m_pData, 0, sizeof(m_pData));
324 	}
325 
326 	/** Construction.
327 	*/
OStorePageNameBlockstore::OStorePageNameBlock328 	OStorePageNameBlock (void)
329 		: m_aGuard(), m_aKey(), m_nAttrib (0)
330 	{
331 		memset (m_pData, 0, sizeof(m_pData));
332 	}
333 
334 	/** guard (external representation).
335 	*/
guardstore::OStorePageNameBlock336 	void guard()
337 	{
338 		sal_uInt32 nCRC32 = 0;
339 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
340 		nCRC32 = rtl_crc32 (nCRC32, &m_aKey, theSize - sizeof(G));
341 		m_aGuard.m_nCRC32 = store::htonl(nCRC32);
342 	}
343 
344 	/** verify (external representation).
345 	*/
verifystore::OStorePageNameBlock346 	storeError verify() const
347 	{
348 		sal_uInt32 nCRC32 = 0;
349 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
350 		nCRC32 = rtl_crc32 (nCRC32, &m_aKey, theSize - sizeof(G));
351 		if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
352 			return store_E_InvalidChecksum;
353 		else
354 			return store_E_None;
355 	}
356 };
357 
358 /*========================================================================
359  *
360  * OStoreDirectoryDataBlock.
361  *
362  *======================================================================*/
363 #define STORE_LIMIT_DATAPAGE_DIRECT 16
364 #define STORE_LIMIT_DATAPAGE_SINGLE  8
365 #define STORE_LIMIT_DATAPAGE_DOUBLE  1
366 #define STORE_LIMIT_DATAPAGE_TRIPLE  1
367 
368 struct OStoreDirectoryDataBlock
369 {
370 	typedef OStorePageGuard G;
371 
372 	/** LinkDescriptor.
373 	*/
374 	struct LinkDescriptor
375 	{
376 		/** Representation.
377 		*/
378 		sal_uInt16 m_nIndex0;
379 		sal_uInt16 m_nIndex1;
380 		sal_uInt16 m_nIndex2;
381 		sal_uInt16 m_nIndex3;
382 
383 		/** Construction.
384 		*/
LinkDescriptorstore::OStoreDirectoryDataBlock::LinkDescriptor385 		LinkDescriptor (void)
386 			: m_nIndex0 ((sal_uInt16)(~0)),
387 			  m_nIndex1 ((sal_uInt16)(~0)),
388 			  m_nIndex2 ((sal_uInt16)(~0)),
389 			  m_nIndex3 ((sal_uInt16)(~0))
390 		{}
391 	};
392 
393 	/** LinkTable.
394 	*/
395 	struct LinkTable
396 	{
397 		/** Representation.
398 		*/
399 		sal_uInt32 m_pDirect[STORE_LIMIT_DATAPAGE_DIRECT];
400 		sal_uInt32 m_pSingle[STORE_LIMIT_DATAPAGE_SINGLE];
401 		sal_uInt32 m_pDouble[STORE_LIMIT_DATAPAGE_DOUBLE];
402 		sal_uInt32 m_pTriple[STORE_LIMIT_DATAPAGE_TRIPLE];
403 
404 		/** initialize.
405 		*/
initializestore::OStoreDirectoryDataBlock::LinkTable406 		void initialize (void)
407 		{
408 		  memset(m_pDirect, STORE_PAGE_NULL, sizeof(m_pDirect));
409 		  memset(m_pSingle, STORE_PAGE_NULL, sizeof(m_pSingle));
410 		  memset(m_pDouble, STORE_PAGE_NULL, sizeof(m_pDouble));
411 		  memset(m_pTriple, STORE_PAGE_NULL, sizeof(m_pTriple));
412 		}
413 
414 		/** Construction.
415 		*/
LinkTablestore::OStoreDirectoryDataBlock::LinkTable416 		LinkTable (void)
417 		{
418 		  initialize();
419 		}
420 	};
421 
422 	/** Representation.
423 	*/
424 	G          m_aGuard;
425 	LinkTable  m_aTable;
426 	sal_uInt32 m_nDataLen;
427 
428 	/** size.
429      */
430     static const size_t theSize = sizeof(G) + sizeof(LinkTable) + sizeof(sal_uInt32);
431 
432 	/** initialize.
433 	*/
initializestore::OStoreDirectoryDataBlock434 	void initialize (void)
435 	{
436 		m_aGuard = G();
437 		m_aTable.initialize();
438 		m_nDataLen = 0;
439 	}
440 
441 	/** Construction.
442 	*/
OStoreDirectoryDataBlockstore::OStoreDirectoryDataBlock443 	OStoreDirectoryDataBlock (void)
444 		: m_aGuard(), m_aTable(), m_nDataLen (0)
445 	{}
446 
447 	/** guard (external representation).
448 	*/
guardstore::OStoreDirectoryDataBlock449 	void guard()
450 	{
451 		sal_uInt32 nCRC32 = 0;
452 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
453 		nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G));
454 		m_aGuard.m_nCRC32 = store::htonl(nCRC32);
455 	}
456 
457 	/** verify (external representation).
458 	*/
verifystore::OStoreDirectoryDataBlock459 	storeError verify() const
460 	{
461 		sal_uInt32 nCRC32 = 0;
462 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
463 		nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G));
464 		if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
465 			return store_E_InvalidChecksum;
466 		else
467 			return store_E_None;
468 	}
469 
470 	/** direct.
471 	*/
directCountstore::OStoreDirectoryDataBlock472 	static sal_uInt16 directCount (void)
473 	{
474 		return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DIRECT));
475 	}
directLinkstore::OStoreDirectoryDataBlock476 	sal_uInt32 directLink (sal_uInt16 nIndex) const
477 	{
478 		if (nIndex < directCount())
479 			return store::ntohl(m_aTable.m_pDirect[nIndex]);
480 		else
481 			return STORE_PAGE_NULL;
482 	}
directLinkstore::OStoreDirectoryDataBlock483 	void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
484 	{
485 		if (nIndex < directCount())
486 			m_aTable.m_pDirect[nIndex] = store::htonl(nAddr);
487 	}
488 
489 	/** single.
490 	*/
singleCountstore::OStoreDirectoryDataBlock491 	static sal_uInt16 singleCount (void)
492 	{
493 		return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_SINGLE));
494 	}
singleLinkstore::OStoreDirectoryDataBlock495 	sal_uInt32 singleLink (sal_uInt16 nIndex) const
496 	{
497 		if (nIndex < singleCount())
498 			return store::ntohl(m_aTable.m_pSingle[nIndex]);
499 		else
500 			return STORE_PAGE_NULL;
501 	}
singleLinkstore::OStoreDirectoryDataBlock502 	void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
503 	{
504 		if (nIndex < singleCount())
505 			m_aTable.m_pSingle[nIndex] = store::htonl(nAddr);
506 	}
507 
508 	/** double.
509 	*/
doubleCountstore::OStoreDirectoryDataBlock510 	static sal_uInt16 doubleCount (void)
511 	{
512 		return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DOUBLE));
513 	}
doubleLinkstore::OStoreDirectoryDataBlock514 	sal_uInt32 doubleLink (sal_uInt16 nIndex) const
515 	{
516 		if (nIndex < doubleCount())
517 			return store::ntohl(m_aTable.m_pDouble[nIndex]);
518 		else
519 			return STORE_PAGE_NULL;
520 	}
doubleLinkstore::OStoreDirectoryDataBlock521 	void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
522 	{
523 		if (nIndex < doubleCount())
524 			m_aTable.m_pDouble[nIndex] = store::htonl(nAddr);
525 	}
526 
527 	/** triple.
528 	*/
tripleCountstore::OStoreDirectoryDataBlock529 	static sal_uInt16 tripleCount (void)
530 	{
531 		return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_TRIPLE));
532 	}
tripleLinkstore::OStoreDirectoryDataBlock533 	sal_uInt32 tripleLink (sal_uInt16 nIndex) const
534 	{
535 		if (nIndex < tripleCount())
536 			return store::ntohl(m_aTable.m_pTriple[nIndex]);
537 		else
538 			return STORE_PAGE_NULL;
539 	}
tripleLinkstore::OStoreDirectoryDataBlock540 	void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
541 	{
542 		if (nIndex < tripleCount())
543 			m_aTable.m_pTriple[nIndex] = store::htonl(nAddr);
544 	}
545 };
546 
547 /*========================================================================
548  *
549  * OStoreDirectoryPageData.
550  *
551  *======================================================================*/
552 #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
553 
554 struct OStoreDirectoryPageData : public store::OStorePageData
555 {
556 	typedef OStorePageData           base;
557 	typedef OStoreDirectoryPageData  self;
558 
559 	typedef OStorePageDescriptor     D;
560 	typedef OStorePageNameBlock      NameBlock;
561 	typedef OStoreDirectoryDataBlock DataBlock;
562 
563 	/** Representation.
564      */
565 	NameBlock m_aNameBlock;
566 	DataBlock m_aDataBlock;
567 	sal_uInt8 m_pData[1];
568 
569     /** type.
570      */
571     static const sal_uInt32 theTypeId = STORE_MAGIC_DIRECTORYPAGE;
572 
573 	/** size.
574      */
575     static const size_t     theSize     = NameBlock::theSize + DataBlock::theSize;
576     static const sal_uInt16 thePageSize = base::theSize + self::theSize;
577     STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
578 
579 	/** capacity.
580 	*/
capacitystore::OStoreDirectoryPageData581 	sal_uInt16 capacity() const
582 	{
583 		return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize);
584 	}
585 
586 	/** usage.
587 	*/
usagestore::OStoreDirectoryPageData588 	sal_uInt16 usage() const
589 	{
590 		return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize);
591 	}
592 
593 	/** initialize.
594 	*/
initializestore::OStoreDirectoryPageData595 	void initialize (void)
596 	{
597 		base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
598 		base::m_aDescr.m_nUsed  = store::htons(self::thePageSize);
599 
600 		m_aNameBlock.initialize();
601 		m_aDataBlock.initialize();
602 
603 		memset (m_pData, 0, capacity());
604 	}
605 
606 	/** Construction.
607 	*/
OStoreDirectoryPageDatastore::OStoreDirectoryPageData608 	explicit OStoreDirectoryPageData (sal_uInt16 nPageSize)
609 		: base (nPageSize), m_aNameBlock(), m_aDataBlock()
610 	{
611 		base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
612 		base::m_aDescr.m_nUsed  = store::htons(self::thePageSize);
613 		memset (m_pData, 0, capacity());
614 	}
615 
616 	/** guard (external representation).
617 	*/
guardstore::OStoreDirectoryPageData618 	void guard()
619 	{
620 		m_aNameBlock.guard();
621 		m_aDataBlock.guard();
622 	}
623 
624 	/** verify (external representation).
625 	*/
verifystore::OStoreDirectoryPageData626 	storeError verify() const
627 	{
628 		storeError eErrCode = m_aNameBlock.verify();
629 		if (eErrCode == store_E_None)
630 			eErrCode = m_aDataBlock.verify();
631 		return eErrCode;
632 	}
633 
634 	/** ChunkDescriptor.
635 	*/
636 	struct ChunkDescriptor
637 	{
638 		/** Representation.
639 		*/
640 		sal_uInt32 m_nPage;
641 		sal_uInt16 m_nOffset;
642 		sal_uInt16 m_nLength;
643 
644 		/** Construction.
645 		*/
ChunkDescriptorstore::OStoreDirectoryPageData::ChunkDescriptor646 		ChunkDescriptor (sal_uInt32 nPosition, sal_uInt16 nCapacity)
647 		{
648 			m_nPage   = nPosition / nCapacity;
649 			m_nOffset = (sal_uInt16)((nPosition % nCapacity) & 0xffff);
650 			m_nLength = nCapacity - m_nOffset;
651 		}
652 	};
653 
654 	/** ChunkScope.
655 	*/
656 	enum ChunkScope
657 	{
658 		SCOPE_INTERNAL,
659 		SCOPE_EXTERNAL,
660 		SCOPE_DIRECT,
661 		SCOPE_SINGLE,
662 		SCOPE_DOUBLE,
663 		SCOPE_TRIPLE,
664 		SCOPE_UNREACHABLE,
665 		SCOPE_UNKNOWN
666 	};
667 
668 	/** scope (internal).
669 	*/
scopestore::OStoreDirectoryPageData670 	ChunkScope scope (sal_uInt32 nPosition) const
671 	{
672 		sal_uInt32 nCapacity = capacity();
673 		if (nPosition < nCapacity)
674 			return SCOPE_INTERNAL;
675 		else
676 			return SCOPE_EXTERNAL;
677 	}
678 };
679 
680 /*========================================================================
681  *
682  * OStoreDirectoryPageObject.
683  *
684  *======================================================================*/
685 class OStoreDirectoryPageObject : public store::OStorePageObject
686 {
687 	typedef OStorePageObject          base;
688 	typedef OStoreDirectoryPageData   page;
689 	typedef OStoreIndirectionPageData indirect;
690 
691 	typedef OStorePageDescriptor      D;
692 
693 public:
694 	/** Construction.
695 	*/
OStoreDirectoryPageObject(PageHolder const & rxPage=PageHolder ())696     explicit OStoreDirectoryPageObject (PageHolder const & rxPage = PageHolder())
697         : OStorePageObject (rxPage)
698     {}
699 
700 	/** External representation.
701 	*/
702 	virtual storeError guard  (sal_uInt32 nAddr);
703 	virtual storeError verify (sal_uInt32 nAddr) const;
704 
705 	/** attrib.
706 	*/
attrib(void) const707 	sal_uInt32 attrib (void) const
708 	{
709 		return store::ntohl(PAGE().m_aNameBlock.m_nAttrib);
710 	}
attrib(sal_uInt32 nAttrib)711 	void attrib (sal_uInt32 nAttrib)
712 	{
713 		PAGE().m_aNameBlock.m_nAttrib = store::htonl(nAttrib);
714 		touch();
715 	}
716 
717 	/** key.
718 	*/
key(void) const719 	OStorePageKey key (void) const
720 	{
721 		return PAGE().m_aNameBlock.m_aKey;
722 	}
key(OStorePageKey const & rKey)723 	void key (OStorePageKey const & rKey)
724 	{
725 		PAGE().m_aNameBlock.m_aKey = rKey;
726 		touch();
727 	}
728 
729 	/** path.
730 	*/
path(void) const731 	sal_uInt32 path (void) const
732 	{
733         page const & rPage = PAGE();
734 		const sal_Char * pszName = rPage.m_aNameBlock.m_pData;
735 		sal_uInt32       nPath   = store::ntohl(rPage.m_aNameBlock.m_aKey.m_nHigh);
736 		return rtl_crc32 (nPath, pszName, rtl_str_getLength(pszName));
737 	}
738 
getName(sal_Char * pBuffer,sal_Size nBufsiz) const739     sal_Size getName (sal_Char * pBuffer, sal_Size nBufsiz) const
740     {
741         sal_Char const * pszName = PAGE().m_aNameBlock.m_pData;
742         sal_Size nLength = rtl_str_getLength(pszName);
743         memcpy (pBuffer, pszName, SAL_MIN(nLength, nBufsiz));
744         return nLength;
745     }
746 
747 	/** dataLength.
748 	*/
dataLength(void) const749 	sal_uInt32 dataLength (void) const
750 	{
751 		return store::ntohl(PAGE().m_aDataBlock.m_nDataLen);
752 	}
dataLength(sal_uInt32 nLength)753 	void dataLength (sal_uInt32 nLength)
754 	{
755 		PAGE().m_aDataBlock.m_nDataLen = store::htonl(nLength);
756 		touch();
757 	}
758 
759 	/** direct.
760 	*/
directLink(sal_uInt16 nIndex) const761 	sal_uInt32 directLink (sal_uInt16 nIndex) const
762 	{
763 		return PAGE().m_aDataBlock.directLink (nIndex);
764 	}
directLink(sal_uInt16 nIndex,sal_uInt32 nAddr)765 	void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
766 	{
767 		PAGE().m_aDataBlock.directLink (nIndex, nAddr);
768 		touch();
769 	}
770 
771 	/** single indirect.
772 	*/
singleLink(sal_uInt16 nIndex) const773 	sal_uInt32 singleLink (sal_uInt16 nIndex) const
774 	{
775 		return PAGE().m_aDataBlock.singleLink (nIndex);
776 	}
singleLink(sal_uInt16 nIndex,sal_uInt32 nAddr)777 	void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
778 	{
779 		PAGE().m_aDataBlock.singleLink (nIndex, nAddr);
780 		touch();
781 	}
782 
783 	/** double indirect.
784 	*/
doubleLink(sal_uInt16 nIndex) const785 	sal_uInt32 doubleLink (sal_uInt16 nIndex) const
786 	{
787 		return PAGE().m_aDataBlock.doubleLink (nIndex);
788 	}
doubleLink(sal_uInt16 nIndex,sal_uInt32 nAddr)789 	void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
790 	{
791 		PAGE().m_aDataBlock.doubleLink (nIndex, nAddr);
792 		touch();
793 	}
794 
795 	/** triple indirect.
796 	*/
tripleLink(sal_uInt16 nIndex) const797 	sal_uInt32 tripleLink (sal_uInt16 nIndex) const
798 	{
799 		return PAGE().m_aDataBlock.tripleLink (nIndex);
800 	}
tripleLink(sal_uInt16 nIndex,sal_uInt32 nAddr)801 	void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
802 	{
803 		PAGE().m_aDataBlock.tripleLink (nIndex, nAddr);
804 		touch();
805 	}
806 
807 	/** read (external data page).
808 	*/
809 	storeError read (
810 		sal_uInt32             nPage,
811 		OStoreDataPageObject  &rData,
812 		OStorePageBIOS        &rBIOS);
813 
814 	/** write (external data page).
815 	*/
816 	storeError write (
817 		sal_uInt32             nPage,
818 		OStoreDataPageObject  &rData,
819 		OStorePageBIOS        &rBIOS);
820 
821 	/** truncate (external data page).
822 	*/
823 	storeError truncate (
824 		sal_uInt32             nPage,
825 		OStorePageBIOS        &rBIOS);
826 
827 private:
828 	/** Representation.
829 	*/
PAGE()830     page & PAGE()
831     {
832         page * pImpl = static_cast<page*>(m_xPage.get());
833         OSL_PRECOND(pImpl != 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
834         return (*pImpl);
835     }
PAGE() const836     page const & PAGE() const
837     {
838         page const * pImpl = static_cast<page const *>(m_xPage.get());
839         OSL_PRECOND(pImpl != 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
840         return (*pImpl);
841     }
842 
843 	/** scope (external data page; private).
844 	*/
845 	page::ChunkScope scope (
846 		sal_uInt32                       nPage,
847 		page::DataBlock::LinkDescriptor &rDescr) const;
848 
849 	/** truncate (external data page scope; private).
850 	*/
851 	storeError truncate (
852 		page::ChunkScope       eScope,
853 		sal_uInt16             nRemain,
854 		OStorePageBIOS        &rBIOS);
855 };
856 
857 /*========================================================================
858  *
859  * The End.
860  *
861  *======================================================================*/
862 
863 } // namespace store
864 
865 #endif /* !_STORE_STORDATA_HXX_ */
866 
867