[ooo-build-commit] 2 commits - patches/dev300 patches/test
Thorsten Behrens
thorsten at kemper.freedesktop.org
Fri Oct 16 13:05:49 PDT 2009
patches/dev300/apply | 4
patches/test/store-v2-fileformat.diff | 3405 ++++++++++++++++++++++++++++++++++
2 files changed, 3407 insertions(+), 2 deletions(-)
New commits:
commit 7cd11cf87418dbd415b0d0ed3754135ab6d290b4
Author: Thorsten Behrens <tbehrens at novell.com>
Date: Fri Oct 16 21:59:35 2009 +0200
Just in case someone needs it: v2 store file format
* patches/test/store-v2-fileformat.diff: re-did the store (.rdb) file
format version v2 reading & writing for the store rewrite; reading
is well-tested, writing not so much (but likely we shouldn't use the
format anyway, anymore)
diff --git a/patches/test/store-v2-fileformat.diff b/patches/test/store-v2-fileformat.diff
new file mode 100644
index 0000000..c24a75b
--- /dev/null
+++ b/patches/test/store-v2-fileformat.diff
@@ -0,0 +1,3405 @@
+The minimal set of changes to read and write store v2 files
+
+(More or less a re-write of the original store-core.diff)
+
+From: Thorsten Behrens <thb at openoffice.org>
+
+
+---
+
+ store/inc/store/store.h | 6
+ store/inc/store/store.hxx | 6
+ store/inc/store/store.inl | 10
+ store/inc/store/types.h | 15 +
+ store/source/lockbyte.cxx | 4
+ store/source/storbase.hxx | 70 +--
+ store/source/storbios.cxx | 92 +++-
+ store/source/storbios.hxx | 7
+ store/source/stordata.cxx | 412 ++++++-------------
+ store/source/stordata.hxx | 958 +++++++++++++++++++++++++++++++++++++--------
+ store/source/stordir.cxx | 40 +-
+ store/source/stordir.hxx | 5
+ store/source/store.cxx | 10
+ store/source/storlckb.cxx | 82 ++--
+ store/source/storlckb.hxx | 9
+ store/source/storpage.cxx | 173 ++++----
+ store/source/storpage.hxx | 28 +
+ store/source/stortree.cxx | 16 +
+ store/source/stortree.hxx | 6
+ store/workben/t_base.cxx | 3
+ store/workben/t_page.cxx | 2
+ 21 files changed, 1244 insertions(+), 710 deletions(-)
+
+
+diff --git store/inc/store/store.h store/inc/store/store.h
+index 18d103b..43e8f00 100644
+--- store/inc/store/store.h
++++ store/inc/store/store.h
+@@ -75,7 +75,8 @@ typedef void* storeFileHandle;
+ */
+ storeError SAL_CALL store_createMemoryFile (
+ sal_uInt16 nPageSize,
+- storeFileHandle *phFile
++ storeFileHandle *phFile,
++ sal_uInt16 nFormatVersion
+ ) SAL_THROW_EXTERN_C();
+
+
+@@ -95,7 +96,8 @@ storeError SAL_CALL store_openFile (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize,
+- storeFileHandle *phFile
++ storeFileHandle *phFile,
++ sal_uInt16 nFormatVersion = STORE_FORMAT_V1
+ ) SAL_THROW_EXTERN_C();
+
+
+diff --git store/inc/store/store.hxx store/inc/store/store.hxx
+index 351f6f7..c97d996 100644
+--- store/inc/store/store.hxx
++++ store/inc/store/store.hxx
+@@ -281,14 +281,16 @@ public:
+ inline storeError create (
+ const rtl::OUString &rFilename,
+ storeAccessMode eAccessMode,
+- sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE
++ sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE,
++ sal_uInt16 nFormatVersion = STORE_FORMAT_V1
+ ) SAL_THROW(());
+
+ /** Open the temporary file in memory.
+ @see store_createMemoryFile()
+ */
+ inline storeError createInMemory (
+- sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE
++ sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE,
++ sal_uInt16 nFormatVersion = STORE_FORMAT_V1
+ ) SAL_THROW(());
+
+ /** Close the file.
+diff --git store/inc/store/store.inl store/inc/store/store.inl
+index 18a8910..3d1e7a3 100644
+--- store/inc/store/store.inl
++++ store/inc/store/store.inl
+@@ -321,25 +321,27 @@ inline sal_Bool OStoreFile::isValid (void) const SAL_THROW(())
+ inline storeError OStoreFile::create (
+ const rtl::OUString &rFilename,
+ storeAccessMode eAccessMode,
+- sal_uInt16 nPageSize) SAL_THROW(())
++ sal_uInt16 nPageSize,
++ sal_uInt16 nFormatVersion) SAL_THROW(())
+ {
+ if (m_hImpl)
+ {
+ store_releaseHandle (m_hImpl);
+ m_hImpl = 0;
+ }
+- return store_openFile (rFilename.pData, eAccessMode, nPageSize, &m_hImpl);
++ return store_openFile (rFilename.pData, eAccessMode, nPageSize, &m_hImpl, nFormatVersion);
+ }
+
+ inline storeError OStoreFile::createInMemory (
+- sal_uInt16 nPageSize) SAL_THROW(())
++ sal_uInt16 nPageSize,
++ sal_uInt16 nFormatVersion) SAL_THROW(())
+ {
+ if (m_hImpl)
+ {
+ store_releaseHandle (m_hImpl);
+ m_hImpl = 0;
+ }
+- return store_createMemoryFile (nPageSize, &m_hImpl);
++ return store_createMemoryFile (nPageSize, &m_hImpl, nFormatVersion);
+ }
+
+ inline void OStoreFile::close (void) SAL_THROW(())
+diff --git store/inc/store/types.h store/inc/store/types.h
+index 4810838..067bd64 100644
+--- store/inc/store/types.h
++++ store/inc/store/types.h
+@@ -38,16 +38,27 @@
+ extern "C" {
+ #endif
+
++/* format version
++ V1 original rdb format, used publicly
++ V2 internal rdb format, which might change during time and
++ should be only used internally for services.rdb, types.rdb
++ and other rdb files shipped with OOo
++*/
++
++#define STORE_FORMAT_V1 1
++#define STORE_FORMAT_V2 2
++
+ /** PageSize (recommended) default.
+ @see store_openFile()
+ */
+-#define STORE_DEFAULT_PAGESIZE ((sal_uInt16)0x0400)
++#define STORE_DEFAULT_PAGESIZE ((sal_uInt16)0x200)
+
+
+ /** PageSize (enforced) limits.
+ @see store_openFile()
+ */
+-#define STORE_MINIMUM_PAGESIZE ((sal_uInt16)0x0200)
++#define STORE_MINIMUM_PAGESIZE_V1 ((sal_uInt16)0x200)
++#define STORE_MINIMUM_PAGESIZE_V2 ((sal_uInt16)0x80)
+ #define STORE_MAXIMUM_PAGESIZE ((sal_uInt16)0x8000)
+
+
+diff --git store/source/lockbyte.cxx store/source/lockbyte.cxx
+index a03628b..953a229 100644
+--- store/source/lockbyte.cxx
++++ store/source/lockbyte.cxx
+@@ -63,7 +63,9 @@ using namespace store;
+
+ storeError ILockBytes::initialize (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize)
+ {
+- OSL_PRECOND((STORE_MINIMUM_PAGESIZE <= nPageSize) && (nPageSize <= STORE_MAXIMUM_PAGESIZE), "invalid PageSize");
++ OSL_PRECOND(((STORE_MINIMUM_PAGESIZE_V1 <= nPageSize)
++ || (STORE_MINIMUM_PAGESIZE_V2 <= nPageSize))
++ && (nPageSize <= STORE_MAXIMUM_PAGESIZE), "invalid PageSize");
+ return initialize_Impl (rxAllocator, nPageSize);
+ }
+
+diff --git store/source/storbase.hxx store/source/storbase.hxx
+index 4a7851f..eb33455 100644
+--- store/source/storbase.hxx
++++ store/source/storbase.hxx
+@@ -455,7 +455,8 @@ struct PageData
+ */
+ static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L);
+ static const sal_uInt16 thePageSize = theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V2 >= thePageSize);
+
+ /** location.
+ */
+@@ -715,6 +716,18 @@ class PageHolderObject
+ return isA<U>(p) ? static_cast<U const *>(p) : 0;
+ }
+
++ template< class U >
++ static U * unsafe_page_cast (PageData * p)
++ {
++ return static_cast<U*>(p);
++ }
++
++ template< class U >
++ static U const * unsafe_page_cast (PageData const * p)
++ {
++ return static_cast<U const *>(p);
++ }
++
+ public:
+ bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
+ {
+@@ -758,10 +771,8 @@ public:
+ return (m_xPage.get() != 0);
+ }
+
+-#if 1 /* EXP */
+ PageHolder & get() { return m_xPage; }
+ PageHolder const & get() const { return m_xPage; }
+-#endif /* EXP */
+
+ T * operator->()
+ {
+@@ -802,7 +813,7 @@ public:
+
+ return store_E_None;
+ }
+- static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr)
++ static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr, sal_uInt16 nVersion)
+ {
+ PageData const * pHead = rxPage.get();
+ if (!pHead)
+@@ -812,7 +823,11 @@ public:
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+- T const * pImpl = dynamic_page_cast<T>(pHead);
++ T const * pImpl = 0;
++ if( nVersion == STORE_FORMAT_V2 )
++ pImpl = unsafe_page_cast<T>(pHead);
++ else
++ pImpl = dynamic_page_cast<T>(pHead);
+ if (!pImpl)
+ return store_E_WrongVersion;
+
+@@ -820,49 +835,6 @@ public:
+ }
+ };
+
+-/*========================================================================
+- *
+- * PageObject.
+- *
+- *======================================================================*/
+-#if 1 /* EXP */
+-class PageObject
+-{
+-public:
+- explicit PageObject (PageHolder const & rxPage = PageHolder())
+- : m_xPage (rxPage), m_bDirty (false)
+- {}
+-
+- virtual ~PageObject()
+- {}
+-
+- PageHolder & get() { return m_xPage; }
+- PageHolder const & get() const { return m_xPage; }
+-
+- void clean() { m_bDirty = false; }
+- void touch() { m_bDirty = true; }
+-
+- sal_uInt32 location() const
+- {
+- PageData const * pagedata = m_xPage.get();
+- return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL;
+- }
+- void location (sal_uInt32 nAddr)
+- {
+- PageData * pagedata = m_xPage.get();
+- if (pagedata != 0)
+- pagedata->location (nAddr);
+- }
+-
+-protected:
+- PageHolder m_xPage;
+- bool m_bDirty;
+-
+- virtual storeError guard (sal_uInt32 nAddr) = 0;
+- virtual storeError verify (sal_uInt32 nAddr) const = 0;
+-};
+-#endif /* EXP */
+-
+ class OStorePageBIOS;
+
+ class OStorePageObject
+@@ -934,7 +906,7 @@ public:
+ PageHolder const & get() const { return m_xPage; }
+
+ virtual storeError guard (sal_uInt32 nAddr) = 0;
+- virtual storeError verify (sal_uInt32 nAddr) const = 0;
++ virtual storeError verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const = 0;
+ };
+
+ inline bool OStorePageObject::dirty (void) const
+diff --git store/source/storbios.cxx store/source/storbios.cxx
+index d1f15dc..368d34d 100644
+--- store/source/storbios.cxx
++++ store/source/storbios.cxx
+@@ -59,7 +59,8 @@ using namespace store;
+ * OStoreSuperBlock.
+ *
+ *======================================================================*/
+-#define STORE_MAGIC_SUPERBLOCK sal_uInt32(0x484D5343)
++#define STORE_MAGIC_SUPERBLOCK_V1 sal_uInt32(0x484D5343)
++#define STORE_MAGIC_SUPERBLOCK_V2 sal_uInt32(0x484D5344)
+
+ struct OStoreSuperBlock
+ {
+@@ -82,9 +83,13 @@ struct OStoreSuperBlock
+
+ /** Construction.
+ */
+- explicit OStoreSuperBlock (sal_uInt16 nPageSize)
+- : m_aGuard (STORE_MAGIC_SUPERBLOCK),
+- m_aDescr (nPageSize, nPageSize, STORE_MINIMUM_PAGESIZE),
++ explicit OStoreSuperBlock (sal_uInt16 nPageSize, sal_uInt16 nFormatVersion)
++ : m_aGuard (nFormatVersion == STORE_FORMAT_V1 ?
++ STORE_MAGIC_SUPERBLOCK_V1 : STORE_MAGIC_SUPERBLOCK_V2),
++ m_aDescr (nPageSize,
++ nPageSize,
++ nFormatVersion == STORE_FORMAT_V1 ?
++ STORE_MINIMUM_PAGESIZE_V1 : STORE_MINIMUM_PAGESIZE_V2),
+ m_nMarked (store::htonl(0)),
+ m_aMarked (0),
+ m_nUnused (store::htonl(0)),
+@@ -163,10 +168,11 @@ struct OStoreSuperBlock
+
+ /** verify (external representation).
+ */
+- storeError verify() const
++ storeError verify(sal_uInt16 nVersion) const
+ {
+ sal_uInt32 nMagic = store::ntohl(m_aGuard.m_nMagic);
+- if (nMagic != STORE_MAGIC_SUPERBLOCK)
++ if ((nVersion == STORE_FORMAT_V1 && nMagic != STORE_MAGIC_SUPERBLOCK_V1) ||
++ (nVersion == STORE_FORMAT_V2 && nMagic != STORE_MAGIC_SUPERBLOCK_V2))
+ return store_E_WrongFormat;
+
+ sal_uInt32 nCRC32 = 0;
+@@ -177,6 +183,26 @@ struct OStoreSuperBlock
+ else
+ return store_E_None;
+ }
++
++ /** return version of superblock, determined by magic number in guard
++ */
++ sal_uInt16 version () const
++ {
++ sal_uInt16 nVersion;
++
++ switch (m_aGuard.m_nMagic) {
++ case STORE_MAGIC_SUPERBLOCK_V1:
++ nVersion = STORE_FORMAT_V1;
++ break;
++ case STORE_MAGIC_SUPERBLOCK_V2:
++ nVersion = STORE_FORMAT_V2;
++ break;
++ default:
++ nVersion = 0;
++ }
++
++ return nVersion;
++ }
+ };
+
+ /*========================================================================
+@@ -266,11 +292,16 @@ struct OStoreSuperBlockPage
+ SuperBlock m_aSuperTwo;
+ StateBlock m_aState;
+
++ /** version
++ */
++ sal_uInt32 m_nVersion;
++
+ /** theSize.
+ */
+ static const size_t theSize = 2 * SuperBlock::theSize + StateBlock::theSize;
+ static const sal_uInt16 thePageSize = theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V2 >= thePageSize);
+
+ /** Allocation.
+ */
+@@ -294,10 +325,11 @@ struct OStoreSuperBlockPage
+
+ /** Construction.
+ */
+- explicit OStoreSuperBlockPage (sal_uInt16 nPageSize = thePageSize)
+- : m_aSuperOne(nPageSize),
+- m_aSuperTwo(nPageSize),
+- m_aState()
++ explicit OStoreSuperBlockPage (sal_uInt16 nPageSize = thePageSize, sal_uInt16 nFormatVersion = STORE_FORMAT_V1)
++ : m_aSuperOne(nPageSize,nFormatVersion),
++ m_aSuperTwo(nPageSize,nFormatVersion),
++ m_aState(),
++ m_nVersion(nFormatVersion)
+ {}
+
+ /** guard (external representation).
+@@ -437,11 +469,11 @@ storeError OStoreSuperBlockPage::modified (OStorePageBIOS &rBIOS)
+ storeError OStoreSuperBlockPage::verify (OStorePageBIOS &rBIOS)
+ {
+ // Verify 1st copy.
+- storeError eErrCode = m_aSuperOne.verify();
++ storeError eErrCode = m_aSuperOne.verify(m_nVersion);
+ if (eErrCode == store_E_None)
+ {
+ // Ok. Verify 2nd copy.
+- eErrCode = m_aSuperTwo.verify();
++ eErrCode = m_aSuperTwo.verify(m_nVersion);
+ if (eErrCode == store_E_None)
+ {
+ // Ok. Ensure identical copies (1st copy wins).
+@@ -472,7 +504,7 @@ storeError OStoreSuperBlockPage::verify (OStorePageBIOS &rBIOS)
+ else
+ {
+ // Failure. Verify 2nd copy.
+- eErrCode = m_aSuperTwo.verify();
++ eErrCode = m_aSuperTwo.verify(m_nVersion);
+ if (eErrCode == store_E_None)
+ {
+ // Ok. Replace 1st copy with 2nd copy.
+@@ -685,6 +717,11 @@ storeError OStorePageBIOS::verify (SuperPage *&rpSuper)
+
+ if (rpSuper->m_aState.flushPending())
+ OSL_TRACE("OStorePageBIOS::verify(): flush pending.\n");
++
++ // glean file format version from super block magic
++ rpSuper->m_nVersion = rpSuper->m_aSuperOne.version() == 0
++ ? rpSuper->m_aSuperTwo.version()
++ : rpSuper->m_aSuperOne.version();
+ }
+
+ // Verify SuperBlock page (with repair).
+@@ -719,15 +756,18 @@ storeError OStorePageBIOS::repair (SuperPage *&rpSuper)
+ * create (SuperBlock).
+ * Internal: Precond: initialized, exclusive access.
+ */
+-storeError OStorePageBIOS::create (sal_uInt16 nPageSize)
++storeError OStorePageBIOS::create (sal_uInt16 nPageSize, sal_uInt16 nFormatVersion)
+ {
+ // Check (internal) precond.
+ OSL_PRECOND(m_xLockBytes.is(), "store::PageBIOS::create(): contract violation");
+
++ const sal_uInt16 nMinPageSize=nFormatVersion == STORE_FORMAT_V1 ?
++ STORE_MINIMUM_PAGESIZE_V1 : STORE_MINIMUM_PAGESIZE_V2;
++
+ // Check PageSize.
+- if ((STORE_MINIMUM_PAGESIZE > nPageSize) || (nPageSize > STORE_MAXIMUM_PAGESIZE))
++ if ((nMinPageSize > nPageSize) || (nPageSize > STORE_MAXIMUM_PAGESIZE))
+ return store_E_InvalidParameter;
+- nPageSize = ((nPageSize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1));
++ nPageSize = ((nPageSize + nMinPageSize - 1) & ~(nMinPageSize - 1));
+
+ // Acquire Lock.
+ storeError eErrCode = acquireLock (0, nPageSize);
+@@ -775,7 +815,8 @@ storeError OStorePageBIOS::create (sal_uInt16 nPageSize)
+ storeError OStorePageBIOS::initialize (
+ ILockBytes * pLockBytes,
+ storeAccessMode eAccessMode,
+- sal_uInt16 & rnPageSize)
++ sal_uInt16 & rnPageSize,
++ sal_uInt16 & rnFormatVersion )
+ {
+ // Acquire exclusive access.
+ osl::MutexGuard aGuard (m_aMutex);
+@@ -838,13 +879,16 @@ storeError OStorePageBIOS::initialize (
+ return store_E_NotExists;
+
+ // Create SuperBlock page.
+- eErrCode = create (rnPageSize);
++ eErrCode = create (rnPageSize,rnFormatVersion);
+ }
+ if (eErrCode == store_E_None)
+ {
+ // Obtain modified state.
+ m_bModified = m_pSuper->m_aState.flushPending();
+
++ // Obtain format version.
++ rnFormatVersion = m_pSuper->m_nVersion;
++
+ // Obtain page size.
+ rnPageSize = store::ntohs(m_pSuper->m_aSuperOne.m_aDescr.m_nSize);
+
+@@ -1284,7 +1328,7 @@ storeError OStorePageBIOS::loadObjectAt_Impl (OStorePageObject & rPage, sal_uInt
+ return eErrCode;
+
+ // Verify page.
+- eErrCode = rPage.verify (nAddr);
++ eErrCode = rPage.verify (nAddr, version());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -1568,3 +1612,11 @@ storeError OStorePageBIOS::poke (OStorePageData &rData)
+ // Write PageHead.
+ return write (rData.location(), &rData, OStorePageData::theSize);
+ }
++
++sal_uInt32 OStorePageBIOS::version () const
++{
++ if (!m_pSuper)
++ return 0;
++
++ return m_pSuper->m_nVersion;
++}
+diff --git store/source/storbios.hxx store/source/storbios.hxx
+index d9a0f98..bc62c65 100644
+--- store/source/storbios.hxx
++++ store/source/storbios.hxx
+@@ -76,7 +76,8 @@ public:
+ virtual storeError initialize (
+ ILockBytes * pLockBytes,
+ storeAccessMode eAccessMode,
+- sal_uInt16 & rnPageSize);
++ sal_uInt16 & rnPageSize,
++ sal_uInt16 & rnFormatVersion);
+
+ rtl::Reference< PageData::Allocator > & allocator()
+ {
+@@ -162,6 +163,8 @@ public:
+ */
+ storeError size (sal_uInt32 &rnSize);
+
++ sal_uInt32 version () const;
++
+ /** ScanContext.
+ */
+ struct ScanContext
+@@ -240,7 +243,7 @@ private:
+
+ /** create (SuperBlock).
+ */
+- storeError create (sal_uInt16 nPageSize);
++ storeError create (sal_uInt16 nPageSize, sal_uInt16 nFormatVersion);
+
+ /** SuperBlock verification and repair.
+ */
+diff --git store/source/stordata.cxx store/source/stordata.cxx
+index 8f37616..07eed5f 100644
+--- store/source/stordata.cxx
++++ store/source/stordata.cxx
+@@ -58,9 +58,31 @@ storeError OStoreDataPageObject::guard (sal_uInt32 nAddr)
+ /*
+ * verify.
+ */
+-storeError OStoreDataPageObject::verify (sal_uInt32 nAddr) const
++storeError OStoreDataPageObject::verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const
+ {
+- return PageHolderObject< page >::verify (m_xPage, nAddr);
++ return PageHolderObject< page >::verify (m_xPage, nAddr, nVersion);
++}
++
++
++/*========================================================================
++ *
++ * OStorePageLongNameDataPageObject implementation.
++ *
++ *======================================================================*/
++/*
++ * guard.
++ */
++storeError OStorePageLongNameDataPageObject::guard (sal_uInt32 nAddr)
++{
++ return PageHolderObject< page >::guard (m_xPage, nAddr);
++}
++
++/*
++ * verify.
++ */
++storeError OStorePageLongNameDataPageObject::verify (sal_uInt32 nAddr,sal_uInt16 nVersion) const
++{
++ return PageHolderObject< page >::verify (m_xPage, nAddr, nVersion);
+ }
+
+ /*========================================================================
+@@ -68,9 +90,10 @@ storeError OStoreDataPageObject::verify (sal_uInt32 nAddr) const
+ * OStoreIndirectionPageObject implementation.
+ *
+ *======================================================================*/
++
+ /*
+- * store_truncate_Impl (single indirect page).
+- */
++ * store_truncate_Impl (single indirect page).
++ */
+ static storeError store_truncate_Impl (
+ sal_uInt32 nAddr,
+ sal_uInt16 nSingle,
+@@ -217,9 +240,9 @@ storeError OStoreIndirectionPageObject::guard (sal_uInt32 nAddr)
+ /*
+ * verify.
+ */
+-storeError OStoreIndirectionPageObject::verify (sal_uInt32 nAddr) const
++storeError OStoreIndirectionPageObject::verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const
+ {
+- return PageHolderObject< page >::verify (m_xPage, nAddr);
++ return PageHolderObject< page >::verify (m_xPage, nAddr, nVersion);
+ }
+
+ /*
+@@ -650,179 +673,33 @@ storeError OStoreIndirectionPageObject::truncate (
+ * OStoreDirectoryPageObject implementation.
+ *
+ *======================================================================*/
+-/*
+- * guard.
+- */
+-storeError OStoreDirectoryPageObject::guard (sal_uInt32 nAddr)
+-{
+- return PageHolderObject< page >::guard (m_xPage, nAddr);
+-}
+
+-/*
+- * verify.
+- */
+-storeError OStoreDirectoryPageObject::verify (sal_uInt32 nAddr) const
++storeError OStoreDirectoryPageObject::store_truncate (
++ sal_uInt32 nAddr,
++ sal_uInt16 nSingle,
++ OStorePageBIOS &rBIOS)
+ {
+- return PageHolderObject< page >::verify (m_xPage, nAddr);
+- // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
++ return store_truncate_Impl(nAddr,nSingle,rBIOS);
+ }
+
+-/*
+- * scope (external data page; private).
+- */
+-OStoreDirectoryPageData::ChunkScope
+-OStoreDirectoryPageObject::scope (
+- sal_uInt32 nPage,
+- page::DataBlock::LinkDescriptor &rDescr) const
++storeError OStoreDirectoryPageObject::store_truncate (
++ sal_uInt32 nAddr,
++ sal_uInt16 nDouble,
++ sal_uInt16 nSingle,
++ OStorePageBIOS &rBIOS)
+ {
+- page const & rPage = PAGE();
+- OStoreDirectoryDataBlock const & rDataBlock = rPage.m_aDataBlock;
+-
+- sal_uInt32 index0, index1, index2, index3;
+-
+- // direct.
+- sal_uInt32 nCount = rDataBlock.directCount();
+- sal_uInt32 nLimit = nCount;
+- if (nPage < nLimit)
+- {
+- // Page to index reduction.
+- index0 = nPage;
+-
+- // Setup LinkDescriptor indices.
+- rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
+-
+- // Done.
+- return page::SCOPE_DIRECT;
+- }
+- nPage -= nLimit;
+-
+- // single indirect.
+- sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr);
+- nCount = rDataBlock.singleCount();
+- nLimit = nCount * nCapacity;
+- if (nPage < nLimit)
+- {
+- // Page to index reduction.
+- sal_uInt32 n = nPage;
+-
+- // Reduce to single indirect i(1), direct n = i(0).
+- index1 = n / nCapacity;
+- index0 = n % nCapacity;
+-
+- // Verify reduction.
+- n = index1 * nCapacity + index0;
+- OSL_POSTCOND(n == nPage, "wrong math on indirect indices");
+- if (n != nPage)
+- return page::SCOPE_UNKNOWN;
+-
+- // Setup LinkDescriptor indices.
+- rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
+- rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
+-
+- // Done.
+- return page::SCOPE_SINGLE;
+- }
+- nPage -= nLimit;
+-
+- // double indirect.
+- nCount = rDataBlock.doubleCount();
+- nLimit = nCount * nCapacity * nCapacity;
+- if (nPage < nLimit)
+- {
+- // Page to index reduction.
+- sal_uInt32 n = nPage;
+-
+- // Reduce to double indirect i(2), single indirect n = i(0).
+- index2 = n / (nCapacity * nCapacity);
+- n = n % (nCapacity * nCapacity);
+-
+- // Reduce to single indirect i(1), direct n = i(0).
+- index1 = n / nCapacity;
+- index0 = n % nCapacity;
+-
+- // Verify reduction.
+- n = index2 * nCapacity * nCapacity +
+- index1 * nCapacity + index0;
+- OSL_POSTCOND(n == nPage, "wrong math on double indirect indices");
+- if (n != nPage)
+- return page::SCOPE_UNKNOWN;
+-
+- // Setup LinkDescriptor indices.
+- rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
+- rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
+- rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
+-
+- // Done.
+- return page::SCOPE_DOUBLE;
+- }
+- nPage -= nLimit;
+-
+- // triple indirect.
+- nCount = rDataBlock.tripleCount();
+- nLimit = nCount * nCapacity * nCapacity * nCapacity;
+- if (nPage < nLimit)
+- {
+- // Page to index reduction.
+- sal_uInt32 n = nPage;
+-
+- // Reduce to triple indirect i(3), double indirect n.
+- index3 = n / (nCapacity * nCapacity * nCapacity);
+- n = n % (nCapacity * nCapacity * nCapacity);
+-
+- // Reduce to double indirect i(2), single indirect n.
+- index2 = n / (nCapacity * nCapacity);
+- n = n % (nCapacity * nCapacity);
+-
+- // Reduce to single indirect i(1), direct n = i(0).
+- index1 = n / nCapacity;
+- index0 = n % nCapacity;
+-
+- // Verify reduction.
+- n = index3 * nCapacity * nCapacity * nCapacity +
+- index2 * nCapacity * nCapacity +
+- index1 * nCapacity + index0;
+- OSL_POSTCOND(n == nPage, "wrong math on triple indirect indices");
+- if (n != nPage)
+- return page::SCOPE_UNKNOWN;
+-
+- // Setup LinkDescriptor indices.
+- rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
+- rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
+- rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
+- rDescr.m_nIndex3 = (sal_uInt16)(index3 & 0xffff);
+-
+- // Done.
+- return page::SCOPE_TRIPLE;
+- }
+-
+- // Unreachable (more than triple indirect).
+- return page::SCOPE_UNREACHABLE;
++ return store_truncate_Impl(nAddr,nDouble,nSingle,rBIOS);
+ }
+
+-#if 0 /* NYI */
+-/*
+- * chunk (external data page).
+- */
+-inode::ChunkDescriptor OStoreDirectoryPageObject::chunk (sal_uInt32 nOffset)
++storeError OStoreDirectoryPageObject::store_truncate (
++ sal_uInt32 nAddr,
++ sal_uInt16 nTriple,
++ sal_uInt16 nDouble,
++ sal_uInt16 nSingle,
++ OStorePageBIOS &rBIOS)
+ {
+- // @@@ INSUFFICIENT: NEED SCOPE AS WELL @@@
+- sal_uInt32 nCapacity = m_rPage.capacity();
+- if (nOffset < nCapacity)
+- // Internal scope (inode page).
+- return inode::ChunkDescriptor (nOffset, nCapacity);
+- else
+- // External scope (data page).
+- return inode::ChunkDescriptor (nOffset - nCapacity, data::capacity(m_rPage.m_aDescr));
+-
+- inode::ChunkScope eScope = m_rPage.scope(nOffset);
+- if (eScope == inode::SCOPE_INTERNAL)
+- // Inode page (internal scope).
+- return inode::ChunkDescriptor (nOffset, m_rPage.capacity());
+- else
+- // Data page (external scope).
+- return inode::ChunkDescriptor (nOffset - m_rPage.capacity(), data::capacity(m_rPage.m_aDescr));
++ return store_truncate_Impl(nAddr,nTriple,nDouble,nSingle,rBIOS);
+ }
+-#endif /* NYI */
+
+ /*
+ * read (external data page).
+@@ -833,11 +710,11 @@ storeError OStoreDirectoryPageObject::read (
+ OStorePageBIOS &rBIOS)
+ {
+ // Determine scope and link indices.
+- page::DataBlock::LinkDescriptor aLink;
+- page::ChunkScope eScope = scope (nPage, aLink);
++ LinkDescriptor aLink;
++ ChunkScope eScope = scope (nPage, aLink);
+
+ storeError eErrCode = store_E_None;
+- if (eScope == page::SCOPE_DIRECT)
++ if (eScope == SCOPE_DIRECT)
+ {
+ sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
+ if (nAddr == STORE_PAGE_NULL)
+@@ -845,7 +722,7 @@ storeError OStoreDirectoryPageObject::read (
+
+ eErrCode = rBIOS.loadObjectAt (rData, nAddr);
+ }
+- else if (eScope == page::SCOPE_SINGLE)
++ else if (eScope == SCOPE_SINGLE)
+ {
+ sal_uInt32 const nAddr = singleLink (aLink.m_nIndex1);
+ if (nAddr == STORE_PAGE_NULL)
+@@ -858,7 +735,7 @@ storeError OStoreDirectoryPageObject::read (
+
+ eErrCode = aSingle.read (aLink.m_nIndex0, rData, rBIOS);
+ }
+- else if (eScope == page::SCOPE_DOUBLE)
++ else if (eScope == SCOPE_DOUBLE)
+ {
+ sal_uInt32 const nAddr = doubleLink (aLink.m_nIndex2);
+ if (nAddr == STORE_PAGE_NULL)
+@@ -871,7 +748,7 @@ storeError OStoreDirectoryPageObject::read (
+
+ eErrCode = aDouble.read (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
+ }
+- else if (eScope == page::SCOPE_TRIPLE)
++ else if (eScope == SCOPE_TRIPLE)
+ {
+ sal_uInt32 const nAddr = tripleLink (aLink.m_nIndex3);
+ if (nAddr == STORE_PAGE_NULL)
+@@ -884,7 +761,7 @@ storeError OStoreDirectoryPageObject::read (
+
+ eErrCode = aTriple.read (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
+ }
+- else if (eScope == page::SCOPE_UNREACHABLE)
++ else if (eScope == SCOPE_UNREACHABLE)
+ {
+ // Out of scope.
+ eErrCode = store_E_CantSeek;
+@@ -909,11 +786,11 @@ storeError OStoreDirectoryPageObject::write (
+ OStorePageBIOS &rBIOS)
+ {
+ // Determine scope and link indices.
+- page::DataBlock::LinkDescriptor aLink;
+- page::ChunkScope eScope = scope (nPage, aLink);
++ LinkDescriptor aLink;
++ ChunkScope eScope = scope (nPage, aLink);
+
+ storeError eErrCode = store_E_None;
+- if (eScope == page::SCOPE_DIRECT)
++ if (eScope == SCOPE_DIRECT)
+ {
+ sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
+ if (nAddr == STORE_PAGE_NULL)
+@@ -932,7 +809,7 @@ storeError OStoreDirectoryPageObject::write (
+ eErrCode = rBIOS.saveObjectAt (rData, nAddr);
+ }
+ }
+- else if (eScope == page::SCOPE_SINGLE)
++ else if (eScope == SCOPE_SINGLE)
+ {
+ OStoreIndirectionPageObject aSingle;
+ eErrCode = aSingle.loadOrCreate (singleLink (aLink.m_nIndex1), rBIOS);
+@@ -945,7 +822,7 @@ storeError OStoreDirectoryPageObject::write (
+
+ eErrCode = aSingle.write (aLink.m_nIndex0, rData, rBIOS);
+ }
+- else if (eScope == page::SCOPE_DOUBLE)
++ else if (eScope == SCOPE_DOUBLE)
+ {
+ OStoreIndirectionPageObject aDouble;
+ eErrCode = aDouble.loadOrCreate (doubleLink (aLink.m_nIndex2), rBIOS);
+@@ -958,7 +835,7 @@ storeError OStoreDirectoryPageObject::write (
+
+ eErrCode = aDouble.write (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
+ }
+- else if (eScope == page::SCOPE_TRIPLE)
++ else if (eScope == SCOPE_TRIPLE)
+ {
+ OStoreIndirectionPageObject aTriple;
+ eErrCode = aTriple.loadOrCreate (tripleLink (aLink.m_nIndex3), rBIOS);
+@@ -971,7 +848,7 @@ storeError OStoreDirectoryPageObject::write (
+
+ eErrCode = aTriple.write (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
+ }
+- else if (eScope == page::SCOPE_UNREACHABLE)
++ else if (eScope == SCOPE_UNREACHABLE)
+ {
+ // Out of scope.
+ eErrCode = store_E_CantSeek;
+@@ -995,39 +872,39 @@ storeError OStoreDirectoryPageObject::truncate (
+ OStorePageBIOS &rBIOS)
+ {
+ // Determine scope and link indices.
+- page::DataBlock::LinkDescriptor aLink;
+- page::ChunkScope eScope = scope (nPage, aLink);
++ LinkDescriptor aLink;
++ ChunkScope eScope = scope (nPage, aLink);
+
+ storeError eErrCode = store_E_None;
+- if (eScope == page::SCOPE_DIRECT)
++ if (eScope == SCOPE_DIRECT)
+ {
+ // Truncate all triple indirect pages.
+- eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
++ eErrCode = truncate (SCOPE_TRIPLE, 0, rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Truncate all double indirect pages.
+- eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
++ eErrCode = truncate (SCOPE_DOUBLE, 0, rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Truncate all single indirect pages.
+- eErrCode = truncate (page::SCOPE_SINGLE, 0, rBIOS);
++ eErrCode = truncate (SCOPE_SINGLE, 0, rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Truncate direct pages, including 'aLink.m_nIndex0'.
+ eErrCode = truncate (eScope, aLink.m_nIndex0, rBIOS);
+ }
+- else if (eScope == page::SCOPE_SINGLE)
++ else if (eScope == SCOPE_SINGLE)
+ {
+ // Truncate all triple indirect pages.
+- eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
++ eErrCode = truncate (SCOPE_TRIPLE, 0, rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Truncate all double indirect pages.
+- eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
++ eErrCode = truncate (SCOPE_DOUBLE, 0, rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -1048,10 +925,10 @@ storeError OStoreDirectoryPageObject::truncate (
+ singleLink (aLink.m_nIndex1, STORE_PAGE_NULL);
+ }
+ }
+- else if (eScope == page::SCOPE_DOUBLE)
++ else if (eScope == SCOPE_DOUBLE)
+ {
+ // Truncate all triple indirect pages.
+- eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
++ eErrCode = truncate (SCOPE_TRIPLE, 0, rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -1073,7 +950,7 @@ storeError OStoreDirectoryPageObject::truncate (
+ doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL);
+ }
+ }
+- else if (eScope == page::SCOPE_TRIPLE)
++ else if (eScope == SCOPE_TRIPLE)
+ {
+ // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
+ eErrCode = truncate (eScope, aLink.m_nIndex3 + 1, rBIOS);
+@@ -1093,7 +970,7 @@ storeError OStoreDirectoryPageObject::truncate (
+ tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL);
+ }
+ }
+- else if (eScope == page::SCOPE_UNREACHABLE)
++ else if (eScope == SCOPE_UNREACHABLE)
+ {
+ // Out of scope.
+ eErrCode = store_E_CantSeek;
+@@ -1109,99 +986,80 @@ storeError OStoreDirectoryPageObject::truncate (
+ return eErrCode;
+ }
+
+-/*
+- * truncate (external data page scope; private).
+- */
+-storeError OStoreDirectoryPageObject::truncate (
+- page::ChunkScope eScope,
+- sal_uInt16 nRemain,
+- OStorePageBIOS &rBIOS)
++sal_uInt32 OStoreDirectoryPageObjectV1::path (void) const
+ {
+- OStoreDirectoryDataBlock const & rDataBlock = PAGE().m_aDataBlock;
++ const sal_Char * pszName = PAGE().m_aNameBlock.m_pData;
++ sal_uInt32 nPath = store::ntohl(PAGE().m_aNameBlock.m_aKey.m_nHigh);
++ return rtl_crc32 (nPath, pszName, rtl_str_getLength(pszName));
++}
+
+- // Enter.
+- storeError eErrCode = store_E_None;
+- if (eScope == page::SCOPE_DIRECT)
+- {
+- // Truncate direct data pages.
+- sal_uInt16 i, n = rDataBlock.directCount();
+- for (i = n; i > nRemain; i--)
+- {
+- // Obtain data page location.
+- sal_uInt32 nAddr = directLink (i - 1);
+- if (nAddr == STORE_PAGE_NULL) continue;
++sal_Size OStoreDirectoryPageObjectV1::getName (sal_Char * pBuffer, sal_Size nBufsiz, OStorePageBIOS &) const
++{
++ sal_Char const * pszName = PAGE().m_aNameBlock.m_pData;
++ sal_Size nLength = rtl_str_getLength(pszName);
++ memcpy (pBuffer, pszName, SAL_MIN(nLength, nBufsiz));
++ return nLength;
++}
+
+- // Free data page.
+- OStoreDataPageData aData;
+- eErrCode = rBIOS.free (aData, nAddr);
+- if (eErrCode != store_E_None)
+- break;
++void OStoreDirectoryPageObjectV1::setName (sal_Char const * pBuffer, sal_Size nBufsiz)
++{
++ memcpy (PAGE().m_aNameBlock.m_pData, pBuffer, SAL_MIN(STORE_MAXIMUM_NAMESIZE-1, nBufsiz));
++}
+
+- // Clear pointer to data page.
+- directLink (i - 1, STORE_PAGE_NULL);
+- }
++sal_uInt32 OStoreDirectoryPageObjectV2::path (void) const
++{
++ const sal_Char * pszName = PAGE().m_aNameBlock.m_pNameData;
++ sal_uInt32 nPath = store::ntohl(PAGE().m_aNameBlock.m_aKey.m_nHigh);
++ return rtl_crc32 (nPath, pszName, rtl_str_getLength(pszName));
++}
+
+- // Done.
+- return eErrCode;
+- }
++static void
++copyAndTerminate( sal_Char *pDest, const sal_Char *pSrc, sal_Int32 nBytes)
++{
++ memcpy (pDest, pSrc, nBytes);
++ pDest[nBytes] = '\0';
++}
+
+- if (eScope == page::SCOPE_SINGLE)
++#define USE_OTHER_BLOCK STORE_MAX_NAMESIZE_V2
++sal_Size OStoreDirectoryPageObjectV2::getName (sal_Char * pBuffer, sal_Size nBufsiz, OStorePageBIOS &rBIOS) const
++{
++ if (PAGE().m_aNameBlock.m_nNameLength >= USE_OTHER_BLOCK)
+ {
+- // Truncate single indirect pages.
+- sal_uInt16 i, n = rDataBlock.singleCount();
+- for (i = n; i > nRemain; i--)
+- {
+- // Truncate single indirect page to zero data pages.
+- eErrCode = store_truncate_Impl (singleLink (i - 1), 0, rBIOS);
+- if (eErrCode != store_E_None)
+- break;
+-
+- // Clear pointer to single indirect page.
+- singleLink (i - 1, STORE_PAGE_NULL);
+- }
+-
+- // Done.
+- return eErrCode;
+- }
++ OStorePageLongNameDataPageObject aLongNamePage;
++ storeError eErrCode = rBIOS.loadObjectAt (aLongNamePage, PAGE().m_aNameBlock.m_nNameBlock);
+
+- if (eScope == page::SCOPE_DOUBLE)
+- {
+- // Truncate double indirect pages.
+- sal_uInt16 i, n = rDataBlock.doubleCount();
+- for (i = n; i > nRemain; i--)
++ if (eErrCode != store_E_None)
+ {
+- // Truncate double indirect page to zero single indirect pages.
+- eErrCode = store_truncate_Impl (doubleLink (i - 1), 0, 0, rBIOS);
+- if (eErrCode != store_E_None)
+- break;
+-
+- // Clear pointer to double indirect page.
+- doubleLink (i - 1, STORE_PAGE_NULL);
++ OSL_TRACE("failed to load name page %d\n", eErrCode);
++ return 0;
+ }
+
+- // Done.
+- return eErrCode;
++ PageHolderObject<OStorePageLongNameData> xPage (aLongNamePage.get());
++ copyAndTerminate (pBuffer, PAGE().m_aNameBlock.m_pNameData,
++ SAL_MIN(USE_OTHER_BLOCK - 1, nBufsiz));
++ nBufsiz -= USE_OTHER_BLOCK - 1;
++ const sal_Size nLength = SAL_MIN(
++ PAGE().m_aNameBlock.m_nNameLength - (USE_OTHER_BLOCK - 1),
++ nBufsiz);
++ copyAndTerminate (pBuffer + USE_OTHER_BLOCK - 1,
++ xPage->m_nData,
++ nLength);
++ return nLength;
+ }
+-
+- if (eScope == page::SCOPE_TRIPLE)
++ else
+ {
+- // Truncate triple indirect pages.
+- sal_uInt16 i, n = rDataBlock.tripleCount();
+- for (i = n; i > nRemain; i--)
+- {
+- // Truncate to zero double indirect pages.
+- eErrCode = store_truncate_Impl (tripleLink (i - 1), 0, 0, 0, rBIOS);
+- if (eErrCode != store_E_None)
+- break;
+-
+- // Clear pointer to triple indirect page.
+- tripleLink (i - 1, STORE_PAGE_NULL);
+- }
+-
+- // Done.
+- return eErrCode;
++ sal_Char const * pszName = PAGE().m_aNameBlock.m_pNameData;
++ const sal_Size nLength = SAL_MIN(PAGE().m_aNameBlock.m_nNameLength, nBufsiz);
++ memcpy (pBuffer, pszName, nLength);
++ return nLength;
+ }
++}
+
+- // Invalid scope.
+- return store_E_InvalidAccess;
++void OStoreDirectoryPageObjectV2::setName (sal_Char const * pBuffer, sal_Size nLen)
++{
++ // TODO TODO TODO - long names not yet written correctly
++ //if (nLen >= USE_OTHER_BLOCK)
++ memcpy (PAGE().m_aNameBlock.m_pNameData, pBuffer, SAL_MIN(STORE_MAX_NAMESIZE_V2-1, nLen));
+ }
++
++
+diff --git store/source/stordata.hxx store/source/stordata.hxx
+index b86287b..c21c4b9 100644
+--- store/source/stordata.hxx
++++ store/source/stordata.hxx
+@@ -33,9 +33,11 @@
+
+ #include "sal/types.h"
+ #include "sal/macros.h"
++#include "osl/diagnose.h"
+
+ #include "store/types.h"
+ #include "storbase.hxx"
++#include "storbios.hxx"
+
+ namespace store
+ {
+@@ -66,7 +68,8 @@ struct OStoreDataPageData : public store::OStorePageData
+ */
+ static const size_t theSize = 0;
+ static const sal_uInt16 thePageSize = base::theSize + self::theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= self::thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V2 >= self::thePageSize);
+
+ /** capacity.
+ */
+@@ -125,7 +128,7 @@ public:
+ /** External representation.
+ */
+ virtual storeError guard (sal_uInt32 nAddr);
+- virtual storeError verify (sal_uInt32 nAddr) const;
++ virtual storeError verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const;
+ };
+
+ /*========================================================================
+@@ -156,7 +159,8 @@ struct OStoreIndirectionPageData : public store::OStorePageData
+ */
+ static const size_t theSize = sizeof(G);
+ static const sal_uInt16 thePageSize = base::theSize + self::theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= self::thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V2 >= self::thePageSize);
+
+ /** capacity.
+ */
+@@ -239,7 +243,7 @@ public:
+ OStorePageBIOS & rBIOS);
+
+ virtual storeError guard (sal_uInt32 nAddr);
+- virtual storeError verify (sal_uInt32 nAddr) const;
++ virtual storeError verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const;
+
+ /** read (indirect data page).
+ */
+@@ -304,7 +308,7 @@ public:
+ * OStorePageNameBlock.
+ *
+ *======================================================================*/
+-struct OStorePageNameBlock
++struct OStorePageNameBlockV1
+ {
+ typedef OStorePageGuard G;
+ typedef OStorePageKey K;
+@@ -332,7 +336,7 @@ struct OStorePageNameBlock
+
+ /** Construction.
+ */
+- OStorePageNameBlock (void)
++ OStorePageNameBlockV1 (void)
+ : m_aGuard(), m_aKey(), m_nAttrib (0)
+ {
+ memset (m_pData, 0, sizeof(m_pData));
+@@ -362,51 +366,283 @@ struct OStorePageNameBlock
+ }
+ };
+
++#define STORE_MAX_NAMESIZE_V2 32
++
++struct OStorePageNameBlockV2
++{
++ typedef OStorePageGuard G;
++ typedef OStorePageKey K;
++
++ /** Representation.
++ */
++ G m_aGuard;
++ K m_aKey;
++ sal_uInt32 m_nAttrib;
++ sal_Char m_pNameData[STORE_MAX_NAMESIZE_V2];
++ sal_uInt32 m_nNameLength;
++ sal_uInt32 m_nNameBlock;
++
++ /** size.
++ */
++ static const size_t theSize = sizeof(G) + sizeof(K) + 3*sizeof(sal_uInt32) + sizeof(sal_Char[STORE_MAX_NAMESIZE_V2]);
++
++ /** initialize.
++ */
++ void initialize (void)
++ {
++ m_aGuard = G();
++ m_aKey = K();
++ m_nAttrib = 0;
++ memset (m_pNameData, 0, sizeof(m_pNameData));
++ m_nNameLength = 0;
++ m_nNameBlock = 0;
++ }
++
++ /** Construction.
++ */
++ OStorePageNameBlockV2 (void)
++ : m_aGuard(), m_aKey(), m_nAttrib (0), m_nNameLength (0), m_nNameBlock (0)
++ {
++ memset (m_pNameData, 0, sizeof(m_pNameData));
++ }
++
++ /** guard (external representation).
++ */
++ void guard()
++ {
++ sal_uInt32 nCRC32 = 0;
++ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
++ nCRC32 = rtl_crc32 (nCRC32, &m_aKey, theSize - sizeof(G));
++ m_aGuard.m_nCRC32 = store::htonl(nCRC32);
++ }
++
++ /** verify (external representation).
++ */
++ storeError verify() const
++ {
++ // apparently v2 file format does _not_ correctly setup
++ // checksums
++#if 0
++ sal_uInt32 nCRC32 = 0;
++ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
++ nCRC32 = rtl_crc32 (nCRC32, &m_aKey, theSize - sizeof(G));
++ if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
++ return store_E_InvalidChecksum;
++ else
++#endif
++ return store_E_None;
++ }
++};
++
+ /*========================================================================
+ *
+ * OStoreDirectoryDataBlock.
+ *
+ *======================================================================*/
+-#define STORE_LIMIT_DATAPAGE_DIRECT 16
+-#define STORE_LIMIT_DATAPAGE_SINGLE 8
+-#define STORE_LIMIT_DATAPAGE_DOUBLE 1
+-#define STORE_LIMIT_DATAPAGE_TRIPLE 1
+
+-struct OStoreDirectoryDataBlock
++/** LinkDescriptor.
++*/
++struct LinkDescriptor
++{
++ /** Representation.
++ */
++ sal_uInt16 m_nIndex0;
++ sal_uInt16 m_nIndex1;
++ sal_uInt16 m_nIndex2;
++ sal_uInt16 m_nIndex3;
++
++ /** Construction.
++ */
++ LinkDescriptor (void)
++ : m_nIndex0 ((sal_uInt16)(~0)),
++ m_nIndex1 ((sal_uInt16)(~0)),
++ m_nIndex2 ((sal_uInt16)(~0)),
++ m_nIndex3 ((sal_uInt16)(~0))
++ {}
++};
++
++#define STORE_LIMIT_DATAPAGE_DIRECT_V1 16
++#define STORE_LIMIT_DATAPAGE_SINGLE_V1 8
++#define STORE_LIMIT_DATAPAGE_DOUBLE_V1 1
++#define STORE_LIMIT_DATAPAGE_TRIPLE_V1 1
++
++struct OStoreDirectoryDataBlockV1
+ {
+ typedef OStorePageGuard G;
+
+- /** LinkDescriptor.
++ /** LinkTable.
+ */
+- struct LinkDescriptor
++ struct LinkTable
+ {
+ /** Representation.
+ */
+- sal_uInt16 m_nIndex0;
+- sal_uInt16 m_nIndex1;
+- sal_uInt16 m_nIndex2;
+- sal_uInt16 m_nIndex3;
++ sal_uInt32 m_pDirect[STORE_LIMIT_DATAPAGE_DIRECT_V1];
++ sal_uInt32 m_pSingle[STORE_LIMIT_DATAPAGE_SINGLE_V1];
++ sal_uInt32 m_pDouble[STORE_LIMIT_DATAPAGE_DOUBLE_V1];
++ sal_uInt32 m_pTriple[STORE_LIMIT_DATAPAGE_TRIPLE_V1];
++
++ /** initialize.
++ */
++ void initialize (void)
++ {
++ memset(m_pDirect, STORE_PAGE_NULL, sizeof(m_pDirect));
++ memset(m_pSingle, STORE_PAGE_NULL, sizeof(m_pSingle));
++ memset(m_pDouble, STORE_PAGE_NULL, sizeof(m_pDouble));
++ memset(m_pTriple, STORE_PAGE_NULL, sizeof(m_pTriple));
++ }
+
+ /** Construction.
+ */
+- LinkDescriptor (void)
+- : m_nIndex0 ((sal_uInt16)(~0)),
+- m_nIndex1 ((sal_uInt16)(~0)),
+- m_nIndex2 ((sal_uInt16)(~0)),
+- m_nIndex3 ((sal_uInt16)(~0))
+- {}
++ LinkTable (void)
++ {
++ initialize();
++ }
+ };
+
++ /** Representation.
++ */
++ G m_aGuard;
++ LinkTable m_aTable;
++ sal_uInt32 m_nDataLen;
++
++ /** size.
++ */
++ static const size_t theSize = sizeof(G) + sizeof(LinkTable) + sizeof(sal_uInt32);
++
++ /** initialize.
++ */
++ void initialize (void)
++ {
++ m_aGuard = G();
++ m_aTable.initialize();
++ m_nDataLen = 0;
++ }
++
++ /** Construction.
++ */
++ OStoreDirectoryDataBlockV1 (void)
++ : m_aGuard(), m_aTable(), m_nDataLen (0)
++ {}
++
++ /** guard (external representation).
++ */
++ void guard()
++ {
++ sal_uInt32 nCRC32 = 0;
++ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
++ nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G));
++ m_aGuard.m_nCRC32 = store::htonl(nCRC32);
++ }
++
++ /** verify (external representation).
++ */
++ storeError verify() const
++ {
++ sal_uInt32 nCRC32 = 0;
++ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
++ nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G));
++ if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
++ return store_E_InvalidChecksum;
++ else
++ return store_E_None;
++ }
++
++ /** direct.
++ */
++ static sal_uInt16 directCount (void)
++ {
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DIRECT_V1));
++ }
++ sal_uInt32 directLink (sal_uInt16 nIndex) const
++ {
++ if (nIndex < directCount())
++ return store::ntohl(m_aTable.m_pDirect[nIndex]);
++ else
++ return STORE_PAGE_NULL;
++ }
++ void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ {
++ if (nIndex < directCount())
++ m_aTable.m_pDirect[nIndex] = store::htonl(nAddr);
++ }
++
++ /** single.
++ */
++ static sal_uInt16 singleCount (void)
++ {
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_SINGLE_V1));
++ }
++ sal_uInt32 singleLink (sal_uInt16 nIndex) const
++ {
++ if (nIndex < singleCount())
++ return store::ntohl(m_aTable.m_pSingle[nIndex]);
++ else
++ return STORE_PAGE_NULL;
++ }
++ void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ {
++ if (nIndex < singleCount())
++ m_aTable.m_pSingle[nIndex] = store::htonl(nAddr);
++ }
++
++ /** double.
++ */
++ static sal_uInt16 doubleCount (void)
++ {
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DOUBLE_V1));
++ }
++ sal_uInt32 doubleLink (sal_uInt16 nIndex) const
++ {
++ if (nIndex < doubleCount())
++ return store::ntohl(m_aTable.m_pDouble[nIndex]);
++ else
++ return STORE_PAGE_NULL;
++ }
++ void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ {
++ if (nIndex < doubleCount())
++ m_aTable.m_pDouble[nIndex] = store::htonl(nAddr);
++ }
++
++ /** triple.
++ */
++ static sal_uInt16 tripleCount (void)
++ {
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_TRIPLE_V1));
++ }
++ sal_uInt32 tripleLink (sal_uInt16 nIndex) const
++ {
++ if (nIndex < tripleCount())
++ return store::ntohl(m_aTable.m_pTriple[nIndex]);
++ else
++ return STORE_PAGE_NULL;
++ }
++ void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ {
++ if (nIndex < tripleCount())
++ m_aTable.m_pTriple[nIndex] = store::htonl(nAddr);
++ }
++};
++
++#define STORE_LIMIT_DATAPAGE_DIRECT_V2 4
++#define STORE_LIMIT_DATAPAGE_SINGLE_V2 2
++#define STORE_LIMIT_DATAPAGE_DOUBLE_V2 1
++#define STORE_LIMIT_DATAPAGE_TRIPLE_V2 1
++
++struct OStoreDirectoryDataBlockV2
++{
++ typedef OStorePageGuard G;
++
+ /** LinkTable.
+ */
+ struct LinkTable
+ {
+ /** Representation.
+ */
+- sal_uInt32 m_pDirect[STORE_LIMIT_DATAPAGE_DIRECT];
+- sal_uInt32 m_pSingle[STORE_LIMIT_DATAPAGE_SINGLE];
+- sal_uInt32 m_pDouble[STORE_LIMIT_DATAPAGE_DOUBLE];
+- sal_uInt32 m_pTriple[STORE_LIMIT_DATAPAGE_TRIPLE];
++ sal_uInt32 m_pDirect[STORE_LIMIT_DATAPAGE_DIRECT_V2];
++ sal_uInt32 m_pSingle[STORE_LIMIT_DATAPAGE_SINGLE_V2];
++ sal_uInt32 m_pDouble[STORE_LIMIT_DATAPAGE_DOUBLE_V2];
++ sal_uInt32 m_pTriple[STORE_LIMIT_DATAPAGE_TRIPLE_V2];
+
+ /** initialize.
+ */
+@@ -447,7 +683,7 @@ struct OStoreDirectoryDataBlock
+
+ /** Construction.
+ */
+- OStoreDirectoryDataBlock (void)
++ OStoreDirectoryDataBlockV2 (void)
+ : m_aGuard(), m_aTable(), m_nDataLen (0)
+ {}
+
+@@ -465,12 +701,16 @@ struct OStoreDirectoryDataBlock
+ */
+ storeError verify() const
+ {
++ // apparently v2 file format does _not_ correctly setup
++ // checksums
++#if 0
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G));
+ if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
+ return store_E_InvalidChecksum;
+ else
++#endif
+ return store_E_None;
+ }
+
+@@ -478,7 +718,7 @@ struct OStoreDirectoryDataBlock
+ */
+ static sal_uInt16 directCount (void)
+ {
+- return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DIRECT));
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DIRECT_V2));
+ }
+ sal_uInt32 directLink (sal_uInt16 nIndex) const
+ {
+@@ -497,7 +737,7 @@ struct OStoreDirectoryDataBlock
+ */
+ static sal_uInt16 singleCount (void)
+ {
+- return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_SINGLE));
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_SINGLE_V2));
+ }
+ sal_uInt32 singleLink (sal_uInt16 nIndex) const
+ {
+@@ -516,7 +756,7 @@ struct OStoreDirectoryDataBlock
+ */
+ static sal_uInt16 doubleCount (void)
+ {
+- return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DOUBLE));
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DOUBLE_V2));
+ }
+ sal_uInt32 doubleLink (sal_uInt16 nIndex) const
+ {
+@@ -535,7 +775,7 @@ struct OStoreDirectoryDataBlock
+ */
+ static sal_uInt16 tripleCount (void)
+ {
+- return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_TRIPLE));
++ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_TRIPLE_V2));
+ }
+ sal_uInt32 tripleLink (sal_uInt16 nIndex) const
+ {
+@@ -551,6 +791,7 @@ struct OStoreDirectoryDataBlock
+ }
+ };
+
++
+ /*========================================================================
+ *
+ * OStoreDirectoryPageData.
+@@ -558,14 +799,14 @@ struct OStoreDirectoryDataBlock
+ *======================================================================*/
+ #define STORE_MAGIC_DIRECTORYPAGE sal_uInt32(0x62190120)
+
+-struct OStoreDirectoryPageData : public store::OStorePageData
++struct OStoreDirectoryPageDataV1 : public store::OStorePageData
+ {
+- typedef OStorePageData base;
+- typedef OStoreDirectoryPageData self;
++ typedef store::OStorePageData base;
++ typedef OStoreDirectoryPageDataV1 self;
+
+- typedef OStorePageDescriptor D;
+- typedef OStorePageNameBlock NameBlock;
+- typedef OStoreDirectoryDataBlock DataBlock;
++ typedef OStorePageDescriptor D;
++ typedef OStorePageNameBlockV1 NameBlock;
++ typedef OStoreDirectoryDataBlockV1 DataBlock;
+
+ /** Representation.
+ */
+@@ -581,7 +822,7 @@ struct OStoreDirectoryPageData : public store::OStorePageData
+ */
+ static const size_t theSize = NameBlock::theSize + DataBlock::theSize;
+ static const sal_uInt16 thePageSize = base::theSize + self::theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= self::thePageSize);
+
+ /** capacity.
+ */
+@@ -612,7 +853,7 @@ struct OStoreDirectoryPageData : public store::OStorePageData
+
+ /** Construction.
+ */
+- explicit OStoreDirectoryPageData (sal_uInt16 nPageSize)
++ explicit OStoreDirectoryPageDataV1 (sal_uInt16 nPageSize)
+ : base (nPageSize), m_aNameBlock(), m_aDataBlock()
+ {
+ base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
+@@ -637,201 +878,553 @@ struct OStoreDirectoryPageData : public store::OStorePageData
+ eErrCode = m_aDataBlock.verify();
+ return eErrCode;
+ }
++};
++
++struct OStoreDirectoryPageDataV2 : public store::OStorePageData
++{
++ typedef store::OStorePageData base;
++ typedef OStoreDirectoryPageDataV2 self;
+
+- /** ChunkDescriptor.
++ typedef OStorePageDescriptor D;
++ typedef OStorePageNameBlockV2 NameBlock;
++ typedef OStoreDirectoryDataBlockV2 DataBlock;
++
++ /** Representation.
++ */
++ NameBlock m_aNameBlock;
++ DataBlock m_aDataBlock;
++ sal_uInt8 m_pData[1];
++
++ /** type.
++ */
++ static const sal_uInt32 theTypeId = STORE_MAGIC_DIRECTORYPAGE;
++
++ /** size.
++ */
++ static const size_t theSize = NameBlock::theSize + DataBlock::theSize;
++ static const sal_uInt16 thePageSize = base::theSize + self::theSize;
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V2 >= self::thePageSize);
++
++ /** capacity.
+ */
+- struct ChunkDescriptor
++ sal_uInt16 capacity() const
+ {
+- /** Representation.
+- */
+- sal_uInt32 m_nPage;
+- sal_uInt16 m_nOffset;
+- sal_uInt16 m_nLength;
++ return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize);
++ }
+
+- /** Construction.
+- */
+- ChunkDescriptor (sal_uInt32 nPosition, sal_uInt16 nCapacity)
+- {
+- m_nPage = nPosition / nCapacity;
+- m_nOffset = (sal_uInt16)((nPosition % nCapacity) & 0xffff);
+- m_nLength = nCapacity - m_nOffset;
+- }
+- };
++ /** usage.
++ */
++ sal_uInt16 usage() const
++ {
++ return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize);
++ }
+
+- /** ChunkScope.
++ /** initialize.
+ */
+- enum ChunkScope
++ void initialize (void)
+ {
+- SCOPE_INTERNAL,
+- SCOPE_EXTERNAL,
+- SCOPE_DIRECT,
+- SCOPE_SINGLE,
+- SCOPE_DOUBLE,
+- SCOPE_TRIPLE,
+- SCOPE_UNREACHABLE,
+- SCOPE_UNKNOWN
+- };
++ base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
++ base::m_aDescr.m_nUsed = store::htons(self::thePageSize);
+
+- /** scope (internal).
++ m_aNameBlock.initialize();
++ m_aDataBlock.initialize();
++
++ memset (m_pData, 0, capacity());
++ }
++
++ /** Construction.
+ */
+- ChunkScope scope (sal_uInt32 nPosition) const
++ explicit OStoreDirectoryPageDataV2 (sal_uInt16 nPageSize)
++ : base (nPageSize), m_aNameBlock(), m_aDataBlock()
+ {
+- sal_uInt32 nCapacity = capacity();
+- if (nPosition < nCapacity)
+- return SCOPE_INTERNAL;
+- else
+- return SCOPE_EXTERNAL;
++ base::m_aGuard.m_nMagic = store::htonl(self::theTypeId);
++ base::m_aDescr.m_nUsed = store::htons(self::thePageSize);
++ memset (m_pData, 0, capacity());
++ }
++
++ /** guard (external representation).
++ */
++ void guard()
++ {
++ m_aNameBlock.guard();
++ m_aDataBlock.guard();
++ }
++
++ /** verify (external representation).
++ */
++ storeError verify() const
++ {
++ storeError eErrCode = m_aNameBlock.verify();
++ if (eErrCode == store_E_None)
++ eErrCode = m_aDataBlock.verify();
++ return eErrCode;
++ }
++};
++
++/** ChunkDescriptor.
++ */
++struct ChunkDescriptor
++{
++ /** Representation.
++ */
++ sal_uInt32 m_nPage;
++ sal_uInt16 m_nOffset;
++ sal_uInt16 m_nLength;
++
++ /** Construction.
++ */
++ ChunkDescriptor (sal_uInt32 nPosition, sal_uInt16 nCapacity)
++ {
++ m_nPage = nPosition / nCapacity;
++ m_nOffset = (sal_uInt16)((nPosition % nCapacity) & 0xffff);
++ m_nLength = nCapacity - m_nOffset;
+ }
+ };
+
+ /*========================================================================
+ *
+- * OStoreDirectoryPageObject.
++ * OStorePageLongNameData.
+ *
+ *======================================================================*/
+-class OStoreDirectoryPageObject : public store::OStorePageObject
++
++#define STORE_MAGIC_LONGNAME sal_uInt32 (0x12345678)
++
++struct OStorePageLongNameData : public OStorePageData
+ {
+- typedef OStorePageObject base;
+- typedef OStoreDirectoryPageData page;
+- typedef OStoreIndirectionPageData indirect;
++ typedef OStorePageData base;
+
+- typedef OStorePageDescriptor D;
++ /** Representation
++ */
++ sal_Char m_nData[1];
++
++ /** type.
++ */
++ static const sal_uInt32 theTypeId = STORE_MAGIC_LONGNAME;
++
++ explicit OStorePageLongNameData(sal_uInt16 nPageSize) :
++ OStorePageData (nPageSize)
++ {
++ m_aGuard.m_nMagic = STORE_MAGIC_LONGNAME;
++ m_aDescr.m_nUsed = sal::static_int_cast< sal_uInt16 >(
++ m_aDescr.m_nUsed);
++ memset (&m_nData, 0, capacity());
++ }
++
++ /** capacity.
++ */
++ sal_uInt16 capacity (void)
++ {
++ return (m_aDescr.m_nSize - (base::size()));
++ }
++};
++
++/*========================================================================
++ *
++ * OStorePageLongNameDataPageObject.
++ *
++ *======================================================================*/
++class OStorePageLongNameDataPageObject : public store::OStorePageObject
++{
++ typedef OStorePageObject base;
++ typedef OStorePageLongNameData page;
+
+ public:
+ /** Construction.
+ */
+- explicit OStoreDirectoryPageObject (PageHolder const & rxPage = PageHolder())
++ explicit OStorePageLongNameDataPageObject (PageHolder const & rxPage = PageHolder())
+ : OStorePageObject (rxPage)
+ {}
+
+ /** External representation.
+- */
++ */
+ virtual storeError guard (sal_uInt32 nAddr);
+- virtual storeError verify (sal_uInt32 nAddr) const;
++ virtual storeError verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const;
++};
+
+- /** attrib.
+- */
+- sal_uInt32 attrib (void) const
+- {
+- return store::ntohl(PAGE().m_aNameBlock.m_nAttrib);
+- }
+- void attrib (sal_uInt32 nAttrib)
++/*========================================================================
++ *
++ * OStoreDirectoryPageObject.
++ *
++ *======================================================================*/
++struct OStoreDirectoryPageObject : public store::OStorePageObject
++{
++ /** ChunkScope.
++ */
++ enum ChunkScope
+ {
+- PAGE().m_aNameBlock.m_nAttrib = store::htonl(nAttrib);
+- touch();
+- }
++ SCOPE_INTERNAL,
++ SCOPE_EXTERNAL,
++ SCOPE_DIRECT,
++ SCOPE_SINGLE,
++ SCOPE_DOUBLE,
++ SCOPE_TRIPLE,
++ SCOPE_UNREACHABLE,
++ SCOPE_UNKNOWN
++ };
+
+- /** key.
+- */
+- OStorePageKey key (void) const
+- {
+- return PAGE().m_aNameBlock.m_aKey;
+- }
+- void key (OStorePageKey const & rKey)
+- {
+- PAGE().m_aNameBlock.m_aKey = rKey;
+- touch();
+- }
++ virtual OStorePageDescriptor const& getDescriptor (void) const = 0;
++ virtual sal_uInt32 capacity (void) const = 0;
++ virtual sal_uInt32 attrib (void) const = 0;
++ virtual void attrib (sal_uInt32 nAttrib) = 0;
++ virtual OStorePageKey key (void) const = 0;
++ virtual void key (OStorePageKey const & rKey) = 0;
++ virtual sal_uInt32 path (void) const = 0;
++ virtual sal_Size getName (sal_Char * pBuffer, sal_Size nBufsiz, OStorePageBIOS &rBIOS) const = 0;
++ virtual void setName (sal_Char const * pBuffer, sal_Size nBufsiz) = 0;
++ virtual sal_uInt32 dataLength (void) const = 0;
++ virtual void dataLength (sal_uInt32 nLength) = 0;
++ virtual sal_uInt8* getDataBuffer (void) = 0;
++ virtual ChunkScope scope (sal_uInt32 nPage,
++ LinkDescriptor &rDescr) const = 0;
++ virtual storeError truncate (
++ ChunkScope eScope,
++ sal_uInt16 nRemain,
++ OStorePageBIOS &rBIOS) = 0;
++
++ storeError read (
++ sal_uInt32 nPage,
++ OStoreDataPageObject &rData,
++ OStorePageBIOS &rBIOS);
++ storeError write (
++ sal_uInt32 nPage,
++ OStoreDataPageObject &rData,
++ OStorePageBIOS &rBIOS);
++ storeError truncate (
++ sal_uInt32 nPage,
++ OStorePageBIOS &rBIOS);
+
+- /** path.
++ /** scope (internal).
+ */
+- sal_uInt32 path (void) const
++ ChunkScope scope (sal_uInt32 nPosition) const
+ {
+- page const & rPage = PAGE();
+- const sal_Char * pszName = rPage.m_aNameBlock.m_pData;
+- sal_uInt32 nPath = store::ntohl(rPage.m_aNameBlock.m_aKey.m_nHigh);
+- return rtl_crc32 (nPath, pszName, rtl_str_getLength(pszName));
++ sal_uInt32 nCapacity = capacity();
++ if (nPosition < nCapacity)
++ return SCOPE_INTERNAL;
++ else
++ return SCOPE_EXTERNAL;
+ }
+
+- sal_Size getName (sal_Char * pBuffer, sal_Size nBufsiz) const
+- {
+- sal_Char const * pszName = PAGE().m_aNameBlock.m_pData;
+- sal_Size nLength = rtl_str_getLength(pszName);
+- memcpy (pBuffer, pszName, SAL_MIN(nLength, nBufsiz));
+- return nLength;
+- }
++private:
++ virtual sal_uInt32 directLink (sal_uInt16 nIndex) const = 0;
++ virtual void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0;
++ virtual sal_uInt32 singleLink (sal_uInt16 nIndex) const = 0;
++ virtual void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0;
++ virtual sal_uInt32 doubleLink (sal_uInt16 nIndex) const = 0;
++ virtual void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0;
++ virtual sal_uInt32 tripleLink (sal_uInt16 nIndex) const = 0;
++ virtual void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0;
++
++protected:
++ storeError store_truncate (
++ sal_uInt32 nAddr,
++ sal_uInt16 nSingle,
++ OStorePageBIOS &rBIOS);
++ storeError store_truncate (
++ sal_uInt32 nAddr,
++ sal_uInt16 nDouble,
++ sal_uInt16 nSingle,
++ OStorePageBIOS &rBIOS);
++ storeError store_truncate (
++ sal_uInt32 nAddr,
++ sal_uInt16 nTriple,
++ sal_uInt16 nDouble,
++ sal_uInt16 nSingle,
++ OStorePageBIOS &rBIOS);
++};
+
+- /** dataLength.
+- */
+- sal_uInt32 dataLength (void) const
+- {
+- return store::ntohl(PAGE().m_aDataBlock.m_nDataLen);
+- }
+- void dataLength (sal_uInt32 nLength)
+- {
+- PAGE().m_aDataBlock.m_nDataLen = store::htonl(nLength);
+- touch();
+- }
++template<class T> class OStoreDirectoryPageObjectTemplate : public OStoreDirectoryPageObject
++{
++ typedef OStorePageObject base;
++ typedef T page;
++ typedef OStoreIndirectionPageData indirect;
+
+- /** direct.
+- */
+- sal_uInt32 directLink (sal_uInt16 nIndex) const
++ typedef OStorePageDescriptor D;
++
++ virtual sal_uInt32 directLink (sal_uInt16 nIndex) const
+ {
+ return PAGE().m_aDataBlock.directLink (nIndex);
+ }
+- void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ virtual void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ PAGE().m_aDataBlock.directLink (nIndex, nAddr);
+- touch();
+ }
+-
+- /** single indirect.
+- */
+- sal_uInt32 singleLink (sal_uInt16 nIndex) const
++ virtual sal_uInt32 singleLink (sal_uInt16 nIndex) const
+ {
+ return PAGE().m_aDataBlock.singleLink (nIndex);
+ }
+- void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ virtual void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ PAGE().m_aDataBlock.singleLink (nIndex, nAddr);
+- touch();
+ }
+-
+- /** double indirect.
+- */
+- sal_uInt32 doubleLink (sal_uInt16 nIndex) const
++ virtual sal_uInt32 doubleLink (sal_uInt16 nIndex) const
+ {
+ return PAGE().m_aDataBlock.doubleLink (nIndex);
+ }
+- void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ virtual void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ PAGE().m_aDataBlock.doubleLink (nIndex, nAddr);
+- touch();
+ }
+-
+- /** triple indirect.
+- */
+- sal_uInt32 tripleLink (sal_uInt16 nIndex) const
++ virtual sal_uInt32 tripleLink (sal_uInt16 nIndex) const
+ {
+ return PAGE().m_aDataBlock.tripleLink (nIndex);
+ }
+- void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
++ virtual void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ PAGE().m_aDataBlock.tripleLink (nIndex, nAddr);
+- touch();
+ }
++ virtual ChunkScope scope (sal_uInt32 nPage,
++ LinkDescriptor &rDescr) const
++ {
++ page const & rPage = PAGE();
++ sal_uInt32 index0, index1, index2, index3;
+
+- /** read (external data page).
+- */
+- storeError read (
+- sal_uInt32 nPage,
+- OStoreDataPageObject &rData,
+- OStorePageBIOS &rBIOS);
++ // direct.
++ sal_uInt32 nCount = rPage.m_aDataBlock.directCount();
++ sal_uInt32 nLimit = nCount;
++ if (nPage < nLimit)
++ {
++ // Page to index reduction.
++ index0 = nPage;
+
+- /** write (external data page).
+- */
+- storeError write (
+- sal_uInt32 nPage,
+- OStoreDataPageObject &rData,
+- OStorePageBIOS &rBIOS);
++ // Setup LinkDescriptor indices.
++ rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
++
++ // Done.
++ return SCOPE_DIRECT;
++ }
++ nPage -= nLimit;
++
++ // single indirect.
++ sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr);
++ nCount = rPage.m_aDataBlock.singleCount();
++ nLimit = nCount * nCapacity;
++ if (nPage < nLimit)
++ {
++ // Page to index reduction.
++ sal_uInt32 n = nPage;
++
++ // Reduce to single indirect i(1), direct n = i(0).
++ index1 = n / nCapacity;
++ index0 = n % nCapacity;
++
++ // Verify reduction.
++ n = index1 * nCapacity + index0;
++ OSL_POSTCOND(n == nPage, "wrong math on indirect indices");
++ if (n != nPage)
++ return SCOPE_UNKNOWN;
++
++ // Setup LinkDescriptor indices.
++ rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
++ rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
++
++ // Done.
++ return SCOPE_SINGLE;
++ }
++ nPage -= nLimit;
++
++ // double indirect.
++ nCount = rPage.m_aDataBlock.doubleCount();
++ nLimit = nCount * nCapacity * nCapacity;
++ if (nPage < nLimit)
++ {
++ // Page to index reduction.
++ sal_uInt32 n = nPage;
++
++ // Reduce to double indirect i(2), single indirect n = i(0).
++ index2 = n / (nCapacity * nCapacity);
++ n = n % (nCapacity * nCapacity);
++
++ // Reduce to single indirect i(1), direct n = i(0).
++ index1 = n / nCapacity;
++ index0 = n % nCapacity;
++
++ // Verify reduction.
++ n = index2 * nCapacity * nCapacity +
++ index1 * nCapacity + index0;
++ OSL_POSTCOND(n == nPage, "wrong math on double indirect indices");
++ if (n != nPage)
++ return SCOPE_UNKNOWN;
++
++ // Setup LinkDescriptor indices.
++ rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
++ rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
++ rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
++
++ // Done.
++ return SCOPE_DOUBLE;
++ }
++ nPage -= nLimit;
++
++ // triple indirect.
++ nCount = rPage.m_aDataBlock.tripleCount();
++ nLimit = nCount * nCapacity * nCapacity * nCapacity;
++ if (nPage < nLimit)
++ {
++ // Page to index reduction.
++ sal_uInt32 n = nPage;
++
++ // Reduce to triple indirect i(3), double indirect n.
++ index3 = n / (nCapacity * nCapacity * nCapacity);
++ n = n % (nCapacity * nCapacity * nCapacity);
++
++ // Reduce to double indirect i(2), single indirect n.
++ index2 = n / (nCapacity * nCapacity);
++ n = n % (nCapacity * nCapacity);
++
++ // Reduce to single indirect i(1), direct n = i(0).
++ index1 = n / nCapacity;
++ index0 = n % nCapacity;
++
++ // Verify reduction.
++ n = index3 * nCapacity * nCapacity * nCapacity +
++ index2 * nCapacity * nCapacity +
++ index1 * nCapacity + index0;
++ OSL_POSTCOND(n == nPage, "wrong math on triple indirect indices");
++ if (n != nPage)
++ return SCOPE_UNKNOWN;
++
++ // Setup LinkDescriptor indices.
++ rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
++ rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
++ rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
++ rDescr.m_nIndex3 = (sal_uInt16)(index3 & 0xffff);
++
++ // Done.
++ return SCOPE_TRIPLE;
++ }
++
++ // Unreachable (more than triple indirect).
++ return SCOPE_UNREACHABLE;
++ }
++
++ /*
++ * truncate (external data page scope; private).
++ */
++ virtual storeError truncate (
++ ChunkScope eScope,
++ sal_uInt16 nRemain,
++ OStorePageBIOS &rBIOS)
++ {
++ page const & rPage = PAGE();
++
++ // Enter.
++ storeError eErrCode = store_E_None;
++ if (eScope == SCOPE_DIRECT)
++ {
++ // Truncate direct data pages.
++ sal_uInt16 i, n = rPage.m_aDataBlock.directCount();
++ for (i = n; i > nRemain; i--)
++ {
++ // Obtain data page location.
++ sal_uInt32 nAddr = directLink (i - 1);
++ if (nAddr == STORE_PAGE_NULL) continue;
++
++ // Free data page.
++ OStoreDataPageData aData;
++ eErrCode = rBIOS.free (aData, nAddr);
++ if (eErrCode != store_E_None)
++ break;
++
++ // Clear pointer to data page.
++ directLink (i - 1, STORE_PAGE_NULL);
++ }
++
++ // Done.
++ return eErrCode;
++ }
++
++ if (eScope == SCOPE_SINGLE)
++ {
++ // Truncate single indirect pages.
++ sal_uInt16 i, n = rPage.m_aDataBlock.singleCount();
++ for (i = n; i > nRemain; i--)
++ {
++ // Truncate single indirect page to zero data pages.
++ eErrCode = store_truncate (singleLink (i - 1), 0, rBIOS);
++ if (eErrCode != store_E_None)
++ break;
++
++ // Clear pointer to single indirect page.
++ singleLink (i - 1, STORE_PAGE_NULL);
++ }
++
++ // Done.
++ return eErrCode;
++ }
++
++ if (eScope == SCOPE_DOUBLE)
++ {
++ // Truncate double indirect pages.
++ sal_uInt16 i, n = rPage.m_aDataBlock.doubleCount();
++ for (i = n; i > nRemain; i--)
++ {
++ // Truncate double indirect page to zero single indirect pages.
++ eErrCode = store_truncate (doubleLink (i - 1), 0, 0, rBIOS);
++ if (eErrCode != store_E_None)
++ break;
++
++ // Clear pointer to double indirect page.
++ doubleLink (i - 1, STORE_PAGE_NULL);
++ }
++
++ // Done.
++ return eErrCode;
++ }
++
++ if (eScope == SCOPE_TRIPLE)
++ {
++ // Truncate triple indirect pages.
++ sal_uInt16 i, n = rPage.m_aDataBlock.tripleCount();
++ for (i = n; i > nRemain; i--)
++ {
++ // Truncate to zero double indirect pages.
++ eErrCode = store_truncate (tripleLink (i - 1), 0, 0, 0, rBIOS);
++ if (eErrCode != store_E_None)
++ break;
++
++ // Clear pointer to triple indirect page.
++ tripleLink (i - 1, STORE_PAGE_NULL);
++ }
++
++ // Done.
++ return eErrCode;
++ }
+
+- /** truncate (external data page).
++ // Invalid scope.
++ return store_E_InvalidAccess;
++ }
++
++public:
++ /** Construction.
+ */
+- storeError truncate (
+- sal_uInt32 nPage,
+- OStorePageBIOS &rBIOS);
++ OStoreDirectoryPageObjectTemplate ()
++ : OStoreDirectoryPageObject ()
++ {}
+
+-private:
++ virtual storeError guard(sal_uInt32 nAddr)
++ { return PageHolderObject< page >::guard (m_xPage, nAddr); }
++ virtual storeError verify(sal_uInt32 nAddr, sal_uInt16 nVersion) const
++ { return PageHolderObject< page >::verify (m_xPage, nAddr, nVersion); }
++ virtual OStorePageDescriptor const& getDescriptor (void) const
++ { return PAGE().m_aDescr; }
++ virtual sal_uInt32 capacity (void) const
++ { return PAGE().capacity(); }
++ virtual sal_uInt32 attrib (void) const
++ { return store::ntohl(PAGE().m_aNameBlock.m_nAttrib); }
++ virtual void attrib (sal_uInt32 nAttrib)
++ { PAGE().m_aNameBlock.m_nAttrib = store::htonl(nAttrib); }
++ virtual OStorePageKey key (void) const
++ { return PAGE().m_aNameBlock.m_aKey; }
++ virtual void key (OStorePageKey const & rKey)
++ { PAGE().m_aNameBlock.m_aKey = rKey; }
++ virtual sal_uInt32 dataLength (void) const
++ { return store::ntohl(PAGE().m_aDataBlock.m_nDataLen); }
++ virtual void dataLength (sal_uInt32 nLength)
++ { PAGE().m_aDataBlock.m_nDataLen = store::htonl(nLength); }
++ virtual sal_uInt8* getDataBuffer (void)
++ { return PAGE().m_pData; }
++
++protected:
+ /** Representation.
+ */
+ page & PAGE()
+@@ -846,19 +1439,30 @@ private:
+ OSL_PRECOND(pImpl != 0, "OStoreDirectoryPageObject::PAGE(): Null pointer");
+ return (*pImpl);
+ }
++};
+
+- /** scope (external data page; private).
++struct OStoreDirectoryPageObjectV1 : public OStoreDirectoryPageObjectTemplate<OStoreDirectoryPageDataV1>
++{
++ /** Construction.
+ */
+- page::ChunkScope scope (
+- sal_uInt32 nPage,
+- page::DataBlock::LinkDescriptor &rDescr) const;
++ OStoreDirectoryPageObjectV1 ()
++ {}
++
++ virtual sal_uInt32 path (void) const;
++ virtual sal_Size getName (sal_Char * pBuffer, sal_Size nBufsiz, OStorePageBIOS &rBIOS) const;
++ virtual void setName (sal_Char const * pBuffer, sal_Size nBufsiz);
++};
+
+- /** truncate (external data page scope; private).
++struct OStoreDirectoryPageObjectV2 : public OStoreDirectoryPageObjectTemplate<OStoreDirectoryPageDataV2>
++{
++ /** Construction.
+ */
+- storeError truncate (
+- page::ChunkScope eScope,
+- sal_uInt16 nRemain,
+- OStorePageBIOS &rBIOS);
++ OStoreDirectoryPageObjectV2 ()
++ {}
++
++ virtual sal_uInt32 path (void) const;
++ virtual sal_Size getName (sal_Char * pBuffer, sal_Size nBufsiz, OStorePageBIOS &rBIOS) const;
++ virtual void setName (sal_Char const * pBuffer, sal_Size nBufsiz);
+ };
+
+ /*========================================================================
+diff --git store/source/stordir.cxx store/source/stordir.cxx
+index 0269e9c..cd2d610 100644
+--- store/source/stordir.cxx
++++ store/source/stordir.cxx
+@@ -82,14 +82,14 @@ using namespace store;
+ */
+ inline sal_Size __store_convertTextToUnicode (
+ rtl_TextToUnicodeConverter hConverter,
+- const sal_Char *pSrcBuffer, sal_Size nSrcLength,
++ rtl_String *pSrc,
+ sal_Unicode *pDstBuffer, sal_Size nDstLength)
+ {
+ sal_uInt32 nCvtInfo = 0;
+ sal_Size nCvtBytes = 0;
+ return rtl_convertTextToUnicode (
+ hConverter, 0,
+- pSrcBuffer, nSrcLength,
++ pSrc->buffer, pSrc->length,
+ pDstBuffer, nDstLength,
+ OSTRING_TO_OUSTRING_CVTFLAGS,
+ &nCvtInfo, &nCvtBytes);
+@@ -149,28 +149,28 @@ storeError OStoreDirectory_Impl::create (
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+- OStoreDirectoryPageObject aPage;
++ boost::scoped_ptr<inode> pPage;
++ xManager->createDirectoryPageObject(pPage);
+ storeError eErrCode = xManager->iget (
+- aPage, STORE_ATTRIB_ISDIR,
++ *pPage, STORE_ATTRIB_ISDIR,
+ pPath, pName, eMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+- if (!(aPage.attrib() & STORE_ATTRIB_ISDIR))
++ if (!(pPage->attrib() & STORE_ATTRIB_ISDIR))
+ return store_E_NotDirectory;
+
+- inode_holder_type xNode (aPage.get());
+- eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
++ eErrCode = xManager->acquirePage (pPage->getDescriptor(), store_AccessReadOnly);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Evaluate iteration path.
+- m_nPath = aPage.path();
++ m_nPath = pPage->path();
+ m_nPath = rtl_crc32 (m_nPath, "/", 1);
+
+ // Save page manager, and descriptor.
+ m_xManager = xManager;
+- m_aDescr = xNode->m_aDescr;
++ m_aDescr = pPage->getDescriptor();
+
+ return store_E_None;
+ }
+@@ -208,19 +208,19 @@ storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData)
+ if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK))
+ {
+ // Load page.
+- OStoreDirectoryPageObject aPage;
+- eErrCode = m_xManager->loadObjectAt (aPage, aLink.location());
++ boost::scoped_ptr<inode> pPage;
++ m_xManager->createDirectoryPageObject(pPage);
++ eErrCode = m_xManager->loadObjectAt (*pPage, aLink.location());
+ if (eErrCode == store_E_None)
+ {
+- inode_holder_type xNode (aPage.get());
+-
+ // Setup FindData.
+- sal_Char *p = xNode->m_aNameBlock.m_pData;
+- sal_Size n = rtl_str_getLength (p);
+- sal_Size k = rFindData.m_nLength;
++ rtl_String *pName=0;
++ rtl_string_new_WithLength (&pName, STORE_MAXIMUM_NAMESIZE - 1);
++ sal_Size n = pPage->getName(pName->buffer, pName->length, *m_xManager);
++ sal_Size k = rFindData.m_nLength;
+
+ n = __store_convertTextToUnicode (
+- m_hTextCvt, p, n,
++ m_hTextCvt, pName,
+ rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1);
+ if (k > n)
+ {
+@@ -229,8 +229,10 @@ storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData)
+ }
+
+ rFindData.m_nLength = n;
+- rFindData.m_nAttrib |= aPage.attrib();
+- rFindData.m_nSize = aPage.dataLength();
++ rFindData.m_nAttrib |= pPage->attrib();
++ rFindData.m_nSize = pPage->dataLength();
++
++ rtl_string_release (pName);
+
+ // Leave.
+ rFindData.m_nReserved = store::ntohl(aKey.m_nLow);
+diff --git store/source/stordir.hxx store/source/stordir.hxx
+index acfbf36..48f79b0 100644
+--- store/source/stordir.hxx
++++ store/source/stordir.hxx
+@@ -63,7 +63,7 @@
+ namespace store
+ {
+
+-struct OStoreDirectoryPageData;
++struct OStoreDirectoryPageObject;
+
+ /*========================================================================
+ *
+@@ -119,8 +119,7 @@ private:
+
+ /** Representation.
+ */
+- typedef OStoreDirectoryPageData inode;
+- typedef PageHolderObject< inode > inode_holder_type;
++ typedef OStoreDirectoryPageObject inode;
+
+ rtl::Reference<OStorePageManager> m_xManager;
+
+diff --git store/source/store.cxx store/source/store.cxx
+index 87e85fc..923ce29 100644
+--- store/source/store.cxx
++++ store/source/store.cxx
+@@ -118,7 +118,8 @@ storeError SAL_CALL store_releaseHandle (
+ */
+ storeError SAL_CALL store_createMemoryFile (
+ sal_uInt16 nPageSize,
+- storeFileHandle *phFile
++ storeFileHandle *phFile,
++ sal_uInt16 nFormatVersion
+ ) SAL_THROW_EXTERN_C()
+ {
+ if (!phFile)
+@@ -137,7 +138,7 @@ storeError SAL_CALL store_createMemoryFile (
+ return store_E_OutOfMemory;
+
+ eErrCode = xManager->initialize (
+- &*xLockBytes, store_AccessCreate, nPageSize);
++ &*xLockBytes, store_AccessCreate, nPageSize, nFormatVersion);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -154,7 +155,8 @@ storeError SAL_CALL store_openFile (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize,
+- storeFileHandle *phFile
++ storeFileHandle *phFile,
++ sal_uInt16 nFormatVersion
+ ) SAL_THROW_EXTERN_C()
+ {
+ if (phFile)
+@@ -175,7 +177,7 @@ storeError SAL_CALL store_openFile (
+ return store_E_OutOfMemory;
+
+ eErrCode = xManager->initialize (
+- &*xLockBytes, eAccessMode, nPageSize);
++ &*xLockBytes, eAccessMode, nPageSize, nFormatVersion);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+diff --git store/source/storlckb.cxx store/source/storlckb.cxx
+index 6175064..4e4adbb 100644
+--- store/source/storlckb.cxx
++++ store/source/storlckb.cxx
+@@ -72,9 +72,9 @@ OStoreLockBytes::~OStoreLockBytes (void)
+ {
+ if (m_xManager.is())
+ {
+- if (m_xNode.is())
++ if (m_xNode.get())
+ {
+- OStorePageDescriptor aDescr (m_xNode->m_aDescr);
++ OStorePageDescriptor aDescr (m_xNode->getDescriptor());
+ if (m_bWriteable)
+ m_xManager->releasePage (aDescr, store_AccessReadWrite);
+ else
+@@ -107,32 +107,30 @@ storeError OStoreLockBytes::create (
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+- OStoreDirectoryPageObject aPage;
++ xManager->createDirectoryPageObject(m_xNode);
+ storeError eErrCode = xManager->iget (
+- aPage, STORE_ATTRIB_ISFILE,
++ *m_xNode, STORE_ATTRIB_ISFILE,
+ pPath, pName, eMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+- if (!(aPage.attrib() & STORE_ATTRIB_ISFILE))
++ if (!(m_xNode->attrib() & STORE_ATTRIB_ISFILE))
+ {
+ // No ISFILE in older versions (backward compatibility).
+- if (aPage.attrib() & STORE_ATTRIB_ISLINK)
++ if (m_xNode->attrib() & STORE_ATTRIB_ISLINK)
+ return store_E_NotFile;
+ }
+
+ // ...
+- inode_holder_type xNode (aPage.get());
+ if (eMode != store_AccessReadOnly)
+- eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadWrite);
++ eErrCode = xManager->acquirePage (m_xNode->getDescriptor(), store_AccessReadWrite);
+ else
+- eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
++ eErrCode = xManager->acquirePage (m_xNode->getDescriptor(), store_AccessReadOnly);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // ...
+ m_xManager = xManager;
+- m_xNode = xNode;
+ m_bWriteable = (eMode != store_AccessReadOnly);
+
+ // Check for truncation.
+@@ -167,9 +165,7 @@ storeError OStoreLockBytes::readAt (
+ osl::MutexGuard aGuard (*m_xManager);
+
+ // Determine data length.
+- OStoreDirectoryPageObject aPage (m_xNode.get());
+-
+- sal_uInt32 nDataLen = aPage.dataLength();
++ sal_uInt32 nDataLen = m_xNode->dataLength();
+ if ((nOffset + nBytes) > nDataLen)
+ nBytes = nDataLen - nOffset;
+
+@@ -183,7 +179,7 @@ storeError OStoreLockBytes::readAt (
+ if (eScope == inode::SCOPE_INTERNAL)
+ {
+ // Read from inode page (internal scope).
+- inode::ChunkDescriptor aDescr (
++ ChunkDescriptor aDescr (
+ nOffset, m_xNode->capacity());
+
+ sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
+@@ -191,7 +187,7 @@ storeError OStoreLockBytes::readAt (
+
+ memcpy (
+ &pData[rnDone],
+- &m_xNode->m_pData[aDescr.m_nOffset],
++ &m_xNode->getDataBuffer()[aDescr.m_nOffset],
+ nLength);
+
+ // Adjust counters.
+@@ -202,13 +198,13 @@ storeError OStoreLockBytes::readAt (
+ else
+ {
+ // Read from data page (external scope).
+- inode::ChunkDescriptor aDescr (
+- nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
++ ChunkDescriptor aDescr (
++ nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->getDescriptor())); // @@@
+
+ sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
+ nLength = SAL_MIN(nLength, nBytes);
+
+- storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
++ storeError eErrCode = m_xNode->read (aDescr.m_nPage, aData, *m_xManager);
+ if (eErrCode != store_E_None)
+ {
+ if (eErrCode != store_E_NotExists)
+@@ -264,8 +260,8 @@ storeError OStoreLockBytes::writeAt (
+ osl::MutexGuard aGuard (*m_xManager);
+
+ // Write data.
+- OStoreDirectoryPageObject aPage (m_xNode.get());
+ const sal_uInt8 *pData = (const sal_uInt8*)pBuffer;
++ bool bDirty=false;
+
+ storeError eErrCode = store_E_None;
+ while (nBytes > 0)
+@@ -275,18 +271,18 @@ storeError OStoreLockBytes::writeAt (
+ if (eScope == inode::SCOPE_INTERNAL)
+ {
+ // Write to inode page (internal scope).
+- inode::ChunkDescriptor aDescr (
++ ChunkDescriptor aDescr (
+ nOffset, m_xNode->capacity());
+
+ sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
+ nLength = SAL_MIN(nLength, nBytes);
+
+ memcpy (
+- &m_xNode->m_pData[aDescr.m_nOffset],
++ &m_xNode->getDataBuffer()[aDescr.m_nOffset],
+ &pData[rnDone], nLength);
+
+ // Mark inode dirty.
+- aPage.touch();
++ bDirty = true;
+
+ // Adjust counters.
+ rnDone += nLength;
+@@ -294,23 +290,23 @@ storeError OStoreLockBytes::writeAt (
+ nBytes -= nLength;
+
+ // Adjust data length.
+- if (aPage.dataLength() < nOffset)
+- aPage.dataLength (nOffset);
++ if (m_xNode->dataLength() < nOffset)
++ m_xNode->dataLength (nOffset);
+ }
+ else
+ {
+ // Write to data page (external scope).
+ OStoreDataPageObject aData;
+
+- inode::ChunkDescriptor aDescr (
+- nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
++ ChunkDescriptor aDescr (
++ nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->getDescriptor())); // @@@
+
+ sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength);
+ if ((aDescr.m_nOffset > 0) || (nBytes < nLength))
+ {
+ // Unaligned. Need to load/create data page.
+ // @@@ loadOrCreate()
+- eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager);
++ eErrCode = m_xNode->read (aDescr.m_nPage, aData, *m_xManager);
+ if (eErrCode != store_E_None)
+ {
+ if (eErrCode != store_E_NotExists)
+@@ -338,7 +334,7 @@ storeError OStoreLockBytes::writeAt (
+ &pData[rnDone], nLength);
+
+ // Save data page.
+- eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager);
++ eErrCode = m_xNode->write (aDescr.m_nPage, aData, *m_xManager);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -348,14 +344,14 @@ storeError OStoreLockBytes::writeAt (
+ nBytes -= nLength;
+
+ // Adjust data length.
+- if (aPage.dataLength() < nOffset)
+- aPage.dataLength (nOffset);
++ if (m_xNode->dataLength() < nOffset)
++ m_xNode->dataLength (nOffset);
+ }
+ }
+
+ // Check for modified inode.
+- if (aPage.dirty())
+- return m_xManager->saveObjectAt (aPage, aPage.location());
++ if (bDirty)
++ return m_xManager->saveObjectAt (*m_xNode, m_xNode->location());
+ else
+ return store_E_None;
+ }
+@@ -385,8 +381,7 @@ storeError OStoreLockBytes::setSize (sal_uInt32 nSize)
+ osl::MutexGuard aGuard (*m_xManager);
+
+ // Determine current length.
+- OStoreDirectoryPageObject aPage (m_xNode.get());
+- sal_uInt32 nDataLen = aPage.dataLength();
++ sal_uInt32 nDataLen = m_xNode->dataLength();
+
+ if (nSize == nDataLen)
+ return store_E_None;
+@@ -405,37 +400,37 @@ storeError OStoreLockBytes::setSize (sal_uInt32 nSize)
+ if (eDataScope == inode::SCOPE_EXTERNAL)
+ {
+ // External 'Data' scope. Truncate all external data pages.
+- eErrCode = aPage.truncate (0, *m_xManager);
++ eErrCode = m_xNode->truncate (0, *m_xManager);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Truncate internal data page.
+- inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity());
++ ChunkDescriptor aDescr (nSize, m_xNode->capacity());
+ memset (
+- &(m_xNode->m_pData[aDescr.m_nOffset]),
++ &(m_xNode->getDataBuffer()[aDescr.m_nOffset]),
+ 0, aDescr.m_nLength);
+ }
+ else
+ {
+ // External 'Size' scope. Truncate external data pages.
+- inode::ChunkDescriptor aDescr (
+- nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@
++ ChunkDescriptor aDescr (
++ nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->getDescriptor())); // @@@
+
+ sal_uInt32 nPage = aDescr.m_nPage;
+ if (aDescr.m_nOffset) nPage += 1;
+
+- eErrCode = aPage.truncate (nPage, *m_xManager);
++ eErrCode = m_xNode->truncate (nPage, *m_xManager);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+ }
+
+ // Set (extended or truncated) size.
+- aPage.dataLength (nSize);
++ m_xNode->dataLength (nSize);
+
+ // Save modified inode.
+- return m_xManager->saveObjectAt (aPage, aPage.location());
++ return m_xManager->saveObjectAt (*m_xNode, m_xNode->location());
+ }
+
+ /*
+@@ -448,7 +443,6 @@ storeError OStoreLockBytes::stat (sal_uInt32 &rnSize)
+ if (!m_xManager.is())
+ return store_E_InvalidAccess;
+
+- OStoreDirectoryPageObject aPage (m_xNode.get());
+- rnSize = aPage.dataLength();
++ rnSize = m_xNode->dataLength();
+ return store_E_None;
+ }
+diff --git store/source/storlckb.hxx store/source/storlckb.hxx
+index 217e8d1..7a0a7b7 100644
+--- store/source/storlckb.hxx
++++ store/source/storlckb.hxx
+@@ -44,7 +44,7 @@ namespace store
+ {
+
+ struct OStoreDataPageData;
+-struct OStoreDirectoryPageData;
++struct OStoreDirectoryPageObject;
+
+ /*========================================================================
+ *
+@@ -137,11 +137,10 @@ private:
+ */
+ rtl::Reference<OStorePageManager> m_xManager;
+
+- typedef OStoreDataPageData data;
+- typedef OStoreDirectoryPageData inode;
++ typedef OStoreDataPageData data;
++ typedef OStoreDirectoryPageObject inode;
+
+- typedef PageHolderObject< inode > inode_holder_type;
+- inode_holder_type m_xNode;
++ boost::scoped_ptr<inode> m_xNode;
+
+ bool m_bWriteable;
+
+diff --git store/source/storpage.cxx store/source/storpage.cxx
+index a7c59be..87d9bae 100644
+--- store/source/storpage.cxx
++++ store/source/storpage.cxx
+@@ -86,7 +86,8 @@ sal_Bool SAL_CALL OStorePageManager::isKindOf (sal_uInt32 nTypeId)
+ storeError OStorePageManager::initialize (
+ ILockBytes * pLockBytes,
+ storeAccessMode eAccessMode,
+- sal_uInt16 & rnPageSize)
++ sal_uInt16 & rnPageSize,
++ sal_uInt16 & rnFormatVersion)
+ {
+ // Acquire exclusive access.
+ osl::MutexGuard aGuard(*this);
+@@ -96,7 +97,7 @@ storeError OStorePageManager::initialize (
+ return store_E_InvalidParameter;
+
+ // Initialize base.
+- storeError eErrCode = base::initialize (pLockBytes, eAccessMode, rnPageSize);
++ storeError eErrCode = base::initialize (pLockBytes, eAccessMode, rnPageSize, rnFormatVersion);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -104,7 +105,9 @@ storeError OStorePageManager::initialize (
+ if (!base::isWriteable())
+ {
+ // Readonly. Load RootNode.
+- return base::loadObjectAt (m_aRoot, rnPageSize);
++ eErrCode = base::loadObjectAt (m_aRoot, rnPageSize);
++ m_aRoot.fixup();
++ return eErrCode;
+ }
+
+ // Writeable. Load or Create RootNode.
+@@ -207,6 +210,7 @@ storeError OStorePageManager::remove_Impl (entry & rEntry)
+
+ // Load next node page.
+ eErrCode = loadObjectAt (aNode, nAddr);
++ aNode.fixup();
+
+ PageHolderObject< page > xNext (aNode.get());
+ xNext.swap (xPage);
+@@ -219,6 +223,7 @@ storeError OStorePageManager::remove_Impl (entry & rEntry)
+ {
+ // Load next node page.
+ eErrCode = loadObjectAt (aNode, nAddr);
++ aNode.fixup();
+
+ page const & rPage = (*xPage);
+
+@@ -266,6 +271,7 @@ storeError OStorePageManager::remove_Impl (entry & rEntry)
+
+ // Load link page.
+ storeError eErrCode = loadObjectAt (aNode, nAddr);
++ aNode.fixup();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -299,6 +305,23 @@ storeError OStorePageManager::remove_Impl (entry & rEntry)
+ return aNode.remove (i, rEntry, *this);
+ }
+
++void OStorePageManager::createDirectoryPageObject(boost::scoped_ptr<inode_type>& rPage)
++{
++ switch(version ())
++ {
++ case STORE_FORMAT_V1:
++ rPage.reset(new OStoreDirectoryPageObjectV1());
++ rPage->construct<OStoreDirectoryPageDataV1>(base::allocator());
++ break;
++ case STORE_FORMAT_V2:
++ rPage.reset(new OStoreDirectoryPageObjectV2());
++ rPage->construct<OStoreDirectoryPageDataV2>(base::allocator());
++ break;
++ default:
++ break;
++ }
++}
++
+ /*
+ * namei.
+ * Precond: none (static).
+@@ -370,19 +393,10 @@ storeError OStorePageManager::iget (
+ return store_E_AccessViolation;
+
+ // Create inode page.
+- eErrCode = rPage.construct< inode >(base::allocator());
+- if (eErrCode != store_E_None)
+- return eErrCode;
+-
+- // Setup inode nameblock.
+- PageHolderObject< inode > xPage (rPage.get());
+-
+ rPage.key (aKey);
+ rPage.attrib (nAttrib);
+
+- memcpy (
+- &(xPage->m_aNameBlock.m_pData[0]),
+- pName->buffer, pName->length);
++ rPage.setName(pName->buffer, pName->length);
+
+ // Save inode page.
+ eErrCode = save_dirpage_Impl (aKey, rPage);
+@@ -394,9 +408,8 @@ storeError OStorePageManager::iget (
+ if (rPage.attrib() & STORE_ATTRIB_ISLINK)
+ {
+ // Obtain 'Destination' page key.
+- PageHolderObject< inode > xPage (rPage.get());
+ OStorePageKey aDstKey;
+- memcpy (&aDstKey, &(xPage->m_pData[0]), sizeof(aDstKey));
++ memcpy (&aDstKey, rPage.getDataBuffer(), sizeof(aDstKey));
+
+ // Load 'Destination' inode.
+ eErrCode = load_dirpage_Impl (aDstKey, rPage);
+@@ -658,34 +671,29 @@ storeError OStorePageManager::symlink (
+ return eErrCode;
+
+ // Initialize directory page.
+- OStoreDirectoryPageObject aPage;
+- eErrCode = aPage.construct< inode >(base::allocator());
+- if (eErrCode != store_E_None)
+- return eErrCode;
++ boost::scoped_ptr<inode_type> pPage;
++ createDirectoryPageObject(pPage);
+
+ // Setup as 'Source' directory page.
+- inode_holder_type xNode (aPage.get());
+- aPage.key (aSrcKey);
+- memcpy (
+- &(xNode->m_aNameBlock.m_pData[0]),
+- pSrcName->buffer, pSrcName->length);
++ pPage->key (aSrcKey);
++ pPage->setName(pSrcName->buffer, pSrcName->length);
+
+ // Store 'Destination' page key.
+ OStorePageKey aDstKey (rDstKey);
+- memcpy (&(xNode->m_pData[0]), &aDstKey, sizeof(aDstKey));
++ memcpy (pPage->getDataBuffer(), &aDstKey, sizeof(aDstKey));
+
+ // Mark 'Source' as symbolic link to 'Destination'.
+- aPage.attrib (STORE_ATTRIB_ISLINK);
+- aPage.dataLength (sal_uInt32(sizeof(aDstKey)));
++ pPage->attrib (STORE_ATTRIB_ISLINK);
++ pPage->dataLength (sal_uInt32(sizeof(aDstKey)));
+
+ // Allocate and save 'Source' directory page.
+- eErrCode = base::allocate (aPage);
++ eErrCode = base::allocate (*pPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Insert 'Source' entry.
+ PageHolderObject< page > xSrcNode (aSrcNode.get());
+- OStorePageLink aSrcLink (aPage.location());
++ OStorePageLink aSrcLink (pPage->location());
+ xSrcNode->insert (i + 1, entry(aSrcKey, aSrcLink));
+
+ // Save modified NodePage.
+@@ -734,16 +742,17 @@ storeError OStorePageManager::rename (
+ entry e (xSrcNode->m_pData[i]);
+
+ // Check for (not a) hardlink.
+- OStoreDirectoryPageObject aPage;
++ boost::scoped_ptr<inode_type> pPage;
++ createDirectoryPageObject(pPage);
+ if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK))
+ {
+ // Load directory page.
+- eErrCode = base::loadObjectAt (aPage, e.m_aLink.location());
++ eErrCode = base::loadObjectAt (*pPage, e.m_aLink.location());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for directory.
+- if (aPage.attrib() & STORE_ATTRIB_ISDIR)
++ if (pPage->attrib() & STORE_ATTRIB_ISDIR)
+ {
+ // Ugly, but necessary (backward compatibility).
+ aDstKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aDstKey.m_nLow), "/", 1));
+@@ -771,20 +780,12 @@ storeError OStorePageManager::rename (
+ if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK))
+ {
+ // Modify 'Source' directory page.
+- inode_holder_type xNode (aPage.get());
+-
+ // Setup 'Destination' NameBlock.
+- sal_Int32 nDstLen = pDstName->length;
+- memcpy (
+- &(xNode->m_aNameBlock.m_pData[0]),
+- pDstName->buffer, pDstName->length);
+- memset (
+- &(xNode->m_aNameBlock.m_pData[nDstLen]),
+- 0, STORE_MAXIMUM_NAMESIZE - nDstLen);
+- aPage.key (e.m_aKey);
++ pPage->setName(pDstName->buffer, pDstName->length);
++ pPage->key (e.m_aKey);
+
+ // Save directory page.
+- eErrCode = base::saveObjectAt (aPage, e.m_aLink.location());
++ eErrCode = base::saveObjectAt (*pPage, e.m_aLink.location());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+@@ -825,35 +826,34 @@ storeError OStorePageManager::remove (const OStorePageKey &rKey)
+ if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK))
+ {
+ // Load directory page.
+- OStoreDirectoryPageObject aPage;
+- eErrCode = base::loadObjectAt (aPage, e.m_aLink.location());
++ boost::scoped_ptr<inode_type> pPage;
++ createDirectoryPageObject(pPage);
++ eErrCode = base::loadObjectAt (*pPage, e.m_aLink.location());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+- inode_holder_type xNode (aPage.get());
+-
+ // Acquire page write access.
+- OStorePageDescriptor aDescr (xNode->m_aDescr);
++ OStorePageDescriptor aDescr (pPage->getDescriptor());
+ eErrCode = base::acquirePage (aDescr, store_AccessReadWrite);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for symbolic link.
+- if (!(aPage.attrib() & STORE_ATTRIB_ISLINK))
++ if (!(pPage->attrib() & STORE_ATTRIB_ISLINK))
+ {
+ // Ordinary inode. Determine 'Data' scope.
+- inode::ChunkScope eScope = xNode->scope (aPage.dataLength());
+- if (eScope == inode::SCOPE_EXTERNAL)
++ inode_type::ChunkScope eScope = pPage->scope (pPage->dataLength());
++ if (eScope == inode_type::SCOPE_EXTERNAL)
+ {
+ // External 'Data' scope. Truncate all external data pages.
+- eErrCode = aPage.truncate (0, *this);
++ eErrCode = pPage->truncate (0, *this);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Truncate internal data page.
+- memset (&(xNode->m_pData[0]), 0, xNode->capacity());
+- aPage.dataLength (0);
++ memset (pPage->getDataBuffer(), 0, pPage->capacity());
++ pPage->dataLength (0);
+ }
+
+ // Release page write access.
+@@ -861,7 +861,7 @@ storeError OStorePageManager::remove (const OStorePageKey &rKey)
+
+ // Release and free directory page.
+ OStorePageData aPageHead;
+- eErrCode = base::free (aPageHead, aPage.location());
++ eErrCode = base::free (aPageHead, pPage->location());
+ }
+
+ // Remove entry.
+@@ -878,12 +878,14 @@ struct RebuildContext
+ rtl::Reference<OStorePageBIOS> m_xBIOS;
+ OStorePageBIOS::ScanContext m_aCtx;
+ sal_uInt16 m_nPageSize;
++ sal_uInt16 m_nFormatVersion;
+
+ /** Construction.
+ */
+ RebuildContext (void)
+- : m_xBIOS (new OStorePageBIOS()),
+- m_nPageSize (0)
++ : m_xBIOS (new OStorePageBIOS()),
++ m_nPageSize (0),
++ m_nFormatVersion(STORE_FORMAT_V1)
+ {}
+
+ /** initialize (PageBIOS and ScanContext).
+@@ -893,7 +895,7 @@ struct RebuildContext
+ storeError eErrCode = store_E_InvalidParameter;
+ if (pLockBytes)
+ {
+- m_xBIOS->initialize (pLockBytes, store_AccessReadOnly, m_nPageSize);
++ m_xBIOS->initialize (pLockBytes, store_AccessReadOnly, m_nPageSize, m_nFormatVersion);
+ eErrCode = m_xBIOS->scanBegin (m_aCtx, nMagic);
+ }
+ return eErrCode;
+@@ -940,52 +942,57 @@ storeError OStorePageManager::rebuild (
+ rtl::Reference<OStorePageBIOS> xSrcBIOS (aCtx.m_xBIOS);
+
+ // Initialize as 'Destination' with 'Source' page size.
+- eErrCode = self::initialize (pDstLB, store_AccessCreate, aCtx.m_nPageSize);
++ // Force V1 format, we migrate away from the V2 version
++ sal_uInt16 nFormat=STORE_FORMAT_V1;
++ eErrCode = self::initialize (pDstLB, store_AccessCreate, aCtx.m_nPageSize, nFormat);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
++ rtl_String* pStr=0;
++ rtl_string_new_WithLength(&pStr, STORE_MAXIMUM_NAMESIZE);
++
+ // Pass One: Scan 'Source' directory pages.
+ {
+ // Scan 'Source' directory pages.
+- OStoreDirectoryPageObject aSrcPage;
+- while ((eErrCode = aCtx.load(aSrcPage)) == store_E_None)
++ boost::scoped_ptr<inode_type> pSrcPage;
++ createDirectoryPageObject(pSrcPage);
++ while ((eErrCode = aCtx.load(*pSrcPage)) == store_E_None)
+ {
+- OStoreDirectoryPageObject aDstPage;
+- eErrCode = aDstPage.construct< inode >(base::allocator());
+- if (eErrCode != store_E_None)
+- break;
+-
+- inode_holder_type xSrcDir (aSrcPage.get());
+- inode_holder_type xDstDir (aDstPage.get());
++ boost::scoped_ptr<inode_type> pDstPage;
++ createDirectoryPageObject(pDstPage);
+
+ // Copy NameBlock @@@ OLD @@@
+- memcpy (&(xDstDir->m_aNameBlock), &(xSrcDir->m_aNameBlock), sizeof(xSrcDir->m_aNameBlock));
++ pSrcPage->getName(pStr->buffer, pStr->length, *xSrcBIOS);
++ pDstPage->setName(pStr->buffer, pStr->length);
+
+ // Obtain 'Source' data length.
+- sal_uInt32 nDataLen = aSrcPage.dataLength();
++ sal_uInt32 nDataLen = pSrcPage->dataLength();
+ if (nDataLen > 0)
+ {
+ // Copy internal data area @@@ OLD @@@
+- memcpy (&(xDstDir->m_pData[0]), &(xSrcDir->m_pData[0]), xSrcDir->capacity());
++ memcpy (pDstPage->getDataBuffer(), pSrcPage->getDataBuffer(), pSrcPage->capacity());
+ }
+
+ // Insert 'Destination' directory page.
+- eErrCode = save_dirpage_Impl (aDstPage.key(), aDstPage);
++ eErrCode = save_dirpage_Impl (pDstPage->key(), *pDstPage);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Check for external data page scope.
+- if (xSrcDir->scope(nDataLen) != inode::SCOPE_INTERNAL)
++ if (pSrcPage->scope(nDataLen) != inode_type::SCOPE_INTERNAL)
+ {
+ // Initialize 'Destination' data page.
+ typedef OStoreDataPageData data;
+ PageHolderObject< data > xData;
+ if (!xData.construct(base::allocator()))
++ {
++ rtl_string_release(pStr);
+ return store_E_OutOfMemory;
++ }
+
+ // Determine data page count.
+- inode::ChunkDescriptor aDescr (
+- nDataLen - xDstDir->capacity(), xData->capacity());
++ ChunkDescriptor aDescr (
++ nDataLen - pDstPage->capacity(), xData->capacity());
+
+ sal_uInt32 i, n = aDescr.m_nPage;
+ if (aDescr.m_nOffset) n += 1;
+@@ -997,23 +1004,24 @@ storeError OStorePageManager::rebuild (
+ // Read 'Source' data page.
+ osl::MutexGuard aSrcGuard (*xSrcBIOS);
+
+- eErrCode = aSrcPage.read (i, aData, *xSrcBIOS);
++ eErrCode = pSrcPage->read (i, aData, *xSrcBIOS);
+ if (eErrCode != store_E_None)
+ continue;
+
+ // Write 'Destination' data page. @@@ READONLY @@@
+- eErrCode = aDstPage.write (i, aData, *this);
++ eErrCode = pDstPage->write (i, aData, *this);
+ }
+ }
+
+ // Update 'Destination' directory page.
+- aDstPage.dataLength (nDataLen);
+- eErrCode = base::saveObjectAt (aDstPage, aDstPage.location());
++ pDstPage->dataLength (nDataLen);
++ eErrCode = base::saveObjectAt (*pDstPage, pDstPage->location());
+ }
+
+ // Save directory scan results.
+ flush();
+ }
++ rtl_string_release(pStr);
+
+ // Pass Two: Scan 'Source' BTree nodes.
+ {
+@@ -1037,11 +1045,12 @@ storeError OStorePageManager::rebuild (
+ if (e.m_nAttrib & STORE_ATTRIB_ISLINK)
+ {
+ // Load the hard link destination.
+- OStoreDirectoryPageObject aSrcPage;
+- eErrCode = xSrcBIOS->loadObjectAt (aSrcPage, e.m_aLink.location());
++ boost::scoped_ptr<inode_type> pSrcPage;
++ createDirectoryPageObject(pSrcPage);
++ eErrCode = xSrcBIOS->loadObjectAt (*pSrcPage, e.m_aLink.location());
+ if (eErrCode == store_E_None)
+ {
+- OStorePageKey aDstKey (aSrcPage.key());
++ OStorePageKey aDstKey (pSrcPage->key());
+ eErrCode = link (e.m_aKey, aDstKey);
+ }
+ e.m_nAttrib &= ~STORE_ATTRIB_ISLINK;
+diff --git store/source/storpage.hxx store/source/storpage.hxx
+index 4ebf05b..f5adae2 100644
+--- store/source/storpage.hxx
++++ store/source/storpage.hxx
+@@ -40,11 +40,12 @@
+ #include "storbios.hxx"
+ #include "stortree.hxx"
+
++#include <boost/scoped_ptr.hpp>
++
+ namespace store
+ {
+
+-struct OStoreDirectoryPageData;
+-class OStoreDirectoryPageObject;
++class OStoreDirectoryPageObject;
+
+ /*========================================================================
+ *
+@@ -54,6 +55,8 @@ class OStoreDirectoryPageObject;
+ class OStorePageManager : public store::OStorePageBIOS
+ {
+ public:
++ typedef OStoreDirectoryPageObject inode_type;
++
+ /** Construction.
+ */
+ OStorePageManager (void);
+@@ -63,7 +66,8 @@ public:
+ virtual storeError initialize (
+ ILockBytes * pLockBytes,
+ storeAccessMode eAccessMode,
+- sal_uInt16 & rnPageSize);
++ sal_uInt16 & rnPageSize,
++ sal_uInt16 & rnFormatVersion);
+
+ /** isValid.
+ * @return sal_True upon successful initialization,
+@@ -71,6 +75,11 @@ public:
+ */
+ inline sal_Bool isValid (void) const;
+
++ /** createDirectoryPageObject.
++ * creates impl object of dir page, differs for v1 and v2
++ */
++ void createDirectoryPageObject(boost::scoped_ptr<inode_type>& rPage);
++
+ /** DirectoryPage I/O (managed).
+ */
+ static storeError namei (
+@@ -79,11 +88,11 @@ public:
+ OStorePageKey &rKey);
+
+ storeError iget (
+- OStoreDirectoryPageObject & rPage, // [out]
+- sal_uInt32 nAttrib,
+- const rtl_String * pPath,
+- const rtl_String * pName,
+- storeAccessMode eMode);
++ inode_type & rPage, // [in/out]
++ sal_uInt32 nAttrib,
++ const rtl_String * pPath,
++ const rtl_String * pName,
++ storeAccessMode eMode);
+
+ storeError iterate (
+ OStorePageKey & rKey,
+@@ -158,9 +167,6 @@ private:
+ typedef OStoreBTreeNodeData page;
+ typedef OStoreBTreeNodeObject node;
+
+- typedef OStoreDirectoryPageData inode;
+- typedef PageHolderObject< inode > inode_holder_type;
+-
+ /** IStoreHandle TypeId.
+ */
+ static const sal_uInt32 m_nTypeId;
+diff --git store/source/stortree.cxx store/source/stortree.cxx
+index 71cdb47..413bc1a 100644
+--- store/source/stortree.cxx
++++ store/source/stortree.cxx
+@@ -182,9 +182,9 @@ storeError OStoreBTreeNodeObject::guard (sal_uInt32 nAddr)
+ /*
+ * verify.
+ */
+-storeError OStoreBTreeNodeObject::verify (sal_uInt32 nAddr) const
++storeError OStoreBTreeNodeObject::verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const
+ {
+- return PageHolderObject< page >::verify (m_xPage, nAddr);
++ return PageHolderObject< page >::verify (m_xPage, nAddr, nVersion);
+ }
+
+ /*
+@@ -311,6 +311,7 @@ storeError OStoreBTreeNodeObject::remove (
+ // Load link node.
+ self aNodeL;
+ eErrCode = rBIOS.loadObjectAt (aNodeL, aEntryL.m_aLink.location());
++ aNodeL.fixup();
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+@@ -352,6 +353,7 @@ storeError OStoreBTreeNodeObject::remove (
+ // Load right link node.
+ self aNodeR;
+ eErrCode = rBIOS.loadObjectAt (aNodeR, rPage.m_pData[nIndexR].m_aLink.location());
++ aNodeR.fixup();
+ if (eErrCode == store_E_None)
+ {
+ if (rPageL.queryMerge (rPageR))
+@@ -406,6 +408,11 @@ storeError OStoreBTreeNodeObject::remove (
+ return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ }
+
++void OStoreBTreeNodeObject::fixup (void)
++{
++ m_xPage->m_aGuard.m_nMagic = STORE_MAGIC_BTREENODE;
++}
++
+ /*========================================================================
+ *
+ * OStoreBTreeRootObject implementation.
+@@ -431,6 +438,7 @@ storeError OStoreBTreeRootObject::loadOrCreate (
+ OStorePageBIOS & rBIOS)
+ {
+ storeError eErrCode = rBIOS.loadObjectAt (*this, nAddr);
++ fixup();
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+@@ -562,6 +570,7 @@ storeError OStoreBTreeRootObject::find_lookup (
+
+ // Load next page.
+ storeError eErrCode = rBIOS.loadObjectAt (rNode, nAddr);
++ rNode.fixup();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+@@ -646,6 +655,7 @@ storeError OStoreBTreeRootObject::find_insert (
+ // Load next page.
+ OStoreBTreeNodeObject aNext;
+ storeError eErrCode = rBIOS.loadObjectAt (aNext, nAddr);
++ aNext.fixup();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+@@ -686,3 +696,5 @@ storeError OStoreBTreeRootObject::find_insert (
+ (void) testInvariant("OStoreBTreeRootObject::find_insert(): leave");
+ return store_E_None;
+ }
++
++
+diff --git store/source/stortree.hxx store/source/stortree.hxx
+index 34c49aa..4e6304c 100644
+--- store/source/stortree.hxx
++++ store/source/stortree.hxx
+@@ -131,7 +131,7 @@ struct OStoreBTreeNodeData : public store::OStorePageData
+ */
+ static const size_t theSize = sizeof(G);
+ static const sal_uInt16 thePageSize = base::theSize + self::theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= self::thePageSize);
+
+ /** capacity.
+ */
+@@ -262,7 +262,7 @@ public:
+ /** External representation.
+ */
+ virtual storeError guard (sal_uInt32 nAddr);
+- virtual storeError verify (sal_uInt32 nAddr) const;
++ virtual storeError verify (sal_uInt32 nAddr, sal_uInt16 nVersion) const;
+
+ /** split.
+ *
+@@ -279,6 +279,8 @@ public:
+ sal_uInt16 nIndexL,
+ OStoreBTreeEntry & rEntryL,
+ OStorePageBIOS & rBIOS);
++
++ void fixup (void);
+ };
+
+ /*========================================================================
+diff --git store/workben/t_base.cxx store/workben/t_base.cxx
+index 548ee86..1282da7 100644
+--- store/workben/t_base.cxx
++++ store/workben/t_base.cxx
+@@ -132,7 +132,8 @@ sal_Bool SAL_CALL OTestBIOS::isKindOf (sal_uInt32 nTypeId)
+ storeError OTestBIOS::initialize (
+ ILockBytes *pLockBytes, storeAccessMode eAccessMode, sal_uInt16 & rnPageSize)
+ {
+- return base::initialize (pLockBytes, eAccessMode, rnPageSize);
++ sal_uInt16 nVersion=STORE_FORMAT_V1;
++ return base::initialize (pLockBytes, eAccessMode, rnPageSize, nVersion);
+ }
+
+ namespace store
+diff --git store/workben/t_page.cxx store/workben/t_page.cxx
+index a0645f0..2dcdeec 100644
+--- store/workben/t_page.cxx
++++ store/workben/t_page.cxx
+@@ -155,7 +155,7 @@ struct PageData
+ */
+ static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L);
+ static const sal_uInt16 thePageSize = theSize;
+- STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
++ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE_V1 >= thePageSize);
+
+ /** type.
+ */
commit b3a3db76d30ee0b9a7227998d8723659019e15fa
Author: Thorsten Behrens <tbehrens at novell.com>
Date: Wed Oct 7 12:39:25 2009 +0200
Filed two upstream Impress patch issues
* patches/dev300/apply: added issue numbers
diff --git a/patches/dev300/apply b/patches/dev300/apply
index c64764f..8c0b8ba 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3069,10 +3069,10 @@ optional-outplace-ole.diff, i#98970, thorsten
slideshow-configurable-paintoverlay.diff, i#97972, fredus
# let ctrl-<keycode> stuff pass dlg keyboard handling, to permit
# global application-wide shortcuts also in open dialogs
-vcl-permit-global-shortcuts.diff, thorsten
+vcl-permit-global-shortcuts.diff, i#105676, thorsten
# make ok and cancel btns work on return and esc, resp. in Impress'
# custom animation create dialog
-sd-customanimation-defbutton.diff, thorsten
+sd-customanimation-defbutton.diff, i#105675, thorsten
[ Fixes < ooo320-m2 ]
# make Impress ruler behave as before 3.0
More information about the ooo-build-commit
mailing list