summaryrefslogtreecommitdiff
path: root/store
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 14:18:43 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 14:18:43 +0000
commit215e8c7210756d6d9033f8d742a6cd0e9be132aa (patch)
treed1a56131d83c8298e6183cf17b912037ae63b9c9 /store
initial import
Diffstat (limited to 'store')
-rw-r--r--store/inc/store/filelckb.hxx209
-rw-r--r--store/inc/store/lockbyte.hxx169
-rw-r--r--store/inc/store/memlckb.hxx197
-rw-r--r--store/inc/store/object.hxx118
-rw-r--r--store/inc/store/store.h377
-rw-r--r--store/inc/store/store.hxx267
-rw-r--r--store/inc/store/store.inl472
-rw-r--r--store/inc/store/types.h194
-rw-r--r--store/prj/d.lst8
-rw-r--r--store/source/filelckb.cxx936
-rw-r--r--store/source/makefile.mk107
-rw-r--r--store/source/memlckb.cxx396
-rw-r--r--store/source/object.cxx103
-rw-r--r--store/source/storbase.cxx1944
-rw-r--r--store/source/storbase.hxx916
-rw-r--r--store/source/storcach.cxx696
-rw-r--r--store/source/storcach.hxx231
-rw-r--r--store/source/stordata.cxx1754
-rw-r--r--store/source/stordata.hxx934
-rw-r--r--store/source/store.cxx817
-rw-r--r--store/source/storlckb.cxx872
-rw-r--r--store/source/storlckb.hxx296
-rw-r--r--store/source/storpage.cxx1562
-rw-r--r--store/source/storpage.hxx276
-rw-r--r--store/source/stortree.cxx608
-rw-r--r--store/source/stortree.hxx451
-rw-r--r--store/util/makefile.mk113
-rw-r--r--store/util/sto.dxp25
-rw-r--r--store/util/sto.map30
-rw-r--r--store/version.mk75
-rw-r--r--store/workben/makefile.mk135
-rw-r--r--store/workben/t_base.cxx376
-rw-r--r--store/workben/t_file.cxx166
-rw-r--r--store/workben/t_store.cxx634
34 files changed, 16464 insertions, 0 deletions
diff --git a/store/inc/store/filelckb.hxx b/store/inc/store/filelckb.hxx
new file mode 100644
index 000000000..a9ef520e9
--- /dev/null
+++ b/store/inc/store/filelckb.hxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * $RCSfile: filelckb.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_FILELCKB_HXX_
+#define _STORE_FILELCKB_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_USTRING_H_
+#include <rtl/ustring.h>
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include <osl/mutex.hxx>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+class OFileLockBytes_Impl;
+
+/*========================================================================
+ *
+ * OFileLockBytes interface.
+ *
+ *======================================================================*/
+class OFileLockBytes :
+ public NAMESPACE_STORE(ILockBytes),
+ public NAMESPACE_STORE(OStoreObject)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OFileLockBytes, store));
+
+public:
+ OFileLockBytes (void);
+
+ /** create.
+ * @param pFilename [in]
+ * @param eAccessMode [in]
+ * @return store_E_None upon success
+ */
+ storeError create (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode);
+
+ /** Read at Offset into Buffer.
+ * @param nOffset [in]
+ * @param pBuffer [out]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ /** Write at Offset from Buffer.
+ * @param nOffset [in]
+ * @param pBuffer [in]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ /** flush.
+ * @return store_E_None upon success
+ */
+ virtual storeError flush (void);
+
+ /** setSize.
+ * @param nSize [in]
+ * @return store_E_None upon success
+ */
+ virtual storeError setSize (sal_uInt32 nSize);
+
+ /** stat.
+ * @param rnSize [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError stat (sal_uInt32 &rnSize);
+
+ /** Lock range at Offset.
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError lockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes);
+
+ /** Unlock range at Offset.
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError unlockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes);
+
+ /** Delegate multiple inherited IReference.
+ */
+ virtual RefCount SAL_CALL acquire (void);
+ virtual RefCount SAL_CALL release (void);
+ virtual RefCount SAL_CALL referenced (void) const;
+
+protected:
+ virtual ~OFileLockBytes (void);
+
+private:
+ /** Representation.
+ */
+ NAMESPACE_OSL(Mutex) m_aMutex;
+ OFileLockBytes_Impl *m_pImpl;
+
+ /** Not implemented.
+ */
+ OFileLockBytes (const OFileLockBytes&);
+ OFileLockBytes& operator= (const OFileLockBytes&);
+};
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_FILELCKB_HXX_ */
+
diff --git a/store/inc/store/lockbyte.hxx b/store/inc/store/lockbyte.hxx
new file mode 100644
index 000000000..dbab735ca
--- /dev/null
+++ b/store/inc/store/lockbyte.hxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * $RCSfile: lockbyte.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_LOCKBYTE_HXX_
+#define _STORE_LOCKBYTE_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _VOS_REFERNCE_HXX_
+#include <vos/refernce.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+/*========================================================================
+ *
+ * ILockBytes interface.
+ *
+ *======================================================================*/
+class ILockBytes : public NAMESPACE_VOS(IReference)
+{
+public:
+ /**
+ * @param nOffset [in]
+ * @param pBuffer [out]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone) = 0;
+
+ /**
+ * @param nOffset [in]
+ * @param pBuffer [in]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone) = 0;
+
+ /**
+ * @return store_E_None upon success
+ */
+ virtual storeError flush (void) = 0;
+
+ /**
+ * @param nSize [in]
+ * @return store_E_None upon success
+ */
+ virtual storeError setSize (sal_uInt32 nSize) = 0;
+
+ /**
+ * @param rnSize [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError stat (sal_uInt32 &rnSize) = 0;
+
+ /**
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError lockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes) = 0;
+
+ /**
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError unlockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes) = 0;
+
+protected:
+ virtual ~ILockBytes (void) {}
+};
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_LOCKBYTE_HXX_ */
+
diff --git a/store/inc/store/memlckb.hxx b/store/inc/store/memlckb.hxx
new file mode 100644
index 000000000..a78b946b6
--- /dev/null
+++ b/store/inc/store/memlckb.hxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * $RCSfile: memlckb.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_MEMLCKB_HXX_
+#define _STORE_MEMLCKB_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+class OMemoryLockBytes_Impl;
+
+/*========================================================================
+ *
+ * OMemoryLockBytes interface.
+ *
+ *======================================================================*/
+class OMemoryLockBytes :
+ public NAMESPACE_STORE(ILockBytes),
+ public NAMESPACE_STORE(OStoreObject)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OMemoryLockBytes, store));
+
+public:
+ OMemoryLockBytes (void);
+
+ /** Read at Offset into Buffer.
+ * @param nOffset [in]
+ * @param pBuffer [out]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ /** Write at Offset from Buffer.
+ * @param nOffset [in]
+ * @param pBuffer [in]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ /** flush.
+ * @return store_E_None upon success
+ */
+ virtual storeError flush (void);
+
+ /** setSize.
+ * @param nSize [in]
+ * @return store_E_None upon success
+ */
+ virtual storeError setSize (sal_uInt32 nSize);
+
+ /** stat.
+ * @param rnSize [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError stat (sal_uInt32 &rnSize);
+
+ /** Lock range at Offset.
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError lockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes);
+
+ /** Unlock range at Offset.
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError unlockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes);
+
+ /** Delegate multiple inherited IReference.
+ */
+ virtual RefCount SAL_CALL acquire (void);
+ virtual RefCount SAL_CALL release (void);
+ virtual RefCount SAL_CALL referenced (void) const;
+
+protected:
+ virtual ~OMemoryLockBytes (void);
+
+private:
+ /** Representation.
+ */
+ NAMESPACE_VOS(OMutex) m_aMutex;
+ OMemoryLockBytes_Impl *m_pImpl;
+
+ /** Not implemented.
+ */
+ OMemoryLockBytes (const OMemoryLockBytes&);
+ OMemoryLockBytes& operator= (const OMemoryLockBytes&);
+};
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_MEMLCKB_HXX_ */
+
diff --git a/store/inc/store/object.hxx b/store/inc/store/object.hxx
new file mode 100644
index 000000000..c5caa83da
--- /dev/null
+++ b/store/inc/store/object.hxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * $RCSfile: object.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_OBJECT_HXX_
+#define _STORE_OBJECT_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _VOS_OBJECT_HXX_
+#include <vos/object.hxx>
+#endif
+#ifndef _VOS_REFERNCE_HXX_
+#include <vos/refernce.hxx>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+/*========================================================================
+ *
+ * OStoreObject interface.
+ *
+ *======================================================================*/
+class OStoreObject :
+ public NAMESPACE_VOS(OReference),
+ public NAMESPACE_VOS(OObject)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OStoreObject, store));
+
+public:
+ OStoreObject (void);
+
+protected:
+ virtual ~OStoreObject (void);
+
+private:
+ /** Not implemented.
+ */
+ OStoreObject (const OStoreObject&);
+ OStoreObject& operator= (const OStoreObject&);
+};
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_OBJECT_HXX_ */
+
diff --git a/store/inc/store/store.h b/store/inc/store/store.h
new file mode 100644
index 000000000..2e8ea11eb
--- /dev/null
+++ b/store/inc/store/store.h
@@ -0,0 +1,377 @@
+/*************************************************************************
+ *
+ * $RCSfile: store.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORE_H_
+#define _STORE_STORE_H_ "$Revision: 1.1.1.1 $"
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Opaque type storeHandle.
+ */
+typedef void* storeHandle;
+
+/** store_acquireHandle.
+ * @param Handle [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_acquireHandle (storeHandle Handle);
+
+/** store_releaseHandle.
+ * @param Handle [in]
+ * @return store_E_None upon success,
+ * store_E_InvalidHandle otherwise.
+ */
+storeError SAL_CALL store_releaseHandle (storeHandle Handle);
+
+
+/** Opaque type storeFileHandle.
+ */
+typedef void* storeFileHandle;
+
+/** store_createMemoryFile.
+ * @param nPageSize [in] the creation page size,
+ * integer multiple of minimum page size.
+ * @param phFile [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_createMemoryFile (
+ sal_uInt16 nPageSize,
+ storeFileHandle *phFile);
+
+/** store_openFile.
+ * @param pFilename [in] the filename in host syntax.
+ * @param eAccessMode [in] the access mode.
+ * store_AccessCreate truncate existing and create,
+ * store_AccessReadCreate create not existing,
+ * store_AccessReadWrite write existing,
+ * store_AccessReadOnly never modifies.
+ * @param nPageSize [in] the creation page size,
+ * integer multiple of minimum page size.
+ * @param phFile [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_openFile (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize,
+ storeFileHandle *phFile);
+
+/** store_closeFile.
+ * @param hFile [in]
+ * @return store_E_None upon success,
+ * store_E_InvalidHandle otherwise.
+ */
+storeError SAL_CALL store_closeFile (
+ storeFileHandle hFile);
+
+/** store_flushFile.
+ * @param hFile [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_flushFile (
+ storeFileHandle hFile);
+
+/** store_getFileRefererCount.
+ * @param hFile [in]
+ * @param pnRefCount [out] number of open directories and streams.
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_getFileRefererCount (
+ storeFileHandle hFile,
+ sal_uInt32 *pnRefCount);
+
+/** store_getFileSize.
+ * @param hFile [in]
+ * @param pnSize [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_getFileSize (
+ storeFileHandle hFile,
+ sal_uInt32 *pnSize);
+
+/** store_rebuildFile.
+ * @param pSrcFilename [in] opened with store_AccessReadOnly.
+ * @param pDstFilename [in] created with store_AccessCreate.
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_rebuildFile (
+ rtl_uString *pSrcFilename,
+ rtl_uString *pDstFilename);
+
+
+/** Opaque type storeDirectoryHandle.
+ */
+typedef void* storeDirectoryHandle;
+
+/** store_openDirectory.
+ * @param hFile [in]
+ * @param pPath [in]
+ * @param pName [in]
+ * @param eAccessMode [in]
+ * @param phDirectory [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_openDirectory (
+ storeFileHandle hFile,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eAccessMode,
+ storeDirectoryHandle *phDirectory);
+
+/** store_closeDirectory.
+ * @param hDirectory [in]
+ * @return store_E_None upon success,
+ * store_E_InvalidHandle otherwise.
+ */
+storeError SAL_CALL store_closeDirectory (
+ storeDirectoryHandle hDirectory);
+
+/** store_findFirst.
+ * @param hDirectory [in]
+ * @param pFindData [out]
+ * @return store_E_None upon success,
+ * store_E_NoMoreFile upon end of iteration.
+ */
+storeError SAL_CALL store_findFirst (
+ storeDirectoryHandle hDirectory,
+ storeFindData *pFindData);
+
+/** store_findNext.
+ * @param hDirectory [in]
+ * @param pFindData [out]
+ * @return store_E_None upon success,
+ * store_E_NoMoreFile upon end of iteration.
+ */
+storeError SAL_CALL store_findNext (
+ storeDirectoryHandle hDirectory,
+ storeFindData *pFindData);
+
+
+/** Opaque type storeStreamHandle.
+ */
+typedef void* storeStreamHandle;
+
+/** store_openStream.
+ * @param hFile [in]
+ * @param pPath [in]
+ * @param pName [in]
+ * @param eAccessMode [in]
+ * @param phStrm [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_openStream (
+ storeFileHandle hFile,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eMode,
+ storeStreamHandle *phStrm);
+
+/** store_closeStream.
+ * @param hStrm [in]
+ * @return store_E_None upon success,
+ * store_E_InvalidHandle otherwise.
+ */
+storeError SAL_CALL store_closeStream (
+ storeStreamHandle hStrm);
+
+/** store_readStream.
+ * @param hStrm [in]
+ * @param nOffset [in]
+ * @param pBuffer [out]
+ * @param nBytes [in]
+ * @param pnDone [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_readStream (
+ storeStreamHandle hStrm,
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 *pnDone);
+
+/** store_writeStream.
+ * @param hStrm [in]
+ * @param nOffset [in]
+ * @param pBuffer [in]
+ * @param nBytes [in]
+ * @param pnDone [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_writeStream (
+ storeStreamHandle hStrm,
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 *pnDone);
+
+/** store_flushStream.
+ * @param hStrm [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_flushStream (
+ storeStreamHandle hStrm);
+
+/** store_getStreamSize.
+ * @param hStrm [in]
+ * @param pnSize [out]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_getStreamSize (
+ storeStreamHandle hStrm,
+ sal_uInt32 *pnSize);
+
+/** store_setStreamSize.
+ * @param hStrm [in]
+ * @param nSize [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_setStreamSize (
+ storeStreamHandle hStrm,
+ sal_uInt32 nSize);
+
+/** store_attrib.
+ * @param hFile [in]
+ * @param pPath [in]
+ * @param pName [in]
+ * @param nMask1 [in]
+ * @param nMask2 [in]
+ * @param pnAttrib [out] may be NULL.
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_attrib (
+ storeFileHandle hFile,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2,
+ sal_uInt32 *pnAttrib);
+
+/** store_link.
+ * @param hFile [in]
+ * @param pSrcPath [in]
+ * @param pSrcName [in]
+ * @param pDstPath [in]
+ * @param pDstName [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_link (
+ storeFileHandle hFile,
+ rtl_uString *pSrcPath, rtl_uString *pSrcName,
+ rtl_uString *pDstPath, rtl_uString *pDstName);
+
+/** store_symlink.
+ * @param hFile [in]
+ * @param pSrcPath [in]
+ * @param pSrcName [in]
+ * @param pDstPath [in]
+ * @param pDstName [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_symlink (
+ storeFileHandle hFile,
+ rtl_uString *pSrcPath, rtl_uString *pSrcName,
+ rtl_uString *pDstPath, rtl_uString *pDstName);
+
+/** store_rename.
+ * @param hFile [in]
+ * @param pSrcPath [in]
+ * @param pSrcName [in]
+ * @param pDstPath [in]
+ * @param pDstName [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_rename (
+ storeFileHandle hFile,
+ rtl_uString *pSrcPath, rtl_uString *pSrcName,
+ rtl_uString *pDstPath, rtl_uString *pDstName);
+
+/** store_remove.
+ * @param hFile [in]
+ * @param pPath [in]
+ * @param pName [in]
+ * @return store_E_None upon success
+ */
+storeError SAL_CALL store_remove (
+ storeFileHandle hFile,
+ rtl_uString *pPath,
+ rtl_uString *pName);
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STORE_STORE_H_ */
+
+
+
+
diff --git a/store/inc/store/store.hxx b/store/inc/store/store.hxx
new file mode 100644
index 000000000..13a25afe0
--- /dev/null
+++ b/store/inc/store/store.hxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * $RCSfile: store.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORE_HXX_
+#define _STORE_STORE_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef _STORE_STORE_H_
+#include <store/store.h>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+/*========================================================================
+ *
+ * OStoreStream interface.
+ *
+ *======================================================================*/
+class OStoreStream
+{
+public:
+ inline OStoreStream (void);
+ inline ~OStoreStream (void);
+
+ inline OStoreStream (const OStoreStream& rOther);
+ inline OStoreStream& operator= (const OStoreStream& rOther);
+
+ inline OStoreStream (storeStreamHandle Handle);
+ inline operator storeStreamHandle (void) const;
+
+ inline sal_Bool isValid (void) const;
+
+ inline storeError create (
+ storeFileHandle hFile,
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ storeAccessMode eMode);
+
+ inline void close (void);
+
+ inline storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ inline storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ inline storeError flush (void) const;
+
+ inline storeError getSize (sal_uInt32 &rnSize) const;
+
+ inline storeError setSize (sal_uInt32 nSize);
+
+private:
+ storeStreamHandle m_hImpl;
+};
+
+/*========================================================================
+ *
+ * OStoreDirectory interface.
+ *
+ *======================================================================*/
+class OStoreDirectory
+{
+public:
+ inline OStoreDirectory (void);
+ inline ~OStoreDirectory (void);
+
+ inline OStoreDirectory (const OStoreDirectory& rOther);
+ inline OStoreDirectory& operator= (const OStoreDirectory& rOther);
+
+ inline OStoreDirectory (storeDirectoryHandle Handle);
+ inline operator storeDirectoryHandle (void) const;
+
+ inline sal_Bool isValid (void) const;
+
+ /** create.
+ */
+ inline storeError create (
+ storeFileHandle hFile,
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ storeAccessMode eMode);
+
+ /** close.
+ */
+ inline void close (void);
+
+ /** Iteration.
+ */
+ typedef storeFindData iterator;
+
+ inline storeError first (iterator& it);
+ inline storeError next (iterator& it);
+
+ /** Traversal.
+ */
+ class traveller
+ {
+ public:
+ virtual sal_Bool visit (const iterator& it) = 0;
+ };
+
+ inline storeError travel (traveller& rTraveller) const;
+
+private:
+ storeDirectoryHandle m_hImpl;
+};
+
+/*========================================================================
+ *
+ * OStoreFile interface.
+ *
+ *======================================================================*/
+class OStoreFile
+{
+public:
+ inline OStoreFile (void);
+ inline ~OStoreFile (void);
+
+ inline OStoreFile (const OStoreFile& rOther);
+ inline OStoreFile& operator= (const OStoreFile& rOther);
+
+ inline OStoreFile (storeFileHandle Handle);
+ inline operator storeFileHandle (void) const;
+
+ inline sal_Bool isValid (void) const;
+
+ inline storeError create (
+ const rtl::OUString &rFilename,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE);
+
+ inline storeError createInMemory (
+ sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE);
+
+ inline void close (void);
+
+ inline storeError flush (void) const;
+
+ inline storeError getRefererCount (sal_uInt32 &rnRefCount) const;
+
+ inline storeError getSize (sal_uInt32 &rnSize) const;
+
+ /** Directory and Stream Manipulation.
+ */
+ inline storeError attrib (
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2,
+ sal_uInt32 &rnAttrib);
+ inline storeError attrib (
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2);
+
+ inline storeError link (
+ const rtl::OUString &rSrcPath, const rtl::OUString &rSrcName,
+ const rtl::OUString &rDstPath, const rtl::OUString &rDstName);
+
+ inline storeError symlink (
+ const rtl::OUString &rSrcPath, const rtl::OUString &rSrcName,
+ const rtl::OUString &rDstPath, const rtl::OUString &rDstName);
+
+ inline storeError rename (
+ const rtl::OUString &rSrcPath, const rtl::OUString &rSrcName,
+ const rtl::OUString &rDstPath, const rtl::OUString &rDstName);
+
+ inline storeError remove (
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName);
+
+private:
+ storeFileHandle m_hImpl;
+};
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+
+#include <store/store.inl>
+
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORE_HXX_ */
+
+
+
+
diff --git a/store/inc/store/store.inl b/store/inc/store/store.inl
new file mode 100644
index 000000000..bfcc2d89a
--- /dev/null
+++ b/store/inc/store/store.inl
@@ -0,0 +1,472 @@
+/*************************************************************************
+ *
+ * $RCSfile: store.inl,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc..
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORE_INL_ "$Revision: 1.1.1.1 $"
+
+/*========================================================================
+ *
+ * OStoreStream implementation.
+ *
+ *======================================================================*/
+inline OStoreStream::OStoreStream (void)
+ : m_hImpl (0)
+{
+}
+
+inline OStoreStream::~OStoreStream (void)
+{
+ if (m_hImpl)
+ store_releaseHandle (m_hImpl);
+}
+
+inline OStoreStream::OStoreStream (const OStoreStream& rOther)
+ : m_hImpl (rOther.m_hImpl)
+{
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+}
+
+inline OStoreStream& OStoreStream::operator= (const OStoreStream& rOther)
+{
+ if (m_hImpl)
+ store_releaseHandle (m_hImpl);
+ m_hImpl = rOther.m_hImpl;
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+ return *this;
+}
+
+inline OStoreStream::OStoreStream (storeStreamHandle Handle)
+ : m_hImpl (Handle)
+{
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+}
+
+inline OStoreStream::operator storeStreamHandle (void) const
+{
+ return m_hImpl;
+}
+
+inline sal_Bool OStoreStream::isValid (void) const
+{
+ return (!!m_hImpl);
+}
+
+inline storeError OStoreStream::create (
+ storeFileHandle hFile,
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ storeAccessMode eMode)
+{
+ if (m_hImpl)
+ {
+ store_releaseHandle (m_hImpl);
+ m_hImpl = 0;
+ }
+ return store_openStream (
+ hFile, rPath.pData, rName.pData, eMode, &m_hImpl);
+}
+
+inline void OStoreStream::close (void)
+{
+ if (m_hImpl)
+ {
+ store_closeStream (m_hImpl);
+ m_hImpl = 0;
+ }
+}
+
+inline storeError OStoreStream::readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_readStream (
+ m_hImpl, nOffset, pBuffer, nBytes, &rnDone);
+}
+
+inline storeError OStoreStream::writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_writeStream (
+ m_hImpl, nOffset, pBuffer, nBytes, &rnDone);
+}
+
+inline storeError OStoreStream::flush (void) const
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_flushStream (m_hImpl);
+}
+
+inline storeError OStoreStream::getSize (sal_uInt32 &rnSize) const
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_getStreamSize (m_hImpl, &rnSize);
+}
+
+inline storeError OStoreStream::setSize (sal_uInt32 nSize)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_setStreamSize (m_hImpl, nSize);
+}
+
+/*========================================================================
+ *
+ * OStoreDirectory implementation.
+ *
+ *======================================================================*/
+inline OStoreDirectory::OStoreDirectory (void)
+ : m_hImpl (0)
+{
+}
+
+inline OStoreDirectory::~OStoreDirectory (void)
+{
+ if (m_hImpl)
+ store_releaseHandle (m_hImpl);
+}
+
+inline OStoreDirectory::OStoreDirectory (const OStoreDirectory& rOther)
+ : m_hImpl (rOther.m_hImpl)
+{
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+}
+
+inline OStoreDirectory&
+OStoreDirectory::operator= (const OStoreDirectory& rOther)
+{
+ if (m_hImpl)
+ store_releaseHandle (m_hImpl);
+ m_hImpl = rOther.m_hImpl;
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+ return *this;
+}
+
+inline OStoreDirectory::OStoreDirectory (storeDirectoryHandle Handle)
+ : m_hImpl (Handle)
+{
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+}
+
+inline OStoreDirectory::operator storeDirectoryHandle (void) const
+{
+ return m_hImpl;
+}
+
+inline sal_Bool OStoreDirectory::isValid (void) const
+{
+ return (!!m_hImpl);
+}
+
+inline storeError OStoreDirectory::create (
+ storeFileHandle hFile,
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ storeAccessMode eMode)
+{
+ if (m_hImpl)
+ {
+ store_releaseHandle (m_hImpl);
+ m_hImpl = 0;
+ }
+ return store_openDirectory (
+ hFile, rPath.pData, rName.pData, eMode, &m_hImpl);
+}
+
+inline void OStoreDirectory::close (void)
+{
+ if (m_hImpl)
+ {
+ store_closeDirectory (m_hImpl);
+ m_hImpl = 0;
+ }
+}
+
+inline storeError OStoreDirectory::first (iterator& it)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_findFirst (m_hImpl, &it);
+}
+
+inline storeError OStoreDirectory::next (iterator& it)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_findNext (m_hImpl, &it);
+}
+
+inline storeError OStoreDirectory::travel (traveller& rTraveller) const
+{
+ storeError eErrCode = store_E_InvalidHandle;
+ if (m_hImpl)
+ {
+ iterator it;
+ eErrCode = store_findFirst (m_hImpl, &it);
+ while ((eErrCode == store_E_None) && rTraveller.visit(it))
+ eErrCode = store_findNext (m_hImpl, &it);
+ }
+ return eErrCode;
+}
+
+/*========================================================================
+ *
+ * OStoreFile implementation.
+ *
+ *======================================================================*/
+inline OStoreFile::OStoreFile (void)
+ : m_hImpl (0)
+{
+}
+
+inline OStoreFile::~OStoreFile (void)
+{
+ if (m_hImpl)
+ store_releaseHandle (m_hImpl);
+}
+
+inline OStoreFile::OStoreFile (const OStoreFile& rOther)
+ : m_hImpl (rOther.m_hImpl)
+{
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+}
+
+inline OStoreFile& OStoreFile::operator= (const OStoreFile& rOther)
+{
+ if (m_hImpl)
+ store_releaseHandle (m_hImpl);
+ m_hImpl = rOther.m_hImpl;
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+ return *this;
+}
+
+inline OStoreFile::OStoreFile (storeFileHandle Handle)
+ : m_hImpl (Handle)
+{
+ if (m_hImpl)
+ store_acquireHandle (m_hImpl);
+}
+
+inline OStoreFile::operator storeFileHandle (void) const
+{
+ return m_hImpl;
+}
+
+inline sal_Bool OStoreFile::isValid (void) const
+{
+ return (!!m_hImpl);
+}
+
+inline storeError OStoreFile::create (
+ const rtl::OUString &rFilename,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize)
+{
+ if (m_hImpl)
+ {
+ store_releaseHandle (m_hImpl);
+ m_hImpl = 0;
+ }
+ return store_openFile (rFilename.pData, eAccessMode, nPageSize, &m_hImpl);
+}
+
+inline storeError OStoreFile::createInMemory (sal_uInt16 nPageSize)
+{
+ if (m_hImpl)
+ {
+ store_releaseHandle (m_hImpl);
+ m_hImpl = 0;
+ }
+ return store_createMemoryFile (nPageSize, &m_hImpl);
+}
+
+inline void OStoreFile::close (void)
+{
+ if (m_hImpl)
+ {
+ store_closeFile (m_hImpl);
+ m_hImpl = 0;
+ }
+}
+
+inline storeError OStoreFile::flush (void) const
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_flushFile (m_hImpl);
+}
+
+inline storeError OStoreFile::getRefererCount (sal_uInt32 &rnRefCount) const
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_getFileRefererCount (m_hImpl, &rnRefCount);
+}
+
+inline storeError OStoreFile::getSize (sal_uInt32 &rnSize) const
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_getFileSize (m_hImpl, &rnSize);
+}
+
+inline storeError OStoreFile::attrib (
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2,
+ sal_uInt32 &rnAttrib)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_attrib (
+ m_hImpl, rPath.pData, rName.pData, nMask1, nMask2, &rnAttrib);
+}
+
+inline storeError OStoreFile::attrib (
+ const rtl::OUString &rPath,
+ const rtl::OUString &rName,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_attrib (
+ m_hImpl, rPath.pData, rName.pData, nMask1, nMask2, NULL);
+}
+
+inline storeError OStoreFile::link (
+ const rtl::OUString &rSrcPath, const rtl::OUString &rSrcName,
+ const rtl::OUString &rDstPath, const rtl::OUString &rDstName)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_link (
+ m_hImpl,
+ rSrcPath.pData, rSrcName.pData,
+ rDstPath.pData, rDstName.pData);
+}
+
+inline storeError OStoreFile::symlink (
+ const rtl::OUString &rSrcPath, const rtl::OUString &rSrcName,
+ const rtl::OUString &rDstPath, const rtl::OUString &rDstName)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_symlink (
+ m_hImpl,
+ rSrcPath.pData, rSrcName.pData,
+ rDstPath.pData, rDstName.pData);
+}
+
+inline storeError OStoreFile::rename (
+ const rtl::OUString &rSrcPath, const rtl::OUString &rSrcName,
+ const rtl::OUString &rDstPath, const rtl::OUString &rDstName)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_rename (
+ m_hImpl,
+ rSrcPath.pData, rSrcName.pData,
+ rDstPath.pData, rDstName.pData);
+}
+
+inline storeError OStoreFile::remove (
+ const rtl::OUString &rPath, const rtl::OUString &rName)
+{
+ if (!m_hImpl)
+ return store_E_InvalidHandle;
+
+ return store_remove (m_hImpl, rPath.pData, rName.pData);
+}
+
diff --git a/store/inc/store/types.h b/store/inc/store/types.h
new file mode 100644
index 000000000..2024c980e
--- /dev/null
+++ b/store/inc/store/types.h
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ * $RCSfile: types.h,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_TYPES_H_
+#define _STORE_TYPES_H_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_USTRING_H_
+#include <rtl/ustring.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** PageSize (recommended) default.
+ * @see store_openFile().
+ */
+#define STORE_DEFAULT_PAGESIZE ((sal_uInt16)0x0400)
+
+
+/** PageSize (enforced) limits.
+ * @see store_openFile().
+ */
+#define STORE_MINIMUM_PAGESIZE ((sal_uInt16)0x0200)
+#define STORE_MAXIMUM_PAGESIZE ((sal_uInt16)0x8000)
+
+
+/** NameSize (enforced) limit.
+ * @see any param pName.
+ * @see store_E_NameTooLong
+ */
+#define STORE_MAXIMUM_NAMESIZE 256
+
+
+/** Attributes (predefined).
+ * @see store_attrib().
+ */
+#define STORE_ATTRIB_ISLINK 0x10000000UL
+#define STORE_ATTRIB_ISDIR 0x20000000UL
+#define STORE_ATTRIB_ISFILE 0x40000000UL
+
+
+/** storeAccessMode.
+ * @see store_openFile().
+ * @see store_openDirectory().
+ * @see store_openStream().
+ */
+typedef enum
+{
+ store_AccessCreate,
+ store_AccessReadCreate,
+ store_AccessReadWrite,
+ store_AccessReadOnly,
+ store_Access_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+} storeAccessMode;
+
+
+/** storeError.
+ */
+typedef enum
+{
+ store_E_None = 0,
+ store_E_AccessViolation,
+ store_E_LockingViolation,
+ store_E_CantSeek,
+ store_E_CantRead,
+ store_E_CantWrite,
+ store_E_InvalidAccess,
+ store_E_InvalidHandle,
+ store_E_InvalidParameter,
+ store_E_InvalidChecksum,
+ store_E_AlreadyExists,
+ store_E_NotExists,
+ store_E_NotDirectory,
+ store_E_NotFile,
+ store_E_NoMoreFiles,
+ store_E_NameTooLong,
+ store_E_OutOfMemory,
+ store_E_OutOfSpace,
+ store_E_Pending,
+ store_E_WrongFormat,
+ store_E_WrongVersion,
+ store_E_Unknown,
+ store_E_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+} storeError;
+
+
+/** storeFindData.
+ * @see store_findFirst().
+ * @see store_findNext().
+ */
+typedef struct
+{
+ /** Name.
+ * @see m_nLength.
+ */
+ sal_Unicode m_pszName[STORE_MAXIMUM_NAMESIZE];
+
+ /** Name Length.
+ * @see m_pszName.
+ */
+ sal_Int32 m_nLength;
+
+ /** Attributes.
+ * @see store_attrib().
+ */
+ sal_uInt32 m_nAttrib;
+
+ /** Size.
+ * @see store_getStreamSize().
+ * @see store_setStreamSize().
+ */
+ sal_uInt32 m_nSize;
+
+ /** Reserved for internal use.
+ */
+ sal_uInt32 m_nReserved;
+} storeFindData;
+
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STORE_TYPES_H_ */
+
diff --git a/store/prj/d.lst b/store/prj/d.lst
new file mode 100644
index 000000000..12834ee9e
--- /dev/null
+++ b/store/prj/d.lst
@@ -0,0 +1,8 @@
+mkdir: %_DEST%\inc%_EXT%\store
+..\inc\store\*.h %_DEST%\inc%_EXT%\store\*.h
+..\inc\store\store.hxx %_DEST%\inc%_EXT%\store\store.hxx
+..\inc\store\store.inl %_DEST%\inc%_EXT%\store\store.inl
+..\%__SRC%\lib\istore.lib %_DEST%\lib%_EXT%\istore.lib
+..\%__SRC%\lib\libsto*.* %_DEST%\lib%_EXT%\libsto*.*
+..\%__SRC%\bin\sto*.dll %_DEST%\bin%_EXT%\sto*.dll
+..\version.mk %_DEST%\inc%_EXT%\store\version.mk
diff --git a/store/source/filelckb.cxx b/store/source/filelckb.cxx
new file mode 100644
index 000000000..a07f7f692
--- /dev/null
+++ b/store/source/filelckb.cxx
@@ -0,0 +1,936 @@
+/*************************************************************************
+ *
+ * $RCSfile: filelckb.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_FILELCKB_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _OSL_MUTEX_HXX_
+#include <osl/mutex.hxx>
+#endif
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+#ifndef _STORE_FILELCKB_HXX_
+#include <store/filelckb.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace rtl;
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OFileLockBytes internals.
+ *
+ *======================================================================*/
+#ifdef DEBUG
+#define inline static
+#endif /* DEBUG */
+
+/*
+ * __store_getProcessTextEncoding (@@@, platform specific).
+ */
+inline rtl_TextEncoding __store_getProcessTextEncoding (void)
+{
+ rtl_TextEncoding eEncoding;
+#if defined(SAL_OS2)
+ eEncoding = RTL_TEXTENCODING_IBM850;
+#elif defined(SAL_UNX)
+ eEncoding = RTL_TEXTENCODING_ISO_8859_1;
+#elif defined(SAL_W32)
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+#else
+ eEncoding = RTL_TEXTENCODING_ASCII_US;
+#endif
+ return eEncoding;
+}
+
+/*
+ * __store_memcpy.
+ */
+#include <string.h>
+inline void __store_memcpy (void *dst, const void *src, sal_uInt32 n)
+{
+ ::memcpy (dst, src, n);
+}
+
+/*
+ * __store_errcode_mapping.
+ */
+struct __store_errcode_mapping_st
+{
+ sal_uInt32 m_nErrno;
+ storeError m_nCode;
+};
+
+static storeError __store_errnoToErrCode (sal_uInt32 nErrno);
+#define ERROR_FROM_NATIVE(e) __store_errnoToErrCode((sal_uInt32)(e))
+
+/*
+ * __store_file (basic file I/O; platform specific; inline).
+ */
+#define store_File_OpenRead 0x01L
+#define store_File_OpenWrite 0x02L
+#define store_File_OpenNoBuffer 0x04L
+#define store_File_OpenNoCreate 0x08L
+#define store_File_OpenTruncate 0x10L
+
+#ifdef __STORE_IO_NATIVE
+#undef __STORE_IO_NATIVE
+#endif
+
+#ifdef SAL_OS2
+#include <fileos2.cxx>
+#endif /* SAL_OS2 */
+
+#ifdef SAL_UNX
+#include <fileunx.cxx>
+#endif /* SAL_UNX */
+
+#ifdef SAL_W32
+#include <filew32.cxx>
+#endif /* SAL_W32 */
+
+#ifndef __STORE_IO_NATIVE
+#include <filestd.cxx>
+#endif /* !_STORE_IO_NATIVE */
+
+/*
+ * __store_errnoToErrCode.
+ */
+static storeError __store_errnoToErrCode (sal_uInt32 nErrno)
+{
+ int i, n = sizeof(__store_errcode_map) / sizeof(__store_errcode_map[0]);
+ for (i = 0; i < n; i++)
+ {
+ if (__store_errcode_map[i].m_nErrno == nErrno)
+ return __store_errcode_map[i].m_nCode;
+ }
+ return store_E_Unknown;
+}
+
+#ifdef DEBUG
+#ifdef inline
+#undef inline
+#endif
+#define inline
+#endif /* DEBUG */
+
+/*========================================================================
+ *
+ * OMappingDescriptor_Impl.
+ *
+ *======================================================================*/
+struct OMappingDescriptor_Impl
+{
+ typedef OMappingDescriptor_Impl self;
+
+ /** Representation.
+ */
+ sal_uInt32 m_nOffset;
+ sal_uInt32 m_nSize;
+ sal_uInt8 *m_pData;
+
+ /** Construction.
+ */
+ inline OMappingDescriptor_Impl (
+ sal_uInt32 nOffset = 0xffffffff,
+ sal_uInt32 nSize = 0);
+
+ /** Assignment.
+ */
+ inline self& operator= (const self& rDescr);
+
+ /** Comparison.
+ */
+ inline sal_Bool operator== (const self& rDescr) const;
+ inline sal_Bool operator<= (const self& rDescr) const;
+
+ /** normalize.
+ */
+ inline void normalize (
+ sal_uInt32 nAlignment,
+ sal_uInt32 nSizeLimit);
+
+ /** cleanup.
+ */
+ inline void cleanup (void);
+
+ /** unmap.
+ */
+ inline void unmap (void);
+
+ /** sync.
+ */
+ inline void sync (void);
+};
+
+/*
+ * OMappingDescriptor_Impl.
+ */
+inline OMappingDescriptor_Impl::OMappingDescriptor_Impl (
+ sal_uInt32 nOffset, sal_uInt32 nSize)
+ : m_nOffset (nOffset),
+ m_nSize (nSize),
+ m_pData (NULL)
+{
+}
+
+/*
+ * operator=().
+ */
+inline OMappingDescriptor_Impl&
+OMappingDescriptor_Impl::operator= (const self& rDescr)
+{
+ m_nOffset = rDescr.m_nOffset;
+ m_nSize = rDescr.m_nSize;
+ m_pData = rDescr.m_pData;
+
+ return *this;
+}
+
+/*
+ * operator==().
+ */
+inline sal_Bool
+OMappingDescriptor_Impl::operator== (const self& rDescr) const
+{
+ return ((m_nOffset == rDescr.m_nOffset) &&
+ (m_nSize == rDescr.m_nSize ) );
+}
+
+/*
+ * operator<=().
+ */
+inline sal_Bool
+OMappingDescriptor_Impl::operator<= (const self& rDescr) const
+{
+ return ((m_nOffset == rDescr.m_nOffset) &&
+ (m_nSize <= rDescr.m_nSize ) );
+}
+
+/*
+ * normalize.
+ */
+inline void OMappingDescriptor_Impl::normalize (
+ sal_uInt32 nAlignment, sal_uInt32 nSizeLimit)
+{
+ sal_uInt32 nRemain = (m_nSize % nAlignment);
+ if (nRemain)
+ m_nSize += (nAlignment - nRemain);
+
+ m_nOffset -= (m_nOffset % nAlignment);
+ if ((m_nOffset + m_nSize) > nSizeLimit)
+ m_nSize = nSizeLimit - m_nOffset;
+}
+
+/*
+ * unmap.
+ */
+inline void OMappingDescriptor_Impl::unmap (void)
+{
+ if (m_pData)
+ {
+ __store_munmap (m_pData, m_nSize);
+ m_pData = 0, m_nSize = 0;
+ }
+}
+
+/*
+ * sync.
+ */
+inline void OMappingDescriptor_Impl::sync (void)
+{
+ if (m_pData)
+ __store_msync (m_pData, m_nSize);
+}
+
+/*
+ * cleanup.
+ */
+inline void OMappingDescriptor_Impl::cleanup (void)
+{
+ if (m_pData)
+ {
+ __store_msync (m_pData, m_nSize);
+ __store_munmap (m_pData, m_nSize);
+ m_pData = 0, m_nSize = 0;
+ }
+}
+
+/*========================================================================
+ *
+ * OFileLockBytes_Impl interface.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+class OFileLockBytes_Impl
+{
+ HSTORE m_hFile;
+#ifdef DEBUG
+ sal_Char *m_pszFilename;
+#endif /* DEBUG */
+ sal_Bool m_bMemmap : 1;
+ sal_Bool m_bWriteable : 1;
+
+ HSTORE m_hMap; // OMappingDescriptor (?)
+ sal_uInt32 m_nAlignment; // mapping alignment
+ sal_uInt32 m_nSize; // mapping size
+
+ OMappingDescriptor_Impl m_aDescrOne; // OMemoryDescriptor (?)
+ OMappingDescriptor_Impl m_aDescrAny;
+
+public:
+ OFileLockBytes_Impl (void);
+ ~OFileLockBytes_Impl (void);
+
+ sal_Bool isValid (void) const { return (!!m_hFile); }
+
+ storeError close (void);
+ storeError create (
+ const sal_Char *pszFilename,
+ storeAccessMode eAccessMode);
+ storeError create (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode);
+
+ storeError memmap (OMappingDescriptor_Impl &rDescr);
+ storeError size (void);
+
+ storeError resize (sal_uInt32 nSize);
+
+ storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+ storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ storeError sync (void);
+ storeError stat (sal_uInt32 &rnSize);
+};
+
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+/*========================================================================
+ *
+ * OFileLockBytes_Impl (inline) implementation.
+ *
+ *======================================================================*/
+/*
+ * OFileLockBytes_Impl.
+ */
+inline OFileLockBytes_Impl::OFileLockBytes_Impl (void)
+ : m_hFile (0),
+#ifdef DEBUG
+ m_pszFilename (0),
+#endif /* DEBUG */
+ m_bWriteable (sal_False),
+ m_hMap (0),
+ m_nSize (0)
+{
+ m_nAlignment = __store_malign();
+ m_bMemmap = (!(m_nAlignment == (sal_uInt32)(-1)));
+}
+
+/*
+ * ~OFileLockBytes_Impl.
+ */
+inline OFileLockBytes_Impl::~OFileLockBytes_Impl (void)
+{
+ if (m_hFile)
+ {
+ if (m_hMap)
+ {
+ m_aDescrOne.cleanup();
+ m_aDescrAny.cleanup();
+
+ __store_funmap (m_hMap);
+ m_hMap = 0;
+ }
+
+ __store_fclose (m_hFile);
+ m_hFile = 0;
+ }
+#ifdef DEBUG
+ if (m_pszFilename)
+ {
+ ::free (m_pszFilename);
+ m_pszFilename = 0;
+ }
+#endif /* DEBUG */
+}
+
+/*
+ * close.
+ */
+inline storeError OFileLockBytes_Impl::close (void)
+{
+ if (m_hFile)
+ {
+ if (m_hMap)
+ {
+ m_aDescrOne.cleanup();
+ m_aDescrAny.cleanup();
+
+ __store_funmap (m_hMap);
+ m_hMap = 0;
+ }
+
+ __store_fclose (m_hFile);
+ m_hFile = 0;
+ }
+ return store_E_None;
+}
+
+/*
+ * create.
+ */
+inline storeError OFileLockBytes_Impl::create (
+ const sal_Char *pszFilename, storeAccessMode eAccessMode)
+{
+ if (m_hFile)
+ {
+ if (m_hMap)
+ {
+ m_aDescrOne.cleanup();
+ m_aDescrAny.cleanup();
+
+ __store_funmap (m_hMap);
+ m_hMap = 0;
+ }
+
+ __store_fclose (m_hFile);
+ m_hFile = 0;
+ }
+
+ m_bWriteable = (!(eAccessMode == store_AccessReadOnly));
+
+ sal_uInt32 nMode = store_File_OpenRead;
+ if (m_bWriteable)
+ nMode |= store_File_OpenWrite;
+ else
+ nMode |= store_File_OpenNoCreate;
+
+ if (eAccessMode == store_AccessCreate)
+ nMode |= store_File_OpenTruncate;
+ if (eAccessMode == store_AccessReadWrite)
+ nMode |= store_File_OpenNoCreate;
+
+ if (m_bMemmap)
+ nMode |= store_File_OpenNoBuffer;
+
+ storeError eErrCode = __store_fopen (pszFilename, nMode, m_hFile);
+#ifdef DEBUG
+ if (eErrCode == store_E_None)
+ {
+ sal_uInt32 nLen = ::strlen (pszFilename);
+ m_pszFilename = (sal_Char*)(::realloc (m_pszFilename, nLen + 1));
+ ::memcpy (m_pszFilename, pszFilename, nLen + 1);
+ }
+#endif /* DEBUG */
+ return eErrCode;
+}
+
+inline storeError OFileLockBytes_Impl::create (
+ rtl_uString *pFilename, storeAccessMode eAccessMode)
+{
+ OString aFilename (
+ pFilename->buffer,
+ pFilename->length,
+ __store_getProcessTextEncoding());
+
+ return create (aFilename.pData->buffer, eAccessMode);
+}
+
+/*
+ * memmap.
+ */
+inline storeError OFileLockBytes_Impl::memmap (OMappingDescriptor_Impl &rDescr)
+{
+ if (rDescr <= m_aDescrOne)
+ rDescr = m_aDescrOne;
+ if (rDescr <= m_aDescrAny)
+ rDescr = m_aDescrAny;
+
+ if (!rDescr.m_pData)
+ {
+ if (rDescr.m_nOffset == 0)
+ m_aDescrOne.unmap();
+ else
+ m_aDescrAny.unmap();
+
+ if (!m_hMap)
+ {
+ if (m_bWriteable)
+ m_hMap = __store_fmap_rw (m_hFile);
+ else
+ m_hMap = __store_fmap_ro (m_hFile);
+ if (!m_hMap)
+ return ERROR_FROM_NATIVE(__store_errno());
+ }
+
+ if (m_bWriteable)
+ rDescr.m_pData = __store_mmap_rw (
+ m_hMap, rDescr.m_nOffset, rDescr.m_nSize);
+ else
+ rDescr.m_pData = __store_mmap_ro (
+ m_hMap, rDescr.m_nOffset, rDescr.m_nSize);
+ if (!rDescr.m_pData)
+ return ERROR_FROM_NATIVE(__store_errno());
+
+ if (rDescr.m_nOffset == 0)
+ m_aDescrOne = rDescr;
+ else
+ m_aDescrAny = rDescr;
+ }
+ return store_E_None;
+}
+
+/*
+ * size.
+ */
+inline storeError OFileLockBytes_Impl::size (void)
+{
+ if (!m_hMap)
+ return __store_fsize (m_hFile, m_nSize);
+ else
+ return store_E_None;
+}
+
+/*
+ * resize.
+ */
+inline storeError OFileLockBytes_Impl::resize (sal_uInt32 nSize)
+{
+ storeError eErrCode = size();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ if (nSize != m_nSize)
+ {
+ if (m_hMap)
+ {
+#ifdef __STORE_FEATURE_WRITETHROUGH
+ // Note: file creation slowed down by about 60 percent.
+ m_aDescrOne.cleanup();
+ m_aDescrAny.cleanup();
+#else
+ m_aDescrOne.unmap();
+ m_aDescrAny.unmap();
+#endif /* __STORE_FEATURE_WRITETHROUGH */
+
+ __store_funmap (m_hMap);
+ m_hMap = 0;
+ }
+
+ eErrCode = __store_ftrunc (m_hFile, nSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ m_nSize = nSize;
+ }
+ return store_E_None;
+}
+
+/*
+ * readAt.
+ */
+inline storeError OFileLockBytes_Impl::readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ storeError eErrCode = store_E_None;
+ if (m_bMemmap)
+ {
+ // Memory mapped I/O.
+ eErrCode = size();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ if (!(nOffset < m_nSize))
+ return store_E_None;
+
+ nBytes = VOS_MIN(nOffset + nBytes, m_nSize) - nOffset;
+ if (!(nBytes > 0))
+ return store_E_None;
+
+ OMappingDescriptor_Impl aDescr;
+ if (m_bWriteable)
+ aDescr = OMappingDescriptor_Impl (nOffset, nBytes);
+ else
+ aDescr = OMappingDescriptor_Impl (0, m_nSize);
+ aDescr.normalize (m_nAlignment, m_nSize);
+
+ eErrCode = memmap (aDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ aDescr.m_pData += (nOffset - aDescr.m_nOffset);
+ __store_memcpy (pBuffer, aDescr.m_pData, nBytes);
+
+ rnDone = nBytes;
+ }
+ else
+ {
+ // File I/O.
+ eErrCode = __store_fseek (m_hFile, nOffset);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = __store_fread (m_hFile, pBuffer, nBytes, rnDone);
+ }
+ return eErrCode;
+}
+
+/*
+ * writeAt.
+ */
+inline storeError OFileLockBytes_Impl::writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ storeError eErrCode = store_E_None;
+ if (m_bMemmap)
+ {
+ // Memory mapped I/O. Determine current size.
+ eErrCode = size();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check current size.
+ if (m_nSize < (nOffset + nBytes))
+ {
+ // Extend.
+ eErrCode = resize (nOffset + nBytes);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ OMappingDescriptor_Impl aDescr (nOffset, nBytes);
+ aDescr.normalize (m_nAlignment, m_nSize);
+
+ eErrCode = memmap (aDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ aDescr.m_pData += (nOffset - aDescr.m_nOffset);
+ __store_memcpy (aDescr.m_pData, pBuffer, nBytes);
+
+ rnDone = nBytes;
+ }
+ else
+ {
+ // File I/O.
+ eErrCode = __store_fseek (m_hFile, nOffset);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = __store_fwrite (m_hFile, pBuffer, nBytes, rnDone);
+ }
+ return eErrCode;
+}
+
+/*
+ * sync.
+ */
+inline storeError OFileLockBytes_Impl::sync (void)
+{
+ if (m_bMemmap)
+ {
+ // Memory mapped I/O.
+ m_aDescrOne.sync();
+ m_aDescrAny.sync();
+ }
+ else
+ {
+ // File I/O.
+ __store_fsync (m_hFile);
+ }
+ return store_E_None;
+}
+
+/*
+ * stat.
+ */
+inline storeError OFileLockBytes_Impl::stat (sal_uInt32 &rnSize)
+{
+ storeError eErrCode = size();
+ if (eErrCode == store_E_None)
+ rnSize = m_nSize;
+ return eErrCode;
+}
+
+/*========================================================================
+ *
+ * OFileLockBytes implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OFileLockBytes, store),
+ VOS_NAMESPACE (OFileLockBytes, store),
+ VOS_NAMESPACE (OStoreObject, store),
+ 0);
+
+/*
+ * OFileLockBytes.
+ */
+OFileLockBytes::OFileLockBytes (void)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ m_pImpl = new OFileLockBytes_Impl();
+}
+
+/*
+ * ~OFileLockBytes.
+ */
+OFileLockBytes::~OFileLockBytes (void)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ delete m_pImpl;
+}
+
+/*
+ * acquire.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OFileLockBytes::acquire (void)
+{
+ return OStoreObject::acquire();
+}
+
+/*
+ * release.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OFileLockBytes::release (void)
+{
+ return OStoreObject::release();
+}
+
+/*
+ * referenced.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OFileLockBytes::referenced (void) const
+{
+ return OStoreObject::referenced();
+}
+
+/*
+ * create.
+ */
+storeError OFileLockBytes::create (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+
+ if (pFilename)
+ return m_pImpl->create (pFilename, eAccessMode);
+ else
+ return store_E_InvalidParameter;
+}
+
+/*
+ * readAt.
+ */
+storeError OFileLockBytes::readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ // Initialize [out] param.
+ rnDone = 0;
+
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return m_pImpl->readAt (nOffset, pBuffer, nBytes, rnDone);
+ else
+ return store_E_InvalidHandle;
+}
+
+/*
+ * writeAt.
+ */
+storeError OFileLockBytes::writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ // Initialize [out] param.
+ rnDone = 0;
+
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return m_pImpl->writeAt (nOffset, pBuffer, nBytes, rnDone);
+ else
+ return store_E_InvalidHandle;
+}
+
+/*
+ * flush.
+ */
+storeError OFileLockBytes::flush (void)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return m_pImpl->sync();
+ else
+ return store_E_InvalidHandle;
+}
+
+/*
+ * setSize.
+ */
+storeError OFileLockBytes::setSize (sal_uInt32 nSize)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return m_pImpl->resize (nSize);
+ else
+ return store_E_InvalidHandle;
+}
+
+/*
+ * stat.
+ */
+storeError OFileLockBytes::stat (sal_uInt32 &rnSize)
+{
+ // Initialize [out] param.
+ rnSize = 0;
+
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return m_pImpl->stat (rnSize);
+ else
+ return store_E_InvalidHandle;
+}
+
+/*
+ * lockRange.
+ */
+storeError OFileLockBytes::lockRange (
+ sal_uInt32 nOffset, sal_uInt32 nBytes)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return store_E_None; // E_Unsupported
+ else
+ return store_E_InvalidHandle;
+}
+
+/*
+ * unlockRange.
+ */
+storeError OFileLockBytes::unlockRange (
+ sal_uInt32 nOffset, sal_uInt32 nBytes)
+{
+ // Acquire exclusive access.
+ osl::Guard<osl::Mutex> aGuard (m_aMutex);
+ if (m_pImpl->isValid())
+ return store_E_None; // E_Unsupported
+ else
+ return store_E_InvalidHandle;
+}
+
diff --git a/store/source/makefile.mk b/store/source/makefile.mk
new file mode 100644
index 000000000..9b6d156d9
--- /dev/null
+++ b/store/source/makefile.mk
@@ -0,0 +1,107 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=store
+TARGET=store
+
+# --- Settings ---
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files ---
+
+SLOFILES= \
+ $(SLO)$/object.obj \
+ $(SLO)$/memlckb.obj \
+ $(SLO)$/filelckb.obj \
+ $(SLO)$/storbase.obj \
+ $(SLO)$/storcach.obj \
+ $(SLO)$/stordata.obj \
+ $(SLO)$/stordmon.obj \
+ $(SLO)$/storlckb.obj \
+ $(SLO)$/stortree.obj \
+ $(SLO)$/storpage.obj \
+ $(SLO)$/store.obj
+
+.IF "$(debug)" != ""
+OBJFILES= \
+ $(OBJ)$/object.obj \
+ $(OBJ)$/memlckb.obj \
+ $(OBJ)$/filelckb.obj \
+ $(OBJ)$/storbase.obj \
+ $(OBJ)$/storcach.obj \
+ $(OBJ)$/stordata.obj \
+ $(OBJ)$/stordmon.obj \
+ $(OBJ)$/storlckb.obj \
+ $(OBJ)$/stortree.obj \
+ $(OBJ)$/storpage.obj \
+ $(OBJ)$/store.obj
+.ENDIF # debug
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/store/source/memlckb.cxx b/store/source/memlckb.cxx
new file mode 100644
index 000000000..c854179b7
--- /dev/null
+++ b/store/source/memlckb.cxx
@@ -0,0 +1,396 @@
+/*************************************************************************
+ *
+ * $RCSfile: memlckb.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_MEMLCKB_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+#ifndef _STORE_MEMLCKB_HXX_
+#include <store/memlckb.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OMemoryLockBytes internals.
+ *
+ *======================================================================*/
+#ifdef DEBUG
+#ifdef inline
+#undef inline
+#endif
+#define inline
+#endif /* DEBUG */
+
+/*========================================================================
+ *
+ * OMemoryLockBytes_Impl interface.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+class OMemoryLockBytes_Impl
+{
+ sal_uInt8 *m_pBuffer;
+ sal_uInt32 m_nSize;
+
+public:
+ OMemoryLockBytes_Impl (void);
+ ~OMemoryLockBytes_Impl (void);
+
+ storeError resize (sal_uInt32 nSize);
+
+ storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+ storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ storeError stat (sal_uInt32 &rnSize);
+};
+
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+/*========================================================================
+ *
+ * OMemoryLockBytes_Impl (inline) implementation.
+ *
+ *======================================================================*/
+/*
+ * OMemoryLockBytes_Impl.
+ */
+inline OMemoryLockBytes_Impl::OMemoryLockBytes_Impl (void)
+ : m_pBuffer (0), m_nSize (0)
+{
+}
+
+/*
+ * ~OMemoryLockBytes_Impl.
+ */
+inline OMemoryLockBytes_Impl::~OMemoryLockBytes_Impl (void)
+{
+ rtl_freeMemory (m_pBuffer);
+}
+
+/*
+ * resize.
+ */
+inline storeError OMemoryLockBytes_Impl::resize (sal_uInt32 nSize)
+{
+ if (!(nSize == m_nSize))
+ {
+ m_pBuffer = (sal_uInt8*)(rtl_reallocateMemory (m_pBuffer, nSize));
+ if (!m_pBuffer)
+ {
+ m_nSize = 0;
+ if (nSize > 0)
+ return store_E_OutOfMemory;
+ else
+ return store_E_None;
+ }
+
+ if (nSize > m_nSize)
+ rtl_zeroMemory (m_pBuffer + m_nSize, nSize - m_nSize);
+ m_nSize = nSize;
+ }
+ return store_E_None;
+}
+
+/*
+ * readAt.
+ */
+inline storeError OMemoryLockBytes_Impl::readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ if (m_pBuffer)
+ {
+ if (!(nOffset < m_nSize))
+ return store_E_None;
+
+ nBytes = VOS_MIN(nOffset + nBytes, m_nSize) - nOffset;
+ if (!(nBytes > 0))
+ return store_E_None;
+
+ rtl_copyMemory (pBuffer, m_pBuffer + nOffset, nBytes);
+ rnDone = nBytes;
+ }
+ return store_E_None;
+}
+
+/*
+ * writeAt.
+ */
+inline storeError OMemoryLockBytes_Impl::writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ if (m_nSize < (nOffset + nBytes))
+ {
+ storeError eErrCode = resize (nOffset + nBytes);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ rtl_copyMemory (m_pBuffer + nOffset, pBuffer, nBytes);
+ rnDone = nBytes;
+
+ return store_E_None;
+}
+
+/*
+ * stat.
+ */
+inline storeError OMemoryLockBytes_Impl::stat (sal_uInt32 &rnSize)
+{
+ rnSize = m_nSize;
+ return store_E_None;
+}
+
+/*========================================================================
+ *
+ * OMemoryLockBytes implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OMemoryLockBytes, store),
+ VOS_NAMESPACE (OMemoryLockBytes, store),
+ VOS_NAMESPACE (OStoreObject, store),
+ 0);
+
+/*
+ * OMemoryLockBytes.
+ */
+OMemoryLockBytes::OMemoryLockBytes (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ m_pImpl = new OMemoryLockBytes_Impl();
+}
+
+/*
+ * ~OMemoryLockBytes.
+ */
+OMemoryLockBytes::~OMemoryLockBytes (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ delete m_pImpl;
+}
+
+/*
+ * acquire.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OMemoryLockBytes::acquire (void)
+{
+ return OStoreObject::acquire();
+}
+
+/*
+ * release.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OMemoryLockBytes::release (void)
+{
+ return OStoreObject::release();
+}
+
+/*
+ * referenced.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OMemoryLockBytes::referenced (void) const
+{
+ return OStoreObject::referenced();
+}
+
+/*
+ * readAt.
+ */
+storeError OMemoryLockBytes::readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ // Initialize [out] param.
+ rnDone = 0;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return m_pImpl->readAt (nOffset, pBuffer, nBytes, rnDone);
+}
+
+/*
+ * writeAt.
+ */
+storeError OMemoryLockBytes::writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ // Initialize [out] param.
+ rnDone = 0;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return m_pImpl->writeAt (nOffset, pBuffer, nBytes, rnDone);
+}
+
+/*
+ * flush.
+ */
+storeError OMemoryLockBytes::flush (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return store_E_None;
+}
+
+/*
+ * setSize.
+ */
+storeError OMemoryLockBytes::setSize (sal_uInt32 nSize)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return m_pImpl->resize (nSize);
+}
+
+/*
+ * stat.
+ */
+storeError OMemoryLockBytes::stat (sal_uInt32 &rnSize)
+{
+ // Initialize [out] param.
+ rnSize = 0;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return m_pImpl->stat (rnSize);
+}
+
+/*
+ * lockRange.
+ */
+storeError OMemoryLockBytes::lockRange (
+ sal_uInt32 nOffset, sal_uInt32 nBytes)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return store_E_None; // E_Unsupported
+}
+
+/*
+ * unlockRange.
+ */
+storeError OMemoryLockBytes::unlockRange (
+ sal_uInt32 nOffset, sal_uInt32 nBytes)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+ return store_E_None; // E_Unsupported
+}
+
diff --git a/store/source/object.cxx b/store/source/object.cxx
new file mode 100644
index 000000000..ac392409e
--- /dev/null
+++ b/store/source/object.cxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * $RCSfile: object.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_OBJECT_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStoreObject implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OStoreObject, store),
+ VOS_NAMESPACE (OStoreObject, store),
+ VOS_NAMESPACE (OObject, vos),
+ 0);
+
+/*
+ * OStoreObject.
+ */
+OStoreObject::OStoreObject (void)
+{
+}
+
+/*
+ * ~OStoreObject.
+ */
+OStoreObject::~OStoreObject (void)
+{
+}
+
diff --git a/store/source/storbase.cxx b/store/source/storbase.cxx
new file mode 100644
index 000000000..11668669b
--- /dev/null
+++ b/store/source/storbase.cxx
@@ -0,0 +1,1944 @@
+/*************************************************************************
+ *
+ * $RCSfile: storbase.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORBASE_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef __STL_USE_NEWALLOC
+#define __STL_USE_NEWALLOC 1
+#endif
+#ifndef __UTILITY__
+#include <utility>
+#endif
+#ifndef __HASH_MAP__
+#include <hash_map>
+#endif
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStorePageGuard.
+ *
+ *======================================================================*/
+/*
+ * CRC polynomial 0xEDB88320.
+ */
+const sal_uInt32 NAMESPACE_STORE(OStorePageGuard)::m_pTable[] =
+{
+ /* 0 */
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+
+ /* 1 */
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+
+ /* 2 */
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+
+ /* 3 */
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+
+ /* 4 */
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+
+ /* 5 */
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+
+ /* 6 */
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+
+ /* 7 */
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+
+ /* 8 */
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+
+ /* 9 */
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+
+ /* A */
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+
+ /* B */
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+
+ /* C */
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+
+ /* D */
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+
+ /* E */
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+
+ /* F */
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
+
+/*
+ * crc32.
+ */
+sal_uInt32 OStorePageGuard::crc32 (
+ sal_uInt32 nCRC32, const void *pData, sal_uInt32 nSize)
+{
+ if (pData)
+ {
+ register const sal_uInt8 *p = (const sal_uInt8*)pData;
+ register const sal_uInt8 *q = p + nSize;
+
+ nCRC32 = ~nCRC32;
+ while (p < q)
+ nCRC32 = updcrc32 (nCRC32, *(p++));
+ nCRC32 = ~nCRC32;
+ }
+ return nCRC32;
+}
+
+/*========================================================================
+ *
+ * OStorePageObject.
+ *
+ *======================================================================*/
+/*
+ * ~OStorePageObject.
+ */
+OStorePageObject::~OStorePageObject (void)
+{
+}
+
+/*
+ * swap.
+ */
+void OStorePageObject::swap (const D& rDescr)
+{
+#ifdef OSL_BIGENDIAN
+ m_rPage.swap (rDescr);
+#endif /* OSL_BIGENDIAN */
+}
+
+/*
+ * guard.
+ */
+void OStorePageObject::guard (const D& rDescr)
+{
+ m_rPage.guard (rDescr);
+}
+
+/*
+ * verify.
+ */
+storeError OStorePageObject::verify (const D& rDescr)
+{
+ return m_rPage.verify (rDescr);
+}
+
+/*========================================================================
+ *
+ * OStoreSuperBlock.
+ *
+ *======================================================================*/
+#define STORE_MAGIC_SUPERBLOCK 0x484D5343UL
+
+struct OStoreSuperBlock
+{
+ typedef OStorePageGuard G;
+ typedef OStorePageDescriptor D;
+ typedef OStorePageLink L;
+
+ /** Representation.
+ */
+ G m_aGuard;
+ D m_aDescr;
+ sal_uInt32 m_nMarked;
+ L m_aMarked;
+ sal_uInt32 m_nUnused;
+ L m_aUnused;
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (sizeof(G) + sizeof(D) + 2 * (sizeof(L) + sizeof(sal_uInt32)));
+ }
+
+ /** Construction.
+ */
+ OStoreSuperBlock (void)
+ : m_aGuard (STORE_MAGIC_SUPERBLOCK),
+ m_nMarked (0),
+ m_aMarked (0),
+ m_nUnused (0),
+ m_aUnused (0)
+ {}
+
+ OStoreSuperBlock (const OStoreSuperBlock& rOther)
+ : m_aGuard (rOther.m_aGuard),
+ m_aDescr (rOther.m_aDescr),
+ m_nMarked (rOther.m_nMarked),
+ m_aMarked (rOther.m_aMarked),
+ m_nUnused (rOther.m_nUnused),
+ m_aUnused (rOther.m_aUnused)
+ {}
+
+ OStoreSuperBlock& operator= (const OStoreSuperBlock& rOther)
+ {
+ m_aGuard = rOther.m_aGuard;
+ m_aDescr = rOther.m_aDescr;
+ m_nMarked = rOther.m_nMarked;
+ m_aMarked = rOther.m_aMarked;
+ m_nUnused = rOther.m_nUnused;
+ m_aUnused = rOther.m_aUnused;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStoreSuperBlock& rOther) const
+ {
+ return ((m_aGuard == rOther.m_aGuard ) &&
+ (m_aDescr == rOther.m_aDescr ) &&
+ (m_nMarked == rOther.m_nMarked) &&
+ (m_aMarked == rOther.m_aMarked) &&
+ (m_nUnused == rOther.m_nUnused) &&
+ (m_aUnused == rOther.m_aUnused) );
+ }
+
+ /** create.
+ */
+ void create (const D& rDescr)
+ {
+ m_aGuard = G(STORE_MAGIC_SUPERBLOCK);
+ m_aDescr = rDescr;
+
+ m_nMarked = 0;
+ m_aMarked = L(0);
+
+ m_nUnused = 0;
+ m_aUnused = L(0);
+ }
+
+ /** unused(Count|Head|Insert|Remove|Reset).
+ */
+ sal_uInt32 unusedCount (void) const
+ {
+ return m_nUnused;
+ }
+ const L& unusedHead (void) const
+ {
+ return m_aUnused;
+ }
+ void unusedInsert (const L& rLink)
+ {
+ m_nUnused++;
+ m_aUnused = rLink;
+ }
+ void unusedRemove (const L& rLink)
+ {
+ m_nUnused--;
+ m_aUnused = rLink;
+ }
+ void unusedReset (void)
+ {
+ m_nUnused = 0;
+ m_aUnused = L(0);
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aGuard.swap();
+ m_aDescr.swap();
+
+ m_nMarked = VOS_SWAPDWORD(m_nMarked);
+ m_aMarked.swap();
+
+ m_nUnused = VOS_SWAPDWORD(m_nUnused);
+ m_aUnused.swap();
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** guard (external representation).
+ */
+ void guard (void)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ m_aGuard.m_nCRC32 = nCRC32;
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (void)
+ {
+ sal_uInt32 nMagic = m_aGuard.m_nMagic;
+#ifdef OSL_BIGENDIAN
+ nMagic = VOS_SWAPDWORD(nMagic);
+#endif /* OSL_BIGENDIAN */
+ if (nMagic != STORE_MAGIC_SUPERBLOCK)
+ store_E_WrongFormat;
+
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ if (m_aGuard.m_nCRC32 != nCRC32)
+ return store_E_InvalidChecksum;
+ else
+ return store_E_None;
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreStateBlock.
+ *
+ *======================================================================*/
+struct OStoreStateBlock
+{
+ enum StateBits
+ {
+ STATE_CLEAN = 0,
+ STATE_CLOSE_WAIT = 1,
+ STATE_FLUSH_WAIT = 2
+ };
+
+ /** Representation.
+ */
+ sal_uInt32 m_nState;
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return sizeof(sal_uInt32);
+ }
+
+ /** Construction.
+ */
+ OStoreStateBlock (void)
+ : m_nState (STATE_CLEAN)
+ {}
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_nState = VOS_SWAPDWORD(m_nState);
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** Operation.
+ */
+ sal_Bool closePending (void) const
+ {
+ return ((m_nState & STATE_CLOSE_WAIT) ? 1 : 0);
+ }
+ void closed (void)
+ {
+ m_nState &= ~STATE_CLOSE_WAIT;
+ }
+
+ sal_Bool flushPending (void) const
+ {
+ return ((m_nState & STATE_FLUSH_WAIT) ? 1 : 0);
+ }
+ void flushed (void)
+ {
+ m_nState &= ~STATE_FLUSH_WAIT;
+ }
+
+ void modified (void)
+ {
+ m_nState |= (STATE_CLOSE_WAIT | STATE_FLUSH_WAIT);
+ }
+ void clean (void)
+ {
+ m_nState &= ~(STATE_CLOSE_WAIT | STATE_FLUSH_WAIT);
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreSuperBlockPage interface.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+struct OStoreSuperBlockPage
+{
+ typedef OStoreSuperBlock SuperBlock;
+ typedef OStoreStateBlock StateBlock;
+
+ /** Representation.
+ */
+ SuperBlock m_aSuperOne;
+ SuperBlock m_aSuperTwo;
+ StateBlock m_aState;
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (2 * SuperBlock::size() + StateBlock::size());
+ }
+
+ /** Construction.
+ */
+ OStoreSuperBlockPage (void)
+ {}
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aSuperOne.swap();
+ m_aSuperTwo.swap();
+ m_aState.swap();
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** load (w/o verification).
+ */
+ storeError load (OStorePageBIOS &rBIOS)
+ {
+ // Read.
+ storeError eErrCode = rBIOS.read (0, this, size());
+
+#ifdef OSL_BIGENDIAN
+ // Swap to internal representation.
+ swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Done.
+ return eErrCode;
+ }
+
+ /** save.
+ */
+ storeError save (OStorePageBIOS &rBIOS)
+ {
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Guard.
+ m_aSuperOne.guard();
+ m_aSuperTwo.guard();
+
+ // Write.
+ storeError eErrCode = rBIOS.write (0, this, size());
+
+#ifdef OSL_BIGENDIAN
+ // Swap back to internal representation.
+ swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Done.
+ return eErrCode;
+ }
+
+ /** create.
+ */
+ storeError create (
+ OStorePageBIOS &rBIOS,
+ const OStorePageDescriptor &rDescr);
+
+ /** close.
+ */
+ storeError close (
+ OStorePageBIOS &rBIOS);
+
+ /** flush.
+ */
+ storeError flush (
+ OStorePageBIOS &rBIOS);
+
+ /** modified.
+ */
+ storeError modified (
+ OStorePageBIOS &rBIOS);
+
+ /** verify (with repair).
+ */
+ storeError verify (
+ OStorePageBIOS &rBIOS);
+};
+
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+/*========================================================================
+ *
+ * OStoreSuperBlockPage implementation.
+ *
+ *======================================================================*/
+/*
+ * create.
+ */
+storeError OStoreSuperBlockPage::create (
+ OStorePageBIOS &rBIOS,
+ const OStorePageDescriptor &rDescr)
+{
+ // Setup initial Page.
+ void *p = rtl_allocateMemory (rDescr.m_nSize);
+ rtl_zeroMemory (p, rDescr.m_nSize);
+
+ // Mark as modified.
+ m_aState.modified();
+
+ // Write initial Page.
+ storeError eErrCode = rBIOS.write (0, p, rDescr.m_nSize);
+ if (eErrCode == store_E_None)
+ {
+ // Setup 1st and 2nd SuperBlock copy.
+ m_aSuperOne.create (rDescr);
+ m_aSuperTwo = m_aSuperOne;
+
+ // Mark as modified.
+ m_aState.modified();
+
+ // Save.
+ eErrCode = save (rBIOS);
+ }
+
+ // Cleanup and finish.
+ rtl_freeMemory (p);
+ return eErrCode;
+}
+
+/*
+ * close.
+ */
+storeError OStoreSuperBlockPage::close (OStorePageBIOS &rBIOS)
+{
+ storeError eErrCode = store_E_None;
+ if (m_aState.closePending())
+ {
+ // Mark as modified.
+ m_aState.modified();
+
+ // Check access mode.
+ if (rBIOS.isWriteable())
+ {
+ // Save StateBlock.
+ StateBlock aState (m_aState);
+
+ // Mark as clean.
+ aState.clean();
+
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ aState.swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Write behind SuperBlock.
+ sal_uInt32 nAddr = 2 * SuperBlock::size();
+ eErrCode = rBIOS.write (nAddr, &aState, StateBlock::size());
+ }
+
+ // Mark as clean.
+ m_aState.clean();
+ }
+ return eErrCode;
+}
+
+/*
+ * flush.
+ */
+storeError OStoreSuperBlockPage::flush (OStorePageBIOS &rBIOS)
+{
+ storeError eErrCode = store_E_None;
+ if (m_aState.flushPending())
+ {
+ // Check access mode.
+ if (rBIOS.isWriteable())
+ {
+ // Save StateBlock.
+ StateBlock aState (m_aState);
+
+ // Mark as flushed.
+ aState.flushed();
+
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ aState.swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Write behind SuperBlock.
+ sal_uInt32 nAddr = 2 * SuperBlock::size();
+ eErrCode = rBIOS.write (nAddr, &aState, StateBlock::size());
+ }
+
+ // Mark as flushed.
+ m_aState.flushed();
+ }
+ return eErrCode;
+}
+
+/*
+ * modified.
+ */
+storeError OStoreSuperBlockPage::modified (OStorePageBIOS &rBIOS)
+{
+ storeError eErrCode = store_E_None;
+ if (!m_aState.flushPending())
+ {
+ // Mark as modified.
+ m_aState.modified();
+
+ // Check access mode.
+ if (rBIOS.isWriteable())
+ {
+ // Save StateBlock.
+ StateBlock aState (m_aState);
+
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ aState.swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Write behind SuperBlock.
+ sal_uInt32 nAddr = 2 * SuperBlock::size();
+ eErrCode = rBIOS.write (nAddr, &aState, StateBlock::size());
+ }
+ }
+ return eErrCode;
+}
+
+/*
+ * verify (with repair).
+ */
+storeError OStoreSuperBlockPage::verify (OStorePageBIOS &rBIOS)
+{
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Verify 1st copy.
+ storeError eErrCode = m_aSuperOne.verify();
+ if (eErrCode == store_E_None)
+ {
+ // Ok. Verify 2nd copy.
+ eErrCode = m_aSuperTwo.verify();
+ if (eErrCode == store_E_None)
+ {
+ // Ok. Ensure identical copies (1st copy wins).
+ if (!(m_aSuperOne == m_aSuperTwo))
+ {
+ // Different. Replace 2nd copy with 1st copy.
+ m_aSuperTwo = m_aSuperOne;
+
+ // Write back.
+ if (rBIOS.isWriteable())
+ eErrCode = rBIOS.write (0, this, size());
+ else
+ eErrCode = store_E_None;
+ }
+ }
+ else
+ {
+ // Failure. Replace 2nd copy with 1st copy.
+ m_aSuperTwo = m_aSuperOne;
+
+ // Write back.
+ if (rBIOS.isWriteable())
+ eErrCode = rBIOS.write (0, this, size());
+ else
+ eErrCode = store_E_None;
+ }
+ }
+ else
+ {
+ // Failure. Verify 2nd copy.
+ eErrCode = m_aSuperTwo.verify();
+ if (eErrCode == store_E_None)
+ {
+ // Ok. Replace 1st copy with 2nd copy.
+ m_aSuperOne = m_aSuperTwo;
+
+ // Write back.
+ if (rBIOS.isWriteable())
+ eErrCode = rBIOS.write (0, this, size());
+ else
+ eErrCode = store_E_None;
+ }
+ else
+ {
+ // Double Failure.
+ VOS_TRACE("OStoreSuperBlockPage::verify(): double failure.\n");
+ }
+ }
+
+#ifdef OSL_BIGENDIAN
+ // Swap back to internal representation.
+ swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Done.
+ return eErrCode;
+}
+
+/*========================================================================
+ *
+ * OStorePageACL.
+ *
+ *======================================================================*/
+typedef sal_uInt32 key_type;
+typedef sal_uInt32 val_type;
+
+typedef NAMESPACE_STD(hash)<key_type> key_hash;
+typedef NAMESPACE_STD(equal_to)<key_type> key_cmp;
+
+typedef NAMESPACE_STD(hash_map)
+ <key_type, val_type, key_hash, key_cmp> map_type;
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+struct OStorePageACL : public map_type
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nRefCount;
+
+ /** Construction.
+ */
+ OStorePageACL (void)
+ : m_nRefCount (0)
+ {}
+};
+
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+/*========================================================================
+ *
+ * OStorePageBIOS implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OStorePageBIOS, store),
+ VOS_NAMESPACE (OStorePageBIOS, store),
+ VOS_NAMESPACE (OStoreObject, store),
+ 0);
+
+/*
+ * OStorePageBIOS.
+ */
+OStorePageBIOS::OStorePageBIOS (void)
+ : m_xLockBytes (NULL),
+ m_pAcl (NULL),
+ m_pSuper (NULL),
+ m_bModified (sal_False),
+ m_bWriteable (sal_False)
+{
+}
+
+/*
+ * ~OStorePageBIOS.
+ */
+OStorePageBIOS::~OStorePageBIOS (void)
+{
+ OStorePageBIOS::close();
+}
+
+/*
+ * verify (SuperBlock with repair).
+ * Internal: Precond: initialized, exclusive access.
+ */
+storeError OStorePageBIOS::verify (SuperPage *&rpSuper)
+{
+ // Check SuperBlock page allocation.
+ if (rpSuper == NULL)
+ {
+ // Allocate.
+ rpSuper = new SuperPage();
+
+ // Load (w/o verification).
+ storeError eErrCode = rpSuper->load (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Cleanup and fail.
+ __STORE_DELETEZ (rpSuper);
+ return eErrCode;
+ }
+
+ // Check SuperBlock state.
+ if (rpSuper->m_aState.closePending())
+ VOS_TRACE("OStorePageBIOS::verify(): close pending.\n");
+
+ if (rpSuper->m_aState.flushPending())
+ VOS_TRACE("OStorePageBIOS::verify(): flush pending.\n");
+ }
+
+ // Verify SuperBlock page (with repair).
+ return rpSuper->verify (*this);
+}
+
+/*
+ * repair (SuperBlock).
+ * Internal: Precond: initialized, exclusive access.
+ */
+storeError OStorePageBIOS::repair (SuperPage *&rpSuper)
+{
+ // Acquire Lock.
+ storeError eErrCode = acquireLock (0, SuperPage::size());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Verify SuperBlock page (with repair).
+ eErrCode = verify (rpSuper);
+ if (eErrCode != store_E_None)
+ {
+ // Failure.
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // ReleaseLock.
+ return releaseLock (0, SuperPage::size());
+}
+
+/*
+ * initialize.
+ * Precond: none.
+ */
+storeError OStorePageBIOS::initialize (
+ ILockBytes *pLockBytes,
+ storeAccessMode eAccessMode)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check arguments.
+ storeError eErrCode = store_E_InvalidParameter;
+ if (pLockBytes)
+ {
+ // Cleanup.
+ __STORE_DELETEZ (m_pAcl);
+ __STORE_DELETEZ (m_pSuper);
+
+ // Initialize.
+ m_xLockBytes = pLockBytes;
+ m_bModified = sal_False;
+ m_bWriteable = (!(eAccessMode == store_AccessReadOnly));
+
+ // Check access mode.
+ if (!(eAccessMode == store_AccessCreate))
+ {
+ // Verify (repair) SuperBlock page.
+ if (!(eAccessMode == store_AccessReadOnly))
+ eErrCode = repair (m_pSuper);
+ else
+ eErrCode = verify (m_pSuper);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Obtain modified state.
+ m_bModified = m_pSuper->m_aState.flushPending();
+ }
+ else
+ {
+ // Truncate to zero length.
+ eErrCode = m_xLockBytes->setSize(0);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Commit.
+ eErrCode = m_xLockBytes->flush();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Mark not existent.
+ eErrCode = store_E_NotExists;
+ }
+ }
+ return eErrCode;
+}
+
+/*
+ * create (SuperBlock).
+ * Precond: initialized, writeable (store_AccessCreate).
+ */
+storeError OStorePageBIOS::create (sal_uInt16 nPageSize)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ // Check PageSize.
+ sal_uInt16 nMinSize = SuperPage::size();
+ nMinSize = VOS_MAX(nMinSize, STORE_MINIMUM_PAGESIZE);
+
+ nPageSize = VOS_MAX(nPageSize, nMinSize);
+ nPageSize = VOS_MIN(nPageSize, STORE_MAXIMUM_PAGESIZE);
+
+ sal_uInt16 nRemSize = nPageSize % nMinSize;
+ if (nRemSize)
+ nPageSize += (nMinSize - nRemSize);
+
+ // Acquire Lock.
+ storeError eErrCode = acquireLock (0, SuperPage::size());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check SuperBlock page allocation.
+ if (m_pSuper == NULL)
+ m_pSuper = new SuperPage();
+
+ // Create SuperBlock page.
+ eErrCode = m_pSuper->create (
+ *this, OStorePageDescriptor (nPageSize, nPageSize, nMinSize));
+ if (eErrCode != store_E_None)
+ {
+ // Cleanup and fail.
+ __STORE_DELETEZ (m_pSuper);
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Flush SuperBlock page.
+ eErrCode = m_pSuper->flush (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Cleanup and fail.
+ __STORE_DELETEZ (m_pSuper);
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Commit.
+ eErrCode = m_xLockBytes->flush();
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageBIOS::create(): flush failed");
+ if (eErrCode == store_E_None)
+ {
+ // Mark not modified.
+ m_bModified = sal_False;
+ }
+
+ // Release Lock and finish.
+ return releaseLock (0, SuperPage::size());
+}
+
+/*
+ * getPageSize.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::getPageSize (sal_uInt16 &rnPageSize)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Initialize [out] param.
+ rnPageSize = 0;
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Load SuperBlock and require good health.
+ storeError eErrCode = verify (m_pSuper);
+ if (eErrCode == store_E_None)
+ {
+ // Obtain PageSize.
+ rnPageSize = m_pSuper->m_aSuperOne.m_aDescr.m_nSize;
+ }
+ return eErrCode;
+}
+
+/*
+ * acquireLock.
+ * Low Level: Precond: initialized, exclusive access.
+ */
+storeError OStorePageBIOS::acquireLock (
+ sal_uInt32 nAddr, sal_uInt32 nSize)
+{
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check Address.
+ VOS_PRECOND(
+ nAddr != STORE_PAGE_NULL,
+ "OStorePageBIOS::acquireLock(): invalid Address");
+ if (nAddr == STORE_PAGE_NULL)
+ return store_E_CantSeek;
+
+ // Acquire Lock.
+#ifdef STORE_FEATURE_LOCKING
+ return m_xLockBytes->lockRegion (nAddr, nSize);
+#else
+ return store_E_None;
+#endif /* STORE_FEATURE_LOCKING */
+}
+
+/*
+ * releaseLock.
+ * Low Level: Precond: initialized, exclusive access.
+ */
+storeError OStorePageBIOS::releaseLock (
+ sal_uInt32 nAddr, sal_uInt32 nSize)
+{
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check Address.
+ VOS_PRECOND(
+ nAddr != STORE_PAGE_NULL,
+ "OStorePageBIOS::releaseLock(): invalid Address");
+ if (nAddr == STORE_PAGE_NULL)
+ return store_E_CantSeek;
+
+ // Release Lock.
+#ifdef STORE_FEATURE_LOCKING
+ return m_xLockBytes->unlockRegion (nAddr, nSize);
+#else
+ return store_E_None;
+#endif /* STORE_FEATURE_LOCKING */
+}
+
+/*
+ * read.
+ * Low Level: Precond: initialized, exclusive access.
+ */
+storeError OStorePageBIOS::read (
+ sal_uInt32 nAddr, void *pData, sal_uInt32 nSize)
+{
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check Address.
+ VOS_PRECOND(
+ nAddr != STORE_PAGE_NULL,
+ "OStorePageBIOS::read(): invalid Address");
+ if (nAddr == STORE_PAGE_NULL)
+ return store_E_CantSeek;
+
+ // Check Data.
+ VOS_PRECOND(pData, "OStorePageBIOS::read(): no Data");
+ if (pData == NULL)
+ return store_E_InvalidParameter;
+
+ // Read Page.
+ sal_uInt32 nDone = 0;
+ storeError eErrCode = m_xLockBytes->readAt (nAddr, pData, nSize, nDone);
+ if ((eErrCode == store_E_None) && (nDone != nSize))
+ {
+ // Page too short.
+ if (nDone == 0)
+ eErrCode = store_E_NotExists;
+ else
+ eErrCode = store_E_CantRead;
+ }
+ return eErrCode;
+}
+
+/*
+ * write.
+ * Low Level: Precond: initialized, writeable, exclusive access.
+ */
+storeError OStorePageBIOS::write (
+ sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize)
+{
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ // Check Address.
+ VOS_PRECOND(
+ nAddr != STORE_PAGE_NULL,
+ "OStorePageBIOS::write(): invalid Address");
+ if (nAddr == STORE_PAGE_NULL)
+ return store_E_CantSeek;
+
+ // Check Data.
+ VOS_PRECOND(pData, "OStorePageBIOS::write(): no Data");
+ if (pData == NULL)
+ return store_E_InvalidParameter;
+
+ // Check modified state.
+ storeError eErrCode = store_E_None;
+ if (!m_bModified)
+ {
+ // Mark as modified.
+ m_bModified = sal_True;
+
+ // Mark SuperBlock modified.
+ eErrCode = m_pSuper->modified (*this);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Write Data.
+ sal_uInt32 nDone = 0;
+ eErrCode = m_xLockBytes->writeAt (nAddr, pData, nSize, nDone);
+ if ((eErrCode == store_E_None) && (nDone != nSize))
+ {
+ // Page too short.
+ eErrCode = store_E_CantWrite;
+ }
+ return eErrCode;
+}
+
+/*
+ * acquirePage.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::acquirePage (
+ const OStorePageDescriptor& rDescr, storeAccessMode eMode)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check access mode.
+ if (!(m_bWriteable || (eMode == store_AccessReadOnly)))
+ return store_E_AccessViolation;
+
+ // Check access control list.
+ if (!m_pAcl)
+ m_pAcl = new OStorePageACL();
+
+ // Find access control list entry.
+ map_type::iterator it = m_pAcl->find (rDescr.m_nAddr);
+ if (it != m_pAcl->end())
+ {
+ // Acquire existing entry (with ShareDenyWrite).
+ if (eMode == store_AccessReadOnly)
+ (*it).second += 1;
+ else
+ return store_E_AccessViolation;
+ }
+ else
+ {
+ // Insert new entry.
+ typedef NAMESPACE_STD(pair)<const sal_uInt32, sal_uInt32> map_entry;
+ m_pAcl->insert (map_entry (rDescr.m_nAddr, 1));
+ }
+
+ // Increment total referer count and finish.
+ m_pAcl->m_nRefCount += 1;
+ return store_E_None;
+}
+
+/*
+ * releasePage.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::releasePage (
+ const OStorePageDescriptor& rDescr, storeAccessMode eMode)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check access control list.
+ if (!m_pAcl)
+ return store_E_NotExists;
+
+ // Find access control list entry.
+ map_type::iterator it = m_pAcl->find (rDescr.m_nAddr);
+ if (it == m_pAcl->end())
+ return store_E_NotExists;
+
+ // Release existing entry.
+ if ((*it).second > 1)
+ (*it).second -= 1;
+ else
+ m_pAcl->erase(it);
+
+ // Decrement total referer count and finish.
+ m_pAcl->m_nRefCount -= 1;
+ return store_E_None;
+}
+
+/*
+ * getRefererCount.
+ * Precond: none.
+ */
+sal_uInt32 OStorePageBIOS::getRefererCount (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Obtain total referer count.
+ if (m_pAcl)
+ return m_pAcl->m_nRefCount;
+ else
+ return 0;
+}
+
+/*
+ * allocate.
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageBIOS::allocate (
+ OStorePageObject& rPage, Allocation eAlloc)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ // Acquire SuperBlock Lock.
+ storeError eErrCode = acquireLock (0, SuperPage::size());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Load SuperBlock and require good health.
+ eErrCode = verify (m_pSuper);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Check allocation.
+ if (eAlloc != ALLOCATE_EOF)
+ {
+ // Check FreeList.
+ OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead());
+ if (aListHead.m_nAddr)
+ {
+ // Allocate from FreeList.
+ OStorePageData aPageHead (OStorePageData::size());
+ aPageHead.location (aListHead.m_nAddr);
+
+ // Load PageHead.
+ eErrCode = peek (aPageHead);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Verify FreeList head.
+ VOS_PRECOND(
+ aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL,
+ "OStorePageBIOS::allocate(): page not free");
+ if (aPageHead.m_aUnused.m_nAddr == STORE_PAGE_NULL)
+ {
+ // Recovery: Reset FreeList.
+ m_pSuper->m_aSuperTwo.unusedReset();
+ m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
+
+ // Save SuperBlock page.
+ eErrCode = m_pSuper->save (*this);
+
+ // Release SuperBlock Lock.
+ releaseLock (0, SuperPage::size());
+
+ // Recovery: Allocate from EOF.
+ if (eErrCode == store_E_None)
+ return allocate (rPage, ALLOCATE_EOF);
+ else
+ return store_E_Unknown;
+ }
+
+ // Assign location.
+ OStorePageData &rData = rPage.getData();
+ rData.location (aPageHead.m_aDescr.m_nAddr);
+
+ // Pop from FreeList.
+ aListHead.m_nAddr = aPageHead.m_aUnused.m_nAddr;
+ rData.m_aUnused.m_nAddr = STORE_PAGE_NULL;
+
+ // Save page.
+ eErrCode = poke (rPage);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Save SuperBlock page.
+ m_pSuper->m_aSuperTwo.unusedRemove (aListHead);
+ m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
+
+ eErrCode = m_pSuper->save (*this);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageBIOS::allocate(): SuperBlock save failed");
+
+ // Release SuperBlock Lock and finish.
+ return releaseLock (0, SuperPage::size());
+ }
+ }
+
+ // Allocate from logical EOF. Determine physical EOF.
+ sal_uInt32 nAddr = STORE_PAGE_NULL;
+ eErrCode = m_xLockBytes->stat (nAddr);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Obtain logical EOF.
+ OStorePageDescriptor aDescr (m_pSuper->m_aSuperTwo.m_aDescr);
+ if (aDescr.m_nAddr == 0)
+ aDescr.m_nAddr = nAddr; /* backward compatibility */
+
+ if (!(aDescr.m_nAddr < nAddr))
+ {
+ // Check modified state.
+ if (!m_bModified)
+ {
+ // Mark modified.
+ m_bModified = sal_True;
+
+ // Mark SuperBlock modified.
+ eErrCode = m_pSuper->modified (*this);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+ }
+
+ // Resize.
+ sal_uInt32 nAlign = VOS_MIN(nAddr, STORE_MAXIMUM_PAGESIZE);
+ nAddr = ((nAddr + nAlign) / nAlign) * nAlign;
+
+ eErrCode = m_xLockBytes->setSize (nAddr);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+ }
+
+ // Save page.
+ rPage.location (aDescr.m_nAddr);
+ eErrCode = poke (rPage);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Save SuperBlock page.
+ aDescr.m_nAddr += aDescr.m_nSize;
+
+ m_pSuper->m_aSuperTwo.m_aDescr = aDescr;
+ m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
+
+ eErrCode = m_pSuper->save (*this);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageBIOS::allocate(): SuperBlock save failed");
+
+ // Release SuperBlock Lock and finish.
+ return releaseLock (0, SuperPage::size());
+}
+
+/*
+ * free.
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageBIOS::free (OStorePageObject& rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ // Acquire SuperBlock Lock.
+ storeError eErrCode = acquireLock (0, SuperPage::size());
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Load SuperBlock and require good health.
+ eErrCode = verify (m_pSuper);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Load PageHead.
+ OStorePageData &rData = rPage.getData();
+
+ eErrCode = peek (rData);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Push onto FreeList.
+ OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead());
+
+ rData.m_aUnused.m_nAddr = aListHead.m_nAddr;
+ aListHead.m_nAddr = rData.m_aDescr.m_nAddr;
+
+ // Save PageHead.
+ eErrCode = poke (rData);
+ if (eErrCode != store_E_None)
+ {
+ releaseLock (0, SuperPage::size());
+ return eErrCode;
+ }
+
+ // Save SuperBlock page.
+ m_pSuper->m_aSuperTwo.unusedInsert (aListHead);
+ m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
+
+ eErrCode = m_pSuper->save (*this);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageBIOS::free(): SuperBlock save failed");
+
+ // Release SuperBlock Lock and finish.
+ return releaseLock (0, SuperPage::size());
+}
+
+/*
+ * load.
+ * Precond: initialized, readable.
+ */
+storeError OStorePageBIOS::load (OStorePageObject& rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Save PageDescriptor.
+ OStorePageData &rData = rPage.getData();
+ OStorePageDescriptor aDescr (rData.m_aDescr);
+
+ // Read page.
+ storeError eErrCode = read (aDescr.m_nAddr, &rData, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ {
+ // Restore PageDescriptor.
+ rData.m_aDescr = aDescr;
+ return eErrCode;
+ }
+
+ // Verify page.
+ eErrCode = rPage.verify (aDescr);
+ if (eErrCode != store_E_None)
+ {
+ // Restore PageDescriptor.
+ rData.m_aDescr = aDescr;
+ return eErrCode;
+ }
+
+#ifdef OSL_BIGENDIAN
+ // Swap to internal representation.
+ rPage.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Verify PageDescriptor.
+ if (!((aDescr == rData.m_aDescr) ||
+ (aDescr <= rData.m_aDescr) ))
+ return store_E_InvalidAccess;
+
+ // Mark page as clean.
+ rPage.clean();
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * save.
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageBIOS::save (OStorePageObject& rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ // Save Page.
+ return poke (rPage);
+}
+
+/*
+ * close.
+ * Precond: none.
+ */
+storeError OStorePageBIOS::close (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check access control list.
+ if (m_pAcl)
+ {
+ // Check referer count.
+ if (m_pAcl->m_nRefCount)
+ {
+ // Report remaining referer count.
+ sal_uInt32 k = m_pAcl->m_nRefCount;
+ VOS_TRACE("OStorePageBIOS::close(): referer count: %d\n", k);
+ }
+ __STORE_DELETEZ (m_pAcl);
+ }
+
+ // Check SuperBlock page.
+ if (m_pSuper)
+ {
+ // Release SuperBlock page.
+ m_pSuper->close (*this);
+ __STORE_DELETEZ (m_pSuper);
+ }
+
+ // Check LockBytes.
+ if (m_xLockBytes.isValid())
+ {
+ // Release LockBytes.
+ m_xLockBytes->flush();
+ m_xLockBytes.unbind();
+ }
+ return store_E_None;
+}
+
+/*
+ * flush.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::flush (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check mode and state.
+ if (!(m_bWriteable && m_bModified))
+ return store_E_None;
+
+ // Flush SuperBlock page.
+ storeError eErrCode = m_pSuper->flush (*this);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageBIOS::flush(): SuperBlock flush failed");
+
+ // Flush LockBytes.
+ eErrCode = m_xLockBytes->flush();
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageBIOS::flush(): LockBytes flush failed");
+ if (eErrCode == store_E_None)
+ {
+ // Mark not modified.
+ m_bModified = sal_False;
+ }
+ return eErrCode;
+}
+
+/*
+ * size.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::size (sal_uInt32 &rnSize)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Initialize [out] param.
+ rnSize = 0;
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Obtain LockBytes size.
+ return m_xLockBytes->stat (rnSize);
+}
+
+/*
+ * scanBegin.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::scanBegin (
+ ScanContext &rCtx, sal_uInt32 nMagic)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Initialize [out] param.
+ rCtx.m_aDescr = OStorePageDescriptor(0, 0, 0);
+ rCtx.m_nSize = 0;
+ rCtx.m_nMagic = nMagic;
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Check SuperBlock page.
+ storeError eErrCode = verify (m_pSuper);
+ if (eErrCode != store_E_None)
+ {
+ // Damaged. Determine page size (NYI).
+ VOS_TRACE ("OStorePageBIOS::scanBegin(): damaged.\n");
+ return eErrCode;
+ }
+
+ // Setup Context descriptor.
+ rCtx.m_aDescr = m_pSuper->m_aSuperOne.m_aDescr;
+ rCtx.m_aDescr.m_nAddr = rCtx.m_aDescr.m_nSize;
+
+ // Setup Context size.
+ eErrCode = size (rCtx.m_nSize);
+ if (eErrCode != store_E_None)
+ rCtx.m_nSize = ((sal_uInt32)(~0));
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * scanNext.
+ * Precond: initialized.
+ */
+storeError OStorePageBIOS::scanNext (
+ ScanContext &rCtx, OStorePageObject &rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (m_aMutex);
+
+ // Check precond.
+ if (!m_xLockBytes.isValid())
+ return store_E_InvalidAccess;
+
+ // Setup PageHead.
+ OStorePageData aPageHead (OStorePageData::size());
+
+ // Check context.
+ while (rCtx.isValid())
+ {
+ // Assign next location.
+ aPageHead.location (rCtx.m_aDescr.m_nAddr);
+ rCtx.m_aDescr.m_nAddr += rCtx.m_aDescr.m_nSize;
+
+ // Load PageHead.
+ storeError eErrCode = peek (aPageHead);
+ if (eErrCode != store_E_None)
+ continue;
+
+ // Check PageHead Magic number.
+ if (aPageHead.m_aGuard.m_nMagic != rCtx.m_nMagic)
+ continue;
+
+ // Check PageHead Unused link.
+ if (aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL)
+ continue;
+
+ // Load page.
+ rPage.location (aPageHead.location());
+ eErrCode = OStorePageBIOS::load (rPage);
+ if (eErrCode != store_E_None)
+ continue;
+
+ // Deliver page.
+ return store_E_None;
+ }
+
+ // Done.
+ return store_E_CantSeek;
+}
+
+/*
+ * peek (PageHead).
+ * Internal: Precond: initialized, readable, exclusive access.
+ */
+storeError OStorePageBIOS::peek (OStorePageData &rData)
+{
+ // Save PageDescriptor.
+ OStorePageDescriptor aDescr (rData.m_aDescr);
+
+ // Read PageHead.
+ storeError eErrCode = read (aDescr.m_nAddr, &rData, rData.size());
+ if (eErrCode != store_E_None)
+ {
+ // Restore PageDescriptor.
+ rData.m_aDescr = aDescr;
+ return eErrCode;
+ }
+
+ // Verify PageHead.
+ eErrCode = rData.verify (aDescr);
+ if (eErrCode != store_E_None)
+ {
+ // Restore PageDescriptor.
+ rData.m_aDescr = aDescr;
+ return eErrCode;
+ }
+
+#ifdef OSL_BIGENDIAN
+ // Swap to internal representation.
+ rData.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Verify PageDescriptor.
+ if (!((aDescr == rData.m_aDescr) ||
+ (aDescr <= rData.m_aDescr) ))
+ return store_E_InvalidAccess;
+ else
+ return store_E_None;
+}
+
+/*
+ * poke (PageHead).
+ * Internal: Precond: initialized, writeable, exclusive access.
+ */
+storeError OStorePageBIOS::poke (OStorePageData &rData)
+{
+ // Save PageDescriptor.
+ OStorePageDescriptor aDescr (rData.m_aDescr);
+
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ rData.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Guard PageHead.
+ rData.guard (aDescr);
+
+ // Write PageHead.
+ storeError eErrCode = write (aDescr.m_nAddr, &rData, rData.size());
+
+#ifdef OSL_BIGENDIAN
+ // Swap back to internal representation.
+ rData.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Done.
+ return eErrCode;
+}
+
+/*
+ * poke (PageObject).
+ * Internal: Precond: initialized, writeable, exclusive access.
+ */
+storeError OStorePageBIOS::poke (OStorePageObject &rPage)
+{
+ // Save PageDescriptor.
+ OStorePageData &rData = rPage.getData();
+ OStorePageDescriptor aDescr (rData.m_aDescr);
+
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ rPage.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Guard page.
+ rPage.guard (aDescr);
+
+ // Write page.
+ storeError eErrCode = write (aDescr.m_nAddr, &rData, aDescr.m_nSize);
+
+#ifdef OSL_BIGENDIAN
+ // Swap back to internal representation.
+ rPage.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Mark page as clean.
+ if (eErrCode == store_E_None)
+ rPage.clean();
+
+ // Done.
+ return eErrCode;
+}
+
diff --git a/store/source/storbase.hxx b/store/source/storbase.hxx
new file mode 100644
index 000000000..843e409fb
--- /dev/null
+++ b/store/source/storbase.hxx
@@ -0,0 +1,916 @@
+/*************************************************************************
+ *
+ * $RCSfile: storbase.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORBASE_HXX_
+#define _STORE_STORBASE_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#ifndef _RTL_STRING_H_
+#include <rtl/string.h>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifndef __STORE_DELETEZ
+#define __STORE_DELETEZ(p) (delete p, p = 0)
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+/*========================================================================
+ *
+ * OStorePageGuard.
+ *
+ *======================================================================*/
+struct OStorePageGuard
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nMagic;
+ sal_uInt32 m_nCRC32;
+
+ /** Construction.
+ */
+ OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0)
+ : m_nMagic (nMagic),
+ m_nCRC32 (nCRC32)
+ {}
+
+ OStorePageGuard (const OStorePageGuard& rOther)
+ : m_nMagic (rOther.m_nMagic),
+ m_nCRC32 (rOther.m_nCRC32)
+ {}
+
+ OStorePageGuard& operator= (const OStorePageGuard& rOther)
+ {
+ m_nMagic = rOther.m_nMagic;
+ m_nCRC32 = rOther.m_nCRC32;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStorePageGuard& rOther) const
+ {
+ return ((m_nMagic == rOther.m_nMagic) &&
+ (m_nCRC32 == rOther.m_nCRC32) );
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_nMagic = VOS_SWAPDWORD(m_nMagic);
+ m_nCRC32 = VOS_SWAPDWORD(m_nCRC32);
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** CRC polynomial 0xEDB88320.
+ */
+ static const sal_uInt32 m_pTable[256];
+
+ static sal_uInt32 updcrc32 (sal_uInt32 crc, sal_uInt8 octet)
+ {
+ return m_pTable[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8);
+ }
+
+ static sal_uInt32 crc32 (
+ sal_uInt32 nCRC32, const void *pData, sal_uInt32 nSize);
+};
+
+/*========================================================================
+ *
+ * OStorePageDescriptor.
+ *
+ *======================================================================*/
+#define STORE_PAGE_NULL ((sal_uInt32)(~0))
+
+struct OStorePageDescriptor
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nAddr;
+ sal_uInt16 m_nSize;
+ sal_uInt16 m_nUsed;
+
+ /** Construction.
+ */
+ OStorePageDescriptor (
+ sal_uInt32 nAddr = STORE_PAGE_NULL,
+ sal_uInt16 nSize = 0,
+ sal_uInt16 nUsed = 0)
+ : m_nAddr (nAddr),
+ m_nSize (nSize),
+ m_nUsed (nUsed)
+ {}
+
+ OStorePageDescriptor (const OStorePageDescriptor& rOther)
+ : m_nAddr (rOther.m_nAddr),
+ m_nSize (rOther.m_nSize),
+ m_nUsed (rOther.m_nUsed)
+ {}
+
+ OStorePageDescriptor& operator= (const OStorePageDescriptor& rOther)
+ {
+ m_nAddr = rOther.m_nAddr;
+ m_nSize = rOther.m_nSize;
+ m_nUsed = rOther.m_nUsed;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStorePageDescriptor& rOther) const
+ {
+ return ((m_nAddr == rOther.m_nAddr) &&
+ (m_nSize == rOther.m_nSize) );
+ }
+
+ sal_Bool operator<= (const OStorePageDescriptor& rOther) const
+ {
+ return ((m_nAddr == rOther.m_nAddr) &&
+ (m_nSize <= rOther.m_nSize) );
+ }
+
+ sal_Bool operator< (const OStorePageDescriptor& rOther) const
+ {
+ if (m_nAddr == rOther.m_nAddr)
+ return (m_nSize < rOther.m_nSize);
+ else
+ return (m_nAddr < rOther.m_nAddr);
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_nAddr = VOS_SWAPDWORD(m_nAddr);
+ m_nSize = VOS_SWAPWORD(m_nSize);
+ m_nUsed = VOS_SWAPWORD(m_nUsed);
+#endif /* OSL_BIGENDIAN */
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageKey.
+ *
+ *======================================================================*/
+struct OStorePageKey
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nLow;
+ sal_uInt32 m_nHigh;
+
+ /** Construction.
+ */
+ OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
+ : m_nLow (nLow), m_nHigh (nHigh)
+ {}
+
+ OStorePageKey (const OStorePageKey& rOther)
+ : m_nLow (rOther.m_nLow), m_nHigh (rOther.m_nHigh)
+ {}
+
+ OStorePageKey& operator= (const OStorePageKey& rOther)
+ {
+ m_nLow = rOther.m_nLow;
+ m_nHigh = rOther.m_nHigh;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStorePageKey& rOther) const
+ {
+ return ((m_nLow == rOther.m_nLow ) &&
+ (m_nHigh == rOther.m_nHigh) );
+ }
+
+ sal_Bool operator< (const OStorePageKey& rOther) const
+ {
+ if (m_nHigh == rOther.m_nHigh)
+ return (m_nLow < rOther.m_nLow);
+ else
+ return (m_nHigh < rOther.m_nHigh);
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_nLow = VOS_SWAPDWORD(m_nLow);
+ m_nHigh = VOS_SWAPDWORD(m_nHigh);
+#endif /* OSL_BIGENDIAN */
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageLink.
+ *
+ *======================================================================*/
+struct OStorePageLink
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nAddr;
+
+ /** Construction.
+ */
+ OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
+ : m_nAddr (nAddr)
+ {}
+
+ OStorePageLink (const OStorePageLink& rOther)
+ : m_nAddr (rOther.m_nAddr)
+ {}
+
+ OStorePageLink& operator= (const OStorePageLink& rOther)
+ {
+ m_nAddr = rOther.m_nAddr;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStorePageLink& rOther) const
+ {
+ return (m_nAddr == rOther.m_nAddr);
+ }
+
+ sal_Bool operator< (const OStorePageLink& rOther) const
+ {
+ return (m_nAddr < rOther.m_nAddr);
+ }
+
+ /** Operation.
+ */
+ void link (OStorePageLink& rPred)
+ {
+ OStorePageLink tmp (rPred);
+ rPred = *this;
+ *this = tmp;
+ }
+
+ void unlink (OStorePageLink& rPred)
+ {
+ rPred = *this;
+ *this = OStorePageLink();
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_nAddr = VOS_SWAPDWORD(m_nAddr);
+#endif /* OSL_BIGENDIAN */
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageNameBlock.
+ *
+ *======================================================================*/
+struct OStorePageNameBlock
+{
+ typedef OStorePageGuard G;
+ typedef OStorePageKey K;
+
+ /** Representation.
+ */
+ G m_aGuard;
+ K m_aKey;
+ sal_uInt32 m_nAttrib;
+ sal_Char m_pData[STORE_MAXIMUM_NAMESIZE];
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (sizeof(G) + sizeof(K) + sizeof(sal_uInt32) +
+ sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE]));
+ }
+
+ /** initialize.
+ */
+ void initialize (void)
+ {
+ m_aGuard = G();
+ m_aKey = K();
+ m_nAttrib = 0;
+ rtl_zeroMemory (m_pData, sizeof(m_pData));
+ }
+
+ /** Construction.
+ */
+ OStorePageNameBlock (void)
+ : m_nAttrib (0)
+ {
+ rtl_zeroMemory (m_pData, sizeof(m_pData));
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStorePageNameBlock& rOther) const
+ {
+ return (m_aGuard == rOther.m_aGuard);
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aGuard.swap();
+ m_aKey.swap();
+ m_nAttrib = VOS_SWAPDWORD(m_nAttrib);
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** guard (external representation).
+ */
+ void guard (void)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aKey, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ m_aGuard.m_nCRC32 = nCRC32;
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (void)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aKey, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ if (m_aGuard.m_nCRC32 != nCRC32)
+ return store_E_InvalidChecksum;
+ else
+ return store_E_None;
+ }
+
+ /** namei.
+ */
+ static storeError namei (
+ const rtl_String *pPath, const rtl_String *pName, K &rKey)
+ {
+ // Check parameter.
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+ // Check name length.
+ if (!(pName->length < sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE])))
+ return store_E_NameTooLong;
+
+ // Transform pathname into key.
+ rKey.m_nLow = G::crc32 (0, pName->buffer, pName->length);
+ rKey.m_nHigh = G::crc32 (0, pPath->buffer, pPath->length);
+
+ // Done.
+ return store_E_None;
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageData.
+ *
+ *======================================================================*/
+struct OStorePageData
+{
+ typedef OStorePageGuard G;
+ typedef OStorePageDescriptor D;
+ typedef OStorePageLink L;
+
+ /** Representation.
+ */
+ G m_aGuard;
+ D m_aDescr;
+ L m_aMarked;
+ L m_aUnused;
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (sizeof(G) + sizeof(D) + 2 * sizeof(L));
+ }
+
+ /** location.
+ */
+ sal_uInt32 location (void) const
+ {
+ return m_aDescr.m_nAddr;
+ }
+
+ void location (sal_uInt32 nAddr)
+ {
+ m_aDescr.m_nAddr = nAddr;
+ }
+
+ /** Allocation.
+ */
+ static void* operator new (size_t n)
+ {
+ return rtl_allocateMemory (n);
+ }
+
+ static void* operator new (size_t n, sal_uInt16 nPageSize)
+ {
+ return rtl_allocateMemory (nPageSize);
+ }
+
+ static void operator delete (void *p)
+ {
+ rtl_freeMemory (p);
+ }
+
+ /** Construction.
+ */
+ OStorePageData (sal_uInt16 nPageSize)
+ {
+ m_aDescr.m_nSize = nPageSize;
+ m_aDescr.m_nUsed = size();
+ }
+
+ OStorePageData& operator= (const OStorePageData& rOther)
+ {
+ m_aGuard = rOther.m_aGuard;
+ m_aDescr = rOther.m_aDescr;
+ m_aMarked = rOther.m_aMarked;
+ m_aUnused = rOther.m_aUnused;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStorePageData& rOther) const
+ {
+ return ((m_aGuard == rOther.m_aGuard ) &&
+ (m_aDescr == rOther.m_aDescr ) &&
+ (m_aMarked == rOther.m_aMarked) &&
+ (m_aUnused == rOther.m_aUnused) );
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (const D& rDescr)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aGuard.swap();
+ m_aDescr.swap();
+ m_aMarked.swap();
+ m_aUnused.swap();
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** guard (external representation).
+ */
+ void guard (const D& rDescr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ m_aGuard.m_nCRC32 = nCRC32;
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (const D& rDescr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ if (m_aGuard.m_nCRC32 != nCRC32)
+ return store_E_InvalidChecksum;
+ else
+ return store_E_None;
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageObject.
+ *
+ *======================================================================*/
+class OStorePageObject
+{
+ typedef OStorePageData page;
+ typedef OStorePageDescriptor D;
+
+public:
+ /** Construction.
+ */
+ inline OStorePageObject (page& rPage);
+
+ /** Destruction.
+ */
+ virtual ~OStorePageObject (void);
+
+ /** External representation.
+ */
+ virtual void swap (const D& rDescr);
+ virtual void guard (const D& rDescr);
+ virtual storeError verify (const D& rDescr);
+
+ /** Data.
+ */
+ inline OStorePageData& getData (void);
+
+ /** State.
+ */
+ inline sal_Bool dirty (void) const;
+ inline void clean (void);
+ inline void touch (void);
+
+ /** Location.
+ */
+ inline sal_uInt32 location (void) const;
+ inline void location (sal_uInt32 nAddr);
+
+private:
+ /** Representation.
+ */
+ page &m_rPage;
+ sal_Bool m_bDirty;
+};
+
+inline OStorePageObject::OStorePageObject (page& rPage)
+ : m_rPage (rPage), m_bDirty (sal_False)
+{
+}
+
+inline OStorePageData& OStorePageObject::getData (void)
+{
+ return m_rPage;
+}
+
+inline sal_Bool OStorePageObject::dirty (void) const
+{
+ return m_bDirty;
+}
+
+inline void OStorePageObject::clean (void)
+{
+ m_bDirty = sal_False;
+}
+
+inline void OStorePageObject::touch (void)
+{
+ m_bDirty = sal_True;
+}
+
+inline sal_uInt32 OStorePageObject::location (void) const
+{
+ return m_rPage.location();
+}
+
+inline void OStorePageObject::location (sal_uInt32 nAddr)
+{
+ m_rPage.location (nAddr);
+ touch();
+}
+
+#define STORE_METHOD_ENTER(pMutex) \
+ if ((pMutex)) (pMutex)->acquire()
+
+#define STORE_METHOD_LEAVE(pMutex, eErrCode) \
+{ \
+ if ((pMutex)) (pMutex)->release(); \
+ return (eErrCode); \
+}
+
+/*========================================================================
+ *
+ * OStorePageBIOS.
+ *
+ *======================================================================*/
+struct OStoreSuperBlockPage;
+struct OStorePageACL;
+
+class OStorePageBIOS : public NAMESPACE_STORE(OStoreObject)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OStorePageBIOS, store));
+
+public:
+ /** Construction.
+ */
+ OStorePageBIOS (void);
+
+ /** Conversion into IMutex&
+ */
+ inline operator NAMESPACE_VOS(IMutex)& (void) const;
+
+ /** Initialization.
+ * @param pLockBytes [in]
+ * @param eAccessMode [in]
+ * @return store_E_None upon success
+ */
+ virtual storeError initialize (
+ ILockBytes *pLockBytes,
+ storeAccessMode eAccessMode);
+
+ /** getPageSize.
+ */
+ storeError getPageSize (sal_uInt16 &rnPageSize);
+
+ /** acquireLock.
+ */
+ storeError acquireLock (
+ sal_uInt32 nAddr, sal_uInt32 nSize);
+
+ /** releaseLock.
+ */
+ storeError releaseLock (
+ sal_uInt32 nAddr, sal_uInt32 nSize);
+
+ /** read.
+ */
+ storeError read (
+ sal_uInt32 nAddr, void *pData, sal_uInt32 nSize);
+
+ /** write.
+ */
+ storeError write (
+ sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize);
+
+ /** isModified.
+ */
+ inline sal_Bool isModified (void) const;
+
+ /** isWriteable.
+ */
+ inline sal_Bool isWriteable (void) const;
+
+ /** isValid.
+ */
+ inline sal_Bool isValid (void) const;
+
+ /** Page Access.
+ */
+ storeError acquirePage (
+ const OStorePageDescriptor& rDescr, storeAccessMode eMode);
+
+ storeError releasePage (
+ const OStorePageDescriptor& rDescr, storeAccessMode eMode);
+
+ sal_uInt32 getRefererCount (void);
+
+ /** Page Allocation.
+ */
+ enum Allocation
+ {
+ ALLOCATE_FIRST = 0,
+ ALLOCATE_BEST = 1,
+ ALLOCATE_EOF = 2
+ };
+
+ storeError allocate (
+ OStorePageObject& rPage, Allocation eAllocation = ALLOCATE_FIRST);
+
+ virtual storeError free (
+ OStorePageObject& rPage);
+
+ /** Page I/O.
+ */
+ virtual storeError load (
+ OStorePageObject& rPage);
+
+ virtual storeError save (
+ OStorePageObject& rPage);
+
+ /** close.
+ * @return store_E_None upon success.
+ */
+ virtual storeError close (void);
+
+ /** flush.
+ * @return store_E_None upon success.
+ */
+ virtual storeError flush (void);
+
+ /** size.
+ */
+ storeError size (sal_uInt32 &rnSize);
+
+ /** ScanContext.
+ */
+ struct ScanContext
+ {
+ /** Representation.
+ */
+ OStorePageDescriptor m_aDescr;
+ sal_uInt32 m_nSize;
+ sal_uInt32 m_nMagic;
+
+ /** Construction.
+ */
+ inline ScanContext (void);
+
+ /** isValid.
+ */
+ inline sal_Bool isValid (void) const;
+ };
+
+ /** scanBegin.
+ */
+ storeError scanBegin (
+ ScanContext &rCtx,
+ sal_uInt32 nMagic = 0);
+
+ /** scanNext.
+ */
+ storeError scanNext (
+ ScanContext &rCtx,
+ OStorePageObject &rPage);
+
+protected:
+ /** Destruction (OReference).
+ */
+ virtual ~OStorePageBIOS (void);
+
+ /** create (SuperBlock).
+ */
+ storeError create (
+ sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE);
+
+ /** Page Maintenance.
+ */
+ storeError peek (
+ OStorePageData &rData);
+ storeError poke (
+ OStorePageData &rData);
+ storeError poke (
+ OStorePageObject &rPage);
+
+private:
+ /** Representation.
+ */
+ NAMESPACE_VOS(ORef)<ILockBytes> m_xLockBytes;
+ NAMESPACE_VOS(OMutex) m_aMutex;
+ OStorePageACL *m_pAcl;
+
+ typedef OStoreSuperBlockPage SuperPage;
+ SuperPage *m_pSuper;
+
+ sal_Bool m_bModified : 1;
+ sal_Bool m_bWriteable : 1;
+
+ /** SuperBlock verification and repair.
+ */
+ storeError verify (SuperPage *&rpSuper);
+ storeError repair (SuperPage *&rpSuper);
+
+ /** Not implemented.
+ */
+ OStorePageBIOS (const OStorePageBIOS&);
+ OStorePageBIOS& operator= (const OStorePageBIOS&);
+};
+
+inline OStorePageBIOS::operator NAMESPACE_VOS(IMutex)& (void) const
+{
+ return (NAMESPACE_VOS(IMutex)&)m_aMutex;
+}
+inline sal_Bool OStorePageBIOS::isModified (void) const
+{
+ return m_bModified;
+}
+inline sal_Bool OStorePageBIOS::isWriteable (void) const
+{
+ return m_bWriteable;
+}
+inline sal_Bool OStorePageBIOS::isValid (void) const
+{
+ return m_xLockBytes.isValid();
+}
+
+inline OStorePageBIOS::ScanContext::ScanContext (void)
+ : m_aDescr (0, 0, 0), m_nSize (0), m_nMagic (0)
+{
+}
+inline sal_Bool OStorePageBIOS::ScanContext::isValid (void) const
+{
+ return (m_aDescr.m_nAddr < m_nSize);
+}
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORBASE_HXX_ */
+
diff --git a/store/source/storcach.cxx b/store/source/storcach.cxx
new file mode 100644
index 000000000..c0d1bad7a
--- /dev/null
+++ b/store/source/storcach.cxx
@@ -0,0 +1,696 @@
+/*************************************************************************
+ *
+ * $RCSfile: storcach.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORCACH_CXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORCACH_HXX_
+#include <storcach.hxx>
+#endif
+
+#include <string.h>
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStorePageCache internals.
+ *
+ *======================================================================*/
+/*
+ * __store_memcpy.
+ */
+inline void __store_memcpy (void *dst, const void *src, sal_uInt32 n)
+{
+ // rtl_copyMemory (dst, src, n);
+ ::memcpy (dst, src, n);
+}
+
+/*========================================================================
+ *
+ * OStorePageCacheEntry.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+struct OStorePageCacheEntry
+{
+ typedef OStorePageCacheEntry self;
+ typedef OStorePageData data;
+ typedef OStorePageDescriptor D;
+
+ /** Representation.
+ */
+ D m_aDescr;
+ data *m_pData;
+ self *m_pNext;
+ self *m_pPrev;
+
+ /** Construction.
+ */
+ OStorePageCacheEntry (const D& rDescr, const data& rData)
+ : m_aDescr (rDescr), m_pData (NULL), m_pNext (this), m_pPrev (this)
+ {
+ sal_uInt16 nSize = m_aDescr.m_nSize;
+ m_pData = new(nSize) data(nSize);
+ __store_memcpy (m_pData, &rData, nSize);
+ }
+
+ /** Data assignment.
+ */
+ void assign (const D& rDescr, const data& rData)
+ {
+ m_aDescr.m_nAddr = rDescr.m_nAddr;
+ if (!(m_aDescr.m_nSize == rDescr.m_nSize))
+ {
+ delete m_pData;
+ m_pData = new(rDescr.m_nSize) data(rDescr.m_nSize);
+ m_aDescr.m_nSize = rDescr.m_nSize;
+ }
+ __store_memcpy (m_pData, &rData, m_aDescr.m_nSize);
+ }
+
+ /** Destruction.
+ */
+ ~OStorePageCacheEntry (void)
+ {
+ delete m_pData;
+ }
+
+ /** Comparison.
+ */
+ enum CompareResult
+ {
+ COMPARE_LESS = -1,
+ COMPARE_EQUAL = 0,
+ COMPARE_GREATER = 1
+ };
+
+ CompareResult compare (const D& rDescr) const
+ {
+ if (m_aDescr.m_nAddr == rDescr.m_nAddr)
+ return COMPARE_EQUAL;
+ if (m_aDescr.m_nAddr < rDescr.m_nAddr)
+ return COMPARE_LESS;
+ else
+ return COMPARE_GREATER;
+ }
+
+ CompareResult compare (const self& rOther) const
+ {
+ return compare (rOther.m_aDescr);
+ }
+
+ /** Address operation.
+ */
+ void invalidate (void)
+ {
+ m_aDescr.m_nAddr = STORE_PAGE_NULL;
+ }
+
+ sal_Bool isValid (void) const
+ {
+ return (m_aDescr.m_nAddr != STORE_PAGE_NULL);
+ }
+
+ /** Index operation.
+ */
+ sal_uInt16 index (void) const
+ {
+ return (m_aDescr.m_nUsed & 0x7fff);
+ }
+
+ void index (sal_uInt16 nIndex)
+ {
+ m_aDescr.m_nUsed = ((m_aDescr.m_nUsed & 0x8000) | (nIndex & 0x7fff));
+ }
+
+ /** DirtyBit operation.
+ */
+ void clean (void)
+ {
+ m_aDescr.m_nUsed &= 0x7fff;
+ }
+
+ void dirty (void)
+ {
+ m_aDescr.m_nUsed |= 0x8000;
+ }
+
+ sal_Bool isDirty (void) const
+ {
+ return ((m_aDescr.m_nUsed & 0x8000) == 0x8000);
+ }
+
+ /** List operation.
+ */
+ void backlink (self& rOther)
+ {
+ rOther.m_pNext = this;
+ rOther.m_pPrev = m_pPrev;
+ m_pPrev = &rOther;
+ rOther.m_pPrev->m_pNext = &rOther;
+ }
+
+ void unlink (void)
+ {
+ m_pNext->m_pPrev = m_pPrev;
+ m_pPrev->m_pNext = m_pNext;
+ m_pNext = this;
+ m_pPrev = this;
+ }
+};
+
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+/*========================================================================
+ *
+ * OStorePageCache debug internals.
+ *
+ *======================================================================*/
+/*
+ * __store_check_entry.
+ */
+static sal_Bool __store_check_entry (
+ OStorePageCacheEntry **ppData, sal_uInt16 nUsed)
+{
+ if (nUsed > 1)
+ {
+ for (sal_uInt16 i = 0; i < nUsed - 1; i++)
+ {
+ sal_uInt32 ai = ppData[i ]->m_aDescr.m_nAddr;
+ sal_uInt32 ak = ppData[i + 1]->m_aDescr.m_nAddr;
+ if (!(ai <= ak))
+ return sal_False;
+ if (!(i == ppData[i]->index()))
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+
+/*
+ * __store_find_entry.
+ */
+static sal_uInt16 __store_find_entry (
+ const OStorePageDescriptor &rDescr,
+ const OStorePageCacheEntry *pHead)
+{
+ if (pHead)
+ {
+ if (pHead->m_aDescr.m_nAddr == rDescr.m_nAddr)
+ return pHead->index();
+
+ OStorePageCacheEntry *pEntry = pHead->m_pNext;
+ while (pEntry != pHead)
+ {
+ if (pEntry->m_aDescr.m_nAddr == rDescr.m_nAddr)
+ return pEntry->index();
+ else
+ pEntry = pEntry->m_pNext;
+ }
+ }
+ return ((sal_uInt16)(-1));
+}
+
+/*========================================================================
+ *
+ * OStorePageCache implementation.
+ *
+ * (two-way association (sorted address array, LRU chain)).
+ * (external OStorePageData representation).
+ *
+ *======================================================================*/
+/*
+ * OStorePageCache.
+ */
+OStorePageCache::OStorePageCache (sal_uInt16 nPages)
+ : m_nSize (STORE_LIMIT_CACHEPAGES),
+ m_nUsed (0),
+ m_pHead (0),
+ m_nHit (0),
+ m_nMissed (0),
+ m_nUpdHit (0),
+ m_nUpdLRU (0),
+ m_nWrtBack (0)
+{
+ for (sal_uInt16 i = 0; i < m_nSize; i++)
+ m_pData[i] = NULL;
+ if (nPages < m_nSize)
+ m_nSize = nPages;
+}
+
+/*
+ * ~OStorePageCache.
+ */
+OStorePageCache::~OStorePageCache (void)
+{
+ double x = hitRatio();
+ for (sal_uInt16 i = 0; i < m_nSize; i++)
+ delete m_pData[i];
+}
+
+/*
+ * find.
+ */
+sal_uInt16 OStorePageCache::find (const OStorePageDescriptor &rDescr) const
+{
+ register sal_Int32 l = 0;
+ register sal_Int32 r = m_nUsed - 1;
+
+ while (l < r)
+ {
+ register sal_Int32 m = ((l + r) >> 1);
+
+ if (m_pData[m]->m_aDescr.m_nAddr == rDescr.m_nAddr)
+ return ((sal_uInt16)(m));
+ if (m_pData[m]->m_aDescr.m_nAddr < rDescr.m_nAddr)
+ l = m + 1;
+ else
+ r = m - 1;
+ }
+
+ // Match or insert position. Caller must do final compare.
+ return ((sal_uInt16)(r));
+}
+
+/*
+ * move.
+ */
+void OStorePageCache::move (sal_uInt16 nSI, sal_uInt16 nDI)
+{
+ entry *p = m_pData[nSI];
+ if (nSI < nDI)
+ {
+ // shift left.
+ rtl_moveMemory (
+ &m_pData[nSI ],
+ &m_pData[nSI + 1],
+ (nDI - nSI) * sizeof(entry*));
+
+ // re-index.
+ for (sal_uInt16 i = nSI; i < nDI; i++)
+ m_pData[i]->index(i);
+ }
+ if (nSI > nDI)
+ {
+ // shift right.
+ rtl_moveMemory (
+ &m_pData[nDI + 1],
+ &m_pData[nDI ],
+ (nSI - nDI) * sizeof(entry*));
+
+ // re-index.
+ for (sal_uInt16 i = nSI; i > nDI; i--)
+ m_pData[i]->index(i);
+ }
+ m_pData[nDI] = p;
+ m_pData[nDI]->index(nDI);
+
+#if 0 /* DEBUG */
+ VOS_POSTCOND(
+ __store_check_entry(&m_pData[0], m_nUsed),
+ "OStorePageCache::move(): check_entry() failed");
+#endif /* DEBUG */
+}
+
+/*
+ * insert.
+ */
+storeError OStorePageCache::insert (
+ sal_uInt16 nDI,
+ const OStorePageDescriptor &rDescr,
+ const OStorePageData &rData,
+ OStorePageBIOS &rBIOS,
+ InsertMode eMode)
+{
+#if 0 /* DEBUG */
+ VOS_PRECOND(
+ __store_check_entry(&m_pData[0], m_nUsed),
+ "OStorePageCache::insert(): check_entry() failed");
+#endif /* DEBUG */
+
+ entry::CompareResult result = entry::COMPARE_EQUAL;
+ if (nDI < m_nUsed)
+ {
+ result = m_pData[nDI]->compare (rDescr);
+ if (result == entry::COMPARE_LESS)
+ nDI += 1;
+ }
+
+ if (nDI == (sal_uInt16)(-1))
+ nDI = 0;
+ if (nDI == m_nSize)
+ nDI -= 1;
+
+ if (m_nUsed < m_nSize)
+ {
+ // Allocate cache entry.
+ m_pData[m_nUsed] = new entry (rDescr, rData);
+ move (m_nUsed, nDI);
+ m_nUsed++;
+
+ // Update LRU.
+ if (m_pHead)
+ m_pHead->backlink (*m_pData[nDI]);
+ m_pHead = m_pData[nDI];
+ }
+ else
+ {
+ // Check for invalidated cache entry.
+ sal_uInt16 nSI = m_nUsed - 1;
+ if (m_pData[nSI]->isValid())
+ {
+ // Replace least recently used cache entry.
+ m_nUpdLRU++;
+
+ m_pHead = m_pHead->m_pPrev;
+ nSI = m_pHead->index();
+
+ // Check DirtyBit.
+ if (m_pHead->isDirty())
+ {
+ // Save PageDescriptor.
+ OStorePageDescriptor aDescr (m_pHead->m_aDescr);
+
+ // Write page.
+ storeError eErrCode = rBIOS.write (
+ aDescr.m_nAddr, m_pHead->m_pData, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Mark as clean.
+ m_pHead->clean();
+ m_nWrtBack++;
+ }
+ }
+ else
+ {
+ // Replace invalidated cache entry. Check LRU.
+ if (!(m_pData[nSI] == m_pHead))
+ {
+ // Update LRU.
+ m_pData[nSI]->unlink();
+ m_pHead->backlink (*m_pData[nSI]);
+ m_pHead = m_pData[nSI];
+ }
+ }
+
+ // Check source and destination indices.
+ if (nSI < nDI)
+ {
+ result = m_pData[nDI]->compare(rDescr);
+ if (result == entry::COMPARE_GREATER)
+ nDI -= 1;
+ }
+
+ // Assign data.
+ m_pData[nSI]->assign (rDescr, rData);
+ move (nSI, nDI);
+ }
+
+ // Check InsertMode.
+ if (eMode == INSERT_CLEAN)
+ m_pHead->clean();
+ else
+ m_pHead->dirty();
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * load.
+ */
+storeError OStorePageCache::load (
+ const OStorePageDescriptor &rDescr,
+ OStorePageData &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Find cache index.
+ sal_uInt16 i = find (rDescr);
+ if (i < m_nUsed)
+ {
+ if (m_pData[i]->compare(rDescr) == entry::COMPARE_EQUAL)
+ {
+ // Cache hit.
+ m_nHit++;
+
+ if (!(m_pData[i] == m_pHead))
+ {
+ // Update LRU.
+ m_pData[i]->unlink();
+ m_pHead->backlink (*m_pData[i]);
+ m_pHead = m_pData[i];
+ }
+
+ // Load data and Leave.
+ __store_memcpy (&rData, m_pHead->m_pData, rDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, store_E_None);
+ }
+ }
+
+ // Cache miss.
+ m_nMissed++;
+
+ // Load data.
+ storeError eErrCode = rBIOS.read (
+ rDescr.m_nAddr, &rData, rDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Insert data.
+ eErrCode = insert (i, rDescr, rData, rBIOS, INSERT_CLEAN);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Leave with pending verification.
+ STORE_METHOD_LEAVE(pMutex, store_E_Pending);
+}
+
+/*
+ * update.
+ */
+storeError OStorePageCache::update (
+ const OStorePageDescriptor &rDescr,
+ const OStorePageData &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex,
+ UpdateMode eMode)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check UpdateMode.
+ if (eMode == UPDATE_WRITE_THROUGH)
+ {
+ // Save data.
+ storeError eErrCode = rBIOS.write (
+ rDescr.m_nAddr, &rData, rDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ m_nWrtBack++;
+ }
+
+ // Find cache index.
+ sal_uInt16 i = find (rDescr);
+ if (i < m_nUsed)
+ {
+ if (m_pData[i]->compare(rDescr) == entry::COMPARE_EQUAL)
+ {
+ // Cache hit. Check LRU.
+ m_nUpdHit++;
+ if (!(m_pData[i] == m_pHead))
+ {
+ // Update LRU.
+ m_pData[i]->unlink();
+ m_pHead->backlink (*m_pData[i]);
+ m_pHead = m_pData[i];
+ }
+
+ // Check UpdateMode.
+ if (eMode == UPDATE_WRITE_THROUGH)
+ m_pHead->clean();
+ else
+ m_pHead->dirty();
+
+ // Update data and leave.
+ __store_memcpy (m_pHead->m_pData, &rData, rDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, store_E_None);
+ }
+ }
+
+ // Cache miss. Insert data and leave.
+ storeError eErrCode = insert (
+ i, rDescr, rData, rBIOS,
+ ((eMode == UPDATE_WRITE_THROUGH) ? INSERT_CLEAN : INSERT_DIRTY));
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * invalidate.
+ */
+storeError OStorePageCache::invalidate (
+ const OStorePageDescriptor &rDescr,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Find cache index.
+ sal_uInt16 i = find (rDescr);
+ if (i < m_nUsed)
+ {
+ if (m_pData[i]->compare(rDescr) == entry::COMPARE_EQUAL)
+ {
+ // Cache hit. Update LRU.
+ if (!(m_pData[i] == m_pHead))
+ {
+ m_pData[i]->unlink();
+ m_pHead->backlink (*m_pData[i]);
+ }
+ else
+ {
+ m_pHead = m_pHead->m_pNext;
+ }
+
+ // Invalidate.
+ m_pData[i]->clean();
+ m_pData[i]->invalidate();
+ move (i, m_nUsed - 1);
+ }
+ }
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, store_E_None);
+}
+
+/*
+ * flush.
+ */
+storeError OStorePageCache::flush (
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check all entries.
+ for (sal_uInt16 i = 0; i < m_nUsed; i++)
+ {
+ // Check for dirty entry.
+ if (m_pData[i]->isDirty() && m_pData[i]->isValid())
+ {
+ // Save PageDescriptor.
+ OStorePageDescriptor aDescr (m_pData[i]->m_aDescr);
+
+ // Write page.
+ storeError eErrCode = rBIOS.write (
+ aDescr.m_nAddr, m_pData[i]->m_pData, aDescr.m_nSize);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageCache::flush(): write() failed");
+
+ // Mark entry clean.
+ if (eErrCode == store_E_None)
+ m_pData[i]->clean();
+ m_nWrtBack++;
+ }
+ }
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, store_E_None);
+}
+
diff --git a/store/source/storcach.hxx b/store/source/storcach.hxx
new file mode 100644
index 000000000..b5d13003b
--- /dev/null
+++ b/store/source/storcach.hxx
@@ -0,0 +1,231 @@
+/*************************************************************************
+ *
+ * $RCSfile: storcach.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORCACH_HXX
+#define _STORE_STORCACH_HXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+struct OStorePageDescriptor;
+struct OStorePageData;
+class OStorePageBIOS;
+
+/*========================================================================
+ *
+ * OStorePageCache interface.
+ * (OStorePageData in external representation)
+ *
+ *======================================================================*/
+#define STORE_DEFAULT_CACHEPAGES 128
+#define STORE_LIMIT_CACHEPAGES 256
+
+struct OStorePageCacheEntry;
+
+class OStorePageCache
+{
+ typedef OStorePageCacheEntry entry;
+
+public:
+ /** Construction.
+ */
+ OStorePageCache (
+ sal_uInt16 nPages = STORE_DEFAULT_CACHEPAGES);
+
+ /** Destruction.
+ */
+ ~OStorePageCache (void);
+
+ /** load.
+ */
+ storeError load (
+ const OStorePageDescriptor &rDescr,
+ OStorePageData &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** update.
+ */
+ enum UpdateMode
+ {
+ UPDATE_WRITE_THROUGH = 0,
+ UPDATE_WRITE_DELAYED = 1
+ };
+
+ storeError update (
+ const OStorePageDescriptor &rDescr,
+ const OStorePageData &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL,
+ UpdateMode eMode = UPDATE_WRITE_THROUGH);
+
+ /** invalidate.
+ */
+ storeError invalidate (
+ const OStorePageDescriptor &rDescr,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** flush.
+ */
+ storeError flush (
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** hitRatio [nHit / (nHit + nMissed)].
+ */
+ inline double hitRatio (void) const;
+
+ /** usageRatio [nUsed / nSize].
+ */
+ inline double usageRatio (void) const;
+
+private:
+ /** Representation.
+ */
+ sal_uInt16 m_nSize;
+ sal_uInt16 m_nUsed;
+ entry *m_pData[STORE_LIMIT_CACHEPAGES];
+ entry *m_pHead;
+
+ sal_uInt32 m_nHit;
+ sal_uInt32 m_nMissed;
+ sal_uInt32 m_nUpdHit;
+ sal_uInt32 m_nUpdLRU;
+ sal_uInt32 m_nWrtBack;
+
+ /** Implementation.
+ */
+ sal_uInt16 find (const OStorePageDescriptor &rDescr) const;
+ void move (sal_uInt16 nSI, sal_uInt16 nDI);
+
+ /** insert.
+ */
+ enum InsertMode
+ {
+ INSERT_CLEAN = 0,
+ INSERT_DIRTY = 1
+ };
+
+ storeError insert (
+ sal_uInt16 nIndex,
+ const OStorePageDescriptor &rDescr,
+ const OStorePageData &rData,
+ OStorePageBIOS &rBIOS,
+ InsertMode eMode = INSERT_CLEAN);
+
+ /** Not implemented.
+ */
+ OStorePageCache (const OStorePageCache& rOther);
+ OStorePageCache& operator= (const OStorePageCache& rOther);
+};
+
+/*
+ * hitRatio [nHit / (nHit + nMissed)].
+ */
+inline double OStorePageCache::hitRatio (void) const
+{
+ if (m_nHit || m_nMissed)
+ return ((double)m_nHit / (double)(m_nHit + m_nMissed));
+ else
+ return 1.0;
+}
+
+/*
+ * usageRatio [nUsed / nSize].
+ */
+inline double OStorePageCache::usageRatio (void) const
+{
+ if (m_nUsed < m_nSize)
+ return ((double)m_nUsed / (double)m_nSize);
+ else
+ return 1.0;
+}
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORCACH_HXX */
+
diff --git a/store/source/stordata.cxx b/store/source/stordata.cxx
new file mode 100644
index 000000000..06078297b
--- /dev/null
+++ b/store/source/stordata.cxx
@@ -0,0 +1,1754 @@
+/*************************************************************************
+ *
+ * $RCSfile: stordata.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORDATA_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORDATA_HXX_
+#include <stordata.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStoreIndirectionPageData implementation.
+ *
+ *======================================================================*/
+/*
+ * OStoreIndirectionPageData.
+ */
+OStoreIndirectionPageData::OStoreIndirectionPageData (sal_uInt16 nPageSize)
+ : OStorePageData (nPageSize)
+{
+ initialize();
+}
+
+/*
+ * initialize.
+ */
+void OStoreIndirectionPageData::initialize (void)
+{
+ base::m_aGuard.m_nMagic = STORE_MAGIC_INDIRECTPAGE;
+ base::m_aDescr.m_nUsed += self::size();
+ self::m_aGuard.m_nMagic = 0;
+
+ sal_uInt16 i, n = capacityCount();
+ for (i = 0; i < n; i++)
+ m_pData[i] = STORE_PAGE_NULL;
+}
+
+/*
+ * swap.
+ */
+void OStoreIndirectionPageData::swap (const D& rDescr)
+{
+#ifdef OSL_BIGENDIAN
+ m_aGuard.swap();
+
+ sal_uInt16 i, n = capacityCount (rDescr);
+ for (i = 0; i < n; i++)
+ m_pData[i] = VOS_SWAPDWORD(m_pData[i]);
+#endif /* OSL_BIGENDIAN */
+}
+
+/*========================================================================
+ *
+ * OStoreIndirectionPageObject implementation.
+ *
+ *======================================================================*/
+/*
+ * swap.
+ */
+void OStoreIndirectionPageObject::swap (const D& rDescr)
+{
+#ifdef OSL_BIGENDIAN
+ base::swap (rDescr);
+ m_rPage.swap (rDescr);
+#endif /* OSL_BIGENDIAN */
+}
+
+/*
+ * guard.
+ */
+void OStoreIndirectionPageObject::guard (const D& rDescr)
+{
+ base::guard (rDescr);
+ m_rPage.guard (rDescr);
+}
+
+/*
+ * verify.
+ */
+storeError OStoreIndirectionPageObject::verify (const D& rDescr)
+{
+ storeError eErrCode = base::verify (rDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ else
+ return m_rPage.verify (rDescr);
+}
+
+/*
+ * get (single indirect).
+ */
+storeError OStoreIndirectionPageObject::get (
+ sal_uInt16 nSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ if (!(nSingle < m_rPage.capacityCount()))
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+
+ // Obtain data page location.
+ sal_uInt32 nAddr = m_rPage.m_pData[nSingle];
+ if (nAddr == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ // Load data page.
+ rData.location (nAddr);
+ storeError eErrCode = rBIOS.load (rData);
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * get (double indirect).
+ */
+storeError OStoreIndirectionPageObject::get (
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ if (!((nDouble < m_rPage.capacityCount()) &&
+ (nSingle < m_rPage.capacityCount()) ))
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+
+ // Check single indirect page location.
+ if (m_rPage.m_pData[nDouble] == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ // Check single indirect page buffer.
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) page(nPageSize);
+ }
+
+ // Load single indirect page.
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (m_rPage.m_pData[nDouble]);
+
+ storeError eErrCode = rBIOS.load (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Get single indirect.
+ eErrCode = aSingle.get (nSingle, rData, rBIOS, NULL);
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * get (triple indirect).
+ */
+storeError OStoreIndirectionPageObject::get (
+ sal_uInt16 nTriple,
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpDouble,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ if (!((nTriple < m_rPage.capacityCount()) &&
+ (nDouble < m_rPage.capacityCount()) &&
+ (nSingle < m_rPage.capacityCount()) ))
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+
+ // Check double indirect page location.
+ if (m_rPage.m_pData[nTriple] == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ // Check double indirect page buffer.
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) page(nPageSize);
+ }
+
+ // Load double indirect page.
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (m_rPage.m_pData[nTriple]);
+
+ storeError eErrCode = rBIOS.load (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Get double indirect.
+ eErrCode = aDouble.get (nDouble, nSingle, rpSingle, rData, rBIOS, NULL);
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * put (single indirect).
+ */
+storeError OStoreIndirectionPageObject::put (
+ sal_uInt16 nSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ storeError eErrCode = store_E_InvalidAccess;
+ if (!(nSingle < m_rPage.capacityCount()))
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Obtain data page location.
+ rData.location (m_rPage.m_pData[nSingle]);
+ if (rData.location() == STORE_PAGE_NULL)
+ {
+ // Allocate data page.
+ eErrCode = rBIOS.allocate (rData);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Save data page location.
+ m_rPage.m_pData[nSingle] = rData.location();
+ touch();
+
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ else
+ {
+ // Save data page.
+ eErrCode = rBIOS.save (rData);
+ }
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * put (double indirect).
+ */
+storeError OStoreIndirectionPageObject::put (
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ storeError eErrCode = store_E_InvalidAccess;
+ if (!((nDouble < m_rPage.capacityCount()) &&
+ (nSingle < m_rPage.capacityCount()) ))
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Check single indirect page buffer.
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) page(nPageSize);
+ }
+
+ // Obtain single indirect page location.
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (m_rPage.m_pData[nDouble]);
+ if (aSingle.location() == STORE_PAGE_NULL)
+ {
+ // Initialize single indirect page buffer.
+ rpSingle->initialize();
+
+ // Allocate single indirect page.
+ eErrCode = rBIOS.allocate (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Save single indirect page location.
+ m_rPage.m_pData[nDouble] = aSingle.location();
+ touch();
+
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ else
+ {
+ // Load single indirect page.
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Put single indirect.
+ eErrCode = aSingle.put (nSingle, rData, rBIOS, NULL);
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * put (triple indirect).
+ */
+storeError OStoreIndirectionPageObject::put (
+ sal_uInt16 nTriple,
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpDouble,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ storeError eErrCode = store_E_InvalidAccess;
+ if (!((nTriple < m_rPage.capacityCount()) &&
+ (nDouble < m_rPage.capacityCount()) &&
+ (nSingle < m_rPage.capacityCount()) ))
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Check double indirect page buffer.
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) page(nPageSize);
+ }
+
+ // Obtain double indirect page location.
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (m_rPage.m_pData[nTriple]);
+ if (aDouble.location() == STORE_PAGE_NULL)
+ {
+ // Initialize double indirect page buffer.
+ rpDouble->initialize();
+
+ // Allocate double indirect page.
+ eErrCode = rBIOS.allocate (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Save double indirect page location.
+ m_rPage.m_pData[nTriple] = aDouble.location();
+ touch();
+
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ else
+ {
+ // Load double indirect page.
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Put double indirect.
+ eErrCode = aDouble.put (nDouble, nSingle, rpSingle, rData, rBIOS, NULL);
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * truncate (single indirect).
+ */
+storeError OStoreIndirectionPageObject::truncate (
+ sal_uInt16 nSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ sal_uInt16 i, n = m_rPage.capacityCount();
+ if (!(nSingle < n))
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+
+ // Save PageDescriptor.
+ D aDescr (m_rPage.m_aDescr);
+
+ // Acquire Lock.
+ storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate.
+ for (i = n; i > nSingle; i--)
+ {
+ // Obtain data page location.
+ sal_uInt32 nAddr = m_rPage.m_pData[i - 1];
+ if (nAddr == STORE_PAGE_NULL) continue;
+
+ // Free data page.
+ rData.location (nAddr);
+ eErrCode = rBIOS.free (rData);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Clear pointer to data page.
+ m_rPage.m_pData[i - 1] = STORE_PAGE_NULL;
+ touch();
+ }
+
+ // Check for modified page.
+ if (dirty())
+ {
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreIndirectionPageObject::truncate(): save failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Release Lock and Leave.
+ eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * truncate (double indirect).
+ */
+storeError OStoreIndirectionPageObject::truncate (
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Acquire Mutex.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ if (!((nDouble < m_rPage.capacityCount()) &&
+ (nSingle < m_rPage.capacityCount()) ))
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+
+ // Save PageDescriptor.
+ D aDescr (m_rPage.m_aDescr);
+
+ // Acquire Lock.
+ storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate.
+ sal_uInt16 i, n = m_rPage.capacityCount();
+ for (i = n; i > nDouble + 1; i--)
+ {
+ // Obtain single indirect page location.
+ sal_uInt32 nAddr = m_rPage.m_pData[i - 1];
+ if (nAddr == STORE_PAGE_NULL) continue;
+
+ // Check single indirect page buffer.
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) page(nPageSize);
+ }
+
+ // Load single indirect page.
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (nAddr);
+
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode == store_E_None)
+ {
+ // Truncate to zero direct pages.
+ eErrCode = aSingle.truncate (0, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Free single indirect page.
+ eErrCode = rBIOS.free (aSingle);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+ else
+ {
+ if (eErrCode != store_E_InvalidChecksum)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Clear pointer to single indirect page.
+ m_rPage.m_pData[i - 1] = STORE_PAGE_NULL;
+ touch();
+ }
+
+ // Obtain last single indirect page location.
+ sal_uInt32 nAddr = m_rPage.m_pData[nDouble];
+ if (nAddr != STORE_PAGE_NULL)
+ {
+ // Check single indirect page buffer.
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) page(nPageSize);
+ }
+
+ // Load last single indirect page.
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (nAddr);
+
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode == store_E_None)
+ {
+ // Truncate to 'nSingle' direct pages.
+ eErrCode = aSingle.truncate (nSingle, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+ else
+ {
+ if (eErrCode != store_E_InvalidChecksum)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Check for complete truncation.
+ if (nSingle == 0)
+ {
+ // Free last single indirect page.
+ eErrCode = rBIOS.free (aSingle);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Clear pointer to last single indirect page.
+ m_rPage.m_pData[nDouble] = STORE_PAGE_NULL;
+ touch();
+ }
+ }
+
+ // Check for modified page.
+ if (dirty())
+ {
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreIndirectionPageObject::truncate(): save failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Release Lock and Leave.
+ eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * truncate (triple indirect).
+ */
+storeError OStoreIndirectionPageObject::truncate (
+ sal_uInt16 nTriple,
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpDouble,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Check arguments.
+ if (!((nTriple < m_rPage.capacityCount()) &&
+ (nDouble < m_rPage.capacityCount()) &&
+ (nSingle < m_rPage.capacityCount()) ))
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+
+ // Save PageDescriptor.
+ D aDescr (m_rPage.m_aDescr);
+
+ // Acquire Lock.
+ storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate.
+ sal_uInt16 i, n = m_rPage.capacityCount();
+ for (i = n; i > nTriple + 1; i--)
+ {
+ // Obtain double indirect page location.
+ sal_uInt32 nAddr = m_rPage.m_pData[i - 1];
+ if (nAddr == STORE_PAGE_NULL) continue;
+
+ // Check double indirect page buffer.
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) page(nPageSize);
+ }
+
+ // Load double indirect page.
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (nAddr);
+
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode == store_E_None)
+ {
+ // Truncate to zero single indirect pages.
+ eErrCode = aDouble.truncate (
+ 0, 0, rpSingle, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Free double indirect page.
+ eErrCode = rBIOS.free (aDouble);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+ else
+ {
+ if (eErrCode != store_E_InvalidChecksum)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Clear pointer to double indirect page.
+ m_rPage.m_pData[i - 1] = STORE_PAGE_NULL;
+ touch();
+ }
+
+ // Obtain last double indirect page location.
+ sal_uInt32 nAddr = m_rPage.m_pData[nTriple];
+ if (nAddr != STORE_PAGE_NULL)
+ {
+ // Check double indirect page buffer.
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) page(nPageSize);
+ }
+
+ // Load last double indirect page.
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (nAddr);
+
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode == store_E_None)
+ {
+ // Truncate to 'nDouble', 'nSingle' pages.
+ eErrCode = aDouble.truncate (
+ nDouble, nSingle, rpSingle, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+ else
+ {
+ if (eErrCode != store_E_InvalidChecksum)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Check for complete truncation.
+ if ((nDouble + nSingle) == 0)
+ {
+ // Free last double indirect page.
+ eErrCode = rBIOS.free (aDouble);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Clear pointer to last double indirect page.
+ m_rPage.m_pData[nTriple] = STORE_PAGE_NULL;
+ touch();
+ }
+ }
+
+ // Check for modified page.
+ if (dirty())
+ {
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreIndirectionPageObject::truncate(): save failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Release Lock and Leave.
+ eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*========================================================================
+ *
+ * OStoreDirectoryDataBlock::LinkTable implementation.
+ *
+ *======================================================================*/
+/*
+ * LinkTable::LinkTable.
+ */
+OStoreDirectoryDataBlock::LinkTable::LinkTable (void)
+{
+ initialize();
+}
+
+/*
+ * LinkTable::initialize.
+ */
+void OStoreDirectoryDataBlock::LinkTable::initialize (void)
+{
+ sal_Int32 i;
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_DIRECT; i++)
+ m_pDirect[i] = STORE_PAGE_NULL;
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_SINGLE; i++)
+ m_pSingle[i] = STORE_PAGE_NULL;
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_DOUBLE; i++)
+ m_pDouble[i] = STORE_PAGE_NULL;
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_TRIPLE; i++)
+ m_pTriple[i] = STORE_PAGE_NULL;
+}
+
+/*
+ * LinkTable::swap.
+ */
+void OStoreDirectoryDataBlock::LinkTable::swap (void)
+{
+#ifdef OSL_BIGENDIAN
+ sal_Int32 i;
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_DIRECT; i++)
+ m_pDirect[i] = VOS_SWAPDWORD(m_pDirect[i]);
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_SINGLE; i++)
+ m_pSingle[i] = VOS_SWAPDWORD(m_pSingle[i]);
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_DOUBLE; i++)
+ m_pDouble[i] = VOS_SWAPDWORD(m_pDouble[i]);
+ for (i = 0; i < STORE_LIMIT_DATAPAGE_TRIPLE; i++)
+ m_pTriple[i] = VOS_SWAPDWORD(m_pTriple[i]);
+#endif /* OSL_BIGENDIAN */
+}
+
+/*========================================================================
+ *
+ * OStoreDirectoryPageObject implementation.
+ *
+ *======================================================================*/
+/*
+ * swap.
+ */
+void OStoreDirectoryPageObject::swap (const D& rDescr)
+{
+#ifdef OSL_BIGENDIAN
+ base::swap (rDescr);
+ m_rPage.swap (rDescr);
+#endif /* OSL_BIGENDIAN */
+}
+
+/*
+ * guard.
+ */
+void OStoreDirectoryPageObject::guard (const D& rDescr)
+{
+ base::guard (rDescr);
+ m_rPage.guard (rDescr);
+}
+
+/*
+ * verify.
+ */
+storeError OStoreDirectoryPageObject::verify (const D& rDescr)
+{
+ storeError eErrCode = base::verify (rDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ else
+ return m_rPage.verify (rDescr);
+}
+
+/*
+ * scope (external data page).
+ */
+OStoreDirectoryPageData::ChunkScope
+OStoreDirectoryPageObject::scope (
+ sal_uInt32 nPage,
+ page::DataBlock::LinkDescriptor &rDescr) const
+{
+ typedef OStoreIndirectionPageData indirect;
+ sal_uInt32 index0, index1, index2, index3;
+
+ // direct.
+ sal_uInt32 nCount = m_rPage.m_aDataBlock.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 nCapacity = indirect::capacityCount(m_rPage.m_aDescr);
+ nCount = m_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;
+ VOS_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 = m_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;
+ VOS_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 = m_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;
+ VOS_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;
+}
+
+/*
+ * get (external data page).
+ */
+storeError OStoreDirectoryPageObject::get (
+ sal_uInt32 nPage,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Determine scope and link indices.
+ page::DataBlock::LinkDescriptor aLink;
+ page::ChunkScope eScope = scope (nPage, aLink);
+
+ storeError eErrCode = store_E_None;
+ if (eScope == page::SCOPE_DIRECT)
+ {
+ sal_uInt32 nAddr = directLink (aLink.m_nIndex0);
+ if (nAddr == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ rData.location (nAddr);
+ eErrCode = rBIOS.load (rData);
+ }
+ else if (eScope == page::SCOPE_SINGLE)
+ {
+ sal_uInt32 nAddr = singleLink (aLink.m_nIndex1);
+ if (nAddr == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (nAddr);
+
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ eErrCode = aSingle.get (
+ aLink.m_nIndex0,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_DOUBLE)
+ {
+ sal_uInt32 nAddr = doubleLink (aLink.m_nIndex2);
+ if (nAddr == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (nAddr);
+
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ eErrCode = aDouble.get (
+ aLink.m_nIndex1,
+ aLink.m_nIndex0,
+ rpSingle,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_TRIPLE)
+ {
+ sal_uInt32 nAddr = tripleLink (aLink.m_nIndex3);
+ if (nAddr == STORE_PAGE_NULL)
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+
+ if (rpTriple == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpTriple = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aTriple (*rpTriple);
+ aTriple.location (nAddr);
+
+ eErrCode = rBIOS.load (aTriple);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ eErrCode = aTriple.get (
+ aLink.m_nIndex2,
+ aLink.m_nIndex1,
+ aLink.m_nIndex0,
+ rpDouble,
+ rpSingle,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_UNREACHABLE)
+ {
+ // Out of scope.
+ eErrCode = store_E_CantSeek;
+ }
+ else
+ {
+ // Unknown scope.
+ VOS_TRACE("OStoreDirectoryPageObject::get(): scope failed");
+ eErrCode = store_E_Unknown;
+ }
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * put (external data page).
+ */
+storeError OStoreDirectoryPageObject::put (
+ sal_uInt32 nPage,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Determine scope and link indices.
+ page::DataBlock::LinkDescriptor aLink;
+ page::ChunkScope eScope = scope (nPage, aLink);
+
+ storeError eErrCode = store_E_None;
+ if (eScope == page::SCOPE_DIRECT)
+ {
+ rData.location (directLink (aLink.m_nIndex0));
+ if (rData.location() == STORE_PAGE_NULL)
+ {
+ eErrCode = rBIOS.allocate (rData);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ directLink (aLink.m_nIndex0, rData.location());
+ }
+ else
+ {
+ eErrCode = rBIOS.save (rData);
+ }
+ }
+ else if (eScope == page::SCOPE_SINGLE)
+ {
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (singleLink (aLink.m_nIndex1));
+ if (aSingle.location() == STORE_PAGE_NULL)
+ {
+ rpSingle->initialize();
+
+ eErrCode = rBIOS.allocate (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ singleLink (aLink.m_nIndex1, aSingle.location());
+ }
+ else
+ {
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ eErrCode = aSingle.put (
+ aLink.m_nIndex0,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_DOUBLE)
+ {
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (doubleLink (aLink.m_nIndex2));
+ if (aDouble.location() == STORE_PAGE_NULL)
+ {
+ rpDouble->initialize();
+
+ eErrCode = rBIOS.allocate (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ doubleLink (aLink.m_nIndex2, aDouble.location());
+ }
+ else
+ {
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ eErrCode = aDouble.put (
+ aLink.m_nIndex1,
+ aLink.m_nIndex0,
+ rpSingle,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_TRIPLE)
+ {
+ if (rpTriple == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpTriple = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aTriple (*rpTriple);
+ aTriple.location (tripleLink (aLink.m_nIndex3));
+ if (aTriple.location() == STORE_PAGE_NULL)
+ {
+ rpTriple->initialize();
+
+ eErrCode = rBIOS.allocate (aTriple);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ tripleLink (aLink.m_nIndex3, aTriple.location());
+ }
+ else
+ {
+ eErrCode = rBIOS.load (aTriple);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ eErrCode = aTriple.put (
+ aLink.m_nIndex2,
+ aLink.m_nIndex1,
+ aLink.m_nIndex0,
+ rpDouble,
+ rpSingle,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_UNREACHABLE)
+ {
+ // Out of scope.
+ eErrCode = store_E_CantSeek;
+ }
+ else
+ {
+ // Unknown scope.
+ VOS_TRACE("OStoreDirectoryPageObject::put(): scope failed");
+ eErrCode = store_E_Unknown;
+ }
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * truncate (external data page).
+ */
+storeError OStoreDirectoryPageObject::truncate (
+ sal_uInt32 nPage,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Determine scope and link indices.
+ page::DataBlock::LinkDescriptor aLink;
+ page::ChunkScope eScope = scope (nPage, aLink);
+
+ storeError eErrCode = store_E_None;
+ if (eScope == page::SCOPE_DIRECT)
+ {
+ // Truncate all triple indirect pages.
+ eErrCode = truncate (
+ page::SCOPE_TRIPLE, 0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate all double indirect pages.
+ eErrCode = truncate (
+ page::SCOPE_DOUBLE, 0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate all single indirect pages.
+ eErrCode = truncate (
+ page::SCOPE_SINGLE, 0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate direct pages, including 'aLink.m_nIndex0'.
+ eErrCode = truncate (
+ eScope, aLink.m_nIndex0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ }
+ else if (eScope == page::SCOPE_SINGLE)
+ {
+ // Truncate all triple indirect pages.
+ eErrCode = truncate (
+ page::SCOPE_TRIPLE, 0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate all double indirect pages.
+ eErrCode = truncate (
+ page::SCOPE_DOUBLE, 0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
+ eErrCode = truncate (
+ eScope, aLink.m_nIndex1 + 1,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Obtain last single indirect page location.
+ sal_uInt32 nAddr = singleLink (aLink.m_nIndex1);
+ if (nAddr != STORE_PAGE_NULL)
+ {
+ // Check single indirect page buffer.
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) indirect(nPageSize);
+ }
+
+ // Load last single indirect page.
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (nAddr);
+
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate to ... pages.
+ eErrCode = aSingle.truncate (
+ aLink.m_nIndex0,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Check for complete truncation.
+ if (aLink.m_nIndex0 == 0)
+ {
+ // Free last single indirect page.
+ eErrCode = rBIOS.free (aSingle);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Clear pointer to last single indirect page.
+ singleLink (aLink.m_nIndex1, STORE_PAGE_NULL);
+ }
+ }
+ }
+ else if (eScope == page::SCOPE_DOUBLE)
+ {
+ // Truncate all triple indirect pages.
+ eErrCode = truncate (
+ page::SCOPE_TRIPLE, 0,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
+ eErrCode = truncate (
+ eScope, aLink.m_nIndex2 + 1,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Obtain last double indirect page location.
+ sal_uInt32 nAddr = doubleLink (aLink.m_nIndex2);
+ if (nAddr != STORE_PAGE_NULL)
+ {
+ // Check double indirect page buffer.
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) indirect(nPageSize);
+ }
+
+ // Load last double indirect page.
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (nAddr);
+
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate to ... pages.
+ eErrCode = aDouble.truncate (
+ aLink.m_nIndex1,
+ aLink.m_nIndex0,
+ rpSingle,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Check for complete truncation.
+ if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
+ {
+ // Free last double indirect page.
+ eErrCode = rBIOS.free (aDouble);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Clear pointer to last double indirect page.
+ doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL);
+ }
+ }
+ }
+ else if (eScope == page::SCOPE_TRIPLE)
+ {
+ // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
+ eErrCode = truncate (
+ eScope, aLink.m_nIndex3 + 1,
+ rpSingle, rpDouble, rpTriple,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Obtain last triple indirect page location.
+ sal_uInt32 nAddr = tripleLink (aLink.m_nIndex3);
+ if (nAddr != STORE_PAGE_NULL)
+ {
+ // Check triple indirect page buffer.
+ if (rpTriple == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpTriple = new(nPageSize) indirect(nPageSize);
+ }
+
+ // Load last triple indirect page.
+ OStoreIndirectionPageObject aTriple (*rpTriple);
+ aTriple.location (nAddr);
+
+ eErrCode = rBIOS.load (aTriple);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Truncate to ... pages.
+ eErrCode = aTriple.truncate (
+ aLink.m_nIndex2,
+ aLink.m_nIndex1,
+ aLink.m_nIndex0,
+ rpDouble, rpSingle,
+ rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Check for complete truncation.
+ if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
+ {
+ // Free last triple indirect page.
+ eErrCode = rBIOS.free (aTriple);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Clear pointer to last triple indirect page.
+ tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL);
+ }
+ }
+ }
+ else if (eScope == page::SCOPE_UNREACHABLE)
+ {
+ // Out of scope.
+ eErrCode = store_E_CantSeek;
+ }
+ else
+ {
+ // Unknown scope.
+ VOS_TRACE("OStoreDirectoryPageObject::put(): scope failed");
+ eErrCode = store_E_Unknown;
+ }
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * truncate (external data page scope; private).
+ */
+storeError OStoreDirectoryPageObject::truncate (
+ page::ChunkScope eScope,
+ sal_uInt16 nRemain,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ storeError eErrCode = store_E_None;
+ if (eScope == page::SCOPE_DIRECT)
+ {
+ // Truncate direct data pages.
+ sal_uInt16 i, n = m_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.
+ rData.location (nAddr);
+ eErrCode = rBIOS.free (rData);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Clear pointer to data page.
+ directLink (i - 1, STORE_PAGE_NULL);
+ }
+
+ // Done.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ if (eScope == page::SCOPE_SINGLE)
+ {
+ // Truncate single indirect pages.
+ sal_uInt16 i, n = m_rPage.m_aDataBlock.singleCount();
+ for (i = n; i > nRemain; i--)
+ {
+ // Obtain single indirect page location.
+ sal_uInt32 nAddr = singleLink (i - 1);
+ if (nAddr == STORE_PAGE_NULL) continue;
+
+ // Check single indirect page buffer.
+ if (rpSingle == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpSingle = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aSingle (*rpSingle);
+ aSingle.location (nAddr);
+
+ // Load single indirect page.
+ eErrCode = rBIOS.load (aSingle);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Truncate to zero data pages.
+ eErrCode = aSingle.truncate (
+ 0, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Free single indirect page.
+ eErrCode = rBIOS.free (aSingle);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Clear pointer to single indirect page.
+ singleLink (i - 1, STORE_PAGE_NULL);
+ }
+
+ // Done.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ if (eScope == page::SCOPE_DOUBLE)
+ {
+ // Truncate double indirect pages.
+ sal_uInt16 i, n = m_rPage.m_aDataBlock.doubleCount();
+ for (i = n; i > nRemain; i--)
+ {
+ // Obtain double indirect page location.
+ sal_uInt32 nAddr = doubleLink (i - 1);
+ if (nAddr == STORE_PAGE_NULL) continue;
+
+ // Check double indirect page buffer.
+ if (rpDouble == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpDouble = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aDouble (*rpDouble);
+ aDouble.location (nAddr);
+
+ // Load double indirect page.
+ eErrCode = rBIOS.load (aDouble);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Truncate to zero single indirect pages.
+ eErrCode = aDouble.truncate (
+ 0, 0, rpSingle, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Free double indirect page.
+ eErrCode = rBIOS.free (aDouble);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Clear pointer to double indirect page.
+ doubleLink (i - 1, STORE_PAGE_NULL);
+ }
+
+ // Done.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ if (eScope == page::SCOPE_TRIPLE)
+ {
+ // Truncate triple indirect pages.
+ sal_uInt16 i, n = m_rPage.m_aDataBlock.tripleCount();
+ for (i = n; i > nRemain; i--)
+ {
+ // Obtain triple indirect page location.
+ sal_uInt32 nAddr = tripleLink (i - 1);
+ if (nAddr == STORE_PAGE_NULL) continue;
+
+ // Check triple indirect page buffer.
+ if (rpTriple == NULL)
+ {
+ sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize;
+ rpTriple = new(nPageSize) indirect(nPageSize);
+ }
+
+ OStoreIndirectionPageObject aTriple (*rpTriple);
+ aTriple.location (nAddr);
+
+ // Load triple indirect page.
+ eErrCode = rBIOS.load (aTriple);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Truncate to zero double indirect pages.
+ eErrCode = aTriple.truncate (
+ 0, 0, 0, rpDouble, rpSingle, rData, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Free triple indirect page.
+ eErrCode = rBIOS.free (aTriple);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Clear pointer to triple indirect page.
+ tripleLink (i - 1, STORE_PAGE_NULL);
+ }
+
+ // Done.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Invalid scope.
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+}
+
diff --git a/store/source/stordata.hxx b/store/source/stordata.hxx
new file mode 100644
index 000000000..174f9a73b
--- /dev/null
+++ b/store/source/stordata.hxx
@@ -0,0 +1,934 @@
+/*************************************************************************
+ *
+ * $RCSfile: stordata.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORDATA_HXX_
+#define _STORE_STORDATA_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+/*========================================================================
+ *
+ * OStoreDataPageData.
+ *
+ *======================================================================*/
+#define STORE_MAGIC_DATAPAGE 0x94190310UL
+
+struct OStoreDataPageData :
+ public NAMESPACE_STORE(OStorePageData)
+{
+ typedef OStorePageData base;
+ typedef OStoreDataPageData self;
+
+ typedef OStorePageDescriptor D;
+
+ /** Representation.
+ */
+ sal_uInt8 m_pData[1];
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return 0;
+ }
+
+ /** capacity.
+ */
+ static sal_uInt16 capacity (const D& rDescr)
+ {
+ return (rDescr.m_nSize - (base::size() + self::size()));
+ }
+
+ sal_uInt16 capacity (void) const
+ {
+ return self::capacity (base::m_aDescr);
+ }
+
+ /** usage.
+ */
+ static sal_uInt16 usage (const D& rDescr)
+ {
+ return (rDescr.m_nUsed - (base::size() + self::size()));
+ }
+
+ sal_uInt16 usage (void) const
+ {
+ return self::usage (base::m_aDescr);
+ }
+
+ /** initialize.
+ */
+ void initialize (void)
+ {
+ base::m_aGuard.m_nMagic = STORE_MAGIC_DATAPAGE;
+ base::m_aDescr.m_nUsed += self::size();
+ rtl_zeroMemory (m_pData, capacity());
+ }
+
+ /** Construction.
+ */
+ OStoreDataPageData (sal_uInt16 nPageSize)
+ : base (nPageSize)
+ {
+ initialize();
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreDataPageObject.
+ *
+ *======================================================================*/
+class OStoreDataPageObject :
+ public NAMESPACE_STORE(OStorePageObject)
+{
+ typedef OStorePageObject base;
+ typedef OStoreDataPageData page;
+
+public:
+ /** Construction.
+ */
+ inline OStoreDataPageObject (page& rPage);
+
+private:
+ /** Representation.
+ */
+ page& m_rPage;
+};
+
+inline OStoreDataPageObject::OStoreDataPageObject (page& rPage)
+ : OStorePageObject (rPage), m_rPage (rPage)
+{
+}
+
+/*========================================================================
+ *
+ * OStoreIndirectionPageData.
+ *
+ *======================================================================*/
+#define STORE_MAGIC_INDIRECTPAGE 0x89191107UL
+
+struct OStoreIndirectionPageData :
+ public NAMESPACE_STORE(OStorePageData)
+{
+ typedef OStorePageData base;
+ typedef OStoreIndirectionPageData self;
+
+ typedef OStorePageGuard G;
+ typedef OStorePageDescriptor D;
+
+ /** Representation.
+ */
+ G m_aGuard;
+ sal_uInt32 m_pData[1];
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (sizeof(G));
+ }
+
+ /** capacity.
+ */
+ static sal_uInt16 capacity (const D& rDescr)
+ {
+ return (rDescr.m_nSize - (base::size() + self::size()));
+ }
+ sal_uInt16 capacity (void) const
+ {
+ return self::capacity (base::m_aDescr);
+ }
+
+ /** capacityCount.
+ */
+ static sal_uInt16 capacityCount (const D& rDescr)
+ {
+ return (capacity(rDescr) / sizeof(sal_uInt32));
+ }
+ sal_uInt16 capacityCount (void) const
+ {
+ return (capacity() / sizeof(sal_uInt32));
+ }
+
+ /** Construction.
+ */
+ OStoreIndirectionPageData (sal_uInt16 nPageSize);
+ void initialize (void);
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStoreIndirectionPageData& rOther) const
+ {
+ return (base::operator==(rOther) && (m_aGuard == rOther.m_aGuard));
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (const D& rDescr);
+
+ /** guard (external representation).
+ */
+ void guard (const D& rDescr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ m_aGuard.m_nCRC32 = nCRC32;
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (const D& rDescr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ if (m_aGuard.m_nCRC32 != nCRC32)
+ return store_E_InvalidChecksum;
+ else
+ return store_E_None;
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreIndirectionPageObject.
+ *
+ *======================================================================*/
+class OStoreIndirectionPageObject :
+ public NAMESPACE_STORE(OStorePageObject)
+{
+ typedef OStorePageObject base;
+ typedef OStoreIndirectionPageData page;
+
+ typedef OStorePageDescriptor D;
+
+public:
+ /** Construction.
+ */
+ inline OStoreIndirectionPageObject (page& rPage);
+
+ /** External representation.
+ */
+ virtual void swap (const D& rDescr);
+ virtual void guard (const D& rDescr);
+ virtual storeError verify (const D& rDescr);
+
+ /** get (indirect data page).
+ */
+ storeError get (
+ sal_uInt16 nSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ storeError get (
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ storeError get (
+ sal_uInt16 nTriple,
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpDouble,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** put (indirect data page).
+ */
+ storeError put (
+ sal_uInt16 nSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ storeError put (
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ storeError put (
+ sal_uInt16 nTriple,
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpDouble,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** truncate (indirect data page).
+ */
+ storeError truncate (
+ sal_uInt16 nSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ storeError truncate (
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ storeError truncate (
+ sal_uInt16 nTriple,
+ sal_uInt16 nDouble,
+ sal_uInt16 nSingle,
+ page *&rpDouble,
+ page *&rpSingle,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+private:
+ /** Representation.
+ */
+ page& m_rPage;
+};
+
+inline OStoreIndirectionPageObject::OStoreIndirectionPageObject (page& rPage)
+ : OStorePageObject (rPage), m_rPage (rPage)
+{
+}
+
+/*========================================================================
+ *
+ * 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
+{
+ typedef OStorePageGuard G;
+
+ /** 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))
+ {}
+ };
+
+ /** 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];
+
+ /** Construction.
+ */
+ LinkTable (void);
+ void initialize (void);
+
+ /** swap (internal and external representation).
+ */
+ void swap (void);
+ };
+
+ /** Representation.
+ */
+ G m_aGuard;
+ LinkTable m_aTable;
+ sal_uInt32 m_nDataLen;
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (sizeof(G) + sizeof(LinkTable) + sizeof(sal_uInt32));
+ }
+
+ /** initialize.
+ */
+ void initialize (void)
+ {
+ m_aGuard = G();
+ m_aTable.initialize();
+ m_nDataLen = 0;
+ }
+
+ /** Construction.
+ */
+ OStoreDirectoryDataBlock (void)
+ : m_nDataLen (0)
+ {}
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const OStoreDirectoryDataBlock& rOther) const
+ {
+ return (m_aGuard == rOther.m_aGuard);
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aGuard.swap();
+ m_aTable.swap();
+ m_nDataLen = VOS_SWAPDWORD(m_nDataLen);
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** guard (external representation).
+ */
+ void guard (void)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aTable, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ m_aGuard.m_nCRC32 = nCRC32;
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (void)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, &m_aTable, size() - sizeof(G));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ if (m_aGuard.m_nCRC32 != nCRC32)
+ return store_E_InvalidChecksum;
+ else
+ return store_E_None;
+ }
+
+ /** direct.
+ */
+ static sal_uInt16 directCount (void)
+ {
+ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DIRECT));
+ }
+ sal_uInt32 directLink (sal_uInt16 nIndex) const
+ {
+ if (nIndex < directCount())
+ return 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] = nAddr;
+ }
+
+ /** single.
+ */
+ static sal_uInt16 singleCount (void)
+ {
+ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_SINGLE));
+ }
+ sal_uInt32 singleLink (sal_uInt16 nIndex) const
+ {
+ if (nIndex < singleCount())
+ return 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] = nAddr;
+ }
+
+ /** double.
+ */
+ static sal_uInt16 doubleCount (void)
+ {
+ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_DOUBLE));
+ }
+ sal_uInt32 doubleLink (sal_uInt16 nIndex) const
+ {
+ if (nIndex < doubleCount())
+ return 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] = nAddr;
+ }
+
+ /** triple.
+ */
+ static sal_uInt16 tripleCount (void)
+ {
+ return ((sal_uInt16)(STORE_LIMIT_DATAPAGE_TRIPLE));
+ }
+ sal_uInt32 tripleLink (sal_uInt16 nIndex) const
+ {
+ if (nIndex < tripleCount())
+ return 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] = nAddr;
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreDirectoryPageData.
+ *
+ *======================================================================*/
+#define STORE_MAGIC_DIRECTORYPAGE 0x62190120UL
+
+struct OStoreDirectoryPageData :
+ public NAMESPACE_STORE(OStorePageData)
+{
+ typedef OStorePageData base;
+ typedef OStoreDirectoryPageData self;
+
+ typedef OStorePageDescriptor D;
+ typedef OStorePageNameBlock NameBlock;
+ typedef OStoreDirectoryDataBlock DataBlock;
+
+ /** Representation.
+ */
+ NameBlock m_aNameBlock;
+ DataBlock m_aDataBlock;
+ sal_uInt8 m_pData[1];
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (NameBlock::size() + DataBlock::size());
+ }
+
+ /** capacity.
+ */
+ static sal_uInt16 capacity (const D& rDescr)
+ {
+ return (rDescr.m_nSize - (base::size() + self::size()));
+ }
+ sal_uInt16 capacity (void) const
+ {
+ return self::capacity (base::m_aDescr);
+ }
+
+ /** usage.
+ */
+ static sal_uInt16 usage (const D& rDescr)
+ {
+ return (rDescr.m_nUsed - (base::size() + self::size()));
+ }
+ sal_uInt16 usage (void) const
+ {
+ return self::usage (base::m_aDescr);
+ }
+
+ /** initialize.
+ */
+ void initialize (void)
+ {
+ base::m_aGuard.m_nMagic = STORE_MAGIC_DIRECTORYPAGE;
+ base::m_aDescr.m_nUsed = base::size() + self::size();
+
+ m_aNameBlock.initialize();
+ m_aDataBlock.initialize();
+
+ rtl_zeroMemory (m_pData, capacity());
+ }
+
+ /** Construction.
+ */
+ OStoreDirectoryPageData (sal_uInt16 nPageSize)
+ : base (nPageSize)
+ {
+ base::m_aGuard.m_nMagic = STORE_MAGIC_DIRECTORYPAGE;
+ base::m_aDescr.m_nUsed += self::size();
+ rtl_zeroMemory (m_pData, capacity());
+ }
+
+ /** Comparsion.
+ */
+ sal_Bool operator== (const OStoreDirectoryPageData& rOther) const
+ {
+ return ((base::operator==(rOther) ) &&
+ (m_aNameBlock == rOther.m_aNameBlock) &&
+ (m_aDataBlock == rOther.m_aDataBlock) );
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (const D& rDescr)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aNameBlock.swap();
+ m_aDataBlock.swap();
+#endif /* OSL_BIGENDIAN */
+ }
+
+ /** guard (external representation).
+ */
+ void guard (const D& rDescr)
+ {
+ m_aNameBlock.guard();
+ m_aDataBlock.guard();
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (const D& rDescr)
+ {
+ 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;
+ }
+ };
+
+ /** ChunkScope.
+ */
+ enum ChunkScope
+ {
+ SCOPE_INTERNAL,
+ SCOPE_EXTERNAL,
+ SCOPE_DIRECT,
+ SCOPE_SINGLE,
+ SCOPE_DOUBLE,
+ SCOPE_TRIPLE,
+ SCOPE_UNREACHABLE,
+ SCOPE_UNKNOWN
+ };
+
+ /** scope (internal).
+ */
+ ChunkScope scope (sal_uInt32 nPosition) const
+ {
+ sal_uInt32 nCapacity = capacity();
+ if (nPosition < nCapacity)
+ return SCOPE_INTERNAL;
+ else
+ return SCOPE_EXTERNAL;
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreDirectoryPageObject.
+ *
+ *======================================================================*/
+class OStoreDirectoryPageObject :
+ public NAMESPACE_STORE(OStorePageObject)
+{
+ typedef OStorePageObject base;
+ typedef OStoreDirectoryPageData page;
+ typedef OStoreIndirectionPageData indirect;
+
+ typedef OStorePageDescriptor D;
+
+public:
+ /** Construction.
+ */
+ inline OStoreDirectoryPageObject (page& rPage);
+
+ /** External representation.
+ */
+ virtual void swap (const D& rDescr);
+ virtual void guard (const D& rDescr);
+ virtual storeError verify (const D& rDescr);
+
+ /** attrib.
+ */
+ sal_uInt32 attrib (void) const
+ {
+ return m_rPage.m_aNameBlock.m_nAttrib;
+ }
+ void attrib (sal_uInt32 nAttrib)
+ {
+ m_rPage.m_aNameBlock.m_nAttrib = nAttrib;
+ touch();
+ }
+
+ /** dataLength.
+ */
+ sal_uInt32 dataLength (void) const
+ {
+ return m_rPage.m_aDataBlock.m_nDataLen;
+ }
+ void dataLength (sal_uInt32 nLength)
+ {
+ m_rPage.m_aDataBlock.m_nDataLen = nLength;
+ touch();
+ }
+
+ /** direct.
+ */
+ sal_uInt32 directLink (sal_uInt16 nIndex) const
+ {
+ return m_rPage.m_aDataBlock.directLink (nIndex);
+ }
+ void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ m_rPage.m_aDataBlock.directLink (nIndex, nAddr);
+ touch();
+ }
+
+ /** single indirect.
+ */
+ sal_uInt32 singleLink (sal_uInt16 nIndex) const
+ {
+ return m_rPage.m_aDataBlock.singleLink (nIndex);
+ }
+ void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ m_rPage.m_aDataBlock.singleLink (nIndex, nAddr);
+ touch();
+ }
+
+ /** double indirect.
+ */
+ sal_uInt32 doubleLink (sal_uInt16 nIndex) const
+ {
+ return m_rPage.m_aDataBlock.doubleLink (nIndex);
+ }
+ void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ m_rPage.m_aDataBlock.doubleLink (nIndex, nAddr);
+ touch();
+ }
+
+ /** triple indirect.
+ */
+ sal_uInt32 tripleLink (sal_uInt16 nIndex) const
+ {
+ return m_rPage.m_aDataBlock.tripleLink (nIndex);
+ }
+ void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr)
+ {
+ m_rPage.m_aDataBlock.tripleLink (nIndex, nAddr);
+ touch();
+ }
+
+ /** scope (external data page).
+ */
+ page::ChunkScope scope (
+ sal_uInt32 nPage,
+ page::DataBlock::LinkDescriptor &rDescr) const;
+
+ /** get (external data page).
+ */
+ storeError get (
+ sal_uInt32 nPage,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** put (external data page).
+ */
+ storeError put (
+ sal_uInt32 nPage,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** truncate (external data page).
+ */
+ storeError truncate (
+ sal_uInt32 nPage,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+private:
+ /** Representation.
+ */
+ page& m_rPage;
+
+ /** truncate (external data page scope; private).
+ */
+ storeError truncate (
+ page::ChunkScope eScope,
+ sal_uInt16 nRemain,
+ indirect *&rpSingle,
+ indirect *&rpDouble,
+ indirect *&rpTriple,
+ OStoreDataPageObject &rData,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+};
+
+inline OStoreDirectoryPageObject::OStoreDirectoryPageObject (page& rPage)
+ : OStorePageObject (rPage), m_rPage (rPage)
+{
+}
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORDATA_HXX_ */
+
diff --git a/store/source/store.cxx b/store/source/store.cxx
new file mode 100644
index 000000000..1cc981f79
--- /dev/null
+++ b/store/source/store.cxx
@@ -0,0 +1,817 @@
+/*************************************************************************
+ *
+ * $RCSfile: store.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORE_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _VOS_OBJECT_HXX_
+#include <vos/object.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_STORE_H_
+#include <store/store.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_FILELCKB_HXX_
+#include <store/filelckb.hxx>
+#endif
+#ifndef _STORE_MEMLCKB_HXX_
+#include <store/memlckb.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORPAGE_HXX_
+#include <storpage.hxx>
+#endif
+#ifndef _STORE_STORLCKB_HXX_
+#include <storlckb.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace rtl;
+using namespace store;
+#endif
+
+typedef NAMESPACE_VOS(ORef)<OStorePageManager> OStorePageManagerRef;
+
+/*========================================================================
+ *
+ * storeHandle implementation.
+ *
+ *======================================================================*/
+/*
+ * store_acquireHandle.
+ */
+storeError SAL_CALL store_acquireHandle (storeHandle Handle)
+{
+ OStoreObject *pObj = (OStoreObject*)Handle;
+ if (!pObj)
+ return store_E_InvalidHandle;
+
+ if (!pObj->isKindOf (VOS_CLASSINFO (OStoreObject)))
+ return store_E_InvalidHandle;
+
+ pObj->acquire();
+ return store_E_None;
+}
+
+/*
+ * store_releaseHandle.
+ */
+storeError SAL_CALL store_releaseHandle (storeHandle Handle)
+{
+ OStoreObject *pObj = (OStoreObject*)Handle;
+ if (!pObj)
+ return store_E_InvalidHandle;
+
+ if (!pObj->isKindOf (VOS_CLASSINFO (OStoreObject)))
+ return store_E_InvalidHandle;
+
+ pObj->release();
+ return store_E_None;
+}
+
+/*========================================================================
+ *
+ * storeFileHandle implementation.
+ *
+ *======================================================================*/
+/*
+ * store_createMemoryFile.
+ */
+storeError SAL_CALL store_createMemoryFile (
+ sal_uInt16 nPageSize,
+ storeFileHandle *phFile)
+{
+ if (!phFile)
+ return store_E_InvalidParameter;
+ *phFile = NULL;
+
+ NAMESPACE_VOS(ORef)<OMemoryLockBytes> xLockBytes (new OMemoryLockBytes());
+ if (!xLockBytes.isValid())
+ return store_E_OutOfMemory;
+
+ NAMESPACE_VOS(ORef)<OStorePageManager> xManager (new OStorePageManager());
+ if (!xManager.isValid())
+ return store_E_OutOfMemory;
+
+ storeError eErrCode = xManager->initialize (
+ &*xLockBytes, store_AccessCreate, nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xManager->acquire();
+
+ *phFile = (storeFileHandle)&(*xManager);
+ return store_E_None;
+}
+
+/*
+ * store_openFile.
+ */
+storeError SAL_CALL store_openFile (
+ rtl_uString *pFilename,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize,
+ storeFileHandle *phFile)
+{
+ if (phFile)
+ *phFile = NULL;
+
+ if (!(pFilename && phFile))
+ return store_E_InvalidParameter;
+
+ NAMESPACE_VOS(ORef)<OFileLockBytes> xLockBytes (new OFileLockBytes());
+ if (!xLockBytes.isValid())
+ return store_E_OutOfMemory;
+
+ storeError eErrCode = xLockBytes->create (pFilename, eAccessMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ NAMESPACE_VOS(ORef)<OStorePageManager> xManager (new OStorePageManager());
+ if (!xManager.isValid())
+ return store_E_OutOfMemory;
+
+ eErrCode = xManager->initialize (&*xLockBytes, eAccessMode, nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xManager->acquire();
+
+ *phFile = (storeFileHandle)&(*xManager);
+ return store_E_None;
+}
+
+/*
+ * store_closeFile.
+ */
+storeError SAL_CALL store_closeFile (storeFileHandle Handle)
+{
+ OStorePageManager *pObj = (OStorePageManager*)Handle;
+ if (!pObj)
+ return store_E_InvalidHandle;
+
+ if (!pObj->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ pObj->close();
+ pObj->release();
+ return store_E_None;
+}
+
+/*
+ * store_flushFile.
+ */
+storeError SAL_CALL store_flushFile (storeFileHandle Handle)
+{
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ return xManager->flush();
+}
+
+/*
+ * store_getFileRefererCount.
+ */
+storeError SAL_CALL store_getFileRefererCount (
+ storeFileHandle Handle, sal_uInt32 *pnRefCount)
+{
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!pnRefCount)
+ return store_E_InvalidParameter;
+
+ *pnRefCount = xManager->getRefererCount();
+ return store_E_None;
+}
+
+/*
+ * store_getFileSize.
+ */
+storeError SAL_CALL store_getFileSize (
+ storeFileHandle Handle, sal_uInt32 *pnSize)
+{
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!pnSize)
+ return store_E_InvalidParameter;
+
+ return xManager->size (*pnSize);
+}
+
+/*
+ * store_rebuildFile.
+ */
+storeError SAL_CALL store_rebuildFile (
+ rtl_uString *pSrcFilename,
+ rtl_uString *pDstFilename)
+{
+ storeError eErrCode = store_E_None;
+
+ if (!(pSrcFilename && pDstFilename))
+ return store_E_InvalidParameter;
+
+ OStorePageManagerRef xManager (new OStorePageManager());
+ if (!xManager.isValid())
+ return store_E_OutOfMemory;
+
+ NAMESPACE_VOS(ORef)<OFileLockBytes> xSrcLB (new OFileLockBytes());
+ if (!xSrcLB.isValid())
+ return store_E_OutOfMemory;
+
+ eErrCode = xSrcLB->create (pSrcFilename, store_AccessReadOnly);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ NAMESPACE_VOS(ORef)<OFileLockBytes> xDstLB (new OFileLockBytes());
+ if (!xDstLB.isValid())
+ return store_E_OutOfMemory;
+
+ eErrCode = xDstLB->create (pDstFilename, store_AccessCreate);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ return xManager->rebuild (&*xSrcLB, &*xDstLB);
+}
+
+/*========================================================================
+ *
+ * storeDirectoryHandle implementation.
+ *
+ *======================================================================*/
+typedef NAMESPACE_VOS(ORef)<OStoreDirectory> OStoreDirectoryRef;
+
+/*
+ * store_openDirectory.
+ */
+storeError SAL_CALL store_openDirectory (
+ storeFileHandle hFile,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eAccessMode,
+ storeDirectoryHandle *phDirectory)
+{
+ storeError eErrCode = store_E_None;
+ if (phDirectory)
+ *phDirectory = NULL;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)hFile);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pPath && pName && phDirectory))
+ return store_E_InvalidParameter;
+
+ OStoreDirectoryRef xDirectory (new OStoreDirectory());
+ if (!xDirectory.isValid())
+ return store_E_OutOfMemory;
+
+ eErrCode = xDirectory->create (&*xManager, pPath, pName, eAccessMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xDirectory->acquire();
+
+ *phDirectory = (storeDirectoryHandle)&(*xDirectory);
+ return store_E_None;
+}
+
+/*
+ * store_closeDirectory.
+ */
+storeError SAL_CALL store_closeDirectory (storeDirectoryHandle Handle)
+{
+ OStoreDirectory *pObj = (OStoreDirectory*)Handle;
+ if (!pObj)
+ return store_E_InvalidHandle;
+
+ if (!pObj->isKindOf (VOS_CLASSINFO (OStoreDirectory)))
+ return store_E_InvalidHandle;
+
+ pObj->release();
+ return store_E_None;
+}
+
+/*
+ * store_findFirst.
+ */
+storeError SAL_CALL store_findFirst (
+ storeDirectoryHandle Handle,
+ storeFindData *pFindData)
+{
+ OStoreDirectoryRef xDirectory ((OStoreDirectory*)Handle);
+ if (!xDirectory.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xDirectory->isKindOf (VOS_CLASSINFO (OStoreDirectory)))
+ return store_E_InvalidHandle;
+
+ if (!pFindData)
+ return store_E_InvalidParameter;
+
+ // Initialize FindData.
+ rtl_zeroMemory (pFindData, sizeof (storeFindData));
+
+ // Find first.
+ pFindData->m_nReserved = (sal_uInt32)(~0);
+ return xDirectory->iterate (*pFindData);
+}
+
+/*
+ * store_findNext.
+ */
+storeError SAL_CALL store_findNext (
+ storeDirectoryHandle Handle,
+ storeFindData *pFindData)
+{
+ OStoreDirectoryRef xDirectory ((OStoreDirectory*)Handle);
+ if (!xDirectory.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xDirectory->isKindOf (VOS_CLASSINFO (OStoreDirectory)))
+ return store_E_InvalidHandle;
+
+ if (!pFindData)
+ return store_E_InvalidParameter;
+
+ // Check FindData.
+ if (!pFindData->m_nReserved)
+ return store_E_NoMoreFiles;
+
+ // Find next.
+ pFindData->m_nReserved -= 1;
+ return xDirectory->iterate (*pFindData);
+}
+
+/*========================================================================
+ *
+ * storeStreamHandle implementation.
+ *
+ *======================================================================*/
+typedef NAMESPACE_VOS(ORef)<OStoreLockBytes> OStoreLockBytesRef;
+
+/*
+ * store_openStream
+ */
+storeError SAL_CALL store_openStream (
+ storeFileHandle hFile,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eAccessMode,
+ storeStreamHandle *phStream)
+{
+ storeError eErrCode = store_E_None;
+ if (phStream)
+ *phStream = NULL;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)hFile);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pPath && pName && phStream))
+ return store_E_InvalidParameter;
+
+ OStoreLockBytesRef xLockBytes (new OStoreLockBytes());
+ if (!xLockBytes.isValid())
+ return store_E_OutOfMemory;
+
+ eErrCode = xLockBytes->create (&*xManager, pPath, pName, eAccessMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xLockBytes->acquire();
+
+ *phStream = (storeStreamHandle)&(*xLockBytes);
+ return store_E_None;
+}
+
+/*
+ * store_closeStream.
+ */
+storeError SAL_CALL store_closeStream (storeStreamHandle Handle)
+{
+ OStoreLockBytes *pObj = (OStoreLockBytes*)Handle;
+ if (!pObj)
+ return store_E_InvalidHandle;
+
+ if (!pObj->isKindOf (VOS_CLASSINFO (OStoreLockBytes)))
+ return store_E_InvalidHandle;
+
+ pObj->release();
+ return store_E_None;
+}
+
+/*
+ * store_readStream.
+ */
+storeError SAL_CALL store_readStream (
+ storeStreamHandle Handle,
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 *pnDone)
+{
+ OStoreLockBytesRef xLockBytes ((OStoreLockBytes*)Handle);
+ if (!xLockBytes.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xLockBytes->isKindOf (VOS_CLASSINFO (OStoreLockBytes)))
+ return store_E_InvalidHandle;
+
+ if (!(pBuffer && pnDone))
+ return store_E_InvalidParameter;
+
+ return xLockBytes->readAt (nOffset, pBuffer, nBytes, *pnDone);
+}
+
+/*
+ * store_writeStream.
+ */
+storeError SAL_CALL store_writeStream (
+ storeStreamHandle Handle,
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 *pnDone)
+{
+ OStoreLockBytesRef xLockBytes ((OStoreLockBytes*)Handle);
+ if (!xLockBytes.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xLockBytes->isKindOf (VOS_CLASSINFO (OStoreLockBytes)))
+ return store_E_InvalidHandle;
+
+ if (!(pBuffer && pnDone))
+ return store_E_InvalidParameter;
+
+ return xLockBytes->writeAt (nOffset, pBuffer, nBytes, *pnDone);
+}
+
+/*
+ * store_flushStream.
+ */
+storeError SAL_CALL store_flushStream (storeStreamHandle Handle)
+{
+ OStoreLockBytesRef xLockBytes ((OStoreLockBytes*)Handle);
+ if (!xLockBytes.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xLockBytes->isKindOf (VOS_CLASSINFO (OStoreLockBytes)))
+ return store_E_InvalidHandle;
+
+ return xLockBytes->flush();
+}
+
+/*
+ * store_getStreamSize.
+ */
+storeError SAL_CALL store_getStreamSize (
+ storeStreamHandle Handle, sal_uInt32 *pnSize)
+{
+ OStoreLockBytesRef xLockBytes ((OStoreLockBytes*)Handle);
+ if (!xLockBytes.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xLockBytes->isKindOf (VOS_CLASSINFO (OStoreLockBytes)))
+ return store_E_InvalidHandle;
+
+ if (!pnSize)
+ return store_E_InvalidParameter;
+
+ return xLockBytes->stat (*pnSize);
+}
+
+/*
+ * store_setStreamSize.
+ */
+storeError SAL_CALL store_setStreamSize (
+ storeStreamHandle Handle, sal_uInt32 nSize)
+{
+ OStoreLockBytesRef xLockBytes ((OStoreLockBytes*)Handle);
+ if (!xLockBytes.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xLockBytes->isKindOf (VOS_CLASSINFO (OStoreLockBytes)))
+ return store_E_InvalidHandle;
+
+ return xLockBytes->setSize (nSize);
+}
+
+/*========================================================================
+ *
+ * Common storeDirectoryHandle and storeStreamHandle operations.
+ *
+ *======================================================================*/
+/*
+ * store_attrib.
+ */
+storeError SAL_CALL store_attrib (
+ storeFileHandle Handle,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2,
+ sal_uInt32 *pnAttrib)
+{
+ storeError eErrCode = store_E_None;
+ if (pnAttrib)
+ *pnAttrib = 0;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+ // Setup page key.
+ OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8);
+ OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8);
+ OStorePageKey aKey;
+
+ eErrCode = OStorePageNameBlock::namei (aPath.pData, aName.pData, aKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Obtain or modify page attributes.
+ sal_uInt32 nAttrib = 0;
+ eErrCode = xManager->attrib (aKey, nMask1, nMask2, nAttrib);
+ if (pnAttrib)
+ *pnAttrib = nAttrib;
+ return eErrCode;
+}
+
+/*
+ * store_link.
+ */
+storeError SAL_CALL store_link (
+ storeFileHandle Handle,
+ rtl_uString *pSrcPath, rtl_uString *pSrcName,
+ rtl_uString *pDstPath, rtl_uString *pDstName)
+{
+ storeError eErrCode = store_E_None;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pSrcPath && pSrcName))
+ return store_E_InvalidParameter;
+
+ if (!(pDstPath && pDstName))
+ return store_E_InvalidParameter;
+
+ // Setup 'Source' page key.
+ OString aSrcPath (
+ pSrcPath->buffer, pSrcPath->length, RTL_TEXTENCODING_UTF8);
+ OString aSrcName (
+ pSrcName->buffer, pSrcName->length, RTL_TEXTENCODING_UTF8);
+ OStorePageKey aSrcKey;
+
+ eErrCode = OStorePageNameBlock::namei (
+ aSrcPath.pData, aSrcName.pData, aSrcKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Setup 'Destination' page key.
+ OString aDstPath (
+ pDstPath->buffer, pDstPath->length, RTL_TEXTENCODING_UTF8);
+ OString aDstName (
+ pDstName->buffer, pDstName->length, RTL_TEXTENCODING_UTF8);
+ OStorePageKey aDstKey;
+
+ eErrCode = OStorePageNameBlock::namei (
+ aDstPath.pData, aDstName.pData, aDstKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Link 'Source' hard to 'Destination'.
+ return xManager->link (aSrcKey, aDstKey);
+}
+
+/*
+ * store_symlink.
+ */
+storeError SAL_CALL store_symlink (
+ storeFileHandle Handle,
+ rtl_uString *pSrcPath, rtl_uString *pSrcName,
+ rtl_uString *pDstPath, rtl_uString *pDstName)
+{
+ storeError eErrCode = store_E_None;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pSrcPath && pSrcName))
+ return store_E_InvalidParameter;
+
+ if (!(pDstPath && pDstName))
+ return store_E_InvalidParameter;
+
+ // Setup 'Destination' page key.
+ OString aDstPath (
+ pDstPath->buffer, pDstPath->length, RTL_TEXTENCODING_UTF8);
+ OString aDstName (
+ pDstName->buffer, pDstName->length, RTL_TEXTENCODING_UTF8);
+ OStorePageKey aDstKey;
+
+ eErrCode = OStorePageNameBlock::namei (
+ aDstPath.pData, aDstName.pData, aDstKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Insert 'Source' as symlink to 'Destination'.
+ OString aSrcPath (
+ pSrcPath->buffer, pSrcPath->length, RTL_TEXTENCODING_UTF8);
+ OString aSrcName (
+ pSrcName->buffer, pSrcName->length, RTL_TEXTENCODING_UTF8);
+
+ return xManager->symlink (aSrcPath.pData, aSrcName.pData, aDstKey);
+}
+
+/*
+ * store_rename.
+ */
+storeError SAL_CALL store_rename (
+ storeFileHandle Handle,
+ rtl_uString *pSrcPath, rtl_uString *pSrcName,
+ rtl_uString *pDstPath, rtl_uString *pDstName)
+{
+ storeError eErrCode = store_E_None;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pSrcPath && pSrcName))
+ return store_E_InvalidParameter;
+
+ if (!(pDstPath && pDstName))
+ return store_E_InvalidParameter;
+
+ // Setup 'Source' page key.
+ OString aSrcPath (
+ pSrcPath->buffer, pSrcPath->length, RTL_TEXTENCODING_UTF8);
+ OString aSrcName (
+ pSrcName->buffer, pSrcName->length, RTL_TEXTENCODING_UTF8);
+ OStorePageKey aSrcKey;
+
+ eErrCode = OStorePageNameBlock::namei (
+ aSrcPath.pData, aSrcName.pData, aSrcKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Rename 'Source' into 'Destination'.
+ OString aDstPath (
+ pDstPath->buffer, pDstPath->length, RTL_TEXTENCODING_UTF8);
+ OString aDstName (
+ pDstName->buffer, pDstName->length, RTL_TEXTENCODING_UTF8);
+
+ return xManager->rename (aSrcKey, aDstPath.pData, aDstName.pData);
+}
+
+/*
+ * store_remove.
+ */
+storeError SAL_CALL store_remove (
+ storeFileHandle Handle,
+ rtl_uString *pPath,
+ rtl_uString *pName)
+{
+ storeError eErrCode = store_E_None;
+
+ OStorePageManagerRef xManager ((OStorePageManager*)Handle);
+ if (!xManager.isValid())
+ return store_E_InvalidHandle;
+
+ if (!xManager->isKindOf (VOS_CLASSINFO (OStorePageManager)))
+ return store_E_InvalidHandle;
+
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+ // Setup page key.
+ OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8);
+ OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8);
+ OStorePageKey aKey;
+
+ eErrCode = OStorePageNameBlock::namei (aPath.pData, aName.pData, aKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Remove.
+ return xManager->remove (aKey);
+}
+
diff --git a/store/source/storlckb.cxx b/store/source/storlckb.cxx
new file mode 100644
index 000000000..2a9ad329f
--- /dev/null
+++ b/store/source/storlckb.cxx
@@ -0,0 +1,872 @@
+/*************************************************************************
+ *
+ * $RCSfile: storlckb.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORLCKB_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#ifndef _RTL_TEXTCVT_H_
+#include <rtl/textcvt.h>
+#endif
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORDATA_HXX_
+#include <stordata.hxx>
+#endif
+#ifndef _STORE_STORPAGE_HXX_
+#include <storpage.hxx>
+#endif
+
+#ifndef _STORE_STORLCKB_HXX_
+#include <storlckb.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace rtl;
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStore... internals.
+ *
+ *======================================================================*/
+/*
+ * __store_convertTextToUnicode.
+ */
+inline sal_Int32 __store_convertTextToUnicode (
+ rtl_TextToUnicodeConverter hConverter,
+ const sal_Char *pSrcBuffer, sal_Int32 nSrcLength,
+ sal_Unicode *pDstBuffer, sal_Int32 nDstLength)
+{
+ sal_uInt32 nCvtInfo, nCvtBytes = 0;
+ return rtl_convertTextToUnicode (
+ hConverter, 0,
+ pSrcBuffer, nSrcLength,
+ pDstBuffer, nDstLength,
+ OSTRING_TO_OUSTRING_CVTFLAGS,
+ &nCvtInfo, &nCvtBytes);
+}
+
+/*
+ * __store_iget.
+ * Precond: exclusive access.
+ */
+static storeError __store_iget (
+ OStorePageManager &rManager,
+ OStoreDirectoryPageData &rNode,
+ sal_uInt32 nAttrib,
+ const rtl_String *pPath,
+ const rtl_String *pName,
+ storeAccessMode eMode)
+{
+ // Setup inode page key.
+ OStorePageKey aKey;
+ storeError eErrCode = OStorePageNameBlock::namei (pPath, pName, aKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for directory.
+ if (nAttrib & STORE_ATTRIB_ISDIR)
+ {
+ // Ugly, but necessary (backward compatibility).
+ aKey.m_nLow = OStorePageGuard::crc32 (aKey.m_nLow, "/", 1);
+ }
+
+ // Load inode page.
+ OStoreDirectoryPageObject aPage (rNode);
+ eErrCode = rManager.load (aKey, aPage);
+ if (eErrCode != store_E_None)
+ {
+ // Check mode and reason.
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ if (eMode == store_AccessReadWrite)
+ return store_E_NotExists;
+ if (eMode == store_AccessReadOnly)
+ return store_E_NotExists;
+
+ if (!rManager.isWriteable())
+ return store_E_AccessViolation;
+
+ // Setup inode nameblock.
+ rNode.m_aNameBlock.m_aKey = aKey;
+ rNode.m_aNameBlock.m_nAttrib = nAttrib;
+
+ rtl_copyMemory (
+ &rNode.m_aNameBlock.m_pData[0],
+ pName->buffer, pName->length);
+
+ // Save inode page.
+ eErrCode = rManager.save (aKey, aPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Check for symbolic link.
+ if (aPage.attrib() & STORE_ATTRIB_ISLINK)
+ {
+ // Obtain 'Destination' page key.
+ OStorePageKey aDstKey;
+ rtl_copyMemory (&aDstKey, &rNode.m_pData[0], sizeof(aDstKey));
+
+#ifdef OSL_BIGENDIAN
+ // Swap to internal representation.
+ aDstKey.swap();
+#endif /* OSL_BIGENDIAN */
+
+ // Load 'Destination' inode.
+ eErrCode = rManager.load (aDstKey, aPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Done.
+ return store_E_None;
+}
+
+/*========================================================================
+ *
+ * OStoreDirectory implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OStoreDirectory, store),
+ VOS_NAMESPACE (OStoreDirectory, store),
+ VOS_NAMESPACE (OStoreObject, store),
+ 0);
+
+/*
+ * OStoreDirectory.
+ */
+OStoreDirectory::OStoreDirectory (void)
+ : m_xManager (NULL),
+ m_pNode (NULL),
+ m_aDescr (0, 0, 0),
+ m_nPath (0),
+ m_hTextCvt (NULL)
+{
+}
+
+/*
+ * ~OStoreDirectory.
+ */
+OStoreDirectory::~OStoreDirectory (void)
+{
+ if (m_xManager.isValid())
+ {
+ NAMESPACE_VOS(OGuard) aGuard (*m_xManager);
+ if (m_pNode)
+ {
+ m_xManager->releasePage (m_aDescr, store_AccessReadOnly);
+ }
+ }
+ delete m_pNode;
+ rtl_destroyTextToUnicodeConverter (m_hTextCvt);
+}
+
+/*
+ * create.
+ */
+storeError OStoreDirectory::create (
+ OStorePageManager *pManager,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eMode)
+{
+ NAMESPACE_VOS(ORef)<OStorePageManager> xManager (pManager);
+ if (!xManager.isValid())
+ return store_E_InvalidAccess;
+
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+ NAMESPACE_VOS(OGuard) aGuard (*xManager);
+ storeError eErrCode = xManager->getPageSize (m_aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ delete m_pNode;
+ m_pNode = new(m_aDescr.m_nSize) inode(m_aDescr.m_nSize);
+ if (!m_pNode)
+ return store_E_OutOfMemory;
+
+ OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8);
+ OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8);
+
+ eErrCode = __store_iget (
+ *xManager, *m_pNode, STORE_ATTRIB_ISDIR,
+ aPath.pData, aName.pData, eMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ sal_uInt32 nAttrib = m_pNode->m_aNameBlock.m_nAttrib;
+ if (!(nAttrib & STORE_ATTRIB_ISDIR))
+ return store_E_NotDirectory;
+
+ m_aDescr = m_pNode->m_aDescr;
+ eErrCode = xManager->acquirePage (m_aDescr, store_AccessReadOnly);
+ if (eErrCode == store_E_None)
+ {
+ // Evaluate iteration path from NameBlock.
+ typedef OStorePageGuard G;
+ sal_Char *pszName = m_pNode->m_aNameBlock.m_pData;
+
+ m_nPath = m_pNode->m_aNameBlock.m_aKey.m_nHigh;
+ m_nPath = G::crc32 (m_nPath, pszName, rtl_str_getLength(pszName));
+ m_nPath = G::crc32 (m_nPath, "/", 1);
+
+ // Accept page manager.
+ m_xManager = xManager;
+ }
+ return eErrCode;
+}
+
+/*
+ * iterate.
+ */
+storeError OStoreDirectory::iterate (storeFindData &rFindData)
+{
+ if (!m_xManager.isValid())
+ return store_E_InvalidAccess;
+
+ storeError eErrCode = store_E_NoMoreFiles;
+ if (!rFindData.m_nReserved)
+ return eErrCode;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (*m_xManager);
+
+ // Check TextConverter.
+ if (m_hTextCvt == NULL)
+ m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8);
+
+ // Setup iteration key and page buffer.
+ OStorePageKey aKey (rFindData.m_nReserved, m_nPath);
+ OStoreDirectoryPageObject aPage (*m_pNode);
+
+ // Iterate.
+ for (;;)
+ {
+ eErrCode = m_xManager->iterate (aKey, aPage, rFindData.m_nAttrib);
+ if (!((eErrCode == store_E_None) && (aKey.m_nHigh == m_nPath)))
+ break;
+
+ if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK))
+ {
+ // Load page.
+ eErrCode = m_xManager->load (aPage);
+ if (eErrCode == store_E_None)
+ {
+ // Setup FindData.
+ sal_Char *p = m_pNode->m_aNameBlock.m_pData;
+ sal_Int32 n = rtl_str_getLength (p);
+ sal_Int32 k = rFindData.m_nLength;
+
+ n = __store_convertTextToUnicode (
+ m_hTextCvt, p, n,
+ rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1);
+ if (k > n)
+ {
+ k = (k - n) * sizeof(sal_Unicode);
+ rtl_zeroMemory (&rFindData.m_pszName[n], k);
+ }
+
+ rFindData.m_nLength = n;
+ rFindData.m_nAttrib |= aPage.attrib();
+ rFindData.m_nSize = aPage.dataLength();
+
+ // Leave.
+ rFindData.m_nReserved = aKey.m_nLow;
+ return store_E_None;
+ }
+ }
+
+ if (aKey.m_nLow > 0)
+ aKey.m_nLow -= 1;
+ else
+ break;
+ }
+
+ // Finished.
+ rtl_zeroMemory (&rFindData, sizeof (storeFindData));
+ return store_E_NoMoreFiles;
+}
+
+/*========================================================================
+ *
+ * OStoreLockBytes implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OStoreLockBytes, store),
+ VOS_NAMESPACE (OStoreLockBytes, store),
+ VOS_NAMESPACE (OStoreObject, store),
+ 0);
+
+/*
+ * OStoreLockBytes.
+ */
+OStoreLockBytes::OStoreLockBytes (void)
+ : m_xManager (NULL),
+ m_nPageSize (0),
+ m_pNode (NULL),
+ m_pData (NULL),
+ m_pSingle (NULL),
+ m_pDouble (NULL),
+ m_pTriple (NULL),
+ m_bWriteable (sal_False)
+{
+}
+
+/*
+ * ~OStoreLockBytes.
+ */
+OStoreLockBytes::~OStoreLockBytes (void)
+{
+ if (m_xManager.isValid())
+ {
+ NAMESPACE_VOS(OGuard) aGuard (*m_xManager);
+ if (m_pNode)
+ {
+ OStorePageDescriptor aDescr (m_pNode->m_aDescr);
+ if (m_bWriteable)
+ m_xManager->releasePage (aDescr, store_AccessReadWrite);
+ else
+ m_xManager->releasePage (aDescr, store_AccessReadOnly);
+ }
+ }
+
+ delete m_pNode;
+ delete m_pData;
+
+ delete m_pSingle;
+ delete m_pDouble;
+ delete m_pTriple;
+}
+
+/*
+ * acquire.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OStoreLockBytes::acquire (void)
+{
+ return OStoreObject::acquire();
+}
+
+/*
+ * release.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OStoreLockBytes::release (void)
+{
+ return OStoreObject::release();
+}
+
+/*
+ * referenced.
+ */
+NAMESPACE_VOS(IReference)::RefCount
+SAL_CALL OStoreLockBytes::referenced (void) const
+{
+ return OStoreObject::referenced();
+}
+
+/*
+ * create.
+ */
+storeError OStoreLockBytes::create (
+ OStorePageManager *pManager,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eMode)
+{
+ NAMESPACE_VOS(ORef)<OStorePageManager> xManager (pManager);
+ if (!xManager.isValid())
+ return store_E_InvalidAccess;
+
+ if (!(pPath && pName))
+ return store_E_InvalidParameter;
+
+ NAMESPACE_VOS(OGuard) aGuard (*xManager);
+ storeError eErrCode = xManager->getPageSize (m_nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ delete m_pNode;
+ m_pNode = new(m_nPageSize) inode(m_nPageSize);
+ if (!m_pNode)
+ return store_E_OutOfMemory;
+
+ OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8);
+ OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8);
+
+ eErrCode = __store_iget (
+ *xManager, *m_pNode, STORE_ATTRIB_ISFILE,
+ aPath.pData, aName.pData, eMode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ sal_uInt32 nAttrib = m_pNode->m_aNameBlock.m_nAttrib;
+ if (!(nAttrib & STORE_ATTRIB_ISFILE))
+ {
+ // No ISFILE in older versions (backward compatibility).
+ if (nAttrib & STORE_ATTRIB_ISLINK)
+ return store_E_NotFile;
+ }
+
+ // ...
+ OStorePageDescriptor aDescr (m_pNode->m_aDescr);
+ if (eMode != store_AccessReadOnly)
+ eErrCode = xManager->acquirePage (aDescr, store_AccessReadWrite);
+ else
+ eErrCode = xManager->acquirePage (aDescr, store_AccessReadOnly);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // ...
+ m_xManager = xManager;
+ m_bWriteable = (eMode != store_AccessReadOnly);
+
+ // Check for truncation.
+ if (eMode == store_AccessCreate)
+ {
+ // Truncate to zero length.
+ eErrCode = setSize(0);
+ }
+ return eErrCode;
+}
+
+/*
+ * readAt.
+ */
+storeError OStoreLockBytes::readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ rnDone = 0;
+
+ if (!m_xManager.isValid())
+ return store_E_InvalidAccess;
+
+ if (!pBuffer)
+ return store_E_InvalidParameter;
+ if (!nBytes)
+ return store_E_None;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (*m_xManager);
+
+ // Determine data length.
+ OStoreDirectoryPageObject aPage (*m_pNode);
+
+ sal_uInt32 nDataLen = aPage.dataLength();
+ if ((nOffset + nBytes) > nDataLen)
+ nBytes = nDataLen - nOffset;
+
+ // Read data.
+ sal_uInt8 *pData = (sal_uInt8*)pBuffer;
+ while ((0 < nBytes) && (nOffset < nDataLen))
+ {
+ // Determine 'Offset' scope.
+ inode::ChunkScope eScope = m_pNode->scope (nOffset);
+ if (eScope == inode::SCOPE_INTERNAL)
+ {
+ // Read from inode page (internal scope).
+ inode::ChunkDescriptor aDescr (
+ nOffset, m_pNode->capacity());
+ sal_uInt32 nLength = VOS_MIN (aDescr.m_nLength, nBytes);
+
+ rtl_copyMemory (
+ &pData[rnDone],
+ &m_pNode->m_pData[aDescr.m_nOffset],
+ nLength);
+
+ // Adjust counters.
+ rnDone += nLength;
+ nOffset += nLength;
+ nBytes -= nLength;
+ }
+ else
+ {
+ // Read from data page (external scope).
+ if (!m_pData)
+ m_pData = new(m_nPageSize) data(m_nPageSize);
+ if (!m_pData)
+ return store_E_OutOfMemory;
+ OStoreDataPageObject aData (*m_pData);
+
+ inode::ChunkDescriptor aDescr (
+ nOffset - m_pNode->capacity(), m_pData->capacity());
+ sal_uInt32 nLength = VOS_MIN (aDescr.m_nLength, nBytes);
+
+ storeError eErrCode = aPage.get (
+ aDescr.m_nPage, m_pSingle, m_pDouble, m_pTriple,
+ aData, *m_xManager, NULL);
+ if (eErrCode != store_E_None)
+ {
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ rtl_zeroMemory (
+ &pData[rnDone],
+ nLength);
+ }
+ else
+ {
+ rtl_copyMemory (
+ &pData[rnDone],
+ &m_pData->m_pData[aDescr.m_nOffset],
+ nLength);
+ }
+
+ // Adjust counters.
+ rnDone += nLength;
+ nOffset += nLength;
+ nBytes -= nLength;
+ }
+ }
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * writeAt.
+ */
+storeError OStoreLockBytes::writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone)
+{
+ rnDone = 0;
+
+ if (!m_xManager.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ if (!pBuffer)
+ return store_E_InvalidParameter;
+ if (!nBytes)
+ return store_E_None;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (*m_xManager);
+
+ // Write data.
+ OStoreDirectoryPageObject aPage (*m_pNode);
+ const sal_uInt8 *pData = (const sal_uInt8*)pBuffer;
+
+ storeError eErrCode = store_E_None;
+ while (nBytes > 0)
+ {
+ // Determine 'Offset' scope.
+ inode::ChunkScope eScope = m_pNode->scope (nOffset);
+ if (eScope == inode::SCOPE_INTERNAL)
+ {
+ // Write to inode page (internal scope).
+ inode::ChunkDescriptor aDescr (
+ nOffset, m_pNode->capacity());
+ sal_uInt32 nLength = VOS_MIN (aDescr.m_nLength, nBytes);
+
+ rtl_copyMemory (
+ &m_pNode->m_pData[aDescr.m_nOffset],
+ &pData[rnDone], nLength);
+
+ // Mark inode dirty.
+ aPage.touch();
+
+ // Adjust counters.
+ rnDone += nLength;
+ nOffset += nLength;
+ nBytes -= nLength;
+
+ // Adjust data length.
+ if (aPage.dataLength() < nOffset)
+ aPage.dataLength (nOffset);
+ }
+ else
+ {
+ // Write to data page (external scope).
+ if (!m_pData)
+ m_pData = new(m_nPageSize) data(m_nPageSize);
+ if (!m_pData)
+ return store_E_OutOfMemory;
+ OStoreDataPageObject aData (*m_pData);
+
+ inode::ChunkDescriptor aDescr (
+ nOffset - m_pNode->capacity(), m_pData->capacity());
+ sal_uInt32 nLength = aDescr.m_nLength;
+
+ if ((aDescr.m_nOffset > 0) || (nBytes < nLength))
+ {
+ // Unaligned. Need to load/create data page.
+ eErrCode = aPage.get (
+ aDescr.m_nPage, m_pSingle, m_pDouble, m_pTriple,
+ aData, *m_xManager, NULL);
+ if (eErrCode != store_E_None)
+ {
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ rtl_zeroMemory (
+ &m_pData->m_pData[0],
+ m_pData->capacity());
+ }
+ }
+
+ // Modify data page.
+ nLength = VOS_MIN (nLength, nBytes);
+
+ rtl_copyMemory (
+ &m_pData->m_pData[aDescr.m_nOffset],
+ &pData[rnDone], nLength);
+
+ // Save data page.
+ eErrCode = aPage.put (
+ aDescr.m_nPage, m_pSingle, m_pDouble, m_pTriple,
+ aData, *m_xManager, NULL);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Adjust counters.
+ rnDone += nLength;
+ nOffset += nLength;
+ nBytes -= nLength;
+
+ // Adjust data length.
+ if (aPage.dataLength() < nOffset)
+ aPage.dataLength (nOffset);
+ }
+ }
+
+ // Check for modified inode.
+ if (aPage.dirty())
+ return m_xManager->save (aPage);
+ else
+ return store_E_None;
+}
+
+/*
+ * flush.
+ */
+storeError OStoreLockBytes::flush (void)
+{
+ if (!m_xManager.isValid())
+ return store_E_InvalidAccess;
+
+ return m_xManager->flush();
+}
+
+/*
+ * setSize.
+ */
+storeError OStoreLockBytes::setSize (sal_uInt32 nSize)
+{
+ if (!m_xManager.isValid())
+ return store_E_InvalidAccess;
+ if (!m_bWriteable)
+ return store_E_AccessViolation;
+
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard (*m_xManager);
+
+ // Determine current length.
+ OStoreDirectoryPageObject aPage (*m_pNode);
+ sal_uInt32 nDataLen = aPage.dataLength();
+
+ if (nSize == nDataLen)
+ return store_E_None;
+
+ if (nSize < nDataLen)
+ {
+ // Truncate.
+ storeError eErrCode = store_E_None;
+
+ // Determine 'Size' scope.
+ inode::ChunkScope eSizeScope = m_pNode->scope (nSize);
+ if (eSizeScope == inode::SCOPE_INTERNAL)
+ {
+ // Internal 'Size' scope. Determine 'Data' scope.
+ inode::ChunkScope eDataScope = m_pNode->scope (nDataLen);
+ if (eDataScope == inode::SCOPE_EXTERNAL)
+ {
+ // External 'Data' scope.
+ if (!m_pData)
+ m_pData = new(m_nPageSize) data(m_nPageSize);
+ if (!m_pData)
+ return store_E_OutOfMemory;
+ OStoreDataPageObject aData (*m_pData);
+
+ // Truncate all external data pages.
+ eErrCode = aPage.truncate (
+ 0, m_pSingle, m_pDouble, m_pTriple,
+ aData, *m_xManager, NULL);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Truncate internal data page.
+ inode::ChunkDescriptor aDescr (nSize, m_pNode->capacity());
+ rtl_zeroMemory (
+ &m_pNode->m_pData[aDescr.m_nOffset],
+ aDescr.m_nLength);
+ }
+ else
+ {
+ // External 'Size' scope.
+ if (!m_pData)
+ m_pData = new(m_nPageSize) data(m_nPageSize);
+ if (!m_pData)
+ return store_E_OutOfMemory;
+ OStoreDataPageObject aData (*m_pData);
+
+ // Truncate external data pages.
+ inode::ChunkDescriptor aDescr (
+ nSize - m_pNode->capacity(), m_pData->capacity());
+
+ sal_uInt32 nPage = aDescr.m_nPage;
+ if (aDescr.m_nOffset) nPage += 1;
+
+ eErrCode = aPage.truncate (
+ nPage, m_pSingle, m_pDouble, m_pTriple,
+ aData, *m_xManager, NULL);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+ }
+
+ // Set (extended or truncated) size.
+ aPage.dataLength (nSize);
+
+ // Save modified inode.
+ return m_xManager->save (aPage);
+}
+
+/*
+ * stat.
+ */
+storeError OStoreLockBytes::stat (sal_uInt32 &rnSize)
+{
+ rnSize = 0;
+
+ if (!m_xManager.isValid())
+ return store_E_InvalidAccess;
+
+ rnSize = m_pNode->m_aDataBlock.m_nDataLen;
+ return store_E_None;
+}
+
+/*
+ * lockRange.
+ */
+storeError OStoreLockBytes::lockRange (
+ sal_uInt32 nOffset, sal_uInt32 nBytes)
+{
+ // (NYI).
+ return store_E_None;
+}
+
+/*
+ * unlockRange.
+ */
+storeError OStoreLockBytes::unlockRange (
+ sal_uInt32 nOffset, sal_uInt32 nBytes)
+{
+ // (NYI).
+ return store_E_None;
+}
+
diff --git a/store/source/storlckb.hxx b/store/source/storlckb.hxx
new file mode 100644
index 000000000..a152dc5cf
--- /dev/null
+++ b/store/source/storlckb.hxx
@@ -0,0 +1,296 @@
+/*************************************************************************
+ *
+ * $RCSfile: storlckb.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORLCKB_HXX_
+#define _STORE_STORLCKB_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_TEXTCVT_H_
+#include <rtl/textcvt.h>
+#endif
+#ifndef _RTL_USTRING_H_
+#include <rtl/ustring.h>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORPAGE_HXX_
+#include <storpage.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+struct OStoreDataPageData;
+struct OStoreDirectoryPageData;
+struct OStoreIndirectionPageData;
+
+/*========================================================================
+ *
+ * OStoreDirectory interface.
+ *
+ *======================================================================*/
+class OStoreDirectory : public NAMESPACE_STORE(OStoreObject)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OStoreDirectory, store));
+
+public:
+ /** Construction.
+ */
+ OStoreDirectory (void);
+
+ /** create (two-phase construction).
+ * @param pManager [in]
+ * @param pszPath [in]
+ * @param pszName [in]
+ * @param eAccessMode [in]
+ * @return store_E_None upon success.
+ */
+ storeError create (
+ OStorePageManager *pManager,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eAccessMode);
+
+ /** iterate.
+ * @param rFindData [out]
+ * @return store_E_None upon success,
+ * store_E_NoMoreFiles upon end of iteration.
+ */
+ storeError iterate (
+ storeFindData &rFindData);
+
+protected:
+ /** Destruction (OReference).
+ */
+ virtual ~OStoreDirectory (void);
+
+private:
+ /** Representation.
+ */
+ NAMESPACE_VOS(ORef)<OStorePageManager> m_xManager;
+
+ typedef OStoreDirectoryPageData inode;
+ inode *m_pNode;
+
+ OStorePageDescriptor m_aDescr;
+ sal_uInt32 m_nPath;
+ rtl_TextToUnicodeConverter m_hTextCvt;
+
+ /** Not implemented.
+ */
+ OStoreDirectory (const OStoreDirectory&);
+ OStoreDirectory& operator= (const OStoreDirectory&);
+};
+
+/*========================================================================
+ *
+ * OStoreLockBytes interface.
+ *
+ *======================================================================*/
+class OStoreLockBytes :
+ public NAMESPACE_STORE(OStoreObject),
+ public NAMESPACE_STORE(ILockBytes)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OStoreLockBytes, store));
+
+public:
+ /** Construction.
+ */
+ OStoreLockBytes (void);
+
+ /** create (two-phase construction).
+ * @param pManager [in]
+ * @param rNode [in]
+ * @param eMode [in]
+ * @return store_E_None upon success
+ */
+ storeError create (
+ OStorePageManager *pManager,
+ rtl_uString *pPath,
+ rtl_uString *pName,
+ storeAccessMode eAccessMode);
+
+ /** Read at Offset into Buffer.
+ * @param nOffset [in]
+ * @param pBuffer [out]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError readAt (
+ sal_uInt32 nOffset,
+ void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ /** Write at Offset from Buffer.
+ * @param nOffset [in]
+ * @param pBuffer [in]
+ * @param nBytes [in]
+ * @param rnDone [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError writeAt (
+ sal_uInt32 nOffset,
+ const void *pBuffer,
+ sal_uInt32 nBytes,
+ sal_uInt32 &rnDone);
+
+ /** flush.
+ * @return store_E_None upon success
+ */
+ virtual storeError flush (void);
+
+ /** setSize.
+ * @param nSize [in]
+ * @return store_E_None upon success
+ */
+ virtual storeError setSize (sal_uInt32 nSize);
+
+ /** stat.
+ * @paran rnSize [out]
+ * @return store_E_None upon success
+ */
+ virtual storeError stat (sal_uInt32 &rnSize);
+
+ /** Lock range at Offset.
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError lockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes);
+
+ /** Unlock range at Offset.
+ * @param nOffset [in]
+ * @param nBytes [in]
+ * @return store_E_None upon success
+ * store_E_LockingViolation
+ */
+ virtual storeError unlockRange (
+ sal_uInt32 nOffset,
+ sal_uInt32 nBytes);
+
+ /** Delegate multiple inherited IReference.
+ */
+ virtual RefCount SAL_CALL acquire (void);
+ virtual RefCount SAL_CALL release (void);
+ virtual RefCount SAL_CALL referenced (void) const;
+
+protected:
+ /** Destruction (OReference).
+ */
+ virtual ~OStoreLockBytes (void);
+
+private:
+ /** Representation.
+ */
+ NAMESPACE_VOS(ORef)<OStorePageManager> m_xManager;
+
+ typedef OStoreDataPageData data;
+ typedef OStoreDirectoryPageData inode;
+ typedef OStoreIndirectionPageData indirect;
+
+ inode *m_pNode;
+ data *m_pData;
+
+ indirect *m_pSingle;
+ indirect *m_pDouble;
+ indirect *m_pTriple;
+
+ sal_Bool m_bWriteable;
+ sal_uInt16 m_nPageSize;
+
+ /** Not implemented.
+ */
+ OStoreLockBytes (const OStoreLockBytes&);
+ OStoreLockBytes& operator= (const OStoreLockBytes&);
+};
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORLCKB_HXX_ */
+
diff --git a/store/source/storpage.cxx b/store/source/storpage.cxx
new file mode 100644
index 000000000..203a5a669
--- /dev/null
+++ b/store/source/storpage.cxx
@@ -0,0 +1,1562 @@
+/*************************************************************************
+ *
+ * $RCSfile: storpage.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORPAGE_CXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#ifndef _RTL_STRING_H_
+#include <rtl/string.h>
+#endif
+
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_OBJECT_HXX_
+#include <store/object.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORCACH_HXX_
+#include <storcach.hxx>
+#endif
+#ifndef _STORE_STORDMON_HXX_
+#include <stordmon.hxx>
+#endif
+#ifndef _STORE_STORDATA_HXX_
+#include <stordata.hxx>
+#endif
+#ifndef _STORE_STORTREE_HXX_
+#include <stortree.hxx>
+#endif
+
+#ifndef _STORE_STORPAGE_HXX_
+#include <storpage.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStorePageManager implementation.
+ *
+ *======================================================================*/
+VOS_IMPLEMENT_CLASSINFO(
+ VOS_CLASSNAME (OStorePageManager, store),
+ VOS_NAMESPACE (OStorePageManager, store),
+ VOS_NAMESPACE (OStorePageBIOS, store),
+ 0);
+
+/*
+ * OStorePageManager.
+ */
+OStorePageManager::OStorePageManager (void)
+ : m_xDaemon (NULL),
+ m_pCache (NULL),
+ m_pDirect (NULL),
+ m_pData (NULL),
+ m_nPageSize (0)
+{
+ // Node pages.
+ m_pNode[0] = NULL;
+ m_pNode[1] = NULL;
+ m_pNode[2] = NULL;
+
+ // Indirect pages.
+ m_pLink[0] = NULL;
+ m_pLink[1] = NULL;
+ m_pLink[2] = NULL;
+
+ // Daemon (kflushd :-).
+ if (OStorePageDaemon::getOrCreate (m_xDaemon))
+ m_xDaemon->insert (this);
+}
+
+/*
+ * ~OStorePageManager.
+ */
+OStorePageManager::~OStorePageManager (void)
+{
+ NAMESPACE_VOS(OGuard) aGuard (*this);
+ if (m_xDaemon.isValid())
+ m_xDaemon->remove (this);
+
+ delete m_pCache;
+ delete m_pDirect;
+ delete m_pData;
+
+ delete m_pNode[0];
+ delete m_pNode[1];
+ delete m_pNode[2];
+
+ delete m_pLink[0];
+ delete m_pLink[1];
+ delete m_pLink[2];
+}
+
+/*
+ * initialize (two-phase construction).
+ * Precond: none.
+ */
+storeError OStorePageManager::initialize (
+ ILockBytes *pLockBytes,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check arguments.
+ if (!pLockBytes)
+ return store_E_InvalidParameter;
+
+ // Initialize base.
+ storeError eErrCode = base::initialize (pLockBytes, eAccessMode);
+ if (eErrCode != store_E_None)
+ {
+ // Check mode and reason.
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ if (eAccessMode == store_AccessReadWrite)
+ return store_E_NotExists;
+ if (eAccessMode == store_AccessReadOnly)
+ return store_E_NotExists;
+
+ // Create.
+ eErrCode = base::create (nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Obtain page size.
+ eErrCode = base::getPageSize (m_nPageSize);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageManager::initialize(): getPageSize() failed");
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Cleanup.
+ __STORE_DELETEZ (m_pCache);
+ __STORE_DELETEZ (m_pDirect);
+ __STORE_DELETEZ (m_pData);
+
+ __STORE_DELETEZ (m_pNode[0]);
+ __STORE_DELETEZ (m_pNode[1]);
+ __STORE_DELETEZ (m_pNode[2]);
+
+ __STORE_DELETEZ (m_pLink[0]);
+ __STORE_DELETEZ (m_pLink[1]);
+ __STORE_DELETEZ (m_pLink[2]);
+
+ // Initialize page buffers.
+ m_pNode[0] = new(m_nPageSize) page(m_nPageSize);
+ if (eAccessMode != store_AccessReadOnly)
+ {
+ m_pNode[1] = new(m_nPageSize) page(m_nPageSize);
+ m_pNode[2] = new(m_nPageSize) page(m_nPageSize);
+ }
+
+ // Initialize page cache.
+ m_pCache = new OStorePageCache();
+
+ // Done.
+ return eErrCode;
+}
+
+/*
+ * free (unmanaged).
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::free (OStorePageObject &rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Check for cacheable page.
+ OStorePageData &rData = rPage.getData();
+ if (rData.m_aGuard.m_nMagic == STORE_MAGIC_BTREENODE)
+ {
+ // Invalidate cache entry.
+ storeError eErrCode = m_pCache->invalidate (rData.m_aDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Free page.
+ return base::free (rPage);
+}
+
+/*
+ * load (unmanaged).
+ * Precond: initialized.
+ */
+storeError OStorePageManager::load (OStorePageObject &rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ // Check for cacheable page.
+ OStorePageData &rData = rPage.getData();
+ if (rData.m_aGuard.m_nMagic == STORE_MAGIC_BTREENODE)
+ {
+ // Save PageDescriptor.
+ OStorePageDescriptor aDescr (rData.m_aDescr);
+
+ // Load (cached) page.
+ storeError eErrCode = m_pCache->load (aDescr, rData, *this);
+ if (eErrCode != store_E_None)
+ {
+ // Check for pending verification.
+ if (eErrCode != store_E_Pending)
+ return eErrCode;
+
+ // Verify page.
+ eErrCode = rPage.verify (aDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+#ifdef OSL_BIGENDIAN
+ // Swap to internal representation.
+ rPage.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Done.
+ return store_E_None;
+ }
+
+ // Load (uncached) page.
+ return base::load (rPage);
+}
+
+/*
+ * save (unmanaged).
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::save (OStorePageObject &rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Check for cacheable page.
+ OStorePageData &rData = rPage.getData();
+ if (rData.m_aGuard.m_nMagic == STORE_MAGIC_BTREENODE)
+ {
+ // Save PageDescriptor.
+ OStorePageDescriptor aDescr (rData.m_aDescr);
+
+#ifdef OSL_BIGENDIAN
+ // Swap to external representation.
+ rPage.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Guard page.
+ rPage.guard (aDescr);
+
+ // Save (cached) page.
+#if 0 /* EXPERIMENTAL */
+ storeError eErrCode = m_pCache->update (
+ aDescr, rData, *this, NULL,
+ OStorePageCache::UPDATE_WRITE_DELAYED);
+#else
+ storeError eErrCode = m_pCache->update (
+ aDescr, rData, *this, NULL,
+ OStorePageCache::UPDATE_WRITE_THROUGH);
+#endif /* EXPERIMENTAL */
+
+#ifdef OSL_BIGENDIAN
+ // Swap back to internal representation.
+ rPage.swap (aDescr);
+#endif /* OSL_BIGENDIAN */
+
+ // Mark page clean.
+ if (eErrCode == store_E_None)
+ rPage.clean();
+
+ // Done.
+ return eErrCode;
+ }
+
+ // Save (uncached) page.
+ return base::save (rPage);
+}
+
+/*
+ * flush.
+ * Precond: initialized.
+ */
+storeError OStorePageManager::flush (void)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ // Check access mode.
+ if (!base::isWriteable())
+ return store_E_None;
+
+ // Flush cache.
+ storeError eErrCode = m_pCache->flush (*this, NULL);
+ VOS_POSTCOND(
+ eErrCode == store_E_None,
+ "OStorePageManager::flush(): cache::flush() failed");
+
+ // Flush base.
+ return base::flush();
+}
+
+/*
+ * find (w/o split()).
+ * Internal: Precond: initialized, readable, exclusive access.
+ */
+storeError OStorePageManager::find (const entry &rEntry, page &rPage)
+{
+ // Load RootNode.
+ OStoreBTreeRootObject aRoot (rPage);
+ aRoot.location (m_nPageSize);
+
+ storeError eErrCode = load (aRoot);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check current Page.
+ while (rPage.depth())
+ {
+ // Find next page.
+ sal_uInt16 i = rPage.find(rEntry), n = rPage.usageCount();
+ if (!(i < n))
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Check address.
+ sal_uInt32 nAddr = rPage.m_pData[i].m_aLink.m_nAddr;
+ if (nAddr == STORE_PAGE_NULL)
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Load next page.
+ node aNode (rPage);
+ aNode.location (nAddr);
+
+ eErrCode = load (aNode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * find (possibly with split()).
+ * Internal: Precond: initialized, writeable, exclusive access.
+ */
+storeError OStorePageManager::find (
+ const entry &rEntry, page &rPage, page &rPageL, page &rPageR)
+{
+ // Load RootNode.
+ OStoreBTreeRootObject aRoot (rPage);
+ aRoot.location (m_nPageSize);
+
+ storeError eErrCode = load (aRoot);
+ if (eErrCode != store_E_None)
+ {
+ // Check existence.
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ // Pre-allocate left most entry (ugly, but we can't insert to left).
+ rPage.insert (0, entry());
+ rPage.m_pData[0].m_aKey.m_nLow = OStorePageGuard::crc32 (0, "/", 1);
+
+ // Allocate RootNode.
+ eErrCode = base::allocate (aRoot, ALLOCATE_EOF);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+ else
+ {
+ // Check for RootNode split.
+ if (aRoot.querySplit())
+ {
+ // Split root.
+ eErrCode = aRoot.split (0, rPageL, rPageR, *this);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+ }
+
+ // Check current Page.
+ while (rPage.depth())
+ {
+ // Find next page.
+ sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount();
+ if (!(i < n))
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Check address.
+ sal_uInt32 nAddr = rPage.m_pData[i].m_aLink.m_nAddr;
+ if (nAddr == STORE_PAGE_NULL)
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Load next page.
+ node aNode (rPageL);
+ aNode.location (nAddr);
+
+ eErrCode = load (aNode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for node split.
+ if (rPageL.querySplit())
+ {
+ // Split node.
+ node aParent (rPage);
+ eErrCode = aParent.split (i, rPageL, rPageR, *this);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Restart.
+ continue;
+ }
+ else
+ {
+ // Let next page be current.
+ rPage = rPageL;
+ continue;
+ }
+ }
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * remove (possibly down from root).
+ * Internal: Precond: initialized, writeable, exclusive access.
+ */
+storeError OStorePageManager::remove (
+ entry &rEntry, page &rPage, page &rPageL)
+{
+ // Load RootNode.
+ OStoreBTreeRootObject aRoot (rPage);
+ aRoot.location (m_nPageSize);
+
+ storeError eErrCode = load (aRoot);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check index.
+ sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount();
+ if (!(i < n))
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Compare entry.
+ entry::CompareResult result = rEntry.compare (rPage.m_pData[i]);
+
+ // Iterate down until equal match.
+ while ((result == entry::COMPARE_GREATER) && (rPage.depth() > 0))
+ {
+ // Check link address.
+ sal_uInt32 nAddr = rPage.m_pData[i].m_aLink.m_nAddr;
+ if (nAddr == STORE_PAGE_NULL)
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Load link page.
+ node aNode (rPage);
+ aNode.location (nAddr);
+
+ eErrCode = load (aNode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check index.
+ i = rPage.find (rEntry), n = rPage.usageCount();
+ if (!(i < n))
+ {
+ // Path to entry not exists (Must not happen(?)).
+ return store_E_NotExists;
+ }
+
+ // Compare entry.
+ result = rEntry.compare (rPage.m_pData[i]);
+ }
+
+ VOS_POSTCOND(
+ result != entry::COMPARE_LESS,
+ "OStorePageManager::remove(): find failed");
+
+ // Check entry comparison.
+ if (result == entry::COMPARE_LESS)
+ {
+ // Must not happen.
+ return store_E_Unknown;
+ }
+
+ // Remove down from current page (recursive).
+ node aNode (rPage);
+ return aNode.remove (i, rEntry, rPageL, *this, NULL);
+}
+
+/*
+ * load.
+ * Precond: initialized.
+ */
+storeError OStorePageManager::load (
+ const OStorePageKey &rKey,
+ OStoreDirectoryPageObject &rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ // Setup BTree entry.
+ entry e;
+ e.m_aKey = rKey;
+
+ // Find NodePage.
+ storeError eErrCode = find (e, *m_pNode[0]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (!(i < n))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for exact match.
+ if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Existing entry. Check address.
+ sal_uInt32 nAddr = m_pNode[0]->m_pData[i].m_aLink.m_nAddr;
+ if (nAddr == STORE_PAGE_NULL)
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Load page.
+ rPage.location (nAddr);
+ return load (rPage);
+}
+
+/*
+ * save.
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::save (
+ const OStorePageKey &rKey,
+ OStoreDirectoryPageObject &rPage)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Setup BTree entry.
+ entry e;
+ e.m_aKey = rKey;
+
+ // Find NodePage.
+ storeError eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (i < n)
+ {
+ // Compare entry.
+ entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]);
+ VOS_POSTCOND(
+ result != entry::COMPARE_LESS,
+ "OStorePageManager::save(): find failed");
+
+ // Check result.
+ if (result == entry::COMPARE_LESS)
+ {
+ // Must not happen.
+ return store_E_Unknown;
+ }
+
+ if (result == entry::COMPARE_EQUAL)
+ {
+ // Existing entry. Check address.
+ sal_uInt32 nAddr = m_pNode[0]->m_pData[i].m_aLink.m_nAddr;
+ if (nAddr == STORE_PAGE_NULL)
+ {
+ // Allocate page.
+ eErrCode = base::allocate (rPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Modify page address.
+ m_pNode[0]->m_pData[i].m_aLink.m_nAddr = rPage.location();
+
+ // Save modified NodePage.
+ node aNode (*m_pNode[0]);
+ return save (aNode);
+ }
+ else
+ {
+ // Save page.
+ rPage.location (nAddr);
+ return save (rPage);
+ }
+ }
+ }
+
+ // Allocate.
+ eErrCode = base::allocate (rPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Insert.
+ e.m_aLink.m_nAddr = rPage.location();
+ m_pNode[0]->insert (i + 1, e);
+
+ // Save modified NodePage.
+ node aNode (*m_pNode[0]);
+ return save (aNode);
+}
+
+/*
+ * attrib [nAttrib = ((nAttrib & ~nMask1) | nMask2)].
+ * Precond: initialized.
+ */
+storeError OStorePageManager::attrib (
+ const OStorePageKey &rKey,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2,
+ sal_uInt32 &rAttrib)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ // Setup BTree entry.
+ entry e;
+ e.m_aKey = rKey;
+
+ // Find NodePage.
+ storeError eErrCode = find (e, *m_pNode[0]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (!(i < n))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for exact match.
+ if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Existing entry.
+ e = m_pNode[0]->m_pData[i];
+ if (nMask1 != nMask2)
+ {
+ // Evaluate new attributes.
+ sal_uInt32 nAttrib = e.m_nAttrib;
+
+ nAttrib &= ~nMask1;
+ nAttrib |= nMask2;
+
+ if (nAttrib != e.m_nAttrib)
+ {
+ // Check access mode.
+ if (base::isWriteable())
+ {
+ // Set new attributes.
+ e.m_nAttrib = nAttrib;
+ m_pNode[0]->m_pData[i] = e;
+
+ // Save modified NodePage.
+ node aNode (*m_pNode[0]);
+ eErrCode = save (aNode);
+ }
+ else
+ {
+ // Access denied.
+ eErrCode = store_E_AccessViolation;
+ }
+ }
+ }
+
+ // Obtain current attributes.
+ rAttrib = e.m_nAttrib;
+ return eErrCode;
+}
+
+/*
+ * link (insert 'Source' as hardlink to 'Destination').
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::link (
+ const OStorePageKey &rSrcKey,
+ const OStorePageKey &rDstKey)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Setup 'Destination' BTree entry.
+ entry e;
+ e.m_aKey = rDstKey;
+
+ // Find 'Destination' NodePage.
+ storeError eErrCode = find (e, *m_pNode[0]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find 'Destination' Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (!(i < n))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for exact match.
+ if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Existing entry. Check address.
+ e = m_pNode[0]->m_pData[i];
+ if (e.m_aLink.m_nAddr == STORE_PAGE_NULL)
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Setup 'Source' BTree entry.
+ e.m_aKey = rSrcKey;
+ e.m_nAttrib = STORE_ATTRIB_ISLINK;
+
+ // Find 'Source' NodePage.
+ eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find 'Source' Index.
+ i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (i < n)
+ {
+ // Compare entry.
+ entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]);
+ VOS_POSTCOND(
+ result != entry::COMPARE_LESS,
+ "OStorePageManager::link(): find failed");
+
+ // Check result.
+ if (result == entry::COMPARE_LESS)
+ {
+ // Must not happen.
+ return store_E_Unknown;
+ }
+
+ if (result == entry::COMPARE_EQUAL)
+ {
+ // Existing 'Source' entry.
+ return store_E_AlreadyExists;
+ }
+ }
+
+ // Insert 'Source' entry.
+ m_pNode[0]->insert (i + 1, e);
+
+ node aNode (*m_pNode[0]);
+ return save (aNode);
+}
+
+/*
+ * symlink (insert 'Source' DirectoryPage as symlink to 'Destination').
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::symlink (
+ const rtl_String *pSrcPath,
+ const rtl_String *pSrcName,
+ const OStorePageKey &rDstKey)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Check 'Source' parameter.
+ storeError eErrCode = store_E_InvalidParameter;
+ if (!(pSrcPath && pSrcName))
+ return eErrCode;
+
+ // Setup 'Source' page key.
+ OStorePageKey aSrcKey;
+ eErrCode = OStorePageNameBlock::namei (pSrcPath, pSrcName, aSrcKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Setup 'Source' BTree entry.
+ entry e;
+ e.m_aKey = aSrcKey;
+
+ // Find 'Source' NodePage.
+ eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find 'Source' Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (i < n)
+ {
+ // Compare entry.
+ entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]);
+ VOS_POSTCOND(
+ result != entry::COMPARE_LESS,
+ "OStorePageManager::symlink(): find failed");
+
+ // Check result.
+ if (result == entry::COMPARE_LESS)
+ {
+ // Must not happen.
+ return store_E_Unknown;
+ }
+
+ if (result == entry::COMPARE_EQUAL)
+ {
+ // Existing 'Source' entry.
+ return store_E_AlreadyExists;
+ }
+ }
+
+ // Initialize directory page buffer.
+ if (m_pDirect)
+ m_pDirect->initialize();
+ if (!m_pDirect)
+ m_pDirect = new(m_nPageSize) inode(m_nPageSize);
+ if (!m_pDirect)
+ return store_E_OutOfMemory;
+
+ // Setup as 'Source' directory page.
+ m_pDirect->m_aNameBlock.m_aKey = aSrcKey;
+ rtl_copyMemory (
+ &m_pDirect->m_aNameBlock.m_pData[0],
+ pSrcName->buffer, pSrcName->length);
+
+ // Store 'Destination' page key.
+ OStorePageKey aDstKey (rDstKey);
+#ifdef OSL_BIGENDIAN
+ aDstKey.swap(); // Swap to external representation.
+#endif /* OSL_BIGENDIAN */
+ rtl_copyMemory (&m_pDirect->m_pData[0], &aDstKey, sizeof(aDstKey));
+
+ // Mark 'Source' as symbolic link to 'Destination'.
+ OStoreDirectoryPageObject aPage (*m_pDirect);
+ aPage.attrib (STORE_ATTRIB_ISLINK);
+ aPage.dataLength (sizeof (aDstKey));
+
+ // Allocate and save 'Source' directory page.
+ eErrCode = base::allocate (aPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Insert 'Source' entry.
+ e.m_aLink.m_nAddr = aPage.location();
+ m_pNode[0]->insert (i + 1, e);
+
+ // Save modified NodePage.
+ node aNode (*m_pNode[0]);
+ return save (aNode);
+}
+
+/*
+ * rename.
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::rename (
+ const OStorePageKey &rSrcKey,
+ const rtl_String *pDstPath,
+ const rtl_String *pDstName)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Check 'Destination' parameter.
+ storeError eErrCode = store_E_InvalidParameter;
+ if (!(pDstPath && pDstName))
+ return eErrCode;
+
+ // Setup 'Destination' page key.
+ OStorePageKey aDstKey;
+ eErrCode = OStorePageNameBlock::namei (pDstPath, pDstName, aDstKey);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Setup 'Source' BTree entry.
+ entry e;
+ e.m_aKey = rSrcKey;
+
+ // Find 'Source' NodePage.
+ eErrCode = find (e, *m_pNode[0]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find 'Source' Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (!(i < n))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for exact match.
+ if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Existing 'Source' entry. Check address.
+ e = m_pNode[0]->m_pData[i];
+ if (e.m_aLink.m_nAddr == STORE_PAGE_NULL)
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for hardlink.
+ if (!(e.m_nAttrib & STORE_ATTRIB_ISLINK))
+ {
+ // Check directory page buffer.
+ if (!m_pDirect)
+ m_pDirect = new(m_nPageSize) inode(m_nPageSize);
+ if (!m_pDirect)
+ return store_E_OutOfMemory;
+
+ // Load directory page.
+ OStoreDirectoryPageObject aPage (*m_pDirect);
+ aPage.location (e.m_aLink.m_nAddr);
+
+ eErrCode = base::load (aPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for directory.
+ if (aPage.attrib() & STORE_ATTRIB_ISDIR)
+ {
+ // Ugly, but necessary (backward compatibility).
+ aDstKey.m_nLow = OStorePageGuard::crc32 (aDstKey.m_nLow, "/", 1);
+ }
+ }
+
+ // Let 'Source' entry be 'Destination' entry.
+ e.m_aKey = aDstKey;
+
+ // Find 'Destination' NodePage.
+ eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find 'Destination' Index.
+ i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (i < n)
+ {
+ // Compare entry.
+ entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]);
+ VOS_POSTCOND(
+ result != entry::COMPARE_LESS,
+ "OStorePageManager::rename(): find failed");
+
+ // Check result.
+ if (result == entry::COMPARE_LESS)
+ {
+ // Must not happen.
+ return store_E_Unknown;
+ }
+
+ if (result == entry::COMPARE_EQUAL)
+ {
+ // Existing 'Destination' entry.
+ return store_E_AlreadyExists;
+ }
+ }
+
+ // Insert 'Destination' entry.
+ node aNode (*m_pNode[0]);
+ m_pNode[0]->insert (i + 1, e);
+
+ eErrCode = save (aNode);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for hardlink.
+ if (!(e.m_nAttrib & STORE_ATTRIB_ISLINK))
+ {
+ // Setup 'Destination' NameBlock.
+ sal_Int32 nDstLen = pDstName->length;
+ rtl_copyMemory (
+ &m_pDirect->m_aNameBlock.m_pData[0],
+ pDstName->buffer, nDstLen);
+ rtl_zeroMemory (
+ &m_pDirect->m_aNameBlock.m_pData[nDstLen],
+ STORE_MAXIMUM_NAMESIZE - nDstLen);
+ m_pDirect->m_aNameBlock.m_aKey = e.m_aKey;
+
+ // Save directory page.
+ OStoreDirectoryPageObject aPage (*m_pDirect);
+ aPage.location (e.m_aLink.m_nAddr);
+
+ eErrCode = base::save (aPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Remove 'Source' entry.
+ e.m_aKey = rSrcKey;
+ return remove (e, *m_pNode[0], *m_pNode[1]);
+}
+
+/*
+ * remove.
+ * Precond: initialized, writeable.
+ */
+storeError OStorePageManager::remove (const OStorePageKey &rKey)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ if (!base::isWriteable())
+ return store_E_AccessViolation;
+
+ // Setup BTree entry.
+ entry e;
+ e.m_aKey = rKey;
+
+ // Find NodePage.
+ storeError eErrCode = find (e, *m_pNode[0]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (!(i < n))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for exact match.
+ if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL))
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Existing entry. Check address.
+ e = m_pNode[0]->m_pData[i];
+ if (e.m_aLink.m_nAddr == STORE_PAGE_NULL)
+ {
+ // Page not present.
+ return store_E_NotExists;
+ }
+
+ // Check for hardlink.
+ if (!(e.m_nAttrib & STORE_ATTRIB_ISLINK))
+ {
+ // Check directory page buffer.
+ if (!m_pDirect)
+ m_pDirect = new(m_nPageSize) inode(m_nPageSize);
+ if (!m_pDirect)
+ return store_E_OutOfMemory;
+
+ // Load directory page.
+ OStoreDirectoryPageObject aPage (*m_pDirect);
+ aPage.location (e.m_aLink.m_nAddr);
+
+ eErrCode = base::load (aPage);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Acquire page write access.
+ OStorePageDescriptor aDescr (m_pDirect->m_aDescr);
+ eErrCode = base::acquirePage (aDescr, store_AccessReadWrite);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check for symbolic link.
+ if (!(aPage.attrib() & STORE_ATTRIB_ISLINK))
+ {
+ // Ordinary inode. Determine 'Data' scope.
+ inode::ChunkScope eScope = m_pDirect->scope (aPage.dataLength());
+ if (eScope == inode::SCOPE_EXTERNAL)
+ {
+ // External 'Data' scope. Check data page buffer.
+ if (!m_pData)
+ m_pData = new(m_nPageSize) data(m_nPageSize);
+ if (!m_pData)
+ return store_E_OutOfMemory;
+
+ // Truncate all external data pages.
+ OStoreDataPageObject aData (*m_pData);
+ eErrCode = aPage.truncate (
+ 0, m_pLink[0], m_pLink[1], m_pLink[2], aData, *this);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ // Truncate internal data page.
+ rtl_zeroMemory (&m_pDirect->m_pData[0], m_pDirect->capacity());
+ aPage.dataLength (0);
+ }
+
+ // Release page write access.
+ eErrCode = base::releasePage (aDescr, store_AccessReadWrite);
+
+ // Release and free directory page.
+ eErrCode = base::free (aPage);
+ }
+
+ // Remove entry.
+ return remove (e, *m_pNode[0], *m_pNode[1]);
+}
+
+/*
+ * iterate.
+ * Precond: initialized.
+ * ToDo: skip hardlink entries.
+ */
+storeError OStorePageManager::iterate (
+ OStorePageKey &rKey,
+ OStorePageObject &rPage,
+ sal_uInt32 &rAttrib)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check precond.
+ if (!self::isValid())
+ return store_E_InvalidAccess;
+
+ // Setup BTree entry.
+ entry e;
+ e.m_aKey = rKey;
+
+ // Find NodePage.
+ storeError eErrCode = find (e, *m_pNode[0]);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Find Index.
+ sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount();
+ if (!(i < n))
+ {
+ // Not found.
+ return store_E_NotExists;
+ }
+
+ // Compare entry.
+ entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]);
+ VOS_POSTCOND(
+ result != entry::COMPARE_LESS,
+ "OStorePageManager::iterate(): find failed");
+
+ // Check result.
+ if (result == entry::COMPARE_LESS)
+ {
+ // Must not happen.
+ return store_E_Unknown;
+ }
+
+ // GreaterEqual. Found next entry.
+ e = m_pNode[0]->m_pData[i];
+
+ // Setup result.
+ rKey = e.m_aKey;
+ rAttrib = e.m_nAttrib;
+
+ rPage.location (e.m_aLink.m_nAddr);
+
+ // Done.
+ return store_E_None;
+}
+
+/*
+ * RebuildContext.
+ */
+struct RebuildContext
+{
+ /** Representation.
+ */
+ NAMESPACE_VOS(ORef)<OStorePageBIOS> m_xBIOS;
+ OStorePageBIOS::ScanContext m_aCtx;
+
+ /** Construction.
+ */
+ RebuildContext (void)
+ : m_xBIOS (new OStorePageBIOS())
+ {}
+
+ /** initialize (PageBIOS and ScanContext).
+ */
+ storeError initialize (ILockBytes *pLockBytes, sal_uInt32 nMagic = 0)
+ {
+ storeError eErrCode = store_E_InvalidParameter;
+ if (pLockBytes)
+ {
+ m_xBIOS->initialize (pLockBytes, store_AccessReadOnly);
+ eErrCode = m_xBIOS->scanBegin (m_aCtx, nMagic);
+ }
+ return eErrCode;
+ }
+
+ /** initialize (ScanContext).
+ */
+ storeError initialize (sal_uInt32 nMagic = 0)
+ {
+ return m_xBIOS->scanBegin (m_aCtx, nMagic);
+ }
+
+ /** load (next ScanContext matching page).
+ */
+ storeError load (OStorePageObject &rPage)
+ {
+ if (m_aCtx.isValid())
+ return m_xBIOS->scanNext (m_aCtx, rPage);
+ else
+ return store_E_CantSeek;
+ }
+
+ /** getPageSize.
+ */
+ storeError getPageSize (sal_uInt16 &rnPageSize)
+ {
+ return m_xBIOS->getPageSize (rnPageSize);
+ }
+};
+
+/*
+ * rebuild.
+ * Precond: none.
+ */
+storeError OStorePageManager::rebuild (
+ ILockBytes *pSrcLB, ILockBytes *pDstLB)
+{
+ // Acquire exclusive access.
+ NAMESPACE_VOS(OGuard) aGuard(*this);
+
+ // Check arguments.
+ storeError eErrCode = store_E_InvalidParameter;
+ if (!(pSrcLB && pDstLB))
+ return eErrCode;
+
+ // Initialize 'Source' rebuild context.
+ RebuildContext aCtx;
+ eErrCode = aCtx.initialize (pSrcLB, STORE_MAGIC_DIRECTORYPAGE);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Obtain 'Source' page size.
+ sal_uInt16 nPageSize = 0;
+ eErrCode = aCtx.getPageSize (nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Initialize as 'Destination' with 'Source' page size.
+ eErrCode = self::initialize (pDstLB, store_AccessCreate, nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Initialize directory and data page buffers.
+ if (!m_pDirect)
+ m_pDirect = new(m_nPageSize) inode(m_nPageSize);
+ if (!m_pData)
+ m_pData = new(m_nPageSize) data(m_nPageSize);
+ if (!(m_pDirect && m_pData))
+ return store_E_OutOfMemory;
+
+ // Initialize 'Source' directory page.
+ inode *pDirect = new(m_nPageSize) inode(m_nPageSize);
+ if (!pDirect)
+ return store_E_OutOfMemory;
+
+ // Scan 'Source' directory pages.
+ OStoreDirectoryPageObject aSrcPage (*pDirect);
+ while ((eErrCode = aCtx.load(aSrcPage)) == store_E_None)
+ {
+ // Obtain page key and data length.
+ OStorePageKey aKey (pDirect->m_aNameBlock.m_aKey);
+ sal_uInt32 nDataLen = pDirect->m_aDataBlock.m_nDataLen;
+
+ // Determine data page scope.
+ inode::ChunkScope eScope = pDirect->scope (nDataLen);
+ if (eScope == inode::SCOPE_INTERNAL)
+ {
+ // Internal scope. Just insert directory node.
+ eErrCode = save (aKey, aSrcPage);
+ if (eErrCode != store_E_None)
+ break;
+ }
+ else
+ {
+ // External scope.
+ OStoreDirectoryPageObject aDstPage (*m_pDirect);
+ rtl_copyMemory (m_pDirect, pDirect, m_nPageSize);
+
+ m_pDirect->m_aDataBlock.initialize();
+ m_pDirect->m_aDataBlock.m_nDataLen = m_pDirect->capacity();
+
+ // Insert 'Destination' directory page.
+ eErrCode = save (aKey, aDstPage);
+ if (eErrCode != store_E_None)
+ break;
+
+ // Determine data page count.
+ inode::ChunkDescriptor aDescr (
+ nDataLen - m_pDirect->capacity(), m_pData->capacity());
+
+ sal_uInt32 i, n = aDescr.m_nPage;
+ if (aDescr.m_nOffset) n += 1;
+
+ // Copy data pages.
+ OStoreDataPageObject aData (*m_pData);
+ for (i = 0; i < n; i++)
+ {
+ // Re-initialize data page size.
+ m_pData->m_aDescr.m_nSize = m_nPageSize;
+
+ // Read 'Source' data page.
+ OStorePageBIOS &rBIOS = *(aCtx.m_xBIOS);
+ NAMESPACE_VOS(IMutex) &rMutex = rBIOS;
+
+ eErrCode = aSrcPage.get (
+ i, m_pLink[0], m_pLink[1], m_pLink[2],
+ aData, rBIOS, &rMutex);
+ if (eErrCode != store_E_None)
+ continue;
+
+ // Write 'Destination' data page.
+ eErrCode = aDstPage.put (
+ i, m_pLink[0], m_pLink[1], m_pLink[2],
+ aData, *this, NULL);
+ }
+
+ // Update 'Destination' directory page.
+ m_pDirect->m_aDataBlock.m_nDataLen = nDataLen;
+ eErrCode = base::save (aDstPage);
+ }
+ }
+
+ // Scan 'Source' BTree nodes.
+ page *pNode = new(m_nPageSize) page(m_nPageSize);
+ node aNode (*pNode);
+ entry e;
+
+ aCtx.initialize (STORE_MAGIC_BTREENODE);
+ while ((eErrCode = aCtx.load(aNode)) == store_E_None)
+ {
+ // Check for leaf node.
+ if (pNode->depth() == 0)
+ {
+ sal_uInt16 i, n = pNode->usageCount();
+ for (i = 0; i < n; i++)
+ {
+ e = pNode->m_pData[i];
+ if (e.m_nAttrib & STORE_ATTRIB_ISLINK)
+ {
+ // Hard link.
+ aSrcPage.location (e.m_aLink.m_nAddr);
+ pDirect->m_aDescr.m_nSize = m_nPageSize;
+
+ eErrCode = aCtx.m_xBIOS->load (aSrcPage);
+ if (eErrCode == store_E_None)
+ {
+ OStorePageKey aDstKey (pDirect->m_aNameBlock.m_aKey);
+ eErrCode = link (e.m_aKey, aDstKey);
+ }
+ e.m_nAttrib &= ~STORE_ATTRIB_ISLINK;
+ }
+
+ if (e.m_nAttrib)
+ {
+ // Ordinary attributes.
+ sal_uInt32 nAttrib = 0;
+ eErrCode = attrib (e.m_aKey, 0, e.m_nAttrib, nAttrib);
+ }
+ }
+ }
+ }
+
+ // Cleanup.
+ delete pDirect;
+ delete pNode;
+
+ // Done.
+ return store_E_None;
+}
+
diff --git a/store/source/storpage.hxx b/store/source/storpage.hxx
new file mode 100644
index 000000000..ef9dd172b
--- /dev/null
+++ b/store/source/storpage.hxx
@@ -0,0 +1,276 @@
+/*************************************************************************
+ *
+ * $RCSfile: storpage.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORPAGE_HXX_
+#define _STORE_STORPAGE_HXX_ "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_OBJECT_HXX_
+#include <vos/object.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_LOCKBYTE_HXX_
+#include <store/lockbyte.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORDMON_HXX_
+#include <stordmon.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+struct OStoreBTreeEntry;
+struct OStoreBTreeNodeData;
+class OStoreBTreeNodeObject;
+
+struct OStoreDataPageData;
+struct OStoreIndirectionPageData;
+struct OStoreDirectoryPageData;
+class OStoreDirectoryPageObject;
+class OStorePageCache;
+
+/*========================================================================
+ *
+ * OStorePageManager interface.
+ *
+ *======================================================================*/
+class OStorePageManager : public NAMESPACE_STORE(OStorePageBIOS)
+{
+ VOS_DECLARE_CLASSINFO (VOS_NAMESPACE (OStorePageManager, store));
+
+public:
+ /** Construction.
+ */
+ OStorePageManager (void);
+
+ /** Initialization (two-phase construction).
+ */
+ virtual storeError initialize (
+ ILockBytes *pLockBytes,
+ storeAccessMode eAccessMode,
+ sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE);
+
+ /** isValid.
+ * @return sal_True upon successful initialization,
+ * sal_False otherwise.
+ */
+ inline sal_Bool isValid (void) const;
+
+ /** Page I/O (unmanaged).
+ */
+ virtual storeError free (
+ OStorePageObject &rPage);
+
+ virtual storeError load (
+ OStorePageObject &rPage);
+
+ virtual storeError save (
+ OStorePageObject &rPage);
+
+ virtual storeError flush (void);
+
+ /** DirectoryPage I/O (managed).
+ */
+ storeError load (
+ const OStorePageKey &rKey,
+ OStoreDirectoryPageObject &rPage);
+
+ storeError save (
+ const OStorePageKey &rKey,
+ OStoreDirectoryPageObject &rPage);
+
+ /** attrib [nAttrib = ((nAttrib & ~nMask1) | nMask2)].
+ */
+ storeError attrib (
+ const OStorePageKey &rKey,
+ sal_uInt32 nMask1,
+ sal_uInt32 nMask2,
+ sal_uInt32 &rAttrib);
+
+ /** link (insert Source Key as hardlink to Destination).
+ */
+ storeError link (
+ const OStorePageKey &rSrcKey,
+ const OStorePageKey &rDstKey);
+
+ /** symlink (insert Source DirectoryPage as symlink to Destination).
+ */
+ storeError symlink (
+ const rtl_String *pSrcPath,
+ const rtl_String *pSrcName,
+ const OStorePageKey &rDstKey);
+
+ /** rename.
+ */
+ storeError rename (
+ const OStorePageKey &rSrcKey,
+ const rtl_String *pDstPath,
+ const rtl_String *pDstName);
+
+ /** remove.
+ */
+ storeError remove (
+ const OStorePageKey &rKey);
+
+ /** iterate.
+ */
+ storeError iterate (
+ OStorePageKey &rKey,
+ OStorePageObject &rPage,
+ sal_uInt32 &rAttrib);
+
+ /** rebuild (combines recover and compact from 'Src' to 'Dst').
+ * @param pSrcLB [in] accessed readonly.
+ * @param pDstLB [in] truncated and accessed readwrite (as initialize()).
+ * @return store_E_None upon success.
+ */
+ storeError rebuild (
+ ILockBytes *pSrcLB,
+ ILockBytes *pDstLB);
+
+protected:
+ /** Destruction (OReference).
+ */
+ virtual ~OStorePageManager (void);
+
+private:
+ /** Implementation.
+ */
+ typedef OStorePageBIOS base;
+ typedef OStorePageManager self;
+
+ typedef OStoreBTreeEntry entry;
+ typedef OStoreBTreeNodeData page;
+ typedef OStoreBTreeNodeObject node;
+
+ typedef OStoreDirectoryPageData inode;
+ typedef OStoreIndirectionPageData indirect;
+ typedef OStoreDataPageData data;
+
+ /** Representation.
+ */
+ typedef NAMESPACE_VOS(ORef)<OStorePageDaemon> OStorePageDaemonRef;
+ OStorePageDaemonRef m_xDaemon;
+ OStorePageCache *m_pCache;
+
+ page *m_pNode[3];
+ inode *m_pDirect;
+ indirect *m_pLink[3];
+ data *m_pData;
+ sal_uInt16 m_nPageSize;
+
+ /** find (node page, w/o split).
+ */
+ storeError find (
+ const entry& rEntry, page& rPage);
+
+ /** find (node page, possibly with split).
+ */
+ storeError find (
+ const entry &rEntry, page &rPage, page &rPageL, page &rPageR);
+
+ /** remove (possibly down from root).
+ */
+ storeError remove (
+ entry &rEntry, page &rPage, page &rPageL);
+
+ /** Not implemented.
+ */
+ OStorePageManager (const OStorePageManager&);
+ OStorePageManager& operator= (const OStorePageManager&);
+};
+
+inline sal_Bool OStorePageManager::isValid (void) const
+{
+ return (base::isValid() && (m_nPageSize > 0));
+}
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORPAGE_HXX_ */
+
diff --git a/store/source/stortree.cxx b/store/source/stortree.cxx
new file mode 100644
index 000000000..69d343f80
--- /dev/null
+++ b/store/source/stortree.cxx
@@ -0,0 +1,608 @@
+/*************************************************************************
+ *
+ * $RCSfile: stortree.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _STORE_STORTREE_CXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX
+#include <storbase.hxx>
+#endif
+#ifndef _STORE_STORTREE_HXX
+#include <stortree.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * OStoreBTreeNodeData implementation.
+ *
+ *======================================================================*/
+/*
+ * OStoreBTreeNodeData.
+ */
+OStoreBTreeNodeData::OStoreBTreeNodeData (sal_uInt16 nPageSize)
+ : OStorePageData (nPageSize)
+{
+ initialize();
+}
+
+/*
+ * initialize.
+ */
+void OStoreBTreeNodeData::initialize (void)
+{
+ base::m_aGuard.m_nMagic = STORE_MAGIC_BTREENODE;
+ base::m_aDescr.m_nUsed = base::size() + self::size();
+ self::m_aGuard.m_nMagic = 0;
+
+ sal_uInt16 i, n = capacityCount();
+ T t;
+
+ for (i = 1; i < n; i++)
+ m_pData[i] = t;
+}
+
+/*
+ * swap.
+ */
+void OStoreBTreeNodeData::swap (const D& rDescr)
+{
+#ifdef OSL_BIGENDIAN
+ m_aGuard.swap();
+
+ sal_uInt16 i, n = capacity(rDescr) / sizeof(T);
+ for (i = 0; i < n; i++)
+ m_pData[i].swap();
+#endif /* OSL_BIGENDIAN */
+}
+
+/*
+ * find.
+ */
+sal_uInt16 OStoreBTreeNodeData::find (const T& t) const
+{
+ register sal_Int32 l = 0;
+ register sal_Int32 r = usageCount() - 1;
+
+ while (l < r)
+ {
+ register sal_Int32 m = ((l + r) >> 1);
+
+ if (t.m_aKey == m_pData[m].m_aKey)
+ return ((sal_uInt16)(m));
+ if (t.m_aKey < m_pData[m].m_aKey)
+ r = m - 1;
+ else
+ l = m + 1;
+ }
+
+ sal_uInt16 k = ((sal_uInt16)(r));
+ if ((k < capacityCount()) && (t.m_aKey < m_pData[k].m_aKey))
+ return(k - 1);
+ else
+ return(k);
+}
+
+/*
+ * insert.
+ */
+void OStoreBTreeNodeData::insert (sal_uInt16 i, const T& t)
+{
+ sal_uInt16 n = usageCount();
+ sal_uInt16 m = capacityCount();
+ if ((n < m) && (i < m))
+ {
+ // shift right.
+ rtl_moveMemory (&m_pData[i + 1], &m_pData[i], (n - i) * sizeof(T));
+
+ // insert.
+ m_pData[i] = t;
+ base::m_aDescr.m_nUsed += sizeof(T);
+ }
+}
+
+/*
+ * remove.
+ */
+void OStoreBTreeNodeData::remove (sal_uInt16 i)
+{
+ sal_uInt16 n = usageCount();
+ sal_uInt16 m = capacityCount();
+ if (i < n)
+ {
+ // shift left.
+ rtl_moveMemory (
+ &m_pData[i], &m_pData[i + 1], (n - i - 1) * sizeof(T));
+
+ // truncate.
+ m_pData[n - 1] = T();
+ base::m_aDescr.m_nUsed -= sizeof(T);
+ }
+}
+
+/*
+ * merge.
+ */
+void OStoreBTreeNodeData::merge (const self& rPageR)
+{
+ if (queryMerge (rPageR))
+ {
+ sal_uInt16 n = usageCount();
+ sal_uInt16 m = rPageR.usageCount();
+ rtl_copyMemory (&m_pData[n], &rPageR.m_pData[0], m * sizeof(T));
+ usageCount (n + m);
+ }
+}
+
+/*
+ * split.
+ */
+void OStoreBTreeNodeData::split (const self& rPageL)
+{
+ sal_uInt16 h = capacityCount() / 2;
+ rtl_copyMemory (&m_pData[0], &rPageL.m_pData[h], h * sizeof(T));
+ truncate (h);
+}
+
+/*
+ * truncate.
+ */
+void OStoreBTreeNodeData::truncate (sal_uInt16 n)
+{
+ sal_uInt16 m = capacityCount();
+ T t;
+
+ for (sal_uInt16 i = n; i < m; i++)
+ m_pData[i] = t;
+ usageCount (n);
+}
+
+/*========================================================================
+ *
+ * OStoreBTreeNodeObject implementation.
+ *
+ *======================================================================*/
+/*
+ * swap.
+ */
+void OStoreBTreeNodeObject::swap (const D& rDescr)
+{
+#ifdef OSL_BIGENDIAN
+ base::swap (rDescr);
+ m_rPage.swap (rDescr);
+#endif /* OSL_BIGENDIAN */
+}
+
+/*
+ * guard.
+ */
+void OStoreBTreeNodeObject::guard (const D& rDescr)
+{
+ base::guard (rDescr);
+ m_rPage.guard (rDescr);
+}
+
+/*
+ * verify.
+ */
+storeError OStoreBTreeNodeObject::verify (const D& rDescr)
+{
+ storeError eErrCode = base::verify (rDescr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ else
+ return m_rPage.verify (rDescr);
+}
+
+/*
+ * split.
+ */
+storeError OStoreBTreeNodeObject::split (
+ sal_uInt16 nIndexL,
+ OStoreBTreeNodeData &rPageL,
+ OStoreBTreeNodeData &rPageR,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Check usage.
+ if (!rPageL.querySplit())
+ return store_E_None;
+
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Save PageDescriptor.
+ D aDescr (m_rPage.m_aDescr);
+
+ // Acquire Lock.
+ storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Begin PageL Lock (NYI).
+
+ // Split right page off left page.
+ rPageR.split (rPageL);
+ rPageR.depth (rPageL.depth());
+
+ // Allocate right page.
+ self aNodeR (rPageR);
+ eErrCode = rBIOS.allocate (aNodeR);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Truncate left page.
+ rPageL.truncate (rPageL.capacityCount() / 2);
+
+ // Save left page.
+ self aNodeL (rPageL);
+ eErrCode = rBIOS.save (aNodeL);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreBTreeNodeObject::split(): save() failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // End PageL Lock (NYI).
+
+ // Insert right page.
+ T entry;
+ entry.m_aKey = rPageR.m_pData[0].m_aKey;
+ entry.m_aLink.m_nAddr = rPageR.location();
+
+ m_rPage.insert (nIndexL + 1, entry);
+
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreBTreeNodeObject::split(): save() failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+#if 0 /* PERFORMANCE */
+ eErrCode = rBIOS.flush();
+#endif /* PERFORMANCE */
+
+ // Release Lock and Leave.
+ eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * remove (down to leaf node, recursive).
+ */
+storeError OStoreBTreeNodeObject::remove (
+ sal_uInt16 nIndexL,
+ OStoreBTreeEntry &rEntryL,
+ OStoreBTreeNodeData &rPageL,
+#if 0 /* NYI */
+ OStoreBTreeNodeData &rPageR,
+#endif /* NYI */
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Save PageDescriptor.
+ D aDescr (m_rPage.m_aDescr);
+
+ // Acquire Lock.
+ storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Check depth.
+ if (m_rPage.depth())
+ {
+ // Check link entry.
+ if (!(rEntryL.compare (m_rPage.m_pData[nIndexL]) == T::COMPARE_EQUAL))
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess);
+ }
+
+ // Load link node.
+ self aNodeL (rPageL);
+ aNodeL.location (m_rPage.m_pData[nIndexL].m_aLink.m_nAddr);
+
+ eErrCode = rBIOS.load (aNodeL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Remove from link node (using current page as link buffer).
+ eErrCode = aNodeL.remove (0, rEntryL, m_rPage, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Reload current page.
+ m_rPage.location (aDescr.m_nAddr);
+ eErrCode = rBIOS.load (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreBTreeNodeObject::remove(): load() failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Check link node usage.
+ if (rPageL.usageCount() == 0)
+ {
+ // Free empty link node.
+ eErrCode = rBIOS.free (aNodeL);
+ if (eErrCode != store_E_None)
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ // Remove index.
+ m_rPage.remove (nIndexL);
+ touch();
+ }
+ else
+ {
+#if 0 /* NYI */
+ // Check for right sibling.
+ sal_uInt16 nIndexR = nIndexL + 1;
+ if (nIndexR < m_rPage.usageCount())
+ {
+ // Load right link node.
+ self aNodeR (rPageR);
+ aNodeR.location (m_rPage.m_pData[nIndexR].m_aLink.m_nAddr);
+
+ eErrCode = rBIOS.load (aNodeR);
+ if (eErrCode == store_E_None)
+ {
+ if (rPageL.queryMerge (rPageR))
+ {
+ rPageL.merge (rPageR);
+
+ eErrCode = rBIOS.free (rPageR);
+ }
+ }
+ }
+#endif /* NYI */
+
+ // Relink.
+ m_rPage.m_pData[nIndexL].m_aKey = rPageL.m_pData[0].m_aKey;
+ touch();
+ }
+ }
+ else
+ {
+ // Check leaf entry.
+ if (!(rEntryL.compare (m_rPage.m_pData[nIndexL]) == T::COMPARE_EQUAL))
+ {
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, store_E_NotExists);
+ }
+
+ // Save leaf entry.
+ rEntryL = m_rPage.m_pData[nIndexL];
+
+ // Remove leaf index.
+ m_rPage.remove (nIndexL);
+ touch();
+ }
+
+ // Check for modified node.
+ if (dirty())
+ {
+ // Save this page.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreBTreeNodeObject::remove(): save() failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+ }
+
+ // Release Lock and Leave.
+ eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*========================================================================
+ *
+ * OStoreBTreeRootObject implementation.
+ *
+ *======================================================================*/
+/*
+ * change.
+ */
+storeError OStoreBTreeRootObject::change (
+ OStoreBTreeNodeData &rPageL,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Save PageDescriptor.
+ typedef OStorePageDescriptor D;
+ D aDescr (m_rPage.m_aDescr);
+
+ // Acquire Lock.
+ storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Change root.
+ rPageL = m_rPage;
+
+ base aNodeL (rPageL);
+ eErrCode = rBIOS.allocate (aNodeL);
+ if (eErrCode != store_E_None)
+ {
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+ m_rPage.m_pData[0].m_aKey = rPageL.m_pData[0].m_aKey;
+ m_rPage.m_pData[0].m_aLink.m_nAddr = rPageL.location();
+
+ m_rPage.truncate (1);
+ m_rPage.depth (m_rPage.depth() + 1);
+
+ // Save root.
+ eErrCode = rBIOS.save (*this);
+ if (eErrCode != store_E_None)
+ {
+ // Must not happen.
+ VOS_TRACE("OStoreBTreeRootObject::change(): save() failed");
+
+ // Release Lock and Leave.
+ rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+ }
+
+#if 1 /* ROBUSTNESS */
+ eErrCode = rBIOS.flush();
+#endif /* ROBUSTNESS */
+
+ // Done. Release Lock and Leave.
+ eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize);
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
+/*
+ * split.
+ */
+storeError OStoreBTreeRootObject::split (
+ sal_uInt16 nIndexL,
+ OStoreBTreeNodeData &rPageL,
+ OStoreBTreeNodeData &rPageR,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex)
+{
+ // Check usage.
+ if (!querySplit())
+ return store_E_None;
+
+ // Enter.
+ STORE_METHOD_ENTER(pMutex);
+
+ // Change root.
+ storeError eErrCode = change (rPageL, rBIOS, NULL);
+ if (eErrCode != store_E_None)
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+
+ // Split Left Page.
+ eErrCode = base::split (0, rPageL, rPageR, rBIOS, NULL);
+
+ // Leave.
+ STORE_METHOD_LEAVE(pMutex, eErrCode);
+}
+
diff --git a/store/source/stortree.hxx b/store/source/stortree.hxx
new file mode 100644
index 000000000..d07f3837c
--- /dev/null
+++ b/store/source/stortree.hxx
@@ -0,0 +1,451 @@
+/*************************************************************************
+ *
+ * $RCSfile: stortree.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORTREE_HXX
+#define _STORE_STORTREE_HXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_MUTEX_HXX_
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _STORE_TYPES_H_
+#include <store/types.h>
+#endif
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX
+#include <storbase.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+namespace store {
+#endif
+
+/*========================================================================
+ *
+ * OStoreBTreeEntry.
+ *
+ *======================================================================*/
+struct OStoreBTreeEntry
+{
+ typedef OStorePageKey K;
+ typedef OStorePageLink L;
+
+ /** Representation.
+ */
+ K m_aKey;
+ L m_aLink;
+ sal_uInt32 m_nAttrib;
+
+ /** Construction.
+ */
+ OStoreBTreeEntry (void)
+ : m_nAttrib (0)
+ {}
+
+ OStoreBTreeEntry (const OStoreBTreeEntry& rOther)
+ : m_aKey (rOther.m_aKey),
+ m_aLink (rOther.m_aLink),
+ m_nAttrib (rOther.m_nAttrib)
+ {}
+
+ OStoreBTreeEntry& operator= (const OStoreBTreeEntry& rOther)
+ {
+ m_aKey = rOther.m_aKey;
+ m_aLink = rOther.m_aLink;
+ m_nAttrib = rOther.m_nAttrib;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ enum CompareResult
+ {
+ COMPARE_LESS = -1,
+ COMPARE_EQUAL = 0,
+ COMPARE_GREATER = 1
+ };
+
+ CompareResult compare (const OStoreBTreeEntry& rOther) const
+ {
+ if (m_aKey < rOther.m_aKey)
+ return COMPARE_LESS;
+ else if (m_aKey == rOther.m_aKey)
+ return COMPARE_EQUAL;
+ else
+ return COMPARE_GREATER;
+ }
+
+ /** swap (internal and external representation).
+ */
+ void swap (void)
+ {
+#ifdef OSL_BIGENDIAN
+ m_aKey.swap();
+ m_aLink.swap();
+ m_nAttrib = VOS_SWAPDWORD(m_nAttrib);
+#endif /* OSL_BIGENDIAN */
+ }
+};
+
+/*========================================================================
+ *
+ * OStoreBTreeNodeData.
+ *
+ *======================================================================*/
+#define STORE_MAGIC_BTREENODE 0x58190322UL
+
+struct OStoreBTreeNodeData : public NAMESPACE_STORE(OStorePageData)
+{
+ typedef OStorePageData base;
+ typedef OStoreBTreeNodeData self;
+
+ typedef OStorePageGuard G;
+ typedef OStoreBTreeEntry T;
+
+ /** Representation.
+ */
+ G m_aGuard;
+ T m_pData[1];
+
+ /** size.
+ */
+ static sal_uInt16 size (void)
+ {
+ return (sizeof(G));
+ }
+
+ /** capacity.
+ */
+ static sal_uInt16 capacity (const D& rDescr)
+ {
+ return (rDescr.m_nSize - (base::size() + self::size()));
+ }
+ sal_uInt16 capacity (void) const
+ {
+ return self::capacity (base::m_aDescr);
+ }
+
+ /** capacityCount (must be even).
+ */
+ sal_uInt16 capacityCount (void) const
+ {
+ return (capacity() / sizeof(T));
+ }
+
+ /** usage.
+ */
+ static sal_uInt16 usage (const D& rDescr)
+ {
+ return (rDescr.m_nUsed - (base::size() + self::size()));
+ }
+ sal_uInt16 usage (void) const
+ {
+ return self::usage (base::m_aDescr);
+ }
+
+ /** usageCount.
+ */
+ sal_uInt16 usageCount (void) const
+ {
+ return (usage() / sizeof(T));
+ }
+ void usageCount (sal_uInt16 nCount)
+ {
+ base::m_aDescr.m_nUsed = base::size() + self::size();
+ base::m_aDescr.m_nUsed += nCount * sizeof(T);
+ }
+
+ /** Construction.
+ */
+ OStoreBTreeNodeData (sal_uInt16 nPageSize);
+ void initialize (void);
+
+ self& operator= (const self& rOther)
+ {
+ if (this != &rOther)
+ {
+ base::operator= (rOther);
+
+ m_aGuard = rOther.m_aGuard;
+ rtl_copyMemory (m_pData, rOther.m_pData, capacity());
+ }
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ sal_Bool operator== (const self& rOther) const
+ {
+ return (base::operator==(rOther) && (m_aGuard == rOther.m_aGuard));
+ }
+
+ /** swap (external and internal representation).
+ */
+ void swap (const D& rDescr);
+
+ /** guard (external representation).
+ */
+ void guard (const D& rDescr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ m_aGuard.m_nCRC32 = nCRC32;
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (const D& rDescr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr));
+#ifdef OSL_BIGENDIAN
+ nCRC32 = VOS_SWAPDWORD(nCRC32);
+#endif /* OSL_BIGENDIAN */
+ if (m_aGuard.m_nCRC32 != nCRC32)
+ return store_E_InvalidChecksum;
+ else
+ return store_E_None;
+ }
+
+ /** depth.
+ */
+ sal_uInt32 depth (void) const
+ {
+ return self::m_aGuard.m_nMagic;
+ }
+ void depth (sal_uInt32 nDepth)
+ {
+ self::m_aGuard.m_nMagic = nDepth;
+ }
+
+ /** queryMerge.
+ */
+ sal_Bool queryMerge (const self &rPageR) const
+ {
+ return ((usageCount() + rPageR.usageCount()) <= capacityCount());
+ }
+
+ /** querySplit.
+ */
+ sal_Bool querySplit (void) const
+ {
+ return (!(usageCount() < capacityCount()));
+ }
+
+ /** Operation.
+ */
+ sal_uInt16 find (const T& t) const;
+ void insert (sal_uInt16 i, const T& t);
+ void remove (sal_uInt16 i);
+
+ /** merge (with right page).
+ */
+ void merge (const self& rPageR);
+
+ /** split (left half copied from right half of left page).
+ */
+ void split (const self& rPageL);
+
+ /** truncate (to n elements).
+ */
+ void truncate (sal_uInt16 n);
+};
+
+/*========================================================================
+ *
+ * OStoreBTreeNodeObject.
+ *
+ *======================================================================*/
+class OStoreBTreeNodeObject :
+ public NAMESPACE_STORE(OStorePageObject)
+{
+ typedef OStorePageObject base;
+ typedef OStoreBTreeNodeObject self;
+ typedef OStoreBTreeNodeData page;
+
+ typedef OStorePageDescriptor D;
+ typedef OStoreBTreeEntry T;
+
+public:
+ /** Construction.
+ */
+ inline OStoreBTreeNodeObject (page& rPage);
+
+ /** External representation.
+ */
+ virtual void swap (const D& rDescr);
+ virtual void guard (const D& rDescr);
+ virtual storeError verify (const D& rDescr);
+
+ /** Query split.
+ */
+ inline sal_Bool querySplit (void) const;
+
+ /** split.
+ */
+ virtual storeError split (
+ sal_uInt16 nIndexL,
+ OStoreBTreeNodeData &rPageL,
+ OStoreBTreeNodeData &rPageR,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+ /** remove (down to leaf node, recursive).
+ */
+ storeError remove (
+ sal_uInt16 nIndexL,
+ OStoreBTreeEntry &rEntryL,
+ OStoreBTreeNodeData &rPageL,
+#if 0 /* NYI */
+ OStoreBTreeNodeData &rPageR,
+#endif /* NYI */
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+private:
+ /** Representation.
+ */
+ page& m_rPage;
+};
+
+inline OStoreBTreeNodeObject::OStoreBTreeNodeObject (page& rPage)
+ : OStorePageObject (rPage), m_rPage (rPage)
+{
+}
+
+inline sal_Bool OStoreBTreeNodeObject::querySplit (void) const
+{
+ return m_rPage.querySplit();
+}
+
+/*========================================================================
+ *
+ * OStoreBTreeRootObject.
+ *
+ *======================================================================*/
+class OStoreBTreeRootObject :
+ public NAMESPACE_STORE(OStoreBTreeNodeObject)
+{
+ typedef OStoreBTreeNodeObject base;
+ typedef OStoreBTreeNodeData page;
+
+public:
+ /** Construction.
+ */
+ inline OStoreBTreeRootObject (page& rPage);
+
+ /** split.
+ */
+ virtual storeError split (
+ sal_uInt16 nIndexL,
+ OStoreBTreeNodeData &rPageL,
+ OStoreBTreeNodeData &rPageR,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+
+private:
+ /** Representation.
+ */
+ page& m_rPage;
+
+ /** change (Root).
+ */
+ storeError change (
+ OStoreBTreeNodeData &rPageL,
+ OStorePageBIOS &rBIOS,
+ NAMESPACE_VOS(IMutex) *pMutex = NULL);
+};
+
+inline OStoreBTreeRootObject::OStoreBTreeRootObject (page& rPage)
+ : OStoreBTreeNodeObject (rPage), m_rPage (rPage)
+{
+}
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+#ifdef _USE_NAMESPACE
+}
+#endif
+
+#endif /* !_STORE_STORTREE_HXX */
+
diff --git a/store/util/makefile.mk b/store/util/makefile.mk
new file mode 100644
index 000000000..9e27d95a6
--- /dev/null
+++ b/store/util/makefile.mk
@@ -0,0 +1,113 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=store
+TARGET=sto
+TARGETTYPE=CUI
+
+USE_LDUMP2=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings ---
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+.INCLUDE : ..$/version.mk
+
+# --- Debug-Library ---
+
+.IF "$(debug)" != ""
+
+LIB1TARGET= $(LB)$/$(TARGET)dbg.lib
+LIB1ARCHIV= $(LB)$/lib$(TARGET)dbg.a
+LIB1FILES= $(LB)$/store.lib
+
+.ENDIF # debug
+
+# --- Shared-Library ---
+
+SHL1TARGET= $(STORE_TARGET)$(STORE_MAJOR)
+SHL1IMPLIB= istore
+SHL1VERSIONMAP= $(TARGET).map
+
+SHL1STDLIBS= $(VOSLIB) $(SALLIB)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN= $(L)$/ivos.lib $(L)$/isal.lib
+SHL1LIBS= $(SLB)$/store.lib
+
+# --- Def-File ---
+
+DEF1NAME= $(SHL1TARGET)
+DEF1EXPORTFILE= $(TARGET).dxp
+DEF1DES=Store
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
+
+
diff --git a/store/util/sto.dxp b/store/util/sto.dxp
new file mode 100644
index 000000000..b973c5e34
--- /dev/null
+++ b/store/util/sto.dxp
@@ -0,0 +1,25 @@
+store_acquireHandle
+store_attrib
+store_closeDirectory
+store_closeFile
+store_closeStream
+store_createMemoryFile
+store_findFirst
+store_findNext
+store_flushFile
+store_flushStream
+store_getFileRefererCount
+store_getFileSize
+store_getStreamSize
+store_link
+store_openDirectory
+store_openFile
+store_openStream
+store_readStream
+store_rebuildFile
+store_releaseHandle
+store_remove
+store_rename
+store_setStreamSize
+store_symlink
+store_writeStream
diff --git a/store/util/sto.map b/store/util/sto.map
new file mode 100644
index 000000000..1f3bca011
--- /dev/null
+++ b/store/util/sto.map
@@ -0,0 +1,30 @@
+STO_1_0 {
+ global:
+ store_acquireHandle;
+ store_attrib;
+ store_closeDirectory;
+ store_closeFile;
+ store_closeStream;
+ store_createMemoryFile;
+ store_findFirst;
+ store_findNext;
+ store_flushFile;
+ store_flushStream;
+ store_getFileRefererCount;
+ store_getFileSize;
+ store_getStreamSize;
+ store_link;
+ store_openDirectory;
+ store_openFile;
+ store_openStream;
+ store_readStream;
+ store_rebuildFile;
+ store_releaseHandle;
+ store_remove;
+ store_rename;
+ store_setStreamSize;
+ store_symlink;
+ store_writeStream;
+ local:
+ *;
+};
diff --git a/store/version.mk b/store/version.mk
new file mode 100644
index 000000000..c31b3dfaf
--- /dev/null
+++ b/store/version.mk
@@ -0,0 +1,75 @@
+#*************************************************************************
+#
+# $RCSfile: version.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 15:18:31 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+# target
+STORE_TARGET=store
+
+# the major
+STORE_MAJOR=2
+# the minor
+STORE_MINOR=0
+# the micro
+STORE_MICRO=0
+
+# this is a c++ compatible library
+STORE_CPP=0
+
diff --git a/store/workben/makefile.mk b/store/workben/makefile.mk
new file mode 100644
index 000000000..1d2965f9b
--- /dev/null
+++ b/store/workben/makefile.mk
@@ -0,0 +1,135 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=store
+TARGET=workben
+
+LIBTARGET=NO
+TARGETTYPE=CUI
+
+# --- Settings ---
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+.IF "$(STORELIB)" == ""
+.IF "$(GUI)" == "UNX"
+STOLIB= -lsto$(UPD)$(DLLPOSTFIX)
+.ELSE # unx
+STOLIB= $(LB)$/istore.lib
+.ENDIF # unx
+.ENDIF # storelib
+
+.IF "$(GUI)" == "UNX"
+STODBGLIB= $(LB)$/libstodbg.a
+.ELSE # unx
+STODBGLIB= $(LB)$/stodbg.lib
+.ENDIF # unx
+
+CFLAGS+= -I..$/source
+
+# --- Files ---
+
+CXXFILES= \
+ t_file.cxx \
+ t_base.cxx \
+ t_store.cxx
+
+OBJFILES= \
+ $(OBJ)$/t_file.obj \
+ $(OBJ)$/t_base.obj \
+ $(OBJ)$/t_store.obj
+
+APP1TARGET= t_file
+APP1OBJS= $(OBJ)$/t_file.obj
+APP1STDLIBS= $(STODBGLIB)
+APP1STDLIBS+= $(VOSLIB) $(SALLIB)
+APP1DEPN= \
+ $(STODBGLIB) \
+ $(L)$/ivos.lib \
+ $(L)$/isal.lib
+
+APP2TARGET= t_base
+APP2OBJS= $(OBJ)$/t_base.obj
+APP2STDLIBS= $(STODBGLIB)
+APP2STDLIBS+= $(VOSLIB) $(SALLIB)
+APP2DEPN= \
+ $(STODBGLIB) \
+ $(L)$/ivos.lib \
+ $(L)$/isal.lib
+
+APP3TARGET= t_store
+APP3OBJS= $(OBJ)$/t_store.obj
+APP3STDLIBS= $(STORELIB)
+APP3STDLIBS+= $(VOSLIB) $(SALLIB)
+APP3DEPN= \
+ $(SLB)$/store.lib \
+ $(L)$/ivos.lib \
+ $(L)$/isal.lib
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/store/workben/t_base.cxx b/store/workben/t_base.cxx
new file mode 100644
index 000000000..078bf1aea
--- /dev/null
+++ b/store/workben/t_base.cxx
@@ -0,0 +1,376 @@
+/*************************************************************************
+ *
+ * $RCSfile: t_base.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _T_BASE_CXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_MEMORY_H_
+#include <rtl/memory.h>
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_FILELCKB_HXX_
+#include <store/filelckb.hxx>
+#endif
+
+#ifndef _STORE_STORBASE_HXX_
+#include "storbase.hxx"
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+#define TEST_PAGESIZE 1024
+
+/*========================================================================
+ *
+ * OTestBIOS.
+ *
+ *======================================================================*/
+class OTestBIOS : public NAMESPACE_STORE(OStorePageBIOS)
+{
+ typedef NAMESPACE_STORE(OStorePageBIOS) base;
+
+public:
+ OTestBIOS (void);
+
+ virtual storeError initialize (
+ ILockBytes *pLockBytes,
+ storeAccessMode eAccessMode);
+
+protected:
+ virtual ~OTestBIOS (void);
+};
+
+OTestBIOS::OTestBIOS (void)
+{
+}
+
+OTestBIOS::~OTestBIOS (void)
+{
+}
+
+storeError OTestBIOS::initialize (
+ ILockBytes *pLockBytes, storeAccessMode eAccessMode)
+{
+ storeError eErrCode = base::initialize (pLockBytes, eAccessMode);
+ if (eErrCode != store_E_None)
+ {
+ if (eAccessMode == store_AccessReadWrite)
+ return eErrCode;
+ if (eAccessMode == store_AccessReadOnly)
+ return eErrCode;
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ eErrCode = base::create (TEST_PAGESIZE);
+ }
+ return eErrCode;
+}
+
+/*========================================================================
+ *
+ * unicode.
+ *
+ *======================================================================*/
+static void __store_string_newFromUnicode_WithLength (
+ rtl_String **newString, const sal_Unicode *value, sal_Int32 length)
+{
+ rtl_uString2String (
+ newString,
+ value, length,
+ RTL_TEXTENCODING_UTF8,
+ OUSTRING_TO_OSTRING_CVTFLAGS);
+}
+
+static void __store_string_newFromUnicode (
+ rtl_String **newString, const rtl_uString *value)
+{
+ __store_string_newFromUnicode_WithLength (
+ newString, value->buffer, value->length);
+}
+
+static void __store_string_newFromUnicode (
+ rtl_String **newString, const sal_Unicode *value)
+{
+ __store_string_newFromUnicode_WithLength (
+ newString, value, rtl_ustr_getLength (value));
+}
+
+static storeError __store_namei (
+ const NAMESPACE_RTL(OString) &rPath,
+ const NAMESPACE_RTL(OString) &rName,
+ OStorePageKey &rKey)
+{
+}
+
+static storeError __store_namei (
+ const sal_Unicode *pszPath,
+ const sal_Unicode *pszName,
+ OStorePageKey &rKey)
+{
+ NAMESPACE_RTL(OString) aName (
+ pszName, rtl_ustr_getLength (pszName), RTL_TEXTENCODING_UTF8);
+
+
+ rtl_String *pszNameA = 0;
+ __store_string_newFromUnicode (&pszNameA, pszName);
+
+ storeError eErrCode = store_E_NameTooLong;
+ if (pszNameA->length < sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE]))
+ {
+ rtl_String *pszPathA = 0;
+ __store_string_newFromUnicode (&pszPathA, pszPath);
+
+ typedef OStorePageGuard G;
+ rKey.m_nLow = G::crc32 (0, pszNameA->buffer, pszNameA->length);
+ rKey.m_nHigh = G::crc32 (0, pszPathA->buffer, pszPathA->length);
+
+ rtl_string_release (pszPathA);
+ eErrCode = store_E_None;
+ }
+
+ rtl_string_release (pszNameA);
+ return eErrCode;
+}
+
+static sal_Int32 __store_convertTextToUnicode (
+ rtl_TextToUnicodeConverter hConvert,
+ const sal_Char *pszText, sal_Int32 nTextLen,
+ sal_Unicode *pBuffer, sal_Int32 nBuffer)
+{
+ sal_uInt32 nInfo, nSrcLen = 0;
+
+ sal_Int32 nDstLen = rtl_convertTextToUnicode (
+ hConvert, 0,
+ pszText, nTextLen,
+ pBuffer, nBuffer,
+ OSTRING_TO_OUSTRING_CVTFLAGS,
+ &nInfo, &nSrcLen);
+
+ pBuffer[nDstLen] = 0;
+ return nDstLen;
+}
+
+struct MyFindData
+{
+ sal_Unicode m_pszName[STORE_MAXIMUM_NAMESIZE];
+ sal_Int32 m_nLength;
+ sal_uInt32 m_nAttrib;
+ sal_uInt32 m_nSize;
+ sal_uInt32 m_nReserved;
+};
+
+static void __store_testUnicode (const sal_Char *pszFilename)
+{
+ // ...
+ rtl_TextToUnicodeConverter hConvert;
+ hConvert = rtl_createTextToUnicodeConverter (RTL_TEXTENCODING_UTF8);
+
+ MyFindData it;
+ rtl_zeroMemory (&it, sizeof(it));
+
+ sal_Int32 n = rtl_str_getLength (pszFilename);
+ n = __store_convertTextToUnicode (
+ hConvert, pszFilename, n,
+ it.m_pszName, STORE_MAXIMUM_NAMESIZE - 1);
+ if (it.m_nLength > n)
+ rtl_zeroMemory (
+ &it.m_pszName[n], ((it.m_nLength - n) * sizeof(sal_Unicode)));
+ it.m_nLength = n;
+
+ rtl_destroyTextToUnicodeConverter (hConvert);
+
+ // ...
+ rtl_String *pszFileA = NULL;
+ rtl_uString *pszFileW = NULL;
+
+ // rtl_uString_newFromAscii (&pszFileW, pszFilename);
+
+ // ...
+ rtl_string_newFromStr (&pszFileA, pszFilename);
+
+ rtl_string2UString (
+ &pszFileW,
+ pszFileA->buffer, pszFileA->length,
+ RTL_TEXTENCODING_MS_1252,
+ OSTRING_TO_OUSTRING_CVTFLAGS);
+
+ rtl_string_release (pszFileA);
+
+ // ...
+ OStorePageKey aKey;
+ __store_namei (pszFileW->buffer, pszFileW->buffer, aKey);
+
+ // ...
+ rtl_uString2String (
+ &pszFileA,
+ pszFileW->buffer, pszFileW->length,
+ RTL_TEXTENCODING_UTF8,
+ OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ rtl_uString_release (pszFileW);
+
+ // ...
+ rtl_string_release (pszFileA);
+}
+
+/*========================================================================
+ *
+ * __store_getProcessTextEncoding.
+ *
+ *======================================================================*/
+inline rtl_TextEncoding __store_getProcessTextEncoding (void)
+{
+ rtl_TextEncoding eEncoding;
+#if defined(SAL_OS2)
+ eEncoding = RTL_TEXTENCODING_IBM850;
+#elif defined(SAL_UNX)
+ eEncoding = RTL_TEXTENCODING_ISO8859_1;
+#elif defined(SAL_W32)
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+#else
+ eEncoding = RTL_TEXTENCODING_ASCII_US;
+#endif
+ return eEncoding;
+}
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+int SAL_CALL main (int argc, char **argv)
+{
+ if (argc < 2)
+ return 0;
+
+#if 0 /* EXP */
+ __store_testUnicode (argv[1]);
+#endif /* EXP */
+
+ NAMESPACE_VOS(ORef)<OFileLockBytes> xLockBytes (new OFileLockBytes());
+ if (!xLockBytes.isValid())
+ return 0;
+
+ NAMESPACE_RTL(OUString) aFilename (
+ argv[1], rtl_str_getLength(argv[1]),
+ __store_getProcessTextEncoding());
+
+ storeError eErrCode = xLockBytes->create (
+ aFilename.pData, store_AccessReadCreate);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ NAMESPACE_VOS(ORef)<OTestBIOS> xBIOS (new OTestBIOS());
+ if (!xBIOS.isValid())
+ return 0;
+
+ eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadWrite);
+ if (eErrCode != store_E_None)
+ {
+ // Check reason.
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ // Create.
+ eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadCreate);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+ xLockBytes.unbind();
+
+ sal_Char pBuffer[TEST_PAGESIZE];
+ rtl_zeroMemory (pBuffer, sizeof (pBuffer));
+ rtl_copyMemory (pBuffer, argv[0], rtl_str_getLength(argv[0]) + 1);
+
+ eErrCode = xBIOS->acquireLock (TEST_PAGESIZE, sizeof(pBuffer));
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = xBIOS->write (TEST_PAGESIZE, pBuffer, sizeof (pBuffer));
+ if (eErrCode != store_E_None)
+ {
+ xBIOS->releaseLock (TEST_PAGESIZE, sizeof(pBuffer));
+ return eErrCode;
+ }
+
+ eErrCode = xBIOS->releaseLock (TEST_PAGESIZE, sizeof(pBuffer));
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xBIOS.unbind();
+ return 0;
+}
+
diff --git a/store/workben/t_file.cxx b/store/workben/t_file.cxx
new file mode 100644
index 000000000..eddebc8db
--- /dev/null
+++ b/store/workben/t_file.cxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * $RCSfile: t_file.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _T_FILE_CXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef _VOS_MACROS_HXX_
+#include <vos/macros.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+#ifndef _STORE_FILELCKB_HXX_
+#include <store/filelckb.hxx>
+#endif
+
+#ifdef _USE_NAMESPACE
+using namespace store;
+#endif
+
+/*========================================================================
+ *
+ * __store_getProcessTextEncoding.
+ *
+ *======================================================================*/
+inline rtl_TextEncoding __store_getProcessTextEncoding (void)
+{
+ rtl_TextEncoding eEncoding;
+#if defined(SAL_OS2)
+ eEncoding = RTL_TEXTENCODING_IBM850;
+#elif defined(SAL_UNX)
+ eEncoding = RTL_TEXTENCODING_ISO8859_1;
+#elif defined(SAL_W32)
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+#else
+ eEncoding = RTL_TEXTENCODING_ASCII_US;
+#endif
+ return eEncoding;
+}
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+int SAL_CALL main (int argc, char **argv)
+{
+ if (argc < 2)
+ return 0;
+
+ NAMESPACE_VOS(ORef)<OFileLockBytes> xLockBytes (new OFileLockBytes());
+ if (!xLockBytes.isValid())
+ return 0;
+
+ NAMESPACE_RTL(OUString) aFilename (
+ argv[1], rtl_str_getLength(argv[1]),
+ __store_getProcessTextEncoding());
+
+ storeError eErrCode = xLockBytes->create (
+ aFilename.pData, store_AccessReadWrite);
+ if (eErrCode != store_E_None)
+ {
+ // Check reason.
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ // Create.
+ eErrCode = xLockBytes->create (
+ aFilename.pData, store_AccessReadCreate);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ sal_uInt32 k = 0;
+ eErrCode = xLockBytes->writeAt (
+ 0, argv[0], rtl_str_getLength(argv[0]), k);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = xLockBytes->setSize (1024);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = xLockBytes->writeAt (
+ 1024, argv[1], rtl_str_getLength(argv[1]), k);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = xLockBytes->setSize (2048);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ eErrCode = xLockBytes->flush();
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xLockBytes.unbind();
+ return 0;
+}
+
diff --git a/store/workben/t_store.cxx b/store/workben/t_store.cxx
new file mode 100644
index 000000000..d017e92dd
--- /dev/null
+++ b/store/workben/t_store.cxx
@@ -0,0 +1,634 @@
+/*************************************************************************
+ *
+ * $RCSfile: t_store.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:18:32 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _T_STORE_CXX "$Revision: 1.1.1.1 $"
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+#ifndef _OSL_TIME_H_
+#include <osl/time.h>
+#endif
+
+#ifndef _RTL_CHAR_H_
+#include <rtl/char.h>
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#ifndef _VOS_THREAD_HXX_
+#include <vos/thread.hxx>
+#endif
+
+#ifndef _STORE_MACROS_HXX_
+#include <store/macros.hxx>
+#endif
+#ifndef _STORE_STORE_HXX_
+#include <store/store.hxx>
+#endif
+
+#include <stdio.h>
+
+#if (defined(WNT) && defined(PROFILE))
+extern "C"
+{
+ void StartCAP (void);
+ void StopCAP (void);
+ void DumpCAP (void);
+}
+#endif /* PROFILE */
+
+using namespace rtl;
+
+/*========================================================================
+ *
+ * Internals.
+ *
+ *======================================================================*/
+#define _DEMOSTOR_BUFSIZ 512 /* 4096, 1024, 512 */
+#define _DEMOSTOR_LOOPS 1000 /* 1000, 2000 */
+
+#define _DEMOSTOR_REMOVE 0
+#define _DEMOSTOR_REBUILD 0
+
+enum Options
+{
+ OPTION_HELP = 0x0001,
+ OPTION_FILE = 0x0002,
+ OPTION_PAUSE = 0x0004,
+ OPTION_REBUILD = 0x0008,
+
+ OPTION_DUMP = 0x0010,
+ OPTION_ITER = 0x0020,
+ OPTION_LINK = 0x0040,
+
+ OPTION_READ = 0x0100,
+ OPTION_WRITE = 0x0200,
+ OPTION_CREAT = 0x0400,
+ OPTION_TRUNC = 0x0800
+};
+
+/*========================================================================
+ *
+ * Timing.
+ *
+ *======================================================================*/
+struct OTime : public TimeValue
+{
+ OTime (void)
+ {
+ Seconds = 0;
+ Nanosec = 0;
+ }
+
+ static OTime getSystemTime (void)
+ {
+ OTime tv;
+ osl_getSystemTime (&tv);
+ return tv;
+ }
+
+ OTime& operator-= (const OTime& rPast)
+ {
+ Seconds -= rPast.Seconds;
+ if (Nanosec < rPast.Nanosec)
+ {
+ Seconds -= 1;
+ Nanosec += 1000000000;
+ }
+ Nanosec -= rPast.Nanosec;
+ return *this;
+ }
+
+ friend OTime operator- (const OTime& rTimeA, const OTime& rTimeB)
+ {
+ OTime aTimeC (rTimeA);
+ aTimeC -= rTimeB;
+ return aTimeC;
+ }
+};
+
+/*========================================================================
+ *
+ * DirectoryTraveller.
+ *
+ *======================================================================*/
+typedef NAMESPACE_STORE(OStoreDirectory) Directory;
+
+class DirectoryTraveller : public Directory::traveller
+{
+ typedef NAMESPACE_STORE(OStoreFile) file;
+ typedef Directory::iterator iter;
+
+ NAMESPACE_STORE(OStoreFile) m_aFile;
+ OUString m_aPath;
+
+ sal_uInt32 m_nOptions;
+ sal_uInt32 m_nLevel;
+ sal_uInt32 m_nCount;
+
+public:
+ DirectoryTraveller (
+ const file& rFile,
+ const OUString &rPath,
+ const OUString &rName,
+ sal_uInt32 nOptions,
+ sal_uInt32 nLevel = 0);
+
+ virtual ~DirectoryTraveller (void);
+
+ virtual sal_Bool visit (const iter& it);
+};
+
+/*
+ * DirectoryTraveller.
+ */
+DirectoryTraveller::DirectoryTraveller (
+ const file& rFile,
+ const OUString &rPath,
+ const OUString &rName,
+ sal_uInt32 nOptions,
+ sal_uInt32 nLevel)
+ : m_aFile (rFile),
+ m_aPath (rPath),
+ m_nOptions (nOptions),
+ m_nLevel (nLevel),
+ m_nCount (0)
+{
+ m_aPath += rName;
+ m_aPath += OUString::createFromAscii("/");
+}
+
+/*
+ * ~DirectoryTraveller.
+ */
+DirectoryTraveller::~DirectoryTraveller (void)
+{
+}
+
+/*
+ * visit.
+ */
+sal_Bool DirectoryTraveller::visit (const iter& it)
+{
+ m_nCount++;
+ if (m_nOptions & OPTION_DUMP)
+ {
+ OString aName (it.m_pszName, it.m_nLength, RTL_TEXTENCODING_UTF8);
+ printf ("Visit(%d,%d): %s [0x%08x] %d [Bytes]\n",
+ m_nLevel, m_nCount,
+ aName.pData->buffer, it.m_nAttrib, it.m_nSize);
+ }
+ if (it.m_nAttrib & STORE_ATTRIB_ISDIR)
+ {
+ OUString aName (it.m_pszName, it.m_nLength);
+ Directory aSubDir;
+
+ storeError eErrCode = aSubDir.create (
+ m_aFile, m_aPath, aName, store_AccessReadOnly);
+ if (eErrCode == store_E_None)
+ {
+ sal_uInt32 nRefCount = 0;
+ m_aFile.getRefererCount (nRefCount);
+
+ DirectoryTraveller aSubTraveller (
+ m_aFile, m_aPath, aName, m_nOptions, m_nLevel + 1);
+ aSubDir.travel (aSubTraveller);
+ }
+ }
+ return sal_True;
+}
+
+/*========================================================================
+ *
+ * __store_getProcessTextEncoding.
+ *
+ *======================================================================*/
+inline rtl_TextEncoding __store_getProcessTextEncoding (void)
+{
+ rtl_TextEncoding eEncoding;
+#if defined(SAL_OS2)
+ eEncoding = RTL_TEXTENCODING_IBM850;
+#elif defined(SAL_UNX)
+ eEncoding = RTL_TEXTENCODING_ISO8859_1;
+#elif defined(SAL_W32)
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+#else
+ eEncoding = RTL_TEXTENCODING_ASCII_US;
+#endif
+ return eEncoding;
+}
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+int SAL_CALL main (int argc, char **argv)
+{
+#if (defined(WNT) && defined(PROFILE))
+ StartCAP();
+#else
+ OTime aStartTime (OTime::getSystemTime());
+#endif /* PROFILE */
+
+ NAMESPACE_STORE(OStoreFile) aFile;
+ storeError eErrCode = store_E_None;
+
+ sal_uInt32 nOptions = 0;
+ for (int i = 1; i < argc; i++)
+ {
+ const char *opt = argv[i];
+ if (opt[0] == '-')
+ {
+ switch (rtl_char_toLowerCase(opt[1]))
+ {
+ case 'f':
+ nOptions |= OPTION_FILE;
+ break;
+
+ case 'd':
+ nOptions |= OPTION_DUMP;
+ break;
+ case 'i':
+ nOptions |= OPTION_ITER;
+ break;
+ case 'l':
+ nOptions |= OPTION_LINK;
+ break;
+
+ case 'r':
+ nOptions |= OPTION_READ;
+ break;
+ case 'w':
+ nOptions |= OPTION_WRITE;
+ break;
+ case 'c':
+ nOptions |= OPTION_CREAT;
+ break;
+ case 't':
+ nOptions |= OPTION_TRUNC;
+ break;
+
+ case 'p':
+ nOptions |= OPTION_PAUSE;
+ break;
+
+ case 'h':
+ default:
+ nOptions |= OPTION_HELP;
+ break;
+ }
+ }
+ else
+ {
+ if (nOptions & OPTION_FILE)
+ {
+ OUString aName (
+ argv[i], rtl_str_getLength(argv[i]),
+ __store_getProcessTextEncoding());
+ if ((nOptions & OPTION_CREAT) && (nOptions & OPTION_TRUNC))
+ eErrCode = aFile.create (aName, store_AccessCreate);
+ else if (nOptions & OPTION_CREAT)
+ eErrCode = aFile.create (aName, store_AccessReadCreate);
+ else if (nOptions & OPTION_WRITE)
+ eErrCode = aFile.create (aName, store_AccessReadWrite);
+ else
+ eErrCode = aFile.create (aName, store_AccessReadOnly);
+ if (eErrCode != store_E_None)
+ {
+ printf ("Error: can't open file: %s\n", argv[i]);
+ exit (0);
+ }
+ }
+ }
+ }
+
+ if ((nOptions == 0) || (nOptions & OPTION_HELP))
+ {
+ printf ("Options:\n");
+ printf ("-f\tfilename\n");
+ printf ("-h\thelp\n");
+ exit (0);
+ }
+
+ if (!aFile.isValid())
+ {
+ eErrCode = aFile.createInMemory();
+ if (eErrCode != store_E_None)
+ {
+ printf ("Error: can't create memory file\n");
+ exit (0);
+ }
+ }
+
+ // Stream Read/Write.
+ OUString aPath (RTL_CONSTASCII_USTRINGPARAM("/"));
+ if ((nOptions & OPTION_READ) || (nOptions & OPTION_WRITE))
+ {
+ // Mode.
+ storeAccessMode eMode = store_AccessReadOnly;
+ if (nOptions & OPTION_WRITE)
+ eMode = store_AccessReadWrite;
+ if (nOptions & OPTION_CREAT)
+ eMode = store_AccessCreate;
+
+ // Buffer.
+ char pBuffer[_DEMOSTOR_BUFSIZ] = "Hello World";
+ pBuffer[_DEMOSTOR_BUFSIZ - 2] = 'B';
+ pBuffer[_DEMOSTOR_BUFSIZ - 1] = '\0';
+
+ // Load/Save.
+#ifndef PROFILE
+ OTime aStartTime (OTime::getSystemTime());
+#endif /* PROFILE */
+
+ for (sal_Int32 i = 0; i < _DEMOSTOR_LOOPS; i++)
+ {
+ OUString aName (RTL_CONSTASCII_USTRINGPARAM("demostor-"));
+ aName += OUString::valueOf ((sal_Int32)(i + 1), 10);
+ aName += OUString::createFromAscii (".dat");
+
+#if (_DEMOSTOR_REMOVE == 1)
+ eErrCode = aFile.remove (aPath, aName);
+ if ((eErrCode != store_E_None ) &&
+ (eErrCode != store_E_NotExists) )
+ break;
+#endif /* _REMOVE */
+
+ NAMESPACE_STORE(OStoreStream) aStream;
+ eErrCode = aStream.create (aFile, aPath, aName, eMode);
+ if (eErrCode != store_E_None)
+ break;
+
+ if (nOptions & OPTION_TRUNC)
+ {
+ eErrCode = aStream.setSize(0);
+ if (eErrCode != store_E_None)
+ break;
+ }
+
+ sal_uInt32 nDone = 0;
+ if (nOptions & OPTION_WRITE)
+ {
+ eErrCode = aStream.writeAt (
+ 0, pBuffer, sizeof(pBuffer), nDone);
+ if (eErrCode != store_E_None)
+ break;
+ }
+
+ if (nOptions & OPTION_READ)
+ {
+ sal_uInt32 nOffset = 0;
+ for (;;)
+ {
+ eErrCode = aStream.readAt (
+ nOffset, pBuffer, sizeof(pBuffer), nDone);
+ if (eErrCode != store_E_None)
+ break;
+ if (nDone == 0)
+ break;
+ nOffset += nDone;
+ }
+ }
+
+ aStream.close();
+
+#ifndef PROFILE
+ if (((i + 1) % (_DEMOSTOR_LOOPS/10)) == 0)
+ {
+ OTime aDelta (OTime::getSystemTime() - aStartTime);
+
+ sal_uInt32 nDelta = aDelta.Seconds * 1000000;
+ nDelta += (aDelta.Nanosec / 1000);
+
+ printf ("%d: %12.4g[usec]\n", (i+1),
+ (double)(nDelta)/(double)(i+1));
+ }
+#endif /* PROFILE */
+ }
+
+#ifndef PROFILE
+ OTime aDelta (OTime::getSystemTime() - aStartTime);
+
+ sal_uInt32 nDelta = aDelta.Seconds * 1000000;
+ nDelta += (aDelta.Nanosec / 1000);
+
+ printf ("Total(rd,wr): %d[usec]\n", nDelta);
+#endif /* PROFILE */
+ }
+
+ // Link/Rename.
+ if (nOptions & OPTION_LINK)
+ {
+ // Create symlink to (root) directory.
+ eErrCode = aFile.symlink (
+ aPath, OUString::createFromAscii("000000/"),
+ OUString(), aPath);
+ VOS_POSTCOND(
+ ((eErrCode == store_E_None ) ||
+ (eErrCode == store_E_AlreadyExists) ),
+ "t_store::main(): store_symlink() failed");
+
+ // Create symlink to file.
+ OUString aLinkName (RTL_CONSTASCII_USTRINGPARAM("demostor-1.lnk"));
+
+ eErrCode = aFile.symlink (
+ aPath, aLinkName,
+ aPath, OUString::createFromAscii("demostor-1.dat"));
+ VOS_POSTCOND(
+ ((eErrCode == store_E_None ) ||
+ (eErrCode == store_E_AlreadyExists) ),
+ "t_store::main(): store_symlink() failed");
+ if ((eErrCode == store_E_None ) ||
+ (eErrCode == store_E_AlreadyExists) )
+ {
+ OUString aShortcut (
+ RTL_CONSTASCII_USTRINGPARAM("Shortcut to demostor-1.dat"));
+ eErrCode = aFile.rename (
+ aPath, aLinkName,
+ aPath, aShortcut);
+ VOS_POSTCOND(
+ ((eErrCode == store_E_None ) ||
+ (eErrCode == store_E_AlreadyExists) ),
+ "t_store::main(): store_rename() failed");
+ }
+
+ // Create directory.
+ OUString aDirName (RTL_CONSTASCII_USTRINGPARAM("demostor-1.dir"));
+ NAMESPACE_STORE(OStoreDirectory) aDir;
+
+ eErrCode = aDir.create (
+ aFile, aPath, aDirName, store_AccessReadCreate);
+ VOS_POSTCOND(
+ (eErrCode == store_E_None),
+ "t_store::main(): store_createDirectory() failed");
+ if (eErrCode == store_E_None)
+ {
+#if 0 /* NYI */
+ // Rename directory.
+ eErrCode = aFile.rename (
+ aPath, "demostor-1.dir/",
+ aPath, "Renamed demostor-1.dir");
+ VOS_POSTCOND(
+ ((eErrCode == store_E_None ) ||
+ (eErrCode == store_E_AlreadyExists) ),
+ "t_store::main(): store_rename() failed");
+
+ eErrCode = aFile.rename (
+ aPath, "Renamed demostor-1.dir/",
+ aPath, "demostor-1.dir");
+ VOS_POSTCOND(
+ (eErrCode == store_E_None),
+ "t_store::main(): store_rename() failed");
+#endif /* NYI */
+ }
+ }
+
+ // Directory iteration.
+ if (nOptions & OPTION_ITER)
+ {
+#ifndef PROFILE
+ OTime aStartTime (OTime::getSystemTime());
+#endif /* PROFILE */
+ OUString aEmpty;
+
+ // Root directory.
+ NAMESPACE_STORE(OStoreDirectory) aRootDir;
+ if (nOptions & OPTION_LINK)
+ {
+ // Open symlink entry.
+ eErrCode = aRootDir.create (
+ aFile, aPath, OUString::createFromAscii("000000"),
+ store_AccessReadOnly);
+ }
+ else
+ {
+ // Open direct entry.
+ if (nOptions & OPTION_CREAT)
+ eErrCode = aRootDir.create (
+ aFile, aEmpty, aEmpty, store_AccessReadCreate);
+ else if (nOptions & OPTION_WRITE)
+ eErrCode = aRootDir.create (
+ aFile, aEmpty, aEmpty, store_AccessReadWrite);
+ else
+ eErrCode = aRootDir.create (
+ aFile, aEmpty, aEmpty, store_AccessReadOnly);
+ }
+
+ if (eErrCode == store_E_None)
+ {
+ // Traverse directory tree.
+ DirectoryTraveller aTraveller (
+ aFile, aEmpty, aEmpty, nOptions, 0);
+ aRootDir.travel (aTraveller);
+ }
+ else
+ {
+ // Failure.
+ printf ("Error: can't open directory: \"/\"\n");
+ }
+
+#ifndef PROFILE
+ OTime aDelta (OTime::getSystemTime() - aStartTime);
+
+ sal_uInt32 nDelta = aDelta.Seconds * 1000000;
+ nDelta += (aDelta.Nanosec / 1000);
+
+ printf ("Total(iter): %d[usec]\n", nDelta);
+#endif /* PROFILE */
+ }
+
+ if (nOptions & OPTION_PAUSE)
+ {
+ TimeValue tv;
+ tv.Seconds = 300;
+ tv.Nanosec = 0;
+ NAMESPACE_VOS(OThread)::wait (tv);
+ }
+
+ // Size.
+ sal_uInt32 nSize = 0;
+ aFile.getSize (nSize);
+
+ // Done.
+ aFile.close();
+
+#if (defined(WNT) && defined(PROFILE))
+ StopCAP();
+ DumpCAP();
+#endif /* PROFILE */
+#ifndef PROFILE
+ OTime aDelta (OTime::getSystemTime() - aStartTime);
+
+ sal_uInt32 nDelta = aDelta.Seconds * 1000000;
+ nDelta += (aDelta.Nanosec / 1000);
+
+ printf ("Total: %d[usec]\n", nDelta);
+#endif /* PROFILE */
+
+ return 0;
+}
+