diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 14:18:43 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 14:18:43 +0000 |
commit | 215e8c7210756d6d9033f8d742a6cd0e9be132aa (patch) | |
tree | d1a56131d83c8298e6183cf17b912037ae63b9c9 /store |
initial import
Diffstat (limited to 'store')
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; +} + |