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