1 /* 2 * t_page.cxx 3 */ 4 5 #include "osl/diagnose.h" 6 #include "rtl/alloc.h" 7 #include "rtl/ref.hxx" 8 9 #include "storbase.hxx" 10 11 #include "osl/file.h" 12 #include "rtl/ustring.hxx" 13 14 /*======================================================================== 15 * 16 * OTest... 17 * 18 *======================================================================*/ 19 20 template< class T > void swap (T & lhs, T & rhs) 21 { 22 T tmp = rhs; rhs = lhs; lhs = tmp; 23 } 24 25 /*======================================================================*/ 26 27 class SharedCount 28 { 29 long * m_pCount; 30 31 class Allocator 32 { 33 rtl_cache_type * m_cache; 34 35 public: 36 static Allocator & get(); 37 38 long * alloc() 39 { 40 return static_cast<long*>(rtl_cache_alloc (m_cache)); 41 } 42 void free (long * pCount) 43 { 44 rtl_cache_free (m_cache, pCount); 45 } 46 47 protected: 48 Allocator(); 49 ~Allocator(); 50 }; 51 52 public: 53 SharedCount() 54 : m_pCount(Allocator::get().alloc()) 55 { 56 if (m_pCount != 0) (*m_pCount) = 1; 57 } 58 59 ~SharedCount() 60 { 61 if (m_pCount != 0) 62 { 63 long new_count = --(*m_pCount); 64 if (new_count == 0) 65 Allocator::get().free(m_pCount); 66 } 67 } 68 69 bool operator== (long count) const 70 { 71 return (m_pCount != 0) ? *m_pCount == count : false; 72 } 73 74 friend void swap<> (SharedCount & lhs, SharedCount & rhs); // nothrow 75 76 SharedCount (SharedCount const & rhs); // nothrow 77 SharedCount & operator= (SharedCount const & rhs); // nothrow 78 }; 79 80 template<> 81 inline void swap (SharedCount & lhs, SharedCount & rhs) // nothrow 82 { 83 swap<long*>(lhs.m_pCount, rhs.m_pCount); 84 } 85 86 SharedCount::SharedCount (SharedCount const & rhs) // nothrow 87 : m_pCount (rhs.m_pCount) 88 { 89 if (m_pCount != 0) ++(*m_pCount); 90 } 91 92 SharedCount & 93 SharedCount::operator= (SharedCount const & rhs) // nothrow 94 { 95 SharedCount tmp(rhs); 96 swap<SharedCount>(tmp, *this); 97 return *this; 98 } 99 100 SharedCount::Allocator & 101 SharedCount::Allocator::get() 102 { 103 static Allocator g_aSharedCountAllocator; 104 return g_aSharedCountAllocator; 105 } 106 107 SharedCount::Allocator::Allocator() 108 { 109 m_cache = rtl_cache_create ( 110 "store_shared_count_cache", 111 sizeof(long), 112 0, // objalign 113 0, // constructor 114 0, // destructor 115 0, // reclaim 116 0, // userarg 117 0, // default source 118 0 // flags 119 ); 120 } 121 122 SharedCount::Allocator::~Allocator() 123 { 124 rtl_cache_destroy (m_cache), m_cache = 0; 125 } 126 127 /*======================================================================*/ 128 129 #if 0 /* OLD */ 130 131 typedef store::OStorePageData PageData; 132 133 #else /* NEW */ 134 135 #if defined(OSL_BIGENDIAN) 136 #define STORE_DWORD(dword) OSL_SWAPDWORD((dword)) 137 #else 138 #define STORE_DWORD(dword) (dword) 139 #endif 140 141 struct PageData 142 { 143 typedef store::OStorePageGuard G; 144 typedef store::OStorePageDescriptor D; 145 typedef store::OStorePageLink L; 146 147 /** Representation. 148 */ 149 G m_aGuard; 150 D m_aDescr; 151 L m_aMarked; 152 L m_aUnused; 153 154 /** theSize. 155 */ 156 static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L); 157 static const sal_uInt16 thePageSize = theSize; 158 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize); 159 160 /** type. 161 */ 162 sal_uInt32 type() const { return m_aGuard.m_nMagic; /* @@@ */ } 163 164 /** offset. 165 */ 166 sal_uInt32 offset() const { return m_aDescr.m_nAddr; /* @@@ */ } 167 void offset (sal_uInt32 nOffset) { m_aDescr.m_nAddr = nOffset; } 168 169 /** size. 170 */ 171 sal_uInt16 size() const { return m_aDescr.m_nSize; /* @@@ */ } 172 173 /** Allocation. 174 */ 175 class Allocator : public rtl::IReference 176 { 177 public: 178 template< class T > T * construct() 179 { 180 void * page = 0; sal_uInt16 size = 0; 181 if (allocate (&page, &size)) 182 { 183 return new(page) T(size); 184 } 185 return 0; 186 } 187 188 virtual bool allocate (void ** ppPage, sal_uInt16 * pnSize) = 0; 189 virtual void deallocate (void * pPage) = 0; 190 }; 191 192 static void * operator new (size_t, void * p) { return p; } 193 static void operator delete (void *, void *) {} 194 195 /** Construction. 196 */ 197 explicit PageData (sal_uInt16 nPageSize = thePageSize) 198 : m_aDescr (STORE_PAGE_NULL, nPageSize, thePageSize) 199 {} 200 201 /** ... 202 */ 203 void guard() 204 {} 205 206 storeError verify() const 207 { 208 return store_E_None; 209 } 210 }; 211 212 #endif /* NEW */ 213 214 class IPageAllocator 215 { 216 public: 217 virtual void deallocate (void * p) = 0; 218 }; 219 220 class PageAllocator 221 { 222 rtl_cache_type * m_cache; 223 SharedCount m_refcount; 224 225 public: 226 PageAllocator() 227 : m_cache(0), m_refcount() 228 {} 229 230 ~PageAllocator() 231 { 232 // NYI 233 if (m_refcount == 1) 234 { 235 } 236 } 237 238 friend void swap<>(PageAllocator & lhs, PageAllocator & rhs); 239 240 PageAllocator (PageAllocator const & rhs); 241 PageAllocator & operator= (PageAllocator const & rhs); 242 }; 243 244 template<> 245 inline void swap (PageAllocator & lhs, PageAllocator & rhs) 246 { 247 swap<rtl_cache_type*>(lhs.m_cache, rhs.m_cache); 248 swap<SharedCount>(lhs.m_refcount, rhs.m_refcount); 249 } 250 251 PageAllocator::PageAllocator (PageAllocator const & rhs) 252 : m_cache (rhs.m_cache), 253 m_refcount (rhs.m_refcount) 254 { 255 } 256 257 PageAllocator & 258 PageAllocator::operator= (PageAllocator const & rhs) 259 { 260 PageAllocator tmp (rhs); 261 swap<PageAllocator>(tmp, *this); 262 return *this; 263 } 264 265 /*======================================================================*/ 266 267 class PageHolder 268 { 269 SharedCount m_refcount; 270 PageData * m_pagedata; 271 272 typedef rtl::Reference< PageData::Allocator > allocator_type; 273 allocator_type m_allocator; 274 275 public: 276 explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type()) 277 : m_refcount (), 278 m_pagedata (pagedata), 279 m_allocator(allocator) 280 {} 281 282 ~PageHolder() 283 { 284 if ((m_refcount == 1) && (m_pagedata != 0) && m_allocator.is()) 285 { 286 // free pagedata. 287 m_allocator->deallocate (m_pagedata); 288 } 289 } 290 291 PageData * get() { return m_pagedata; } 292 PageData const * get() const { return m_pagedata; } 293 294 PageData * operator->() { return m_pagedata; } 295 PageData const * operator->() const { return m_pagedata; } 296 297 friend void swap<> (PageHolder & lhs, PageHolder & rhs); // nothrow 298 299 PageHolder (PageHolder const & rhs); // nothrow 300 PageHolder & operator= (PageHolder const & rhs); // nothrow 301 }; 302 303 template<> 304 inline void swap (PageHolder & lhs, PageHolder & rhs) // nothrow 305 { 306 swap<SharedCount>(lhs.m_refcount, rhs.m_refcount); 307 swap<PageData*>(lhs.m_pagedata, rhs.m_pagedata); 308 swap<PageHolder::allocator_type>(lhs.m_allocator, rhs.m_allocator); 309 } 310 311 PageHolder::PageHolder (PageHolder const & rhs) // nothrow 312 : m_refcount (rhs.m_refcount), 313 m_pagedata (rhs.m_pagedata), 314 m_allocator(rhs.m_allocator) 315 {} 316 317 PageHolder & 318 PageHolder::operator= (PageHolder const & rhs) // nothrow 319 { 320 PageHolder tmp (rhs); 321 swap<PageHolder>(tmp, *this); 322 return *this; 323 } 324 325 /*======================================================================*/ 326 327 template< class T > 328 class PageHolderObject 329 { 330 protected: 331 /** Representation. 332 */ 333 PageHolder m_xPage; 334 335 /** Checked cast. 336 */ 337 template< class U > 338 static bool isA (PageData const * p) 339 { 340 return ((p != 0) && (p->type() == U::theTypeId)); 341 } 342 343 template< class U > 344 static U * dynamic_page_cast (PageData * p) 345 { 346 return isA<U>(p) ? static_cast<U*>(p) : 0; 347 } 348 349 template< class U > 350 static U const * dynamic_page_cast (PageData const * p) 351 { 352 return isA<U>(p) ? static_cast<U const *>(p) : 0; 353 } 354 355 public: 356 static PageHolderObject<T> construct (rtl::Reference< PageData::Allocator > const & rxAllocator) 357 { 358 PageHolderObject<T> tmp; 359 if (rxAllocator.is()) 360 { 361 PageHolder xPage (rxAllocator->construct<T>(), rxAllocator); 362 store::swap<PageHolder>(tmp.m_xPage, xPage); 363 } 364 return tmp; 365 } 366 367 explicit PageHolderObject (PageHolder const & rxPage = PageHolder()) 368 : m_xPage (rxPage) 369 {} 370 371 void swap (PageHolderObject<T> & rhs) 372 { 373 store::swap<PageHolder>(m_xPage, rhs.m_xPage); 374 } 375 376 PageHolderObject (PageHolderObject<T> const & rhs) 377 : m_xPage (rhs.m_xPage) 378 { 379 } 380 381 PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs) 382 { 383 PageHolderObject<T> tmp (rhs); 384 this->swap(tmp); 385 return *this; 386 } 387 388 T * operator->() 389 { 390 T * pImpl = dynamic_page_cast<T>(m_xPage.get()); 391 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer"); 392 return pImpl; 393 } 394 T const * operator->() const 395 { 396 T const * pImpl = dynamic_page_cast<T>(m_xPage.get()); 397 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer"); 398 return pImpl; 399 } 400 401 T & operator*() 402 { 403 T * pImpl = dynamic_page_cast<T>(m_xPage.get()); 404 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); 405 return *pImpl; 406 } 407 T const & operator*() const 408 { 409 T const * pImpl = dynamic_page_cast<T>(m_xPage.get()); 410 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); 411 return *pImpl; 412 } 413 414 static storeError guard (PageHolder & rxPage) 415 { 416 T * pImpl = dynamic_page_cast<T>(rxPage.get()); 417 if (pImpl != 0) 418 { pImpl->guard(); return store_E_None; } 419 else if (rxPage.get() != 0) 420 return store_E_WrongVersion; 421 else 422 return store_E_InvalidAccess; 423 } 424 static storeError verify (PageHolder const & rxPage) 425 { 426 T const * pImpl = dynamic_page_cast<T>(rxPage.get()); 427 if (pImpl != 0) 428 return pImpl->verify(); 429 else if (rxPage.get() != 0) 430 return store_E_WrongVersion; 431 else 432 return store_E_InvalidAccess; 433 } 434 }; 435 436 /*======================================================================*/ 437 438 class PageObject 439 { 440 public: 441 explicit PageObject (PageHolder const & rxPage = PageHolder()) 442 : m_xPage (rxPage) 443 {} 444 445 virtual ~PageObject(); 446 447 PageHolder & get() { return m_xPage; } 448 PageHolder const & get() const { return m_xPage; } 449 450 PageData * operator->() 451 { 452 PageData * pImpl = m_xPage.get(); 453 OSL_PRECOND(pImpl != 0, "store::PageObject::operator->(): Null pointer"); 454 return pImpl; 455 } 456 PageData & operator*() 457 { 458 PageData * pImpl = m_xPage.get(); 459 OSL_PRECOND(pImpl != 0, "store::PageObject::operator*(): Null pointer"); 460 return *pImpl; 461 } 462 463 virtual void guard(); 464 virtual storeError verify() const; 465 466 protected: 467 PageHolder m_xPage; 468 }; 469 470 PageObject::~PageObject() 471 {} 472 void PageObject::guard() 473 { 474 PageData * p = m_xPage.get(); 475 p->guard(); 476 } 477 storeError PageObject::verify() const 478 { 479 PageData const * p = m_xPage.get(); 480 return p->verify(); 481 } 482 483 /*======================================================================*/ 484 485 template< class T > 486 T * dynamic_page_cast (PageData * pagedata) 487 { 488 if ((pagedata != 0) && (pagedata->type() == T::theTypeId)) 489 return static_cast<T*>(pagedata); 490 return 0; 491 } 492 493 template< class T > 494 T * dynamic_page_cast (PageData const * pagedata) 495 { 496 if ((pagedata != 0) && (pagedata->type() == T::theTypeId)) 497 return static_cast<T*>(pagedata); 498 return 0; 499 } 500 501 /*======================================================================*/ 502 503 class TestBIOS 504 { 505 public: 506 storeError loadPageAt (PageHolder & rPage, storeError (*pfnVerify)(PageHolder const &)) 507 { 508 return (pfnVerify)(rPage); 509 } 510 511 storeError allocate (PageHolder & rxPage, ...) 512 { 513 // NYI: PageObject.save(nAddr, *this); 514 (void)rxPage; // NYI 515 return store_E_Unknown; // NYI 516 } 517 518 storeError loadAt (PageHolder & rPage, sal_uInt32 nOffset) 519 { 520 (void)rPage; // NYI 521 (void)nOffset; // NYI 522 return store_E_Unknown; // NYI 523 } 524 storeError saveAt (PageHolder const & rPage, sal_uInt32 nOffset) 525 { 526 (void)rPage; // NYI 527 (void)nOffset; // NYI 528 return store_E_Unknown; // NYI 529 } 530 531 template< class T > 532 storeError save (PageHolder & rxPage, sal_uInt32 nOffset) 533 { 534 storeError result = PageHolderObject<T>::guard (rxPage); 535 if (result != store_E_None) 536 return result; 537 return saveAt (rxPage, nOffset); 538 } 539 540 storeError lookupAt (PageHolder & rPage, sal_uInt32 nOffset) 541 { 542 (void)rPage; // NYI 543 (void)nOffset; // NYI 544 return store_E_NotExists; 545 } 546 storeError replaceAt (PageHolder const & rPage, sal_uInt32 nOffset) 547 { 548 (void)rPage; // NYI 549 (void)nOffset; // NYI 550 return store_E_None; 551 } 552 }; 553 554 struct TestDataV1 : public PageData 555 { 556 static const sal_uInt32 theTypeId = 6 * 9; 557 }; 558 struct TestData : public PageData 559 { 560 typedef PageData base; 561 typedef TestData self; 562 563 static const sal_uInt32 theTypeId = 42; 564 565 void guard() 566 { 567 base::guard(); 568 // self::m_aGuard = ...; 569 } 570 storeError verify() const 571 { 572 storeError result = base::verify(); 573 if (result != store_E_None) 574 return result; 575 if (!(base::type() == self::theTypeId)) 576 return store_E_WrongVersion; 577 return store_E_None; 578 } 579 580 storeError dwim() const 581 { 582 return store_E_None; 583 } 584 }; 585 class TestObject : public PageObject 586 { 587 typedef PageObject base; 588 589 public: 590 591 void dwim() 592 { 593 PageHolderObject< TestData > xPage (m_xPage); 594 xPage->guard(); 595 } 596 597 virtual void guard() 598 { 599 TestData * pagedata = dynamic_page_cast< TestData >(m_xPage.get()); 600 if (pagedata != 0) 601 {} 602 } 603 virtual storeError verify() const 604 { 605 storeError result = base::verify(); 606 if (result != store_E_None) 607 return result; 608 609 TestData const * pagedata = dynamic_page_cast< TestData const >(m_xPage.get()); 610 if (!pagedata) 611 return store_E_WrongVersion; 612 613 return pagedata->verify(); 614 } 615 616 static storeError verify (PageHolder const & rPage) 617 { 618 return PageHolderObject< TestData >::verify (rPage); 619 } 620 621 storeError loadAt (sal_uInt32 nOffset, TestBIOS & rBIOS) 622 { 623 storeError result = rBIOS.lookupAt (m_xPage, nOffset); // cache lookup 624 if (result == store_E_NotExists) 625 { 626 result = rBIOS.loadAt (m_xPage, nOffset); 627 if (result != store_E_None) 628 return result; 629 630 result = PageHolderObject< TestData >::verify (m_xPage); 631 if (result != store_E_None) 632 return result; 633 634 result = rBIOS.replaceAt (m_xPage, nOffset); // cache insert 635 } 636 return result; 637 } 638 storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS) 639 { 640 if (!m_xPage.get()) 641 return store_E_InvalidAccess; 642 m_xPage->m_aDescr.m_nAddr = store::htonl(nOffset); // m_xPage->location (nOffset); 643 644 storeError result = PageHolderObject< TestData >::guard (m_xPage); 645 if (result != store_E_None) 646 return result; 647 648 result = rBIOS.saveAt (m_xPage, nOffset); 649 if (result != store_E_None) 650 return result; 651 652 return rBIOS.replaceAt (m_xPage, nOffset); // cache update 653 } 654 }; 655 656 class TestObjectV2 : public PageHolderObject< TestData > 657 { 658 typedef PageHolderObject< TestData > base; 659 660 public: 661 storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS) 662 { 663 m_xPage->offset(nOffset); 664 665 storeError result = PageHolderObject< TestData >::guard (m_xPage); 666 if (result != store_E_None) 667 return result; 668 669 result = rBIOS.saveAt (m_xPage, nOffset); 670 if (result != store_E_None) 671 return result; 672 673 return rBIOS.replaceAt (m_xPage, nOffset); 674 } 675 #if 1 676 storeError dwim() const 677 { 678 TestData const * pImpl1 = operator->(); 679 680 PageHolderObject< TestData > xImpl (m_xPage); 681 682 TestData const * pImpl2 = &*xImpl; 683 OSL_ASSERT(pImpl1 == pImpl2); 684 685 return xImpl->dwim(); 686 } 687 #endif 688 }; 689 690 class TestClient 691 { 692 public: 693 void dwim(TestBIOS & rBIOS) 694 { 695 TestObject aObj; 696 697 rBIOS.loadPageAt(aObj.get(), aObj.verify); 698 rBIOS.loadPageAt(aObj.get(), TestObject::verify); 699 rBIOS.loadPageAt(aObj.get(), PageHolderObject<TestData>::verify); 700 701 aObj.loadAt (1024, rBIOS); 702 703 TestObjectV2 aObj2; 704 aObj2.dwim(); 705 aObj2->dwim(); 706 } 707 }; 708 709 /*======================================================================*/ 710 #if 0 /* NYI */ 711 BIOS::load (PageObject & rPage, sal_uInt32 nOffset) 712 { 713 result = m_xCache->readPageAt (rPage.get(), nOffset); 714 if (result == NotExists) 715 { 716 result = m_xLockBytes->readPageAt (rPage.get(), nOffset); 717 if (result != None) 718 return result; 719 720 result = rPage.verify(); 721 if (result != None) 722 return result; 723 724 result = m_xCache->writePageAt (rPage.get(), nOffset); 725 } 726 return result; 727 } 728 BIOS::save (PageObject & rPage, sal_uInt32 nOffset) 729 { 730 rPage.guard(); 731 result = m_xLockBytes->writePageAt (rPage.get(), nOffset); 732 if (result != None) 733 return result; 734 735 return m_xCache->writePageAt (rPage.get(), nOffset); 736 } 737 BIOS::init (rxLockBytes, eAccessMode, nPageSize) 738 { 739 SuperPage super; 740 if (eAccessMode == store_AccessCreate) 741 { 742 sal_uInt16 pagesize = nPageSize; 743 if ((STORE_MINIMUM_PAGESIZE > pagesize) || (pagesize > STORE_MAXIMUM_PAGESIZE)) 744 return store_E_InvalidParameter; 745 746 pagesize = ((pagesize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1)); 747 rxLockBytes->init (pagesize); 748 749 super = allocator->construct<SuperPage>(); 750 super->guard(); 751 752 rxLockBytes->writeAt (0, super, super->size()); 753 754 } 755 if (eAccessMode != store_AccessCreate) 756 { 757 rxLockBytes->readAt (0, &super, super::theSize); 758 759 super.verify(); 760 } 761 if (eErrCode != store_E_NotExists) 762 763 764 } 765 #endif /* NYI */ 766 /*======================================================================*/ 767 768 #if 0 /* NYI */ 769 class PageCache 770 { 771 std::set<const sal_uInt32, PageObject> m_pages; 772 public: 773 storeError readPageAt (PageObject & rPage, sal_uInt32 nOffset); 774 storeError writePageAt (PageObject const & rPage, sal_uInt32 nOffset); 775 }; 776 #endif /* NYI */ 777 778 /*======================================================================*/ 779 780 class IPageAllocator; 781 class IPageAccess 782 { 783 public: 784 virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) = 0; 785 virtual IPageAllocator & getAllocator () = 0; 786 787 public: 788 storeError readPageAt (PageHolder & rPage, sal_uInt32 nOffset) 789 { 790 return readPageAt_Impl (rPage, nOffset); 791 } 792 storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset) 793 { 794 // [SECURITY:ValInput] 795 PageData const * pagedata = rPage.get(); 796 OSL_PRECOND(!(pagedata == 0), "invalid Page"); 797 if (pagedata == 0) 798 return store_E_InvalidParameter; 799 800 sal_uInt32 const offset = pagedata->offset(); 801 OSL_PRECOND(!(nOffset != offset), "inconsistent Offset"); 802 if (nOffset != offset) 803 return store_E_InvalidParameter; 804 805 OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::IPageAccess::writePageAt(): invalid Offset"); 806 if (nOffset == STORE_PAGE_NULL) 807 return store_E_CantSeek; 808 809 return writePageAt_Impl (rPage, nOffset); 810 } 811 812 storeError peekAt (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) 813 { 814 // [SECURITY:ValInput] 815 sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer); 816 if (!(dst_lo != 0)) 817 return store_E_InvalidParameter; 818 819 sal_uInt8 * dst_hi = dst_lo + nBytes; 820 if (!(dst_lo < dst_hi)) 821 return (dst_lo > dst_hi) ? store_E_InvalidParameter : store_E_None; 822 823 sal_uInt64 const dst_size = nOffset + nBytes; 824 if (dst_size > SAL_MAX_UINT32) 825 return store_E_CantSeek; 826 827 return peekAt_Impl (nOffset, dst_lo, (dst_hi - dst_lo)); 828 } 829 830 storeError pokeAt (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) 831 { 832 // [SECURITY:ValInput] 833 sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer); 834 if (!(src_lo != 0)) 835 return store_E_InvalidParameter; 836 837 sal_uInt8 const * src_hi = src_lo + nBytes; 838 if (!(src_lo < src_hi)) 839 return (src_lo > src_hi) ? store_E_InvalidParameter : store_E_None; 840 841 sal_uInt64 const dst_size = nOffset + nBytes; 842 if (dst_size > SAL_MAX_UINT32) 843 return store_E_CantSeek; 844 845 return pokeAt_Impl (nOffset, src_lo, (src_hi - src_lo)); 846 } 847 848 storeError getSize (sal_uInt32 & rnSize) 849 { 850 rnSize = 0; 851 return getSize_Impl (rnSize); 852 } 853 854 storeError setSize (sal_uInt32 nSize) 855 { 856 return setSize_Impl (nSize); 857 } 858 859 private: 860 virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) = 0; 861 virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) = 0; 862 863 virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) = 0; 864 virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) = 0; 865 866 virtual storeError getSize_Impl (sal_uInt32 & rnSize) = 0; 867 virtual storeError setSize_Impl (sal_uInt32 nSize) = 0; 868 }; 869 870 /*======================================================================*/ 871 872 template< class T > struct ResourceHolder 873 { 874 typedef typename T::destructor_type destructor_type; 875 876 T m_value; 877 878 explicit ResourceHolder (T const & value = T()) : m_value (value) {} 879 ~ResourceHolder() { reset(); } 880 881 T & get() { return m_value; } 882 T const & get() const { return m_value; } 883 884 void set (T const & value) { m_value = value; } 885 void reset (T const & value = T()) 886 { 887 T tmp (m_value); 888 if (tmp != value) 889 destructor_type()(tmp); 890 set (value); 891 } 892 T release() 893 { 894 T tmp (m_value); 895 set (T()); 896 return tmp; 897 } 898 899 ResourceHolder (ResourceHolder & rhs) 900 { 901 set (rhs.release()); 902 } 903 ResourceHolder & operator= (ResourceHolder & rhs) 904 { 905 reset (rhs.release()); 906 return *this; 907 } 908 }; 909 910 struct FileHandle 911 { 912 oslFileHandle m_handle; 913 914 FileHandle() : m_handle(0) {} 915 916 operator oslFileHandle() { return m_handle; } 917 918 bool operator != (FileHandle const & rhs) 919 { 920 return (m_handle != rhs.m_handle); 921 } 922 923 oslFileError initialize (rtl_uString * pFilename, sal_uInt32 nFlags) 924 { 925 // Verify arguments. 926 if (!pFilename || !nFlags) 927 return osl_File_E_INVAL; 928 929 // Convert into FileUrl. 930 rtl::OUString aFileUrl; 931 if (osl_getFileURLFromSystemPath (pFilename, &(aFileUrl.pData)) != osl_File_E_None) 932 { 933 // Not system path. Maybe a file url, already. 934 rtl_uString_assign (&(aFileUrl.pData), pFilename); 935 } 936 937 // Acquire handle. 938 return osl_openFile (aFileUrl.pData, &m_handle, nFlags); 939 } 940 941 struct CloseFile 942 { 943 void operator()(FileHandle & rFile) const 944 { 945 if (rFile.m_handle != 0) 946 { 947 // Release handle. 948 (void) osl_closeFile (rFile.m_handle); 949 rFile.m_handle = 0; 950 } 951 } 952 }; 953 typedef CloseFile destructor_type; 954 }; 955 956 struct FileMapping 957 { 958 void * m_pAddr; 959 sal_uInt64 m_uSize; 960 961 FileMapping() : m_pAddr(0), m_uSize(0) {} 962 963 bool operator != (FileMapping const & rhs) const 964 { 965 return ((m_pAddr != rhs.m_pAddr) || (m_uSize != rhs.m_uSize)); 966 } 967 968 oslFileError initialize (oslFileHandle hFile) 969 { 970 // Determine mapping size. 971 oslFileError result = osl_getFileSize (hFile, &m_uSize); 972 if (result != osl_File_E_None) 973 return result; 974 if (m_uSize > SAL_MAX_UINT32) 975 return osl_File_E_OVERFLOW; 976 977 // Acquire mapping. 978 return osl_mapFile (hFile, &m_pAddr, m_uSize, 0, 0); 979 } 980 981 struct UnmapFile 982 { 983 void operator ()(FileMapping & rMapping) const 984 { 985 if ((rMapping.m_pAddr != 0) && (rMapping.m_uSize != 0)) 986 { 987 // Release mapping. 988 (void) osl_unmapFile (rMapping.m_pAddr, rMapping.m_uSize); 989 rMapping.m_pAddr = 0, rMapping.m_uSize = 0; 990 } 991 } 992 }; 993 typedef UnmapFile destructor_type; 994 }; 995 996 /*======================================================================*/ 997 998 class FilePageAccess : public IPageAccess 999 { 1000 oslFileHandle m_hFile; 1001 1002 public: 1003 static storeError ERROR_FROM_NATIVE (oslFileError eErrno); 1004 static sal_uInt32 MODE_TO_NATIVE (storeAccessMode eMode); 1005 1006 public: 1007 explicit FilePageAccess (oslFileHandle hFile = 0) : m_hFile (hFile) {} 1008 virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize); 1009 1010 private: 1011 virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); 1012 virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); 1013 1014 /* see @ OFileLockBytes */ 1015 virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); 1016 virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); 1017 1018 virtual storeError getSize_Impl (sal_uInt32 & rnSize); 1019 virtual storeError setSize_Impl (sal_uInt32 nSize); 1020 1021 protected: 1022 virtual ~FilePageAccess(); 1023 1024 private: 1025 /** Not implemented. 1026 */ 1027 FilePageAccess (FilePageAccess const &); 1028 FilePageAccess & operator= (FilePageAccess const &); 1029 }; 1030 1031 storeError FilePageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) 1032 { 1033 (void) eAccessMode; // UNUSED 1034 (void) nPageSize; // UNUSED 1035 return store_E_Unknown; // NYI 1036 } 1037 FilePageAccess::~FilePageAccess() 1038 { 1039 if (m_hFile != 0) 1040 (void) osl_closeFile (m_hFile); 1041 } 1042 storeError FilePageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) 1043 { 1044 PageHolder page (0/*allocate()*/); /* @@@ construct w/ deallocator argument @@@ */ 1045 if (!page.get()) 1046 return store_E_OutOfMemory; 1047 1048 swap<PageHolder>(page, rPage); 1049 return peekAt (nOffset, rPage.get(), 0/*size*/); 1050 } 1051 storeError FilePageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) 1052 { 1053 return pokeAt (nOffset, rPage.get(), 0/*size*/); 1054 } 1055 storeError FilePageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) 1056 { 1057 sal_uInt64 nDone = 0; 1058 oslFileError result = osl_readFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone); 1059 if (result != osl_File_E_None) 1060 return ERROR_FROM_NATIVE(result); 1061 if (nDone != nBytes) 1062 return (nDone != 0) ? store_E_CantRead : store_E_NotExists; 1063 return store_E_None; 1064 } 1065 storeError FilePageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) 1066 { 1067 sal_uInt64 nDone = 0; 1068 oslFileError result = osl_writeFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone); 1069 if (result != osl_File_E_None) 1070 return ERROR_FROM_NATIVE(result); 1071 if (nDone != nBytes) 1072 return store_E_CantWrite; 1073 return store_E_None; 1074 } 1075 storeError FilePageAccess::getSize_Impl (sal_uInt32 & rnSize) 1076 { 1077 sal_uInt64 uSize = 0; 1078 oslFileError result = osl_getFileSize (m_hFile, &uSize); 1079 if (result != osl_File_E_None) 1080 return ERROR_FROM_NATIVE(result); 1081 if (uSize > SAL_MAX_UINT32) 1082 return store_E_CantSeek; 1083 1084 rnSize = sal::static_int_cast<sal_uInt32>(uSize); 1085 return store_E_None; 1086 } 1087 storeError FilePageAccess::setSize_Impl (sal_uInt32 nSize) 1088 { 1089 oslFileError result = osl_setFileSize (m_hFile, nSize); 1090 if (result != osl_File_E_None) 1091 return ERROR_FROM_NATIVE(result); 1092 return store_E_None; 1093 } 1094 storeError FilePageAccess::ERROR_FROM_NATIVE (oslFileError eErrno) 1095 { 1096 switch (eErrno) 1097 { 1098 case osl_File_E_None: 1099 return store_E_None; 1100 1101 case osl_File_E_NOENT: 1102 return store_E_NotExists; 1103 1104 case osl_File_E_ACCES: 1105 case osl_File_E_PERM: 1106 return store_E_AccessViolation; 1107 1108 case osl_File_E_AGAIN: 1109 case osl_File_E_DEADLK: 1110 return store_E_LockingViolation; 1111 1112 case osl_File_E_BADF: 1113 return store_E_InvalidHandle; 1114 1115 case osl_File_E_INVAL: 1116 return store_E_InvalidParameter; 1117 1118 case osl_File_E_NOSPC: 1119 return store_E_OutOfSpace; 1120 1121 case osl_File_E_OVERFLOW: 1122 return store_E_CantSeek; 1123 1124 default: 1125 return store_E_Unknown; 1126 } 1127 } 1128 sal_uInt32 FilePageAccess::MODE_TO_NATIVE(storeAccessMode eAccessMode) 1129 { 1130 sal_uInt32 nMode = 0; 1131 switch (eAccessMode) 1132 { 1133 case store_AccessCreate: 1134 case store_AccessReadCreate: 1135 nMode |= osl_File_OpenFlag_Create; 1136 // fall through 1137 case store_AccessReadWrite: 1138 nMode |= osl_File_OpenFlag_Write; 1139 // fall through 1140 case store_AccessReadOnly: 1141 nMode |= osl_File_OpenFlag_Read; 1142 break; 1143 default: 1144 OSL_PRECOND(0, "store::FilePageAccess: unknown storeAccessMode"); 1145 } 1146 return nMode; 1147 } 1148 1149 /*===*/ 1150 1151 class MemoryPageAccess : public IPageAccess 1152 { 1153 /** Representation. 1154 */ 1155 sal_uInt8 * m_pData; 1156 sal_uInt32 m_nSize; 1157 1158 /** Callback function to release Representation. 1159 */ 1160 typedef void (*destructor_type)(sal_uInt8 * pData, sal_uInt32 nSize); 1161 destructor_type m_destructor; 1162 1163 /** Default destructor callback. 1164 */ 1165 static void freeMemory (sal_uInt8 * pData, sal_uInt32 nSize); 1166 1167 public: 1168 MemoryPageAccess() 1169 : m_pData (0), m_nSize (0), m_destructor (MemoryPageAccess::freeMemory) 1170 {} 1171 MemoryPageAccess (sal_uInt8 * pData, sal_uInt32 nSize, destructor_type destructor = MemoryPageAccess::freeMemory) 1172 : m_pData (pData), m_nSize (nSize), m_destructor (destructor) 1173 {} 1174 1175 virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize); 1176 1177 private: 1178 /** Page (size aligned) access. 1179 */ 1180 virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); 1181 virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); 1182 1183 /** Low level access. 1184 */ 1185 virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); 1186 virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); 1187 1188 virtual storeError getSize_Impl (sal_uInt32 & rnSize); 1189 virtual storeError setSize_Impl (sal_uInt32 nSize); 1190 1191 protected: 1192 virtual ~MemoryPageAccess(); 1193 1194 private: 1195 /** Not implemented. 1196 */ 1197 MemoryPageAccess (MemoryPageAccess const &); 1198 MemoryPageAccess & operator= (MemoryPageAccess const &); 1199 }; 1200 1201 storeError MemoryPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) 1202 { 1203 (void) eAccessMode; // UNUSED 1204 (void) nPageSize; // UNUSED 1205 return store_E_Unknown; // NYI 1206 } 1207 MemoryPageAccess::~MemoryPageAccess() 1208 { 1209 if (m_destructor != 0) 1210 { 1211 // release resource. 1212 (*m_destructor)(m_pData, m_nSize); 1213 } 1214 } 1215 storeError MemoryPageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) 1216 { 1217 /* OSL_PRECOND(nOffset % size == 0, "Unaligned page read."); */ 1218 PageHolder page (reinterpret_cast< PageData* >(m_pData + nOffset)); 1219 swap<PageHolder>(page, rPage); 1220 return store_E_None; 1221 } 1222 storeError MemoryPageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) 1223 { 1224 PageData const * pagedata = rPage.get(); 1225 if (!(pagedata != 0)) 1226 return store_E_InvalidParameter; 1227 1228 #if 0 /* NYI */ 1229 sal_uInt16 const bytes = pagedata->size(); // Descr.m_nSize; 1230 OSL_ASSERT(bytes >= PageData::thePageSize); 1231 1232 offset = rPage.location(); // Descr.m_nAddr; 1233 OSL_ASSERT(nOffset == offset); 1234 1235 OSL_PRECOND(offset % bytes == 0, "Unaligned page write."); 1236 #endif /* NYI */ 1237 return pokeAt (nOffset, pagedata, pagedata->size()); 1238 } 1239 storeError MemoryPageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) 1240 { 1241 // [SECURITY:ValInput] 1242 sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer); 1243 if (!(dst_lo != 0)) 1244 return store_E_InvalidParameter; 1245 1246 sal_uInt8 * dst_hi = dst_lo + nBytes; 1247 if (!(dst_lo <= dst_hi)) 1248 return store_E_InvalidParameter; 1249 1250 // ... 1251 sal_uInt8 const * src_lo = m_pData + nOffset; 1252 if (!(src_lo <= m_pData + m_nSize)) 1253 return store_E_CantSeek; 1254 1255 sal_uInt8 const * src_hi = src_lo + nBytes; 1256 if (!(src_hi <= m_pData + m_nSize)) 1257 return store_E_CantRead; 1258 1259 // copy. 1260 memcpy (pBuffer, src_lo, (src_hi - src_lo)); 1261 return store_E_None; 1262 } 1263 storeError MemoryPageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) 1264 { 1265 // [SECURITY:ValInput] 1266 sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer); 1267 if (!(src_lo != 0)) 1268 return store_E_InvalidParameter; 1269 1270 sal_uInt8 const * src_hi = src_lo + nBytes; 1271 if (!(src_lo <= src_hi)) 1272 return store_E_InvalidParameter; 1273 1274 sal_uInt64 const uSize = nOffset + nBytes; 1275 if (uSize > SAL_MAX_UINT32) 1276 return store_E_CantSeek; 1277 1278 // ... 1279 if (uSize > m_nSize) 1280 { 1281 // increase size. 1282 storeError eErrCode = setSize (sal::static_int_cast<sal_uInt32>(uSize)); 1283 if (eErrCode != store_E_None) 1284 return eErrCode; 1285 } 1286 1287 sal_uInt8 * dst_lo = m_pData + nOffset; 1288 if (!(dst_lo <= m_pData + m_nSize)) 1289 return store_E_CantSeek; 1290 1291 sal_uInt8 * dst_hi = dst_lo + nBytes; 1292 if (!(dst_hi <= m_pData + m_nSize)) 1293 return store_E_CantWrite; 1294 1295 // copy. 1296 memcpy (dst_lo, src_lo, (src_hi - src_lo)); 1297 return store_E_None; 1298 } 1299 storeError MemoryPageAccess::getSize_Impl (sal_uInt32 & rnSize) 1300 { 1301 rnSize = m_nSize; 1302 return store_E_None; 1303 } 1304 storeError MemoryPageAccess::setSize_Impl (sal_uInt32 nSize) 1305 { 1306 if (nSize != m_nSize) 1307 { 1308 sal_uInt8 * pData = static_cast<sal_uInt8*>(rtl_reallocateMemory (m_pData, nSize)); 1309 if (pData != 0) 1310 { 1311 if (nSize > m_nSize) 1312 memset (pData + m_nSize, 0, sal::static_int_cast< size_t >(nSize - m_nSize)); 1313 } 1314 else 1315 { 1316 if (nSize != 0) 1317 return store_E_OutOfMemory; 1318 } 1319 m_pData = pData, m_nSize = nSize; 1320 } 1321 return store_E_None; 1322 } 1323 void MemoryPageAccess::freeMemory (sal_uInt8 * pData, sal_uInt32 /*nSize*/) 1324 { 1325 rtl_freeMemory (pData); 1326 } 1327 1328 /*===*/ 1329 1330 class MappedPageAccess : public MemoryPageAccess 1331 { 1332 /** @see MemoryPageAccess::destructor_type callback function. 1333 */ 1334 static void unmapFile (sal_uInt8 * pData, sal_uInt32 nSize); 1335 1336 public: 1337 MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize); 1338 1339 virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize); 1340 1341 virtual storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset); 1342 1343 private: 1344 virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); 1345 virtual storeError setSize_Impl (sal_uInt32 nSize); 1346 1347 protected: 1348 virtual ~MappedPageAccess() {} 1349 }; 1350 1351 MappedPageAccess::MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize) 1352 : MemoryPageAccess (pData, nSize, MappedPageAccess::unmapFile) 1353 { 1354 } 1355 storeError MappedPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) 1356 { 1357 OSL_PRECOND(eAccessMode == store_AccessReadOnly, "store::MappedPageAccess: invalid AccessMode"); 1358 return MemoryPageAccess::initialize (eAccessMode, nPageSize); 1359 } 1360 storeError MappedPageAccess::writePageAt (PageHolder const & /*rPage*/, sal_uInt32 /*nOffset*/) 1361 { 1362 return store_E_AccessViolation; 1363 } 1364 storeError MappedPageAccess::pokeAt_Impl (sal_uInt32 /*nOffset*/, void const * /*pBuffer*/, sal_uInt32 /*nBytes*/) 1365 { 1366 return store_E_AccessViolation; 1367 } 1368 storeError MappedPageAccess::setSize_Impl (sal_uInt32 /*nSize*/) 1369 { 1370 return store_E_AccessViolation; 1371 } 1372 void MappedPageAccess::unmapFile (sal_uInt8 * pData, sal_uInt32 nSize) 1373 { 1374 (void) osl_unmapFile (pData, nSize); 1375 } 1376 1377 #if 0 /* NYI */ 1378 storeError MemoryPageAccess_createInstance ( 1379 rtl::Reference< IPageAccess > & rxPageAccess, 1380 storeAccessMode eAccessMode, 1381 sal_uInt16 nPageSize 1382 ) 1383 { 1384 rxPageAccess = new MemoryPageAccess(); 1385 if (!rxPageAccess.is()) 1386 return store_E_OutOfMemory; 1387 1388 return rxPageAccess->initialize (eAccessMode, nPageSize); 1389 } 1390 1391 storeError FilePageAccess_createInstance ( 1392 rtl::Reference< IPageAccess > & rxPageAccess, 1393 rtl_uString * pFilename, 1394 storeAccessMode eAccessMode, 1395 sal_uInt16 nPageSize 1396 ) 1397 { 1398 // Acquire file handle. 1399 ResourceHolder<FileHandle> xFile; 1400 result = xFile.get().initialize (pFilename, MODE_TO_NATIVE(eAccessMode)); 1401 if (result != osl_File_E_None) 1402 return ERROR_FROM_NATIVE(result); 1403 1404 if (eAccessMode == store_AccessReadOnly) 1405 { 1406 ResourceHolder<FileMapping> xMapping; 1407 result = xMapping.get().initialize (xFile.get()); 1408 if (result == osl_File_E_None) 1409 { 1410 const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(xMapping.get().m_uSize); 1411 rxPageAccess = new MappedPageAccess (xMapping.get().m_pAddr, nSize); 1412 if (!rxPageAccess.is()) 1413 return store_E_OutOfMemory; 1414 (void) xMapping.release(); 1415 } 1416 } 1417 if (!rxPageAccess.is()) 1418 { 1419 rxPageAccess = new FilePageAccess (xFile.get()); 1420 if (!rxPageAccess.is()) 1421 return store_E_OutOfMemory; 1422 (void) xFile.release(); 1423 } 1424 return rxPageAccess->initialize (eAccessMode, nPageSize); 1425 } 1426 #endif /* NYI */ 1427 1428 /*======================================================================== 1429 * 1430 * test... 1431 * 1432 *======================================================================*/ 1433 #if 0 /* NYI */ 1434 1435 struct IDataBlock 1436 { 1437 virtual sal_uInt16 singleCount() const = 0; 1438 virtual sal_uInt32 singleLink (sal_uInt16 nIndex) const = 0; 1439 virtual void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0; 1440 1441 virtual storeError get() = 0; 1442 virtual storeError put() = 0; 1443 virtual storeError truncate() = 0; 1444 }; 1445 1446 struct InodePageData : public PageData 1447 { 1448 virtual INameBlock & getNameBlock() = 0; 1449 virtual IDataBlock & getDataBlock() = 0; 1450 }; 1451 1452 template< class page_data_type > 1453 page_data_type * query (PageData *, page_data_type *); 1454 1455 template<> InodePageDataV2* 1456 query (PageData & rData, InodePageDataV2 *) 1457 { 1458 if (rData.isKindOf(InodePageDataV2::m_nTypeId)) 1459 return static_cast<InodePageDataV2*>(&rData); 1460 return 0; 1461 } 1462 1463 class InodePageObject : public PageObject 1464 { 1465 public: 1466 static InodePageObject createInstance (PageData & rData) 1467 { 1468 if (query(&rData, static_cast<InodePageDataV2*>(0))) 1469 return InodePageObjectV2 (static_cast<InodePageDataV2&>(rData)); 1470 else if (query(&rData, static_cast<InodePageDataV1*>(0))) 1471 return InodePageObjectV1 (static_cast<InodePageDataV1&>(rData)); 1472 } 1473 }; 1474 1475 #endif /* NYI */ 1476 1477 /*======================================================================== 1478 * 1479 * main. 1480 * 1481 *======================================================================*/ 1482 1483 #include <stdio.h> 1484 1485 #if 0 /* EXP */ 1486 class Interface 1487 { 1488 public: 1489 virtual void deallocate(void *) /* = 0 */; 1490 }; 1491 1492 class Implementation : public Interface 1493 { 1494 SharedCount m_count; 1495 1496 public: 1497 Implementation() : Interface() { printf("Ctor(%p)\n", this); } 1498 ~Implementation() { printf("Dtor(%p)\n", this); } 1499 1500 Implementation (Implementation const & rhs) : Interface(), m_count (rhs.m_count) { printf("CopyCtor(%p)\n", this); } 1501 1502 virtual void deallocate(void *) {} 1503 }; 1504 1505 Interface Interface_createInstance() 1506 { 1507 Implementation aInst; 1508 return aInst; 1509 } 1510 #endif /* EXP */ 1511 1512 int SAL_CALL main (int argc, char ** argv) 1513 { 1514 OSL_PRECOND(argc >= 1, "t_page: error: insufficient number of arguments."); 1515 if (argc < 1) 1516 return 0; 1517 1518 { 1519 void *a = (void*)1, *b = (void*)2; 1520 swap<void*>(a, b); 1521 } 1522 { 1523 PageObject a; 1524 PageObject b (a); 1525 PageObject c; 1526 1527 c = b; 1528 a = a; 1529 1530 } 1531 { 1532 TestBIOS aBIOS; 1533 TestClient aClient; 1534 aClient.dwim (aBIOS); 1535 } 1536 #if 0 /* EXP */ 1537 { 1538 Interface aIfc1 (Interface_createInstance()); 1539 Interface aIfc2 (aIfc1); 1540 } 1541 #endif /* EXP */ 1542 1543 if (argc > 1) 1544 { 1545 rtl_uString * pFilename = 0; 1546 rtl_uString_newFromAscii (&pFilename, argv[1]); 1547 storeAccessMode eAccessMode = store_AccessReadOnly; 1548 1549 // Acquire file handle. 1550 ResourceHolder<FileHandle> h1; 1551 oslFileError result = h1.get().initialize (pFilename, FilePageAccess::MODE_TO_NATIVE(eAccessMode)); 1552 if (result == osl_File_E_None) 1553 { 1554 ResourceHolder<FileHandle> h2 (h1); 1555 h1 = h2; 1556 1557 if (eAccessMode == store_AccessReadOnly) 1558 { 1559 ResourceHolder<FileMapping> m1; 1560 result = m1.get().initialize (h1.get()); 1561 1562 const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(m1.get().m_uSize); 1563 (void) nSize; // UNUSED 1564 1565 ResourceHolder<FileMapping> m2 (m1); 1566 m1 = m2; 1567 1568 result = osl_File_E_None; 1569 } 1570 } 1571 } 1572 1573 return 0; 1574 } 1575