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_STORBASE_HXX_ 29 #define _STORE_STORBASE_HXX_ "$Revision: 1.10.8.4 $" 30 31 #include "sal/types.h" 32 33 #include "rtl/alloc.h" 34 #include "rtl/crc.h" 35 #include "rtl/ref.hxx" 36 37 #include "osl/diagnose.h" 38 #include "osl/endian.h" 39 40 #include "store/types.h" 41 42 #ifndef INCLUDED_STDDEF_H 43 #include <stddef.h> 44 #define INCLUDED_STDDEF_H 45 #endif 46 47 #ifndef INCLUDED_STRING_H 48 #include <string.h> 49 #define INCLUDED_STRING_H 50 #endif 51 52 /*======================================================================== 53 * 54 * store common internals. 55 * 56 *======================================================================*/ 57 58 #ifndef STORE_IMPL_ISP2 59 #define STORE_IMPL_ISP2(value) (((value) & ((value) - 1)) == 0) 60 #endif 61 62 #ifndef STORE_IMPL_CONCAT 63 #define STORE_IMPL_CONCAT(x, y) STORE_IMPL_CONCAT2(x,y) 64 #define STORE_IMPL_CONCAT2(x, y) x##y 65 #endif 66 67 #ifndef STORE_STATIC_ASSERT /* Compile time assertion */ 68 namespace store 69 { 70 template< bool x > struct STATIC_ASSERTION_FAILURE; 71 template<> struct STATIC_ASSERTION_FAILURE< true > { enum { value = 1 }; }; 72 73 template< int x > struct static_assert_test{}; 74 } // namespace store 75 76 #define STORE_STATIC_ASSERT(pred) \ 77 typedef \ 78 store::static_assert_test< sizeof( store::STATIC_ASSERTION_FAILURE< (bool)(pred) > ) > \ 79 STORE_IMPL_CONCAT(static_assert_typedef_, __LINE__) 80 81 #endif /* !STORE_STATIC_ASSERT */ 82 83 namespace store 84 { 85 86 #ifdef htons 87 #undef htons 88 #endif 89 #ifdef ntohs 90 #undef ntohs 91 #endif 92 93 #ifdef htonl 94 #undef htonl 95 #endif 96 #ifdef ntohl 97 #undef ntohl 98 #endif 99 100 #ifdef OSL_BIGENDIAN 101 inline sal_uInt16 htons (sal_uInt16 h) { return OSL_SWAPWORD(h); } 102 inline sal_uInt16 ntohs (sal_uInt16 n) { return OSL_SWAPWORD(n); } 103 104 inline sal_uInt32 htonl (sal_uInt32 h) { return OSL_SWAPDWORD(h); } 105 inline sal_uInt32 ntohl (sal_uInt32 n) { return OSL_SWAPDWORD(n); } 106 #else 107 inline sal_uInt16 htons (sal_uInt16 h) { return (h); } 108 inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); } 109 110 inline sal_uInt32 htonl (sal_uInt32 h) { return (h); } 111 inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); } 112 #endif /* OSL_BIGENDIAN */ 113 114 /** swap. 115 */ 116 template< typename T > void swap (T & lhs, T & rhs) 117 { 118 T tmp = lhs; lhs = rhs; rhs = tmp; 119 } 120 121 /*======================================================================== 122 * 123 * SharedCount. 124 * 125 *======================================================================*/ 126 class SharedCount 127 { 128 long * m_pCount; 129 130 class Allocator 131 { 132 rtl_cache_type * m_cache; 133 134 public: 135 static Allocator & get(); 136 137 long * alloc() 138 { 139 return static_cast<long*>(rtl_cache_alloc (m_cache)); 140 } 141 void free (long * pCount) 142 { 143 rtl_cache_free (m_cache, pCount); 144 } 145 146 protected: 147 Allocator(); 148 ~Allocator(); 149 }; 150 151 public: 152 SharedCount() 153 : m_pCount(Allocator::get().alloc()) 154 { 155 if (m_pCount != 0) (*m_pCount) = 1; 156 } 157 158 ~SharedCount() 159 { 160 if (m_pCount != 0) 161 { 162 long new_count = --(*m_pCount); 163 if (new_count == 0) 164 Allocator::get().free(m_pCount); 165 } 166 } 167 168 void swap (SharedCount & rhs) // nothrow 169 { 170 store::swap(m_pCount, rhs.m_pCount); 171 } 172 173 SharedCount (SharedCount const & rhs) // nothrow 174 : m_pCount (rhs.m_pCount) 175 { 176 if (m_pCount != 0) ++(*m_pCount); 177 } 178 SharedCount & operator= (SharedCount const & rhs) // nothrow 179 { 180 SharedCount tmp(rhs); 181 swap(tmp); 182 return *this; 183 } 184 185 bool operator== (long count) const 186 { 187 return (m_pCount != 0) ? *m_pCount == count : false; 188 } 189 }; 190 191 /*======================================================================== 192 * 193 * OStorePageGuard. 194 * 195 *======================================================================*/ 196 struct OStorePageGuard 197 { 198 /** Representation. 199 */ 200 sal_uInt32 m_nMagic; 201 sal_uInt32 m_nCRC32; 202 203 /** Construction. 204 */ 205 explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0) 206 : m_nMagic (store::htonl(nMagic)), 207 m_nCRC32 (store::htonl(nCRC32)) 208 {} 209 210 void swap (OStorePageGuard & rhs) 211 { 212 store::swap(m_nMagic, rhs.m_nMagic); 213 store::swap(m_nCRC32, rhs.m_nCRC32); 214 } 215 216 OStorePageGuard (OStorePageGuard const & rhs) 217 : m_nMagic (rhs.m_nMagic), 218 m_nCRC32 (rhs.m_nCRC32) 219 {} 220 221 OStorePageGuard& operator= (const OStorePageGuard& rhs) 222 { 223 m_nMagic = rhs.m_nMagic; 224 m_nCRC32 = rhs.m_nCRC32; 225 return *this; 226 } 227 228 /** Comparison. 229 */ 230 bool operator== (const OStorePageGuard& rhs) const 231 { 232 return ((m_nMagic == rhs.m_nMagic) && 233 (m_nCRC32 == rhs.m_nCRC32) ); 234 } 235 }; 236 237 /*======================================================================== 238 * 239 * OStorePageDescriptor. 240 * 241 *======================================================================*/ 242 #define STORE_PAGE_NULL ((sal_uInt32)(~0)) 243 244 struct OStorePageDescriptor 245 { 246 /** Representation. 247 */ 248 sal_uInt32 m_nAddr; 249 sal_uInt16 m_nSize; 250 sal_uInt16 m_nUsed; 251 252 /** Construction. 253 */ 254 explicit OStorePageDescriptor ( 255 sal_uInt32 nAddr = STORE_PAGE_NULL, 256 sal_uInt16 nSize = 0, 257 sal_uInt16 nUsed = 0) 258 : m_nAddr (store::htonl(nAddr)), 259 m_nSize (store::htons(nSize)), 260 m_nUsed (store::htons(nUsed)) 261 {} 262 263 void swap (OStorePageDescriptor & rhs) 264 { 265 store::swap(m_nAddr, rhs.m_nAddr); 266 store::swap(m_nSize, rhs.m_nSize); 267 store::swap(m_nUsed, rhs.m_nUsed); 268 } 269 270 OStorePageDescriptor (const OStorePageDescriptor & rhs) 271 : m_nAddr (rhs.m_nAddr), 272 m_nSize (rhs.m_nSize), 273 m_nUsed (rhs.m_nUsed) 274 {} 275 276 OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs) 277 { 278 m_nAddr = rhs.m_nAddr; 279 m_nSize = rhs.m_nSize; 280 m_nUsed = rhs.m_nUsed; 281 return *this; 282 } 283 284 /** Comparison. 285 */ 286 bool operator== (const OStorePageDescriptor & rhs) const 287 { 288 return ((m_nAddr == rhs.m_nAddr) && 289 (m_nSize == rhs.m_nSize) ); 290 } 291 292 bool operator<= (const OStorePageDescriptor & rhs) const 293 { 294 return ((m_nAddr == rhs.m_nAddr ) && 295 (store::ntohs(m_nSize) <= store::ntohs(rhs.m_nSize)) ); 296 } 297 298 bool operator< (const OStorePageDescriptor & rhs) const 299 { 300 if (m_nAddr == rhs.m_nAddr) 301 return (store::ntohs(m_nSize) < store::ntohs(rhs.m_nSize)); 302 else 303 return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr)); 304 } 305 }; 306 307 /*======================================================================== 308 * 309 * OStorePageKey. 310 * 311 *======================================================================*/ 312 struct OStorePageKey 313 { 314 /** Representation. 315 */ 316 sal_uInt32 m_nLow; 317 sal_uInt32 m_nHigh; 318 319 /** Construction. 320 */ 321 explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0) 322 : m_nLow (store::htonl(nLow)), 323 m_nHigh (store::htonl(nHigh)) 324 {} 325 326 void swap (OStorePageKey & rhs) 327 { 328 store::swap(m_nLow, rhs.m_nLow); 329 store::swap(m_nHigh, rhs.m_nHigh); 330 } 331 332 OStorePageKey (const OStorePageKey & rhs) 333 : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh) 334 {} 335 336 OStorePageKey & operator= (const OStorePageKey & rhs) 337 { 338 m_nLow = rhs.m_nLow; 339 m_nHigh = rhs.m_nHigh; 340 return *this; 341 } 342 343 /** Comparison. 344 */ 345 bool operator== (const OStorePageKey & rhs) const 346 { 347 return ((m_nLow == rhs.m_nLow ) && 348 (m_nHigh == rhs.m_nHigh) ); 349 } 350 351 bool operator< (const OStorePageKey & rhs) const 352 { 353 if (m_nHigh == rhs.m_nHigh) 354 return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow)); 355 else 356 return (store::ntohl(m_nHigh) < store::ntohl(rhs.m_nHigh)); 357 } 358 }; 359 360 /*======================================================================== 361 * 362 * OStorePageLink. 363 * 364 *======================================================================*/ 365 struct OStorePageLink 366 { 367 /** Representation. 368 */ 369 sal_uInt32 m_nAddr; 370 371 /** Construction. 372 */ 373 explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL) 374 : m_nAddr (store::htonl(nAddr)) 375 {} 376 377 void swap (OStorePageLink & rhs) 378 { 379 store::swap(m_nAddr, rhs.m_nAddr); 380 } 381 382 OStorePageLink (const OStorePageLink & rhs) 383 : m_nAddr (rhs.m_nAddr) 384 {} 385 386 OStorePageLink & operator= (const OStorePageLink & rhs) 387 { 388 m_nAddr = rhs.m_nAddr; 389 return *this; 390 } 391 392 OStorePageLink & operator= (sal_uInt32 nAddr) 393 { 394 m_nAddr = store::htonl(nAddr); 395 return *this; 396 } 397 398 /** Comparison. 399 */ 400 bool operator== (const OStorePageLink & rhs) const 401 { 402 return (m_nAddr == rhs.m_nAddr); 403 } 404 405 bool operator< (const OStorePageLink& rhs) const 406 { 407 return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr)); 408 } 409 410 /** Operation. 411 */ 412 sal_uInt32 location() const 413 { 414 return store::ntohl(m_nAddr); 415 } 416 417 void link (OStorePageLink & rPred) 418 { 419 // @@@ swap (rPred); @@@ 420 OStorePageLink tmp (rPred); 421 rPred = *this; 422 *this = tmp; 423 } 424 425 void unlink (OStorePageLink& rPred) 426 { 427 rPred = *this; 428 *this = OStorePageLink(); 429 } 430 }; 431 432 /*======================================================================== 433 * 434 * PageData. 435 * 436 *======================================================================*/ 437 typedef struct PageData OStorePageData; // backward compat. 438 struct PageData 439 { 440 typedef OStorePageGuard G; 441 typedef OStorePageDescriptor D; 442 typedef OStorePageLink L; 443 444 /** Representation. 445 */ 446 G m_aGuard; 447 D m_aDescr; 448 L m_aMarked; 449 L m_aUnused; 450 451 /** theSize. 452 */ 453 static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L); 454 static const sal_uInt16 thePageSize = theSize; 455 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize); 456 457 /** location. 458 */ 459 sal_uInt32 location() const 460 { 461 return store::ntohl(m_aDescr.m_nAddr); 462 } 463 void location (sal_uInt32 nAddr) 464 { 465 m_aDescr.m_nAddr = store::htonl(nAddr); 466 } 467 468 /** size. 469 */ 470 sal_uInt16 size() const 471 { 472 return store::ntohs(m_aDescr.m_nSize); 473 } 474 475 /** type. 476 */ 477 sal_uInt32 type() const 478 { 479 return store::ntohl(m_aGuard.m_nMagic); 480 } 481 482 /** Allocation. 483 */ 484 class Allocator_Impl; 485 class Allocator : public rtl::IReference 486 { 487 public: 488 template< class T > T * construct() 489 { 490 void * page = 0; sal_uInt16 size = 0; 491 if (allocate (&page, &size)) 492 { 493 return new(page) T(size); 494 } 495 return 0; 496 } 497 498 bool allocate (void ** ppPage, sal_uInt16 * pnSize) 499 { 500 allocate_Impl (ppPage, pnSize); 501 return ((*ppPage != 0) && (*pnSize != 0)); 502 } 503 504 void deallocate (void * pPage) 505 { 506 if (pPage != 0) 507 deallocate_Impl (pPage); 508 } 509 510 static storeError createInstance ( 511 rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize); 512 513 private: 514 /** Implementation (abstract). 515 */ 516 virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) = 0; 517 virtual void deallocate_Impl (void * pPage) = 0; 518 }; 519 520 static void* operator new (size_t, void * p) { return p; } 521 static void operator delete (void * , void *) {} 522 523 /** Construction. 524 */ 525 explicit PageData (sal_uInt16 nPageSize = thePageSize) 526 : m_aGuard(), 527 m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize), 528 m_aMarked(), 529 m_aUnused() 530 {} 531 532 void swap (PageData & rhs) // nothrow 533 { 534 m_aGuard.swap(rhs.m_aGuard); 535 m_aDescr.swap(rhs.m_aDescr); 536 m_aMarked.swap(rhs.m_aMarked); 537 m_aUnused.swap(rhs.m_aUnused); 538 } 539 540 PageData (PageData const & rhs) // nothrow 541 : m_aGuard (rhs.m_aGuard), 542 m_aDescr (rhs.m_aDescr), 543 m_aMarked(rhs.m_aMarked), 544 m_aUnused(rhs.m_aUnused) 545 {} 546 547 PageData & operator= (PageData const & rhs) // nothrow 548 { 549 PageData tmp (rhs); 550 swap (tmp); 551 return *this; 552 } 553 554 /** guard (external representation). 555 */ 556 void guard (sal_uInt32 nAddr) 557 { 558 sal_uInt32 nCRC32 = 0; 559 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); 560 m_aDescr.m_nAddr = store::htonl(nAddr); 561 nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); 562 m_aGuard.m_nCRC32 = store::htonl(nCRC32); 563 } 564 565 /** verify (external representation). 566 */ 567 storeError verify (sal_uInt32 nAddr) const 568 { 569 sal_uInt32 nCRC32 = 0; 570 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); 571 nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); 572 if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) 573 return store_E_InvalidChecksum; 574 if (m_aDescr.m_nAddr != store::htonl(nAddr)) 575 return store_E_InvalidAccess; 576 return store_E_None; 577 } 578 579 storeError verifyVersion (sal_uInt32 nMagic) const 580 { 581 if (m_aGuard.m_nMagic != store::htonl(nMagic)) 582 return store_E_WrongVersion; 583 else 584 return store_E_None; 585 } 586 }; 587 588 /*======================================================================== 589 * 590 * PageHolder. 591 * 592 *======================================================================*/ 593 class PageHolder 594 { 595 SharedCount m_refcount; 596 PageData * m_pagedata; 597 598 typedef rtl::Reference< PageData::Allocator > allocator_type; 599 allocator_type m_allocator; 600 601 public: 602 explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type()) 603 : m_refcount (), 604 m_pagedata (pagedata), 605 m_allocator(allocator) 606 { 607 OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator."); 608 } 609 610 ~PageHolder() 611 { 612 if ((m_refcount == 1) && (m_pagedata != 0)) 613 { 614 // free pagedata. 615 OSL_ENSURE(m_allocator.is(), "store::PageHolder::dtor(): pagedata w/o allocator."); 616 m_allocator->deallocate (m_pagedata); 617 } 618 } 619 620 void swap (PageHolder & rhs) // nothrow 621 { 622 m_refcount.swap(rhs.m_refcount); 623 store::swap(m_pagedata, rhs.m_pagedata); 624 store::swap(m_allocator, rhs.m_allocator); 625 } 626 627 PageHolder (PageHolder const & rhs) // nothrow 628 : m_refcount (rhs.m_refcount), 629 m_pagedata (rhs.m_pagedata), 630 m_allocator(rhs.m_allocator) 631 {} 632 633 PageHolder & operator= (PageHolder const & rhs) // nothrow 634 { 635 PageHolder tmp (rhs); 636 swap(tmp); 637 return *this; 638 } 639 640 PageData * get() { return m_pagedata; } 641 PageData const * get() const { return m_pagedata; } 642 643 PageData * operator->() 644 { 645 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer"); 646 return m_pagedata; 647 } 648 PageData const * operator->() const 649 { 650 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer"); 651 return m_pagedata; 652 } 653 654 PageData & operator*() 655 { 656 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer"); 657 return *m_pagedata; 658 } 659 PageData const & operator*() const 660 { 661 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer"); 662 return *m_pagedata; 663 } 664 }; 665 666 /*======================================================================== 667 * 668 * PageHolderObject. 669 * 670 *======================================================================*/ 671 template< class T > 672 class PageHolderObject 673 { 674 /** Representation. 675 */ 676 PageHolder m_xPage; 677 678 /** Checked cast. 679 */ 680 template< class U > 681 static bool isA (PageData const * p) 682 { 683 return ((p != 0) && (p->type() == U::theTypeId)); 684 } 685 686 template< class U > 687 static U * dynamic_page_cast (PageData * p) 688 { 689 return isA<U>(p) ? static_cast<U*>(p) : 0; 690 } 691 692 template< class U > 693 static U const * dynamic_page_cast (PageData const * p) 694 { 695 return isA<U>(p) ? static_cast<U const *>(p) : 0; 696 } 697 698 public: 699 bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator) 700 { 701 if ((m_xPage.get() == 0) && rxAllocator.is()) 702 { 703 PageHolder tmp (rxAllocator->construct<T>(), rxAllocator); 704 m_xPage.swap (tmp); 705 } 706 return (m_xPage.get() != 0); 707 } 708 709 static PageHolderObject<T> createInstance (rtl::Reference< PageData::Allocator > const & rxAllocator) 710 { 711 PageHolderObject<T> tmp; 712 (void) tmp.construct (rxAllocator); 713 return tmp; 714 } 715 716 explicit PageHolderObject (PageHolder const & rxPage = PageHolder()) 717 : m_xPage (rxPage) 718 {} 719 720 void swap (PageHolderObject<T> & rhs) 721 { 722 m_xPage.swap (rhs.m_xPage); 723 } 724 725 PageHolderObject (PageHolderObject<T> const & rhs) 726 : m_xPage (rhs.m_xPage) 727 {} 728 729 PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs) 730 { 731 PageHolderObject<T> tmp (rhs); 732 this->swap (tmp); 733 return *this; 734 } 735 736 bool is() const 737 { 738 return (m_xPage.get() != 0); 739 } 740 741 #if 1 /* EXP */ 742 PageHolder & get() { return m_xPage; } 743 PageHolder const & get() const { return m_xPage; } 744 #endif /* EXP */ 745 746 T * operator->() 747 { 748 T * pImpl = dynamic_page_cast<T>(m_xPage.get()); 749 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); 750 return pImpl; 751 } 752 T const * operator->() const 753 { 754 T const * pImpl = dynamic_page_cast<T>(m_xPage.get()); 755 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); 756 return pImpl; 757 } 758 759 T & operator*() 760 { 761 T * pImpl = dynamic_page_cast<T>(m_xPage.get()); 762 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); 763 return (*pImpl); 764 } 765 T const & operator*() const 766 { 767 T const * pImpl = dynamic_page_cast<T>(m_xPage.get()); 768 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); 769 return (*pImpl); 770 } 771 772 static storeError guard (PageHolder & rxPage, sal_uInt32 nAddr) 773 { 774 PageData * pHead = rxPage.get(); 775 if (!pHead) 776 return store_E_InvalidAccess; 777 pHead->guard(nAddr); 778 779 T * pImpl = dynamic_page_cast<T>(pHead); 780 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::guard(): Null pointer"); 781 pImpl->guard(); 782 783 return store_E_None; 784 } 785 static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr) 786 { 787 PageData const * pHead = rxPage.get(); 788 if (!pHead) 789 return store_E_InvalidAccess; 790 791 storeError eErrCode = pHead->verify(nAddr); 792 if (eErrCode != store_E_None) 793 return eErrCode; 794 795 T const * pImpl = dynamic_page_cast<T>(pHead); 796 if (!pImpl) 797 return store_E_WrongVersion; 798 799 return pImpl->verify(); 800 } 801 }; 802 803 /*======================================================================== 804 * 805 * PageObject. 806 * 807 *======================================================================*/ 808 #if 1 /* EXP */ 809 class PageObject 810 { 811 public: 812 explicit PageObject (PageHolder const & rxPage = PageHolder()) 813 : m_xPage (rxPage), m_bDirty (false) 814 {} 815 816 virtual ~PageObject() 817 {} 818 819 PageHolder & get() { return m_xPage; } 820 PageHolder const & get() const { return m_xPage; } 821 822 void clean() { m_bDirty = false; } 823 void touch() { m_bDirty = true; } 824 825 sal_uInt32 location() const 826 { 827 PageData const * pagedata = m_xPage.get(); 828 return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL; 829 } 830 void location (sal_uInt32 nAddr) 831 { 832 PageData * pagedata = m_xPage.get(); 833 if (pagedata != 0) 834 pagedata->location (nAddr); 835 } 836 837 protected: 838 PageHolder m_xPage; 839 bool m_bDirty; 840 841 virtual storeError guard (sal_uInt32 nAddr) = 0; 842 virtual storeError verify (sal_uInt32 nAddr) const = 0; 843 }; 844 #endif /* EXP */ 845 846 class OStorePageBIOS; 847 848 class OStorePageObject 849 { 850 typedef OStorePageData page; 851 852 public: 853 /** Allocation. 854 */ 855 static void * operator new (size_t n) SAL_THROW(()) 856 { 857 return rtl_allocateMemory (sal_uInt32(n)); 858 } 859 static void operator delete (void * p, size_t) SAL_THROW(()) 860 { 861 rtl_freeMemory (p); 862 } 863 864 /** State. 865 */ 866 inline bool dirty (void) const; 867 inline void clean (void); 868 inline void touch (void); 869 870 /** Location. 871 */ 872 inline sal_uInt32 location (void) const; 873 inline void location (sal_uInt32 nAddr); 874 875 protected: 876 /** Representation. 877 */ 878 PageHolder m_xPage; 879 bool m_bDirty; 880 881 /** Construction. 882 */ 883 explicit OStorePageObject (PageHolder const & rxPage = PageHolder()) 884 : m_xPage (rxPage), m_bDirty (false) 885 {} 886 887 /** Destruction. 888 */ 889 virtual ~OStorePageObject (void); 890 891 public: 892 template< class U > 893 PageHolderObject<U> makeHolder() const 894 { 895 return PageHolderObject<U>(m_xPage); 896 } 897 898 template< class U > 899 storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator) 900 { 901 if (!rxAllocator.is()) 902 return store_E_InvalidAccess; 903 904 PageHolder tmp (rxAllocator->construct<U>(), rxAllocator); 905 if (!tmp.get()) 906 return store_E_OutOfMemory; 907 908 m_xPage.swap (tmp); 909 return store_E_None; 910 } 911 912 913 PageHolder & get() { return m_xPage; } 914 PageHolder const & get() const { return m_xPage; } 915 916 virtual storeError guard (sal_uInt32 nAddr) = 0; 917 virtual storeError verify (sal_uInt32 nAddr) const = 0; 918 }; 919 920 inline bool OStorePageObject::dirty (void) const 921 { 922 return m_bDirty; 923 } 924 925 inline void OStorePageObject::clean (void) 926 { 927 m_bDirty = false; 928 } 929 930 inline void OStorePageObject::touch (void) 931 { 932 m_bDirty = true; 933 } 934 935 inline sal_uInt32 OStorePageObject::location (void) const 936 { 937 return m_xPage->location(); 938 } 939 940 inline void OStorePageObject::location (sal_uInt32 nAddr) 941 { 942 m_xPage->location(nAddr); 943 touch(); 944 } 945 946 /*======================================================================== 947 * 948 * The End. 949 * 950 *======================================================================*/ 951 952 } // namespace store 953 954 #endif /* !_STORE_STORBASE_HXX_ */ 955