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