summaryrefslogtreecommitdiff
path: root/store/workben
diff options
context:
space:
mode:
Diffstat (limited to 'store/workben')
-rw-r--r--store/workben/makefile.mk108
-rw-r--r--store/workben/t_base.cxx365
-rw-r--r--store/workben/t_file.cxx225
-rw-r--r--store/workben/t_leak.cxx18
-rw-r--r--store/workben/t_page.cxx1358
-rw-r--r--store/workben/t_store.cxx591
6 files changed, 2665 insertions, 0 deletions
diff --git a/store/workben/makefile.mk b/store/workben/makefile.mk
new file mode 100644
index 000000000000..8893f4c7d646
--- /dev/null
+++ b/store/workben/makefile.mk
@@ -0,0 +1,108 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=store
+TARGET=workben
+
+LIBTARGET=NO
+TARGETTYPE=CUI
+NO_DEFAULT_STL=TRUE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+
+.IF "$(STORELIB)" == ""
+.IF "$(GUI)" == "UNX"
+STORELIB= -lstore
+.ELSE # unx
+.IF "$(GUI)$(COM)"=="WNTGCC"
+STORELIB= -lstore$(UDK_MAJOR)
+.ELSE
+STORELIB= $(LB)$/istore.lib
+.ENDIF
+.ENDIF # unx
+.ENDIF # storelib
+
+.IF "$(GUI)" == "UNX"
+STOREDBGLIB= $(LB)$/libstoredbg.a
+.ELSE # unx
+.IF "$(GUI)$(COM)"=="WNTGCC"
+STOREDBGLIB= $(LB)$/libstoredbg.a
+.ELSE
+STOREDBGLIB= $(LB)$/storedbg.lib
+.ENDIF
+.ENDIF # unx
+
+CFLAGS+= -I..$/source
+
+# --- Files ---
+
+OBJFILES= \
+ $(OBJ)$/t_leak.obj \
+ $(OBJ)$/t_file.obj \
+ $(OBJ)$/t_page.obj \
+ $(OBJ)$/t_base.obj \
+ $(OBJ)$/t_store.obj
+
+APP1TARGET= t_file
+APP1OBJS= $(OBJ)$/t_file.obj
+APP1STDLIBS= $(STOREDBGLIB)
+APP1STDLIBS+= $(SALLIB)
+APP1DEPN= $(STOREDBGLIB)
+APP1RPATH= UREBIN
+
+APP2TARGET= t_page
+APP2OBJS= $(OBJ)$/t_page.obj
+APP2STDLIBS= $(STOREDBGLIB)
+APP2STDLIBS+= $(SALLIB)
+APP2DEPN= $(STOREDBGLIB)
+
+APP3TARGET= t_base
+APP3OBJS= $(OBJ)$/t_base.obj
+APP3STDLIBS= $(STOREDBGLIB)
+APP3STDLIBS+= $(SALLIB)
+APP3DEPN= $(STOREDBGLIB)
+APP3RPATH= UREBIN
+
+APP4TARGET= t_store
+APP4OBJS= $(OBJ)$/t_store.obj
+APP4STDLIBS= $(STORELIB)
+APP4STDLIBS+= $(SALLIB)
+APP4DEPN= $(SLB)$/store.lib
+APP4RPATH= UREBIN
+
+ APP5TARGET= t_leak
+ APP5OBJS= $(OBJ)$/t_leak.obj
+ APP5STDLIBS+= $(SALLIB)
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/store/workben/t_base.cxx b/store/workben/t_base.cxx
new file mode 100644
index 000000000000..6a96b7c15bb1
--- /dev/null
+++ b/store/workben/t_base.cxx
@@ -0,0 +1,365 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_store.hxx"
+
+#include "sal/types.h"
+#include "osl/diagnose.h"
+#include "osl/thread.h"
+#include "rtl/memory.h"
+#include "rtl/ustring.hxx"
+
+#include "object.hxx"
+#include "storbase.hxx"
+#include "storbios.hxx"
+#include "lockbyte.hxx"
+
+using namespace store;
+
+#define TEST_PAGESIZE 1024
+
+/*========================================================================
+ *
+ * OTestObject.
+ *
+ *======================================================================*/
+class OTestObject : public store::OStoreObject
+{
+public:
+ OTestObject (void);
+
+ virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId);
+
+protected:
+ virtual ~OTestObject (void);
+};
+
+OTestObject::OTestObject (void)
+{
+}
+
+OTestObject::~OTestObject (void)
+{
+}
+
+sal_Bool SAL_CALL OTestObject::isKindOf (sal_uInt32 nTypeId)
+{
+ return (nTypeId == 42);
+}
+
+namespace store
+{
+static OTestObject* SAL_CALL query (IStoreHandle *pHandle, OTestObject*)
+{
+ if (pHandle && pHandle->isKindOf (42))
+ return static_cast<OTestObject*>(pHandle);
+ else
+ return 0;
+}
+}
+
+/*========================================================================
+ *
+ * OTestBIOS.
+ *
+ *======================================================================*/
+namespace store
+{
+
+class OTestBIOS : public store::OStorePageBIOS
+{
+ typedef store::OStorePageBIOS base;
+
+ friend OTestBIOS* SAL_CALL query<> (IStoreHandle * pHandle, OTestBIOS *);
+
+public:
+ OTestBIOS (void);
+
+ virtual storeError initialize (
+ ILockBytes * pLockBytes,
+ storeAccessMode eAccessMode,
+ sal_uInt16 & rnPageSize);
+
+ virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId);
+
+protected:
+ virtual ~OTestBIOS (void);
+};
+
+} // namespace store
+
+OTestBIOS::OTestBIOS (void)
+{
+}
+
+OTestBIOS::~OTestBIOS (void)
+{
+}
+
+sal_Bool SAL_CALL OTestBIOS::isKindOf (sal_uInt32 nTypeId)
+{
+ return (nTypeId == 4242);
+}
+
+storeError OTestBIOS::initialize (
+ ILockBytes *pLockBytes, storeAccessMode eAccessMode, sal_uInt16 & rnPageSize)
+{
+ return base::initialize (pLockBytes, eAccessMode, rnPageSize);
+}
+
+namespace store
+{
+template<> OTestBIOS* SAL_CALL query (IStoreHandle *pHandle, OTestBIOS*)
+{
+ if (pHandle && pHandle->isKindOf (4242))
+ return static_cast<OTestBIOS*>(pHandle);
+ else
+ return 0;
+}
+}
+
+/*========================================================================
+ *
+ * __store_test_handle.
+ *
+ *======================================================================*/
+static void __store_test_handle (void* Handle)
+{
+ IStoreHandle *pHandle = static_cast<IStoreHandle*>(Handle);
+ if (pHandle)
+ {
+ pHandle->acquire();
+ pHandle->isKindOf (42);
+ pHandle->release();
+ }
+
+ OTestObject *pObj = query (pHandle, static_cast<OTestObject*>(0));
+ if (pObj)
+ {
+ pObj->acquire();
+ pObj->isKindOf (42);
+ pObj->release();
+ }
+}
+
+/*========================================================================
+ *
+ * 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 sal_Unicode *value)
+{
+ __store_string_newFromUnicode_WithLength (
+ newString, value, rtl_ustr_getLength (value));
+}
+
+static storeError __store_namei (
+ const sal_Unicode *pszPath,
+ const sal_Unicode *pszName,
+ OStorePageKey &rKey)
+{
+ 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 < sal_Int32(sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE])))
+ {
+ rtl_String *pszPathA = 0;
+ __store_string_newFromUnicode (&pszPathA, pszPath);
+
+ rKey.m_nLow = rtl_crc32 (0, pszNameA->buffer, pszNameA->length);
+ rKey.m_nHigh = rtl_crc32 (0, pszPathA->buffer, pszPathA->length);
+
+ rtl_string_release (pszPathA);
+ eErrCode = store_E_None;
+ }
+
+ rtl_string_release (pszNameA);
+ return eErrCode;
+}
+
+static sal_Size __store_convertTextToUnicode (
+ rtl_TextToUnicodeConverter hConvert,
+ const sal_Char *pszText, sal_Size nTextLen,
+ sal_Unicode *pBuffer, sal_Size nBuffer)
+{
+ sal_uInt32 nInfo = 0;
+ sal_Size 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);
+}
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+int SAL_CALL main (int argc, char **argv)
+{
+ OSL_PRECOND(argc > 1, "t_base: error: insufficient number of arguments.");
+ if (argc < 2)
+ return 0;
+
+ __store_testUnicode (argv[1]);
+
+ rtl::Reference<ILockBytes> xLockBytes;
+
+ rtl::OUString aFilename (
+ argv[1], rtl_str_getLength(argv[1]),
+ osl_getThreadTextEncoding());
+
+ storeError eErrCode = FileLockBytes_createInstance (
+ xLockBytes, aFilename.pData, store_AccessReadCreate);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+
+ rtl::Reference<OTestObject> xObject (new OTestObject());
+ __store_test_handle (&*xObject);
+
+ rtl::Reference<OTestBIOS> xBIOS (new OTestBIOS());
+ __store_test_handle (&*xBIOS);
+
+
+ if (!xBIOS.is())
+ return 0;
+
+ sal_uInt16 nPageSize = TEST_PAGESIZE;
+ eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadWrite, nPageSize);
+ if (eErrCode != store_E_None)
+ {
+ // Check reason.
+ if (eErrCode != store_E_NotExists)
+ return eErrCode;
+
+ // Create.
+ eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadCreate, nPageSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+ xLockBytes.clear();
+
+ sal_Char pBuffer[TEST_PAGESIZE];
+ rtl_zeroMemory (pBuffer, sizeof (pBuffer));
+ rtl_copyMemory (pBuffer, argv[0], rtl_str_getLength(argv[0]) + 1);
+
+ eErrCode = xBIOS->write (TEST_PAGESIZE, pBuffer, sizeof (pBuffer));
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ xBIOS.clear();
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/store/workben/t_file.cxx b/store/workben/t_file.cxx
new file mode 100644
index 000000000000..6357e7b8a5a6
--- /dev/null
+++ b/store/workben/t_file.cxx
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_store.hxx"
+
+#include "sal/types.h"
+#include "osl/thread.h"
+#include "rtl/ustring.hxx"
+
+#include "lockbyte.hxx"
+
+#ifndef INCLUDED_STDIO_H
+#include <stdio.h>
+#define INCLUDED_STDIO_H
+#endif
+
+#include "osl/file.h"
+#include "osl/process.h"
+
+using namespace store;
+
+#define TEST_PAGESIZE 16384
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+int SAL_CALL main (int argc, char **argv)
+{
+ storeError eErrCode = store_E_None;
+ rtl::Reference<ILockBytes> xLockBytes;
+
+ if (argc > 1)
+ {
+ rtl::OUString aFilename (
+ argv[1], rtl_str_getLength(argv[1]),
+ osl_getThreadTextEncoding());
+
+ eErrCode = FileLockBytes_createInstance (
+ xLockBytes, aFilename.pData, store_AccessReadWrite);
+ if (eErrCode != store_E_None)
+ {
+ // Check reason.
+ if (eErrCode != store_E_NotExists)
+ {
+ fprintf (stderr, "t_file: create() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ // Create.
+ eErrCode = FileLockBytes_createInstance (
+ xLockBytes, aFilename.pData, store_AccessReadCreate);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: create() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+ }
+ fprintf (stdout, "t_file: using FileLockBytes(\"%s\") implementation.\n", argv[1]);
+ }
+ else
+ {
+ eErrCode = MemoryLockBytes_createInstance (xLockBytes);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: create() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+ fprintf (stdout, "t_file: using MemoryLockBytes implementation.\n");
+ }
+
+ rtl::Reference< PageData::Allocator > xAllocator;
+ eErrCode = xLockBytes->initialize (xAllocator, TEST_PAGESIZE);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: initialize() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ sal_Char buffer[TEST_PAGESIZE];
+ rtl_fillMemory (buffer, sizeof(buffer), sal_uInt8('B'));
+
+ sal_uInt32 i, k;
+ for (k = 0; k < 4; k++)
+ {
+ sal_uInt32 index = k * TEST_PAGESIZE / 4;
+ buffer[index] = 'A';
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ sal_uInt32 offset = i * TEST_PAGESIZE;
+ eErrCode = xLockBytes->setSize (offset + TEST_PAGESIZE);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: setSize() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ for (k = 0; k < 4; k++)
+ {
+ sal_uInt32 magic = i * 4 + k;
+ if (magic)
+ {
+ sal_uInt32 verify = 0;
+ eErrCode = xLockBytes->readAt (
+ 0, &verify, sizeof(verify));
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: readAt() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+ if (verify != magic)
+ {
+ // Failure.
+ fprintf (stderr, "Expected %ld read %ld\n", (unsigned long)(magic), (unsigned long)(verify));
+ }
+ }
+
+ sal_uInt32 index = k * TEST_PAGESIZE / 4;
+ eErrCode = xLockBytes->writeAt (
+ offset + index, &(buffer[index]), TEST_PAGESIZE / 4);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: writeAt() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ magic += 1;
+ eErrCode = xLockBytes->writeAt (
+ 0, &magic, sizeof(magic));
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: writeAt() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+ }
+ }
+
+ eErrCode = xLockBytes->flush();
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: flush() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ sal_Char verify[TEST_PAGESIZE];
+ for (i = 0; i < 256; i++)
+ {
+ sal_uInt32 offset = i * TEST_PAGESIZE;
+
+ eErrCode = xLockBytes->readAt (offset, verify, TEST_PAGESIZE);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: readAt() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ sal_uInt32 index = 0;
+ if (offset == 0)
+ {
+ sal_uInt32 magic = 256 * 4;
+ if (rtl_compareMemory (&verify[index], &magic, sizeof(magic)))
+ {
+ // Failure.
+ fprintf (stderr, "t_file: Unexpected value at 0x00000000\n");
+ }
+ index += 4;
+ }
+ if (rtl_compareMemory (
+ &verify[index], &buffer[index], TEST_PAGESIZE - index))
+ {
+ // Failure.
+ fprintf (stderr, "t_file: Unexpected block at 0x%08x\n", (unsigned)(offset));
+ }
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ PageHolder xPage;
+ sal_uInt32 offset = i * TEST_PAGESIZE;
+
+ eErrCode = xLockBytes->readPageAt (xPage, offset);
+ if (eErrCode != store_E_None)
+ {
+ fprintf (stderr, "t_file: readPageAt() error: %d\n", eErrCode);
+ return eErrCode;
+ }
+
+ PageData * page = xPage.get();
+ (void)page; // UNUSED
+ }
+
+ xLockBytes.clear();
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/store/workben/t_leak.cxx b/store/workben/t_leak.cxx
new file mode 100644
index 000000000000..32033268d618
--- /dev/null
+++ b/store/workben/t_leak.cxx
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * t_leak.cxx
+ */
+
+#include "sal/main.h"
+#include "osl/process.h"
+#include "osl/thread.h"
+
+ int main (int /*argc*/, char ** /*argv*/)
+//SAL_IMPLEMENT_MAIN()
+{
+ rtl_Locale * pLocale = 0;
+ osl_getProcessLocale (&pLocale);
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/store/workben/t_page.cxx b/store/workben/t_page.cxx
new file mode 100644
index 000000000000..33ca80ea81a9
--- /dev/null
+++ b/store/workben/t_page.cxx
@@ -0,0 +1,1358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * t_page.cxx
+ */
+
+#include "osl/diagnose.h"
+#include "rtl/alloc.h"
+#include "rtl/ref.hxx"
+
+#include "storbase.hxx"
+
+#include "osl/file.h"
+#include "rtl/ustring.hxx"
+
+/*========================================================================
+ *
+ * OTest...
+ *
+ *======================================================================*/
+
+template< class T > void swap (T & lhs, T & rhs)
+{
+ T tmp = rhs; rhs = lhs; lhs = tmp;
+}
+
+/*======================================================================*/
+
+class SharedCount
+{
+ long * m_pCount;
+
+ class Allocator
+ {
+ rtl_cache_type * m_cache;
+
+ public:
+ static Allocator & get();
+
+ long * alloc()
+ {
+ return static_cast<long*>(rtl_cache_alloc (m_cache));
+ }
+ void free (long * pCount)
+ {
+ rtl_cache_free (m_cache, pCount);
+ }
+
+ protected:
+ Allocator();
+ ~Allocator();
+ };
+
+public:
+ SharedCount()
+ : m_pCount(Allocator::get().alloc())
+ {
+ if (m_pCount != 0) (*m_pCount) = 1;
+ }
+
+ ~SharedCount()
+ {
+ if (m_pCount != 0)
+ {
+ long new_count = --(*m_pCount);
+ if (new_count == 0)
+ Allocator::get().free(m_pCount);
+ }
+ }
+
+ bool operator== (long count) const
+ {
+ return (m_pCount != 0) ? *m_pCount == count : false;
+ }
+
+ friend void swap<> (SharedCount & lhs, SharedCount & rhs); // nothrow
+
+ SharedCount (SharedCount const & rhs); // nothrow
+ SharedCount & operator= (SharedCount const & rhs); // nothrow
+};
+
+template<>
+inline void swap (SharedCount & lhs, SharedCount & rhs) // nothrow
+{
+ swap<long*>(lhs.m_pCount, rhs.m_pCount);
+}
+
+SharedCount::SharedCount (SharedCount const & rhs) // nothrow
+ : m_pCount (rhs.m_pCount)
+{
+ if (m_pCount != 0) ++(*m_pCount);
+}
+
+SharedCount &
+SharedCount::operator= (SharedCount const & rhs) // nothrow
+{
+ SharedCount tmp(rhs);
+ swap<SharedCount>(tmp, *this);
+ return *this;
+}
+
+SharedCount::Allocator &
+SharedCount::Allocator::get()
+{
+ static Allocator g_aSharedCountAllocator;
+ return g_aSharedCountAllocator;
+}
+
+SharedCount::Allocator::Allocator()
+{
+ m_cache = rtl_cache_create (
+ "store_shared_count_cache",
+ sizeof(long),
+ 0, // objalign
+ 0, // constructor
+ 0, // destructor
+ 0, // reclaim
+ 0, // userarg
+ 0, // default source
+ 0 // flags
+ );
+}
+
+SharedCount::Allocator::~Allocator()
+{
+ rtl_cache_destroy (m_cache), m_cache = 0;
+}
+
+/*======================================================================*/
+
+#if defined(OSL_BIGENDIAN)
+#define STORE_DWORD(dword) OSL_SWAPDWORD((dword))
+#else
+#define STORE_DWORD(dword) (dword)
+#endif
+
+struct PageData
+{
+ typedef store::OStorePageGuard G;
+ typedef store::OStorePageDescriptor D;
+ typedef store::OStorePageLink L;
+
+ /** Representation.
+ */
+ G m_aGuard;
+ D m_aDescr;
+ L m_aMarked;
+ L m_aUnused;
+
+ /** theSize.
+ */
+ static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L);
+ static const sal_uInt16 thePageSize = theSize;
+ STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
+
+ /** type.
+ */
+ sal_uInt32 type() const { return m_aGuard.m_nMagic; /* @@@ */ }
+
+ /** offset.
+ */
+ sal_uInt32 offset() const { return m_aDescr.m_nAddr; /* @@@ */ }
+ void offset (sal_uInt32 nOffset) { m_aDescr.m_nAddr = nOffset; }
+
+ /** size.
+ */
+ sal_uInt16 size() const { return m_aDescr.m_nSize; /* @@@ */ }
+
+ /** Allocation.
+ */
+ class Allocator : public rtl::IReference
+ {
+ public:
+ template< class T > T * construct()
+ {
+ void * page = 0; sal_uInt16 size = 0;
+ if (allocate (&page, &size))
+ {
+ return new(page) T(size);
+ }
+ return 0;
+ }
+
+ virtual bool allocate (void ** ppPage, sal_uInt16 * pnSize) = 0;
+ virtual void deallocate (void * pPage) = 0;
+ };
+
+ static void * operator new (size_t, void * p) { return p; }
+ static void operator delete (void *, void *) {}
+
+ /** Construction.
+ */
+ explicit PageData (sal_uInt16 nPageSize = thePageSize)
+ : m_aDescr (STORE_PAGE_NULL, nPageSize, thePageSize)
+ {}
+
+ /** ...
+ */
+ void guard()
+ {}
+
+ storeError verify() const
+ {
+ return store_E_None;
+ }
+};
+
+class IPageAllocator
+{
+public:
+ virtual void deallocate (void * p) = 0;
+};
+
+class PageAllocator
+{
+ rtl_cache_type * m_cache;
+ SharedCount m_refcount;
+
+public:
+ PageAllocator()
+ : m_cache(0), m_refcount()
+ {}
+
+ ~PageAllocator()
+ {
+ // NYI
+ if (m_refcount == 1)
+ {
+ }
+ }
+
+ friend void swap<>(PageAllocator & lhs, PageAllocator & rhs);
+
+ PageAllocator (PageAllocator const & rhs);
+ PageAllocator & operator= (PageAllocator const & rhs);
+};
+
+template<>
+inline void swap (PageAllocator & lhs, PageAllocator & rhs)
+{
+ swap<rtl_cache_type*>(lhs.m_cache, rhs.m_cache);
+ swap<SharedCount>(lhs.m_refcount, rhs.m_refcount);
+}
+
+PageAllocator::PageAllocator (PageAllocator const & rhs)
+ : m_cache (rhs.m_cache),
+ m_refcount (rhs.m_refcount)
+{
+}
+
+PageAllocator &
+PageAllocator::operator= (PageAllocator const & rhs)
+{
+ PageAllocator tmp (rhs);
+ swap<PageAllocator>(tmp, *this);
+ return *this;
+}
+
+/*======================================================================*/
+
+class PageHolder
+{
+ SharedCount m_refcount;
+ PageData * m_pagedata;
+
+ typedef rtl::Reference< PageData::Allocator > allocator_type;
+ allocator_type m_allocator;
+
+public:
+ explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type())
+ : m_refcount (),
+ m_pagedata (pagedata),
+ m_allocator(allocator)
+ {}
+
+ ~PageHolder()
+ {
+ if ((m_refcount == 1) && (m_pagedata != 0) && m_allocator.is())
+ {
+ // free pagedata.
+ m_allocator->deallocate (m_pagedata);
+ }
+ }
+
+ PageData * get() { return m_pagedata; }
+ PageData const * get() const { return m_pagedata; }
+
+ PageData * operator->() { return m_pagedata; }
+ PageData const * operator->() const { return m_pagedata; }
+
+ friend void swap<> (PageHolder & lhs, PageHolder & rhs); // nothrow
+
+ PageHolder (PageHolder const & rhs); // nothrow
+ PageHolder & operator= (PageHolder const & rhs); // nothrow
+};
+
+template<>
+inline void swap (PageHolder & lhs, PageHolder & rhs) // nothrow
+{
+ swap<SharedCount>(lhs.m_refcount, rhs.m_refcount);
+ swap<PageData*>(lhs.m_pagedata, rhs.m_pagedata);
+ swap<PageHolder::allocator_type>(lhs.m_allocator, rhs.m_allocator);
+}
+
+PageHolder::PageHolder (PageHolder const & rhs) // nothrow
+ : m_refcount (rhs.m_refcount),
+ m_pagedata (rhs.m_pagedata),
+ m_allocator(rhs.m_allocator)
+{}
+
+PageHolder &
+PageHolder::operator= (PageHolder const & rhs) // nothrow
+{
+ PageHolder tmp (rhs);
+ swap<PageHolder>(tmp, *this);
+ return *this;
+}
+
+/*======================================================================*/
+
+template< class T >
+class PageHolderObject
+{
+protected:
+ /** Representation.
+ */
+ PageHolder m_xPage;
+
+ /** Checked cast.
+ */
+ template< class U >
+ static bool isA (PageData const * p)
+ {
+ return ((p != 0) && (p->type() == U::theTypeId));
+ }
+
+ template< class U >
+ static U * dynamic_page_cast (PageData * p)
+ {
+ return isA<U>(p) ? static_cast<U*>(p) : 0;
+ }
+
+ template< class U >
+ static U const * dynamic_page_cast (PageData const * p)
+ {
+ return isA<U>(p) ? static_cast<U const *>(p) : 0;
+ }
+
+public:
+ static PageHolderObject<T> construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
+ {
+ PageHolderObject<T> tmp;
+ if (rxAllocator.is())
+ {
+ PageHolder xPage (rxAllocator->construct<T>(), rxAllocator);
+ store::swap<PageHolder>(tmp.m_xPage, xPage);
+ }
+ return tmp;
+ }
+
+ explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
+ : m_xPage (rxPage)
+ {}
+
+ void swap (PageHolderObject<T> & rhs)
+ {
+ store::swap<PageHolder>(m_xPage, rhs.m_xPage);
+ }
+
+ PageHolderObject (PageHolderObject<T> const & rhs)
+ : m_xPage (rhs.m_xPage)
+ {
+ }
+
+ PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs)
+ {
+ PageHolderObject<T> tmp (rhs);
+ this->swap(tmp);
+ return *this;
+ }
+
+ T * operator->()
+ {
+ T * pImpl = dynamic_page_cast<T>(m_xPage.get());
+ OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer");
+ return pImpl;
+ }
+ T const * operator->() const
+ {
+ T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
+ OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer");
+ return pImpl;
+ }
+
+ T & operator*()
+ {
+ T * pImpl = dynamic_page_cast<T>(m_xPage.get());
+ OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
+ return *pImpl;
+ }
+ T const & operator*() const
+ {
+ T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
+ OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
+ return *pImpl;
+ }
+
+ static storeError guard (PageHolder & rxPage)
+ {
+ T * pImpl = dynamic_page_cast<T>(rxPage.get());
+ if (pImpl != 0)
+ { pImpl->guard(); return store_E_None; }
+ else if (rxPage.get() != 0)
+ return store_E_WrongVersion;
+ else
+ return store_E_InvalidAccess;
+ }
+ static storeError verify (PageHolder const & rxPage)
+ {
+ T const * pImpl = dynamic_page_cast<T>(rxPage.get());
+ if (pImpl != 0)
+ return pImpl->verify();
+ else if (rxPage.get() != 0)
+ return store_E_WrongVersion;
+ else
+ return store_E_InvalidAccess;
+ }
+};
+
+/*======================================================================*/
+
+class PageObject
+{
+public:
+ explicit PageObject (PageHolder const & rxPage = PageHolder())
+ : m_xPage (rxPage)
+ {}
+
+ virtual ~PageObject();
+
+ PageHolder & get() { return m_xPage; }
+ PageHolder const & get() const { return m_xPage; }
+
+ PageData * operator->()
+ {
+ PageData * pImpl = m_xPage.get();
+ OSL_PRECOND(pImpl != 0, "store::PageObject::operator->(): Null pointer");
+ return pImpl;
+ }
+ PageData & operator*()
+ {
+ PageData * pImpl = m_xPage.get();
+ OSL_PRECOND(pImpl != 0, "store::PageObject::operator*(): Null pointer");
+ return *pImpl;
+ }
+
+ virtual void guard();
+ virtual storeError verify() const;
+
+protected:
+ PageHolder m_xPage;
+};
+
+PageObject::~PageObject()
+{}
+void PageObject::guard()
+{
+ PageData * p = m_xPage.get();
+ p->guard();
+}
+storeError PageObject::verify() const
+{
+ PageData const * p = m_xPage.get();
+ return p->verify();
+}
+
+/*======================================================================*/
+
+template< class T >
+T * dynamic_page_cast (PageData * pagedata)
+{
+ if ((pagedata != 0) && (pagedata->type() == T::theTypeId))
+ return static_cast<T*>(pagedata);
+ return 0;
+}
+
+template< class T >
+T * dynamic_page_cast (PageData const * pagedata)
+{
+ if ((pagedata != 0) && (pagedata->type() == T::theTypeId))
+ return static_cast<T*>(pagedata);
+ return 0;
+}
+
+/*======================================================================*/
+
+class TestBIOS
+{
+public:
+ storeError loadPageAt (PageHolder & rPage, storeError (*pfnVerify)(PageHolder const &))
+ {
+ return (pfnVerify)(rPage);
+ }
+
+ storeError allocate (PageHolder & rxPage, ...)
+ {
+ // NYI: PageObject.save(nAddr, *this);
+ (void)rxPage; // NYI
+ return store_E_Unknown; // NYI
+ }
+
+ storeError loadAt (PageHolder & rPage, sal_uInt32 nOffset)
+ {
+ (void)rPage; // NYI
+ (void)nOffset; // NYI
+ return store_E_Unknown; // NYI
+ }
+ storeError saveAt (PageHolder const & rPage, sal_uInt32 nOffset)
+ {
+ (void)rPage; // NYI
+ (void)nOffset; // NYI
+ return store_E_Unknown; // NYI
+ }
+
+ template< class T >
+ storeError save (PageHolder & rxPage, sal_uInt32 nOffset)
+ {
+ storeError result = PageHolderObject<T>::guard (rxPage);
+ if (result != store_E_None)
+ return result;
+ return saveAt (rxPage, nOffset);
+ }
+
+ storeError lookupAt (PageHolder & rPage, sal_uInt32 nOffset)
+ {
+ (void)rPage; // NYI
+ (void)nOffset; // NYI
+ return store_E_NotExists;
+ }
+ storeError replaceAt (PageHolder const & rPage, sal_uInt32 nOffset)
+ {
+ (void)rPage; // NYI
+ (void)nOffset; // NYI
+ return store_E_None;
+ }
+};
+
+struct TestDataV1 : public PageData
+{
+ static const sal_uInt32 theTypeId = 6 * 9;
+};
+struct TestData : public PageData
+{
+ typedef PageData base;
+ typedef TestData self;
+
+ static const sal_uInt32 theTypeId = 42;
+
+ void guard()
+ {
+ base::guard();
+ // self::m_aGuard = ...;
+ }
+ storeError verify() const
+ {
+ storeError result = base::verify();
+ if (result != store_E_None)
+ return result;
+ if (!(base::type() == self::theTypeId))
+ return store_E_WrongVersion;
+ return store_E_None;
+ }
+
+ storeError dwim() const
+ {
+ return store_E_None;
+ }
+};
+class TestObject : public PageObject
+{
+ typedef PageObject base;
+
+public:
+
+ void dwim()
+ {
+ PageHolderObject< TestData > xPage (m_xPage);
+ xPage->guard();
+ }
+
+ virtual void guard()
+ {
+ TestData * pagedata = dynamic_page_cast< TestData >(m_xPage.get());
+ if (pagedata != 0)
+ {}
+ }
+ virtual storeError verify() const
+ {
+ storeError result = base::verify();
+ if (result != store_E_None)
+ return result;
+
+ TestData const * pagedata = dynamic_page_cast< TestData const >(m_xPage.get());
+ if (!pagedata)
+ return store_E_WrongVersion;
+
+ return pagedata->verify();
+ }
+
+ static storeError verify (PageHolder const & rPage)
+ {
+ return PageHolderObject< TestData >::verify (rPage);
+ }
+
+ storeError loadAt (sal_uInt32 nOffset, TestBIOS & rBIOS)
+ {
+ storeError result = rBIOS.lookupAt (m_xPage, nOffset); // cache lookup
+ if (result == store_E_NotExists)
+ {
+ result = rBIOS.loadAt (m_xPage, nOffset);
+ if (result != store_E_None)
+ return result;
+
+ result = PageHolderObject< TestData >::verify (m_xPage);
+ if (result != store_E_None)
+ return result;
+
+ result = rBIOS.replaceAt (m_xPage, nOffset); // cache insert
+ }
+ return result;
+ }
+ storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS)
+ {
+ if (!m_xPage.get())
+ return store_E_InvalidAccess;
+ m_xPage->m_aDescr.m_nAddr = store::htonl(nOffset); // m_xPage->location (nOffset);
+
+ storeError result = PageHolderObject< TestData >::guard (m_xPage);
+ if (result != store_E_None)
+ return result;
+
+ result = rBIOS.saveAt (m_xPage, nOffset);
+ if (result != store_E_None)
+ return result;
+
+ return rBIOS.replaceAt (m_xPage, nOffset); // cache update
+ }
+};
+
+class TestObjectV2 : public PageHolderObject< TestData >
+{
+ typedef PageHolderObject< TestData > base;
+
+public:
+ storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS)
+ {
+ m_xPage->offset(nOffset);
+
+ storeError result = PageHolderObject< TestData >::guard (m_xPage);
+ if (result != store_E_None)
+ return result;
+
+ result = rBIOS.saveAt (m_xPage, nOffset);
+ if (result != store_E_None)
+ return result;
+
+ return rBIOS.replaceAt (m_xPage, nOffset);
+ }
+#if 1
+ storeError dwim() const
+ {
+ TestData const * pImpl1 = operator->();
+
+ PageHolderObject< TestData > xImpl (m_xPage);
+
+ TestData const * pImpl2 = &*xImpl;
+ OSL_ASSERT(pImpl1 == pImpl2);
+
+ return xImpl->dwim();
+ }
+#endif
+};
+
+class TestClient
+{
+public:
+ void dwim(TestBIOS & rBIOS)
+ {
+ TestObject aObj;
+
+ rBIOS.loadPageAt(aObj.get(), aObj.verify);
+ rBIOS.loadPageAt(aObj.get(), TestObject::verify);
+ rBIOS.loadPageAt(aObj.get(), PageHolderObject<TestData>::verify);
+
+ aObj.loadAt (1024, rBIOS);
+
+ TestObjectV2 aObj2;
+ aObj2.dwim();
+ aObj2->dwim();
+ }
+};
+
+/*======================================================================*/
+
+class IPageAllocator;
+class IPageAccess
+{
+public:
+ virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) = 0;
+ virtual IPageAllocator & getAllocator () = 0;
+
+public:
+ storeError readPageAt (PageHolder & rPage, sal_uInt32 nOffset)
+ {
+ return readPageAt_Impl (rPage, nOffset);
+ }
+ storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset)
+ {
+ // [SECURITY:ValInput]
+ PageData const * pagedata = rPage.get();
+ OSL_PRECOND(!(pagedata == 0), "invalid Page");
+ if (pagedata == 0)
+ return store_E_InvalidParameter;
+
+ sal_uInt32 const offset = pagedata->offset();
+ OSL_PRECOND(!(nOffset != offset), "inconsistent Offset");
+ if (nOffset != offset)
+ return store_E_InvalidParameter;
+
+ OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::IPageAccess::writePageAt(): invalid Offset");
+ if (nOffset == STORE_PAGE_NULL)
+ return store_E_CantSeek;
+
+ return writePageAt_Impl (rPage, nOffset);
+ }
+
+ storeError peekAt (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
+ {
+ // [SECURITY:ValInput]
+ sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer);
+ if (!(dst_lo != 0))
+ return store_E_InvalidParameter;
+
+ sal_uInt8 * dst_hi = dst_lo + nBytes;
+ if (!(dst_lo < dst_hi))
+ return (dst_lo > dst_hi) ? store_E_InvalidParameter : store_E_None;
+
+ sal_uInt64 const dst_size = nOffset + nBytes;
+ if (dst_size > SAL_MAX_UINT32)
+ return store_E_CantSeek;
+
+ return peekAt_Impl (nOffset, dst_lo, (dst_hi - dst_lo));
+ }
+
+ storeError pokeAt (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
+ {
+ // [SECURITY:ValInput]
+ sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer);
+ if (!(src_lo != 0))
+ return store_E_InvalidParameter;
+
+ sal_uInt8 const * src_hi = src_lo + nBytes;
+ if (!(src_lo < src_hi))
+ return (src_lo > src_hi) ? store_E_InvalidParameter : store_E_None;
+
+ sal_uInt64 const dst_size = nOffset + nBytes;
+ if (dst_size > SAL_MAX_UINT32)
+ return store_E_CantSeek;
+
+ return pokeAt_Impl (nOffset, src_lo, (src_hi - src_lo));
+ }
+
+ storeError getSize (sal_uInt32 & rnSize)
+ {
+ rnSize = 0;
+ return getSize_Impl (rnSize);
+ }
+
+ storeError setSize (sal_uInt32 nSize)
+ {
+ return setSize_Impl (nSize);
+ }
+
+private:
+ virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) = 0;
+ virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) = 0;
+
+ virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) = 0;
+ virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) = 0;
+
+ virtual storeError getSize_Impl (sal_uInt32 & rnSize) = 0;
+ virtual storeError setSize_Impl (sal_uInt32 nSize) = 0;
+};
+
+/*======================================================================*/
+
+template< class T > struct ResourceHolder
+{
+ typedef typename T::destructor_type destructor_type;
+
+ T m_value;
+
+ explicit ResourceHolder (T const & value = T()) : m_value (value) {}
+ ~ResourceHolder() { reset(); }
+
+ T & get() { return m_value; }
+ T const & get() const { return m_value; }
+
+ void set (T const & value) { m_value = value; }
+ void reset (T const & value = T())
+ {
+ T tmp (m_value);
+ if (tmp != value)
+ destructor_type()(tmp);
+ set (value);
+ }
+ T release()
+ {
+ T tmp (m_value);
+ set (T());
+ return tmp;
+ }
+
+ ResourceHolder (ResourceHolder & rhs)
+ {
+ set (rhs.release());
+ }
+ ResourceHolder & operator= (ResourceHolder & rhs)
+ {
+ reset (rhs.release());
+ return *this;
+ }
+};
+
+struct FileHandle
+{
+ oslFileHandle m_handle;
+
+ FileHandle() : m_handle(0) {}
+
+ operator oslFileHandle() { return m_handle; }
+
+ bool operator != (FileHandle const & rhs)
+ {
+ return (m_handle != rhs.m_handle);
+ }
+
+ oslFileError initialize (rtl_uString * pFilename, sal_uInt32 nFlags)
+ {
+ // Verify arguments.
+ if (!pFilename || !nFlags)
+ return osl_File_E_INVAL;
+
+ // Convert into FileUrl.
+ rtl::OUString aFileUrl;
+ if (osl_getFileURLFromSystemPath (pFilename, &(aFileUrl.pData)) != osl_File_E_None)
+ {
+ // Not system path. Maybe a file url, already.
+ rtl_uString_assign (&(aFileUrl.pData), pFilename);
+ }
+
+ // Acquire handle.
+ return osl_openFile (aFileUrl.pData, &m_handle, nFlags);
+ }
+
+ struct CloseFile
+ {
+ void operator()(FileHandle & rFile) const
+ {
+ if (rFile.m_handle != 0)
+ {
+ // Release handle.
+ (void) osl_closeFile (rFile.m_handle);
+ rFile.m_handle = 0;
+ }
+ }
+ };
+ typedef CloseFile destructor_type;
+};
+
+struct FileMapping
+{
+ void * m_pAddr;
+ sal_uInt64 m_uSize;
+
+ FileMapping() : m_pAddr(0), m_uSize(0) {}
+
+ bool operator != (FileMapping const & rhs) const
+ {
+ return ((m_pAddr != rhs.m_pAddr) || (m_uSize != rhs.m_uSize));
+ }
+
+ oslFileError initialize (oslFileHandle hFile)
+ {
+ // Determine mapping size.
+ oslFileError result = osl_getFileSize (hFile, &m_uSize);
+ if (result != osl_File_E_None)
+ return result;
+ if (m_uSize > SAL_MAX_UINT32)
+ return osl_File_E_OVERFLOW;
+
+ // Acquire mapping.
+ return osl_mapFile (hFile, &m_pAddr, m_uSize, 0, 0);
+ }
+
+ struct UnmapFile
+ {
+ void operator ()(FileMapping & rMapping) const
+ {
+ if ((rMapping.m_pAddr != 0) && (rMapping.m_uSize != 0))
+ {
+ // Release mapping.
+ (void) osl_unmapFile (rMapping.m_pAddr, rMapping.m_uSize);
+ rMapping.m_pAddr = 0, rMapping.m_uSize = 0;
+ }
+ }
+ };
+ typedef UnmapFile destructor_type;
+};
+
+/*======================================================================*/
+
+class FilePageAccess : public IPageAccess
+{
+ oslFileHandle m_hFile;
+
+public:
+ static storeError ERROR_FROM_NATIVE (oslFileError eErrno);
+ static sal_uInt32 MODE_TO_NATIVE (storeAccessMode eMode);
+
+public:
+ explicit FilePageAccess (oslFileHandle hFile = 0) : m_hFile (hFile) {}
+ virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize);
+
+private:
+ virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
+ virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
+
+ /* see @ OFileLockBytes */
+ virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
+ virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
+
+ virtual storeError getSize_Impl (sal_uInt32 & rnSize);
+ virtual storeError setSize_Impl (sal_uInt32 nSize);
+
+protected:
+ virtual ~FilePageAccess();
+
+private:
+ /** Not implemented.
+ */
+ FilePageAccess (FilePageAccess const &);
+ FilePageAccess & operator= (FilePageAccess const &);
+};
+
+storeError FilePageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize)
+{
+ (void) eAccessMode; // UNUSED
+ (void) nPageSize; // UNUSED
+ return store_E_Unknown; // NYI
+}
+FilePageAccess::~FilePageAccess()
+{
+ if (m_hFile != 0)
+ (void) osl_closeFile (m_hFile);
+}
+storeError FilePageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
+{
+ PageHolder page (0/*allocate()*/); /* @@@ construct w/ deallocator argument @@@ */
+ if (!page.get())
+ return store_E_OutOfMemory;
+
+ swap<PageHolder>(page, rPage);
+ return peekAt (nOffset, rPage.get(), 0/*size*/);
+}
+storeError FilePageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset)
+{
+ return pokeAt (nOffset, rPage.get(), 0/*size*/);
+}
+storeError FilePageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
+{
+ sal_uInt64 nDone = 0;
+ oslFileError result = osl_readFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone);
+ if (result != osl_File_E_None)
+ return ERROR_FROM_NATIVE(result);
+ if (nDone != nBytes)
+ return (nDone != 0) ? store_E_CantRead : store_E_NotExists;
+ return store_E_None;
+}
+storeError FilePageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
+{
+ sal_uInt64 nDone = 0;
+ oslFileError result = osl_writeFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone);
+ if (result != osl_File_E_None)
+ return ERROR_FROM_NATIVE(result);
+ if (nDone != nBytes)
+ return store_E_CantWrite;
+ return store_E_None;
+}
+storeError FilePageAccess::getSize_Impl (sal_uInt32 & rnSize)
+{
+ sal_uInt64 uSize = 0;
+ oslFileError result = osl_getFileSize (m_hFile, &uSize);
+ if (result != osl_File_E_None)
+ return ERROR_FROM_NATIVE(result);
+ if (uSize > SAL_MAX_UINT32)
+ return store_E_CantSeek;
+
+ rnSize = sal::static_int_cast<sal_uInt32>(uSize);
+ return store_E_None;
+}
+storeError FilePageAccess::setSize_Impl (sal_uInt32 nSize)
+{
+ oslFileError result = osl_setFileSize (m_hFile, nSize);
+ if (result != osl_File_E_None)
+ return ERROR_FROM_NATIVE(result);
+ return store_E_None;
+}
+storeError FilePageAccess::ERROR_FROM_NATIVE (oslFileError eErrno)
+{
+ switch (eErrno)
+ {
+ case osl_File_E_None:
+ return store_E_None;
+
+ case osl_File_E_NOENT:
+ return store_E_NotExists;
+
+ case osl_File_E_ACCES:
+ case osl_File_E_PERM:
+ return store_E_AccessViolation;
+
+ case osl_File_E_AGAIN:
+ case osl_File_E_DEADLK:
+ return store_E_LockingViolation;
+
+ case osl_File_E_BADF:
+ return store_E_InvalidHandle;
+
+ case osl_File_E_INVAL:
+ return store_E_InvalidParameter;
+
+ case osl_File_E_NOSPC:
+ return store_E_OutOfSpace;
+
+ case osl_File_E_OVERFLOW:
+ return store_E_CantSeek;
+
+ default:
+ return store_E_Unknown;
+ }
+}
+sal_uInt32 FilePageAccess::MODE_TO_NATIVE(storeAccessMode eAccessMode)
+{
+ sal_uInt32 nMode = 0;
+ switch (eAccessMode)
+ {
+ case store_AccessCreate:
+ case store_AccessReadCreate:
+ nMode |= osl_File_OpenFlag_Create;
+ // fall through
+ case store_AccessReadWrite:
+ nMode |= osl_File_OpenFlag_Write;
+ // fall through
+ case store_AccessReadOnly:
+ nMode |= osl_File_OpenFlag_Read;
+ break;
+ default:
+ OSL_PRECOND(0, "store::FilePageAccess: unknown storeAccessMode");
+ }
+ return nMode;
+}
+
+/*===*/
+
+class MemoryPageAccess : public IPageAccess
+{
+ /** Representation.
+ */
+ sal_uInt8 * m_pData;
+ sal_uInt32 m_nSize;
+
+ /** Callback function to release Representation.
+ */
+ typedef void (*destructor_type)(sal_uInt8 * pData, sal_uInt32 nSize);
+ destructor_type m_destructor;
+
+ /** Default destructor callback.
+ */
+ static void freeMemory (sal_uInt8 * pData, sal_uInt32 nSize);
+
+public:
+ MemoryPageAccess()
+ : m_pData (0), m_nSize (0), m_destructor (MemoryPageAccess::freeMemory)
+ {}
+ MemoryPageAccess (sal_uInt8 * pData, sal_uInt32 nSize, destructor_type destructor = MemoryPageAccess::freeMemory)
+ : m_pData (pData), m_nSize (nSize), m_destructor (destructor)
+ {}
+
+ virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize);
+
+private:
+ /** Page (size aligned) access.
+ */
+ virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
+ virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
+
+ /** Low level access.
+ */
+ virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
+ virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
+
+ virtual storeError getSize_Impl (sal_uInt32 & rnSize);
+ virtual storeError setSize_Impl (sal_uInt32 nSize);
+
+protected:
+ virtual ~MemoryPageAccess();
+
+private:
+ /** Not implemented.
+ */
+ MemoryPageAccess (MemoryPageAccess const &);
+ MemoryPageAccess & operator= (MemoryPageAccess const &);
+};
+
+storeError MemoryPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize)
+{
+ (void) eAccessMode; // UNUSED
+ (void) nPageSize; // UNUSED
+ return store_E_Unknown; // NYI
+}
+MemoryPageAccess::~MemoryPageAccess()
+{
+ if (m_destructor != 0)
+ {
+ // release resource.
+ (*m_destructor)(m_pData, m_nSize);
+ }
+}
+storeError MemoryPageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
+{
+ /* OSL_PRECOND(nOffset % size == 0, "Unaligned page read."); */
+ PageHolder page (reinterpret_cast< PageData* >(m_pData + nOffset));
+ swap<PageHolder>(page, rPage);
+ return store_E_None;
+}
+storeError MemoryPageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset)
+{
+ PageData const * pagedata = rPage.get();
+ if (!(pagedata != 0))
+ return store_E_InvalidParameter;
+
+ return pokeAt (nOffset, pagedata, pagedata->size());
+}
+storeError MemoryPageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
+{
+ // [SECURITY:ValInput]
+ sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer);
+ if (!(dst_lo != 0))
+ return store_E_InvalidParameter;
+
+ sal_uInt8 * dst_hi = dst_lo + nBytes;
+ if (!(dst_lo <= dst_hi))
+ return store_E_InvalidParameter;
+
+ // ...
+ sal_uInt8 const * src_lo = m_pData + nOffset;
+ if (!(src_lo <= m_pData + m_nSize))
+ return store_E_CantSeek;
+
+ sal_uInt8 const * src_hi = src_lo + nBytes;
+ if (!(src_hi <= m_pData + m_nSize))
+ return store_E_CantRead;
+
+ // copy.
+ memcpy (pBuffer, src_lo, (src_hi - src_lo));
+ return store_E_None;
+}
+storeError MemoryPageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
+{
+ // [SECURITY:ValInput]
+ sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer);
+ if (!(src_lo != 0))
+ return store_E_InvalidParameter;
+
+ sal_uInt8 const * src_hi = src_lo + nBytes;
+ if (!(src_lo <= src_hi))
+ return store_E_InvalidParameter;
+
+ sal_uInt64 const uSize = nOffset + nBytes;
+ if (uSize > SAL_MAX_UINT32)
+ return store_E_CantSeek;
+
+ // ...
+ if (uSize > m_nSize)
+ {
+ // increase size.
+ storeError eErrCode = setSize (sal::static_int_cast<sal_uInt32>(uSize));
+ if (eErrCode != store_E_None)
+ return eErrCode;
+ }
+
+ sal_uInt8 * dst_lo = m_pData + nOffset;
+ if (!(dst_lo <= m_pData + m_nSize))
+ return store_E_CantSeek;
+
+ sal_uInt8 * dst_hi = dst_lo + nBytes;
+ if (!(dst_hi <= m_pData + m_nSize))
+ return store_E_CantWrite;
+
+ // copy.
+ memcpy (dst_lo, src_lo, (src_hi - src_lo));
+ return store_E_None;
+}
+storeError MemoryPageAccess::getSize_Impl (sal_uInt32 & rnSize)
+{
+ rnSize = m_nSize;
+ return store_E_None;
+}
+storeError MemoryPageAccess::setSize_Impl (sal_uInt32 nSize)
+{
+ if (nSize != m_nSize)
+ {
+ sal_uInt8 * pData = static_cast<sal_uInt8*>(rtl_reallocateMemory (m_pData, nSize));
+ if (pData != 0)
+ {
+ if (nSize > m_nSize)
+ memset (pData + m_nSize, 0, sal::static_int_cast< size_t >(nSize - m_nSize));
+ }
+ else
+ {
+ if (nSize != 0)
+ return store_E_OutOfMemory;
+ }
+ m_pData = pData, m_nSize = nSize;
+ }
+ return store_E_None;
+}
+void MemoryPageAccess::freeMemory (sal_uInt8 * pData, sal_uInt32 /*nSize*/)
+{
+ rtl_freeMemory (pData);
+}
+
+/*===*/
+
+class MappedPageAccess : public MemoryPageAccess
+{
+ /** @see MemoryPageAccess::destructor_type callback function.
+ */
+ static void unmapFile (sal_uInt8 * pData, sal_uInt32 nSize);
+
+public:
+ MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize);
+
+ virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize);
+
+ virtual storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset);
+
+private:
+ virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
+ virtual storeError setSize_Impl (sal_uInt32 nSize);
+
+protected:
+ virtual ~MappedPageAccess() {}
+};
+
+MappedPageAccess::MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize)
+ : MemoryPageAccess (pData, nSize, MappedPageAccess::unmapFile)
+{
+}
+storeError MappedPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize)
+{
+ OSL_PRECOND(eAccessMode == store_AccessReadOnly, "store::MappedPageAccess: invalid AccessMode");
+ return MemoryPageAccess::initialize (eAccessMode, nPageSize);
+}
+storeError MappedPageAccess::writePageAt (PageHolder const & /*rPage*/, sal_uInt32 /*nOffset*/)
+{
+ return store_E_AccessViolation;
+}
+storeError MappedPageAccess::pokeAt_Impl (sal_uInt32 /*nOffset*/, void const * /*pBuffer*/, sal_uInt32 /*nBytes*/)
+{
+ return store_E_AccessViolation;
+}
+storeError MappedPageAccess::setSize_Impl (sal_uInt32 /*nSize*/)
+{
+ return store_E_AccessViolation;
+}
+void MappedPageAccess::unmapFile (sal_uInt8 * pData, sal_uInt32 nSize)
+{
+ (void) osl_unmapFile (pData, nSize);
+}
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+
+#include <stdio.h>
+
+int SAL_CALL main (int argc, char ** argv)
+{
+ OSL_PRECOND(argc >= 1, "t_page: error: insufficient number of arguments.");
+ if (argc < 1)
+ return 0;
+
+ {
+ void *a = (void*)1, *b = (void*)2;
+ swap<void*>(a, b);
+ }
+ {
+ PageObject a;
+ PageObject b (a);
+ PageObject c;
+
+ c = b;
+ a = a;
+
+ }
+ {
+ TestBIOS aBIOS;
+ TestClient aClient;
+ aClient.dwim (aBIOS);
+ }
+
+ if (argc > 1)
+ {
+ rtl_uString * pFilename = 0;
+ rtl_uString_newFromAscii (&pFilename, argv[1]);
+ storeAccessMode eAccessMode = store_AccessReadOnly;
+
+ // Acquire file handle.
+ ResourceHolder<FileHandle> h1;
+ oslFileError result = h1.get().initialize (pFilename, FilePageAccess::MODE_TO_NATIVE(eAccessMode));
+ if (result == osl_File_E_None)
+ {
+ ResourceHolder<FileHandle> h2 (h1);
+ h1 = h2;
+
+ if (eAccessMode == store_AccessReadOnly)
+ {
+ ResourceHolder<FileMapping> m1;
+ result = m1.get().initialize (h1.get());
+
+ const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(m1.get().m_uSize);
+ (void) nSize; // UNUSED
+
+ ResourceHolder<FileMapping> m2 (m1);
+ m1 = m2;
+
+ result = osl_File_E_None;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/store/workben/t_store.cxx b/store/workben/t_store.cxx
new file mode 100644
index 000000000000..19678b2ab86e
--- /dev/null
+++ b/store/workben/t_store.cxx
@@ -0,0 +1,591 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_store.hxx"
+
+#define _T_STORE_CXX
+#include <sal/types.h>
+#include <osl/diagnose.h>
+#include <osl/thread.h>
+#include <osl/time.h>
+#include <rtl/ustring.hxx>
+#include <store/store.hxx>
+
+#include <stdio.h>
+
+#if (defined(WNT) && defined(PROFILE))
+extern "C"
+{
+ void StartCAP (void);
+ void StopCAP (void);
+ void DumpCAP (void);
+}
+#endif /* PROFILE */
+
+using rtl::OUString;
+
+/*========================================================================
+ *
+ * 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
+};
+
+inline sal_Char ascii_toLowerCase (sal_Char ch)
+{
+ if ((ch >= 0x41) && (ch <= 0x5A))
+ return (ch + 0x20);
+ else
+ return (ch);
+}
+
+/*========================================================================
+ *
+ * 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 store::OStoreDirectory Directory;
+
+class DirectoryTraveller : public Directory::traveller
+{
+ typedef store::OStoreFile file;
+ typedef Directory::iterator iter;
+
+ store::OStoreFile m_aFile;
+ OUString m_aPath;
+
+ sal_uInt32 m_nOptions;
+ unsigned int m_nLevel;
+ unsigned int m_nCount;
+
+public:
+ DirectoryTraveller (
+ const file& rFile,
+ const OUString &rPath,
+ const OUString &rName,
+ sal_uInt32 nOptions,
+ unsigned int 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,
+ unsigned int nLevel)
+ : m_aFile (rFile),
+ m_aPath (rPath),
+ m_nOptions (nOptions),
+ m_nLevel (nLevel),
+ m_nCount (0)
+{
+ m_aPath += rName;
+ m_aPath += OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+}
+
+/*
+ * ~DirectoryTraveller.
+ */
+DirectoryTraveller::~DirectoryTraveller (void)
+{
+}
+
+/*
+ * visit.
+ */
+sal_Bool DirectoryTraveller::visit (const iter& it)
+{
+ m_nCount++;
+ if (m_nOptions & OPTION_DUMP)
+ {
+ rtl::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, (unsigned int)(it.m_nAttrib), (unsigned int)(it.m_nSize));
+ }
+ if (it.m_nAttrib & STORE_ATTRIB_ISDIR)
+ {
+ OUString aName (it.m_pszName, it.m_nLength);
+ if (aName.compareToAscii ("XTextViewCursorSupplier") == 0)
+ {
+ m_nCount += 1 - 1;
+ }
+ 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;
+}
+
+/*========================================================================
+ *
+ * main.
+ *
+ *======================================================================*/
+int SAL_CALL main (int argc, char **argv)
+{
+#if (defined(WNT) && defined(PROFILE))
+ StartCAP();
+#else
+ OTime aMainStartTime (OTime::getSystemTime());
+#endif /* PROFILE */
+
+ 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 (ascii_toLowerCase(sal_Char(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]),
+ osl_getThreadTextEncoding());
+ 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 ("Usage:\tt_store "
+ "[[-c] [-t] [-r] [-w]] [[-i] [-d] [-h]] "
+ "[-f filename]\n");
+
+ printf ("\nOptions:\n");
+ printf ("-c\tcreate\n");
+ printf ("-t\ttruncate\n");
+ printf ("-r\tread\n");
+ printf ("-w\twrite\n");
+ printf ("-i\titerate\n");
+ printf ("-d\tdump\n");
+ printf ("-h\thelp\n");
+ printf ("-f\tfilename\n");
+
+ printf ("\nExamples:");
+ printf ("\nt_store -c -w -f t_store.rdb\n");
+ printf ("\tCreate file 't_store.rdb',\n"
+ "\twrite fixed number (1000) of streams.\n");
+ printf ("\nt_store -c -i -d -f t_store.rdb\n");
+ printf ("\tOpen file 't_store.rdb', "
+ "create '/' directory,\n"
+ "\titerate directory tree, "
+ "dump directory info.\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 (int i = 0; i < _DEMOSTOR_LOOPS; i++)
+ {
+ OUString aName (RTL_CONSTASCII_USTRINGPARAM("demostor-"));
+ aName += OUString::valueOf ((sal_Int32)(i + 1), 10);
+ aName += OUString(RTL_CONSTASCII_USTRINGPARAM (".dat"));
+
+#if (_DEMOSTOR_REMOVE == 1)
+ eErrCode = aFile.remove (aPath, aName);
+ if ((eErrCode != store_E_None ) &&
+ (eErrCode != store_E_NotExists) )
+ break;
+#endif /* _REMOVE */
+
+ store::OStoreStream aStream;
+ eErrCode = aStream.create (aFile, aPath, aName, eMode);
+ if (eErrCode != store_E_None)
+ {
+ OSL_TRACE("OStoreStream(%d)::create(): error: %d", i, eErrCode);
+ break;
+ }
+
+ if (nOptions & OPTION_TRUNC)
+ {
+ eErrCode = aStream.setSize(0);
+ if (eErrCode != store_E_None)
+ {
+ OSL_TRACE("OStoreStream(%d)::setSize(0): error: %d", i, eErrCode);
+ break;
+ }
+ }
+
+ sal_uInt32 nDone = 0;
+ if (nOptions & OPTION_WRITE)
+ {
+ eErrCode = aStream.writeAt (
+ 0, pBuffer, sizeof(pBuffer), nDone);
+ if (eErrCode != store_E_None)
+ {
+ OSL_TRACE("OStoreStream(%d)::writeAt(): error: %d", i, eErrCode);
+ break;
+ }
+ }
+
+ if (nOptions & OPTION_READ)
+ {
+ sal_uInt32 nOffset = 0;
+ for (;;)
+ {
+ eErrCode = aStream.readAt (
+ nOffset, pBuffer, sizeof(pBuffer), nDone);
+ if (eErrCode != store_E_None)
+ {
+ OSL_TRACE("OStoreStream(%d)::readAt(): error: %d", i, eErrCode);
+ 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", (unsigned int)(nDelta));
+#endif /* PROFILE */
+ }
+
+ // Link/Rename.
+ if (nOptions & OPTION_LINK)
+ {
+ // Create symlink to (root) directory.
+ eErrCode = aFile.symlink (
+ aPath, OUString(RTL_CONSTASCII_USTRINGPARAM("000000/")),
+ OUString(), aPath);
+ OSL_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(RTL_CONSTASCII_USTRINGPARAM("demostor-1.dat")));
+ OSL_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);
+ OSL_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"));
+ store::OStoreDirectory aDir;
+
+ eErrCode = aDir.create (
+ aFile, aPath, aDirName, store_AccessReadCreate);
+ OSL_POSTCOND(
+ (eErrCode == store_E_None),
+ "t_store::main(): store_createDirectory() failed");
+ if (eErrCode == store_E_None)
+ {
+ }
+ }
+
+ // Directory iteration.
+ if (nOptions & OPTION_ITER)
+ {
+#ifndef PROFILE
+ OTime aStartTime (OTime::getSystemTime());
+#endif /* PROFILE */
+ OUString aEmpty;
+
+ // Root directory.
+ store::OStoreDirectory aRootDir;
+ if (nOptions & OPTION_LINK)
+ {
+ // Open symlink entry.
+ eErrCode = aRootDir.create (
+ aFile, aPath, OUString(RTL_CONSTASCII_USTRINGPARAM("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", (unsigned int)(nDelta));
+#endif /* PROFILE */
+ }
+
+ if (nOptions & OPTION_PAUSE)
+ {
+ TimeValue tv;
+ tv.Seconds = 300;
+ tv.Nanosec = 0;
+ osl_waitThread (&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() - aMainStartTime);
+
+ sal_uInt32 nDelta = aDelta.Seconds * 1000000;
+ nDelta += (aDelta.Nanosec / 1000);
+
+ printf ("Total: %d[usec]\n", (unsigned int)(nDelta));
+#endif /* PROFILE */
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */