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