diff options
Diffstat (limited to 'registry')
53 files changed, 19496 insertions, 0 deletions
diff --git a/registry/inc/makefile.mk b/registry/inc/makefile.mk new file mode 100644 index 000000000000..1a212316147a --- /dev/null +++ b/registry/inc/makefile.mk @@ -0,0 +1,47 @@ +#************************************************************************* +# +# 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=registry +TARGET=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/registry/inc/pch/precompiled_registry.cxx b/registry/inc/pch/precompiled_registry.cxx new file mode 100644 index 000000000000..23c19ddd1599 --- /dev/null +++ b/registry/inc/pch/precompiled_registry.cxx @@ -0,0 +1,29 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_registry.hxx" + diff --git a/registry/inc/pch/precompiled_registry.hxx b/registry/inc/pch/precompiled_registry.hxx new file mode 100644 index 000000000000..7709276aefa4 --- /dev/null +++ b/registry/inc/pch/precompiled_registry.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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): Generated on 2006-09-01 17:49:54.670626 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/registry/inc/registry/reader.h b/registry/inc/registry/reader.h new file mode 100644 index 000000000000..50fa802c4f83 --- /dev/null +++ b/registry/inc/registry/reader.h @@ -0,0 +1,610 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_registry_reader_h +#define INCLUDED_registry_reader_h + +#include "registry/types.h" +#include "registry/version.h" + +#include "rtl/ustring.h" +#include "sal/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @HTML + +/** + Creates a type reader working on a binary blob that represents a UNOIDL type. + + <p>If a non-null handle is returned through <code>result</code>, its + reference count will be one. Operations on a non-null handle are not + multi-thread–safe.</p> + + @param buffer the binary blob representing the type; must point to at least + <code>length</code> bytes, and need only be byte-aligned + + @param length the size in bytes of the binary blob representing the type + + @param copy if true, the type reader creates an internal copy of the given + buffer, and the given buffer is not accessed after this function returns; if + false, the type reader works directly on the given buffer, which must remain + available unmodified until the type reader is destroyed + + @param maxVersion the maximum binary blob version the client is prepared to + handle; must not be negative + + @param result an out-parameter obtaining a handle on the type reader; must + not be null; if the given binary blob is malformed, or of a version larger + than <code>maxVersion</code>, null is returned + + @return false iff an out-of-memory condition occured, in which case + <code>result</code> is left unchanged, and no type reader is created + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_reader_create( + void const * buffer, sal_uInt32 length, sal_Bool copy, + enum typereg_Version maxVersion, void ** result) + SAL_THROW_EXTERN_C(); + +/** + Increments the reference count of a type reader. + + @param handle a handle on a type reader; may be null + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_acquire(void * handle) SAL_THROW_EXTERN_C(); + +/** + Decrements the reference count of a type reader. + + <p>If the reference count drops to zero, the type reader is destroyed.</p> + + @param handle a handle on a type reader; may be null + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_release(void * handle) SAL_THROW_EXTERN_C(); + +/** + Returns the binary blob version of a type reader. + + @param handle a handle on a type reader; may be null + + @return the version of the binary blob from which the type reader was + constructed; if <code>handle</code> is null, <code>TYPEREG_VERSION_0</code> + is returned + + @since UDK 3.2.0 + */ +enum typereg_Version SAL_CALL typereg_reader_getVersion(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns the documentation of a type reader. + + @param handle a handle on a type reader; may be null + + @param result an out-parameter obtaining the documentation string; must not + be null; if <code>handle</code> is null, an empty string is returned; if an + out-of-memory condition occurs, a pointer to a null pointer is returned + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getDocumentation( + void * handle, rtl_uString ** result) SAL_THROW_EXTERN_C(); + +/** + Returns the file name of a type reader. + + @param handle a handle on a type reader; may be null + + @param result an out-parameter obtaining the file name string; must not be + null; if <code>handle</code> is null, an empty string is returned; if an + out-of-memory condition occurs, a pointer to a null pointer is returned + + @since UDK 3.2.0 + @deprecated + */ +void SAL_CALL typereg_reader_getFileName(void * handle, rtl_uString ** result) + SAL_THROW_EXTERN_C(); + +/** + Returns the type class of a type reader. + + <p>This function will always return the type class without the internal + <code>RT_TYPE_PUBLISHED</code> flag set. Use + <code>typereg_reader_isPublished</code> to determine whether a type reader is + published.</p> + + @param handle a handle on a type reader; may be null + + @return the type class of the type reader; if <code>handle</code> is null, + <code>RT_TYPE_INVALID</code> is returned + + @since UDK 3.2.0 + */ +enum RTTypeClass SAL_CALL typereg_reader_getTypeClass(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns whether a type reader is published. + + @param handle a handle on a type reader; may be null + + @return whether the type reader is published; if <code>handle</code> is null, + <code>sal_False</code> is returned + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_reader_isPublished(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns the type name of a type reader. + + @param handle a handle on a type reader; may be null + + @param result an out-parameter obtaining the type name string; must not be + null; if <code>handle</code> is null, an empty string is returned; if an + out-of-memory condition occurs, a pointer to a null pointer is returned + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getTypeName(void * handle, rtl_uString ** result) + SAL_THROW_EXTERN_C(); + +/** + Returns the number of super types of a type reader. + + @param handle a handle on a type reader; may be null + + @return the number of super types of the type reader; if <code>handle</code> + is null, zero is returned + + @since UDK 3.2.0 + */ +sal_uInt16 SAL_CALL typereg_reader_getSuperTypeCount(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns the type name of a super type of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the super type's type name string; + must not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param index a valid index into the range of super types of the given type + reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getSuperTypeName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the number of fields of a type reader. + + @param handle a handle on a type reader; may be null + + @return the number of fields of the type reader; if <code>handle</code> is + null, zero is returned + + @since UDK 3.2.0 + */ +sal_uInt16 SAL_CALL typereg_reader_getFieldCount(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns the documentation of a field of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the field's documentation string; + must not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param index a valid index into the range of fields of the given type reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getFieldDocumentation( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the file name of a field of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the field's file name string; must + not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param index a valid index into the range of fields of the given type reader + + @since UDK 3.2.0 + @deprecated + */ +void SAL_CALL typereg_reader_getFieldFileName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the flags of a field of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of fields of the given type reader + + @return the flags of the given field of the type reader + + @since UDK 3.2.0 + */ +RTFieldAccess SAL_CALL typereg_reader_getFieldFlags( + void * handle, sal_uInt16 index) SAL_THROW_EXTERN_C(); + +/** + Returns the name of a field of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the field's name string; must not be + null; if an out-of-memory condition occurs, a pointer to a null pointer is + returned + + @param index a valid index into the range of fields of the given type reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getFieldName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the type name of a field of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the field's type name string; must + not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param index a valid index into the range of fields of the given type reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getFieldTypeName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the value of a field of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of fields of the given type reader + + @param type an out-parameter obtaining the field value's type; must not be + null + + @param result an out-parameter obtaining the field value's value; must not be + null + + @return false iff an out-of-memory condition occured, in which case + <code>type</code> and <code>value</code> are left unchanged + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_reader_getFieldValue( + void * handle, sal_uInt16 index, enum RTValueType * type, + union RTConstValueUnion * value) + SAL_THROW_EXTERN_C(); + +/** + Returns the number of methods of a type reader. + + @param handle a handle on a type reader; may be null + + @return the number of methods of the type reader; if <code>handle</code> is + null, zero is returned + + @since UDK 3.2.0 + */ +sal_uInt16 SAL_CALL typereg_reader_getMethodCount(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns the documentation of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the methods's documentation string; + must not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param index a valid index into the range of methods of the given type reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getMethodDocumentation( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the flags of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of methods of the given type reader + + @return the flags of the given method of the type reader + + @since UDK 3.2.0 + */ +enum RTMethodMode SAL_CALL typereg_reader_getMethodFlags( + void * handle, sal_uInt16 index) SAL_THROW_EXTERN_C(); + +/** + Returns the name of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the methods's name string; must not + be null; if an out-of-memory condition occurs, a pointer to a null pointer is + returned + + @param index a valid index into the range of methods of the given type reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getMethodName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the return type name of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the methods's return type name + string; must not be null; if an out-of-memory condition occurs, a pointer to + a null pointer is returned + + @param index a valid index into the range of methods of the given type reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getMethodReturnTypeName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the number of parameters of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of methods of the given type reader + + @return the number of parameters of the given method of the type reader + + @since UDK 3.2.0 + */ +sal_uInt16 SAL_CALL typereg_reader_getMethodParameterCount( + void * handle, sal_uInt16 index) SAL_THROW_EXTERN_C(); + +/** + Returns the flags of a parameter of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param methodIndex a valid index into the range of methods of the given type + reader + + @param parameterIndex a valid index into the range of parameters of the given + method + + @return the flags of the given parameter of the given method of the type + reader + + @since UDK 3.2.0 + */ +enum RTParamMode SAL_CALL typereg_reader_getMethodParameterFlags( + void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex) + SAL_THROW_EXTERN_C(); + +/** + Returns the name of a parameter of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the parameter's name string; must + not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param methodIndex a valid index into the range of methods of the given type + reader + + @param parameterIndex a valid index into the range of parameters of the given + method + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getMethodParameterName( + void * handle, rtl_uString ** result, sal_uInt16 methodIndex, + sal_uInt16 parameterIndex) + SAL_THROW_EXTERN_C(); + +/** + Returns the type name of a parameter of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the parameter's type name string; + must not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param methodIndex a valid index into the range of methods of the given type + reader + + @param parameterIndex a valid index into the range of parameters of the given + method + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getMethodParameterTypeName( + void * handle, rtl_uString ** result, sal_uInt16 methodIndex, + sal_uInt16 parameterIndex) + SAL_THROW_EXTERN_C(); + +/** + Returns the number of exceptions of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of methods of the given type reader + + @return the number of exceptions of the given method of the type reader + + @since UDK 3.2.0 + */ +sal_uInt16 SAL_CALL typereg_reader_getMethodExceptionCount( + void * handle, sal_uInt16 index) SAL_THROW_EXTERN_C(); + +/** + Returns the type name of an exception of a method of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the exception's type name string; + must not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param methodIndex a valid index into the range of methods of the given type + reader + + @param exceptionIndex a valid index into the range of exceptions of the given + method + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getMethodExceptionTypeName( + void * handle, rtl_uString ** result, sal_uInt16 methodIndex, + sal_uInt16 exceptionIndex) + SAL_THROW_EXTERN_C(); + +/** + Returns the number of references of a type reader. + + @param handle a handle on a type reader; may be null + + @return the number of references of the type reader; if <code>handle</code> + is null, zero is returned + + @since UDK 3.2.0 + */ +sal_uInt16 SAL_CALL typereg_reader_getReferenceCount(void * handle) + SAL_THROW_EXTERN_C(); + +/** + Returns the documentation of a reference of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the reference's documentation + string; must not be null; if an out-of-memory condition occurs, a pointer to + a null pointer is returned + + @param index a valid index into the range of references of the given type + reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getReferenceDocumentation( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +/** + Returns the flags of a reference of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of references of the given type + reader + + @return the flags of the given reference of the type reader + + @since UDK 3.2.0 + */ +RTFieldAccess SAL_CALL typereg_reader_getReferenceFlags( + void * handle, sal_uInt16 index) SAL_THROW_EXTERN_C(); + +/** + Returns the sort of a reference of a type reader. + + @param handle a handle on a type reader; must not be null + + @param index a valid index into the range of references of the given type + reader + + @return the sort of the given reference of the type reader + + @since UDK 3.2.0 + */ +enum RTReferenceType SAL_CALL typereg_reader_getReferenceSort( + void * handle, sal_uInt16 index) SAL_THROW_EXTERN_C(); + +/** + Returns the type name of a reference of a type reader. + + @param handle a handle on a type reader; must not be null + + @param result an out-parameter obtaining the reference's type name string; + must not be null; if an out-of-memory condition occurs, a pointer to a null + pointer is returned + + @param index a valid index into the range of references of the given type + reader + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_reader_getReferenceTypeName( + void * handle, rtl_uString ** result, sal_uInt16 index) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/registry/inc/registry/reader.hxx b/registry/inc/registry/reader.hxx new file mode 100644 index 000000000000..30e5abb148aa --- /dev/null +++ b/registry/inc/registry/reader.hxx @@ -0,0 +1,632 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_registry_reader_hxx +#define INCLUDED_registry_reader_hxx + +#include "registry/reader.h" +#include "registry/refltype.hxx" +#include "registry/types.h" +#include "registry/version.h" + +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <algorithm> +#include <new> + +namespace typereg { + +/// @HTML + +/** + A type reader working on a binary blob that represents a UNOIDL type. + + <p>Instances of this class are not multi-thread–safe.</p> + + @since UDK 3.2.0 + */ +class Reader { +public: + /** + Creates an invalid type reader. + */ + Reader(): m_handle(0) {} + + /** + Creates a type reader. + + <p>If the given binary blob is malformed, or of a version larger than + <code>maxVersion</code>, the created type reader is flagged as + invalid.</p> + + @param buffer the binary blob representing the type; must point to at + least <code>length</code> bytes, and need only be byte-aligned + + @param length the size in bytes of the binary blob representing the type + + @param copy if true, the type reader creates an internal copy of the + given buffer, and the given buffer is not accessed after this constructor + returns; if false, the type reader works directly on the given buffer, + which must remain available unmodified until the underlying type reader + is destroyed (note that the lifetime of the underlying type reader can be + different from the lifetime of this <code>Reader</code> instance) + + @param maxVersion the maximum binary blob version the client is prepared + to handle; must not be negative + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + Reader( + void const * buffer, sal_uInt32 length, bool copy, + typereg_Version maxVersion) + { + if (!typereg_reader_create(buffer, length, copy, maxVersion, &m_handle)) + { + throw std::bad_alloc(); + } + } + + /** + Shares a type reader between two <code>Reader</code> instances. + + @param other another <code>Reader</code> instance + */ + Reader(Reader const & other): m_handle(other.m_handle) { + typereg_reader_acquire(m_handle); + } + + /** + Destroys this <code>Reader</code> instance. + + <p>The underlying type reader is only destroyed if this instance was its + last user.</p> + */ + ~Reader() { + typereg_reader_release(m_handle); + } + + /** + Replaces the underlying type reader. + + @param other any <code>Reader</code> instance + + @return this <code>Reader</code> instance + */ + Reader & operator =(Reader const & other) { + Reader temp(other); + std::swap(this->m_handle, temp.m_handle); + return *this; + } + + /** + Returns whether this type reader is valid. + + @return true iff this type reader is valid + */ + bool isValid() const { + return m_handle != 0; + } + + /** + Returns the binary blob version of this type reader. + + @return the version of the binary blob from which this type reader was + constructed; if this type reader is invalid, + <code>TYPEREG_VERSION_0</code> is returned + */ + typereg_Version getVersion() const { + return typereg_reader_getVersion(m_handle); + } + + /** + Returns the documentation of this type reader. + + @return the documentation of this type reader; if this type reader is + invalid, an empty string is returned + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getDocumentation() const { + rtl_uString * s = 0; + typereg_reader_getDocumentation(m_handle, &s); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the file name of this type reader. + + @return the file name of this type reader; if this type reader is + invalid, an empty string is returned + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + @deprecated + */ + rtl::OUString getFileName() const { + rtl_uString * s = 0; + typereg_reader_getFileName(m_handle, &s); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the type class of this type reader. + + <p>This function will always return the type class without the internal + <code>RT_TYPE_PUBLISHED</code> flag set. Use <code>isPublished</code> to + determine whether this type reader is published.</p> + + @return the type class of this type reader; if this type reader is + invalid, <code>RT_TYPE_INVALID</code> is returned + */ + RTTypeClass getTypeClass() const { + return typereg_reader_getTypeClass(m_handle); + } + + /** + Returns whether this type reader is published. + + @return whether this type reader is published; if this type reader is + invalid, <code>false</code> is returned + */ + bool isPublished() const { + return typereg_reader_isPublished(m_handle); + } + + /** + Returns the type name of this type reader. + + @return the type name of this type reader; if this type reader is + invalid, an empty string is returned + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getTypeName() const { + rtl_uString * s = 0; + typereg_reader_getTypeName(m_handle, &s); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the number of super types of this type reader. + + @return the number of super types of this type reader; if this type + reader is invalid, zero is returned + */ + sal_uInt16 getSuperTypeCount() const { + return typereg_reader_getSuperTypeCount(m_handle); + } + + /** + Returns the type name of a super type of this type reader. + + @param index a valid index into the range of super types of this type + reader + + @return the type name of the given super type + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getSuperTypeName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getSuperTypeName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the number of fields of this type reader. + + @return the number of fields of this type reader; if this type reader is + invalid, zero is returned + */ + sal_uInt16 getFieldCount() const { + return typereg_reader_getFieldCount(m_handle); + } + + /** + Returns the documentation of a field of this type reader. + + @param index a valid index into the range of fields of this type reader + + @return the documentation of the given field + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getFieldDocumentation(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getFieldDocumentation(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the file name of a field of this type reader. + + @param index a valid index into the range of fields of this type reader + + @return the file name of the given field + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + @deprecated + */ + rtl::OUString getFieldFileName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getFieldFileName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the flags of a field of this type reader. + + @param index a valid index into the range of fields of this type reader + + @return the flags of the given field + */ + RTFieldAccess getFieldFlags(sal_uInt16 index) const { + return typereg_reader_getFieldFlags(m_handle, index); + } + + /** + Returns the name of a field of this type reader. + + @param index a valid index into the range of fields of this type reader + + @return the name of the given field + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getFieldName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getFieldName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the type name of a field of this type reader. + + @param index a valid index into the range of fields of this type reader + + @return the type name of the given field + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getFieldTypeName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getFieldTypeName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the value of a field of this type reader. + + @param index a valid index into the range of fields of this type reader + + @return the value of the given field + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + RTConstValue getFieldValue(sal_uInt16 index) const { + RTConstValue v; + if (!typereg_reader_getFieldValue( + m_handle, index, &v.m_type, &v.m_value)) + { + throw std::bad_alloc(); + } + return v; + } + + /** + Returns the number of methods of this type reader. + + @return the number of methods of this type reader; if this type reader is + invalid, zero is returned + */ + sal_uInt16 getMethodCount() const { + return typereg_reader_getMethodCount(m_handle); + } + + /** + Returns the documentation of a method of this type reader. + + @param index a valid index into the range of methods of this type reader + + @return the documentation of the given method + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getMethodDocumentation(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getMethodDocumentation(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the flags of a method of this type reader. + + @param index a valid index into the range of methods of this type reader + + @return the flags of the given method + */ + RTMethodMode getMethodFlags(sal_uInt16 index) const { + return typereg_reader_getMethodFlags(m_handle, index); + } + + /** + Returns the name of a method of this type reader. + + @param index a valid index into the range of methods of this type reader + + @return the name of the given method + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getMethodName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getMethodName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the return type name of a method of this type reader. + + @param index a valid index into the range of methods of this type reader + + @return the return type name of the given method + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getMethodReturnTypeName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getMethodReturnTypeName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the number of parameters of a method of this type reader. + + @param index a valid index into the range of methods of this type reader + + @return the number of parameters of the given method + */ + sal_uInt16 getMethodParameterCount(sal_uInt16 index) const { + return typereg_reader_getMethodParameterCount(m_handle, index); + } + + /** + Returns the flags of a parameter of a method of this type reader. + + @param methodIndex a valid index into the range of methods of this type + reader + + @param parameterIndex a valid index into the range of parameters of the + given method + + @return the flags of the given method parameter + */ + RTParamMode getMethodParameterFlags( + sal_uInt16 methodIndex, sal_uInt16 parameterIndex) const + { + return typereg_reader_getMethodParameterFlags( + m_handle, methodIndex, parameterIndex); + } + + /** + Returns the name of a parameter of a method of this type reader. + + @param methodIndex a valid index into the range of methods of this type + reader + + @param parameterIndex a valid index into the range of parameters of the + given method + + @return the name of the given method parameter + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getMethodParameterName( + sal_uInt16 methodIndex, sal_uInt16 parameterIndex) const + { + rtl_uString * s = 0; + typereg_reader_getMethodParameterName( + m_handle, &s, methodIndex, parameterIndex); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the type name of a parameter of a method of this type reader. + + @param methodIndex a valid index into the range of methods of this type + reader + + @param parameterIndex a valid index into the range of parameters of the + given method + + @return the type name of the given method parameter + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getMethodParameterTypeName( + sal_uInt16 methodIndex, sal_uInt16 parameterIndex) const + { + rtl_uString * s = 0; + typereg_reader_getMethodParameterTypeName( + m_handle, &s, methodIndex, parameterIndex); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the number of exceptions of a method of this type reader. + + @param index a valid index into the range of methods of this type reader + + @return the number of exceptions of the given method + */ + sal_uInt16 getMethodExceptionCount(sal_uInt16 index) const { + return typereg_reader_getMethodExceptionCount(m_handle, index); + } + + /** + Returns the type name of an exception of a method of this type reader. + + @param methodIndex a valid index into the range of methods of this type + reader + + @param exceptionIndex a valid index into the range of exceptions of the + given method + + @return the type name of the given method exception + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getMethodExceptionTypeName( + sal_uInt16 methodIndex, sal_uInt16 exceptionIndex) const + { + rtl_uString * s = 0; + typereg_reader_getMethodExceptionTypeName( + m_handle, &s, methodIndex, exceptionIndex); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the number of references of this type reader. + + @return the number of references of this type reader; if this type reader + is invalid, zero is returned + */ + sal_uInt16 getReferenceCount() const { + return typereg_reader_getReferenceCount(m_handle); + } + + /** + Returns the documentation of a reference of this type reader. + + @param index a valid index into the range of references of this type + reader + + @return the documentation of the given reference + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getReferenceDocumentation(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getReferenceDocumentation(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns the flags of a reference of this type reader. + + @param index a valid index into the range of references of this type + reader + + @return the flags of the given reference + */ + RTFieldAccess getReferenceFlags(sal_uInt16 index) const { + return typereg_reader_getReferenceFlags(m_handle, index); + } + + /** + Returns the sort of a reference of this type reader. + + @param index a valid index into the range of references of this type + reader + + @return the sort of the given reference + */ + RTReferenceType getReferenceSort(sal_uInt16 index) const { + return typereg_reader_getReferenceSort(m_handle, index); + } + + /** + Returns the type name of a reference of this type reader. + + @param index a valid index into the range of references of this type + reader + + @return the type name of the given reference + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + rtl::OUString getReferenceTypeName(sal_uInt16 index) const { + rtl_uString * s = 0; + typereg_reader_getReferenceTypeName(m_handle, &s, index); + if (s == 0) { + throw std::bad_alloc(); + } + return rtl::OUString(s, SAL_NO_ACQUIRE); + } + +private: + void * m_handle; +}; + +} + +#endif diff --git a/registry/inc/registry/reflread.hxx b/registry/inc/registry/reflread.hxx new file mode 100644 index 000000000000..4b964ee8a013 --- /dev/null +++ b/registry/inc/registry/reflread.hxx @@ -0,0 +1,519 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGISTRY_REFLREAD_HXX_ +#define _REGISTRY_REFLREAD_HXX_ + +#include <registry/refltype.hxx> +#include <registry/regtype.h> +#include <rtl/ustring.hxx> + +/// Implememetation handle +typedef void* TypeReaderImpl; + +/**************************************************************************** + + C-Api + +*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** specifies a collection of function pointers which represents the complete registry type reader C-API. + + This funtions pointers are used by the C++ wrapper to call the C-API. +*/ +struct RegistryTypeReader_Api +{ + TypeReaderImpl (TYPEREG_CALLTYPE *createEntry) (const sal_uInt8*, sal_uInt32, sal_Bool); + void (TYPEREG_CALLTYPE *acquire) (TypeReaderImpl); + void (TYPEREG_CALLTYPE *release) (TypeReaderImpl); + sal_uInt16 (TYPEREG_CALLTYPE *getMinorVersion) (TypeReaderImpl); + sal_uInt16 (TYPEREG_CALLTYPE *getMajorVersion) (TypeReaderImpl); + RTTypeClass (TYPEREG_CALLTYPE *getTypeClass) (TypeReaderImpl); + void (TYPEREG_CALLTYPE *getUik) (TypeReaderImpl, RTUik*); + void (TYPEREG_CALLTYPE *getDoku) (TypeReaderImpl, rtl_uString**); + void (TYPEREG_CALLTYPE *getFileName) (TypeReaderImpl, rtl_uString**); + void (TYPEREG_CALLTYPE *getTypeName) (TypeReaderImpl, rtl_uString**); + void (TYPEREG_CALLTYPE *getSuperTypeName) (TypeReaderImpl, rtl_uString**); + sal_uInt32 (TYPEREG_CALLTYPE *getFieldCount) (TypeReaderImpl); + void (TYPEREG_CALLTYPE *getFieldName) (TypeReaderImpl, rtl_uString**, sal_uInt16); + void (TYPEREG_CALLTYPE *getFieldType) (TypeReaderImpl, rtl_uString**, sal_uInt16); + RTFieldAccess (TYPEREG_CALLTYPE *getFieldAccess) (TypeReaderImpl, sal_uInt16); + RTValueType (TYPEREG_CALLTYPE *getFieldConstValue) (TypeReaderImpl, sal_uInt16, RTConstValueUnion*); + void (TYPEREG_CALLTYPE *getFieldDoku) (TypeReaderImpl, rtl_uString**, sal_uInt16); + void (TYPEREG_CALLTYPE *getFieldFileName) (TypeReaderImpl, rtl_uString**, sal_uInt16); + sal_uInt32 (TYPEREG_CALLTYPE *getMethodCount) (TypeReaderImpl); + void (TYPEREG_CALLTYPE *getMethodName) (TypeReaderImpl, rtl_uString**, sal_uInt16); + sal_uInt32 (TYPEREG_CALLTYPE *getMethodParamCount) (TypeReaderImpl, sal_uInt16); + void (TYPEREG_CALLTYPE *getMethodParamType) (TypeReaderImpl, rtl_uString**, sal_uInt16, sal_uInt16); + void (TYPEREG_CALLTYPE *getMethodParamName) (TypeReaderImpl, rtl_uString**, sal_uInt16, sal_uInt16); + RTParamMode (TYPEREG_CALLTYPE *getMethodParamMode) (TypeReaderImpl, sal_uInt16, sal_uInt16); + sal_uInt32 (TYPEREG_CALLTYPE *getMethodExcCount) (TypeReaderImpl, sal_uInt16); + void (TYPEREG_CALLTYPE *getMethodExcType) (TypeReaderImpl, rtl_uString**, sal_uInt16, sal_uInt16); + void (TYPEREG_CALLTYPE *getMethodReturnType) (TypeReaderImpl, rtl_uString**, sal_uInt16); + RTMethodMode (TYPEREG_CALLTYPE *getMethodMode) (TypeReaderImpl, sal_uInt16); + void (TYPEREG_CALLTYPE *getMethodDoku) (TypeReaderImpl, rtl_uString**, sal_uInt16); + + sal_uInt32 (TYPEREG_CALLTYPE *getReferenceCount) (TypeReaderImpl); + void (TYPEREG_CALLTYPE *getReferenceName) (TypeReaderImpl, rtl_uString**, sal_uInt16); + RTReferenceType (TYPEREG_CALLTYPE *getReferenceType) (TypeReaderImpl, sal_uInt16); + void (TYPEREG_CALLTYPE *getReferenceDoku) (TypeReaderImpl, rtl_uString**, sal_uInt16); + RTFieldAccess (TYPEREG_CALLTYPE *getReferenceAccess) (TypeReaderImpl, sal_uInt16); +}; + +/** the API initialization function. +*/ +RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api(void); + +#ifdef __cplusplus +} +#endif + +/** RegistryTypeReades reads a binary type blob. + + This class provides the necessary functions to read type informations + for all kinds of types of a type blob. + The class is inline and use a C-Api. + + @deprecated + use typereg::Reader instead +*/ +class RegistryTypeReader +{ +public: + + /** Constructor. + + @param buffer points to the binary data block. + @param bufferlen specifies the size of the binary data block. + @param copyData specifies if the data block should be copied. + The block can be copied to ensure that the data + is valid for the lifetime of this instance. + */ + inline RegistryTypeReader(const sal_uInt8* buffer, + sal_uInt32 bufferLen, + sal_Bool copyData); + + /// Copy constructcor + inline RegistryTypeReader(const RegistryTypeReader& toCopy); + + /// Destructor. The Destructor frees the data block if the copyData flag was TRUE. + inline ~RegistryTypeReader(); + + /// Assign operator + inline RegistryTypeReader& operator == (const RegistryTypeReader& toAssign); + + /// checks if the registry type reader points to a valid Api. + inline sal_Bool isValid() const; + + /** @deprecated + returns the minor version number. + + We currently don't support a versioning concept of IDL interfaces and + so this function is currently not used. + */ + inline sal_uInt16 getMinorVersion() const; + + /** @deprecated + returns the major version number. + + We currently don't support a versioning concept of IDL interfaces and + so this function is currently not used. + */ + inline sal_uInt16 getMajorVersion() const; + + /** returns the typeclass of the type represented by this blob. + + This function will always return the type class without the internal + RT_TYPE_PUBLISHED flag set. + */ + inline RTTypeClass getTypeClass() const; + + /** returns the full qualified name of the type. + */ + inline ::rtl::OUString getTypeName() const; + + /** returns the full qualified name of the supertype. + */ + inline ::rtl::OUString getSuperTypeName() const; + + /** @deprecated + returns the unique identifier for an interface type as an out parameter. + + An earlier version of UNO used an unique identifier for interfaces. In the + current version of UNO this uik was eliminated and this function is + not longer used. + */ + inline void getUik(RTUik& uik) const; + + /** returns the documentation string of this type. + */ + inline ::rtl::OUString getDoku() const; + + /** returns the IDL filename where the type is defined. + */ + inline ::rtl::OUString getFileName() const; + + /** returns the number of fields (attributes/properties, enum values or number + of constants in a module). + + */ + inline sal_uInt32 getFieldCount() const; + + /** returns the name of the field specified by index. + */ + inline ::rtl::OUString getFieldName( sal_uInt16 index ) const; + + /** returns the full qualified name of the field specified by index. + */ + inline ::rtl::OUString getFieldType( sal_uInt16 index ) const; + + /** returns the access mode of the field specified by index. + */ + inline RTFieldAccess getFieldAccess( sal_uInt16 index ) const; + + /** returns the value of the field specified by index. + + This function returns the value of an enum value or of a constant. + */ + inline RTConstValue getFieldConstValue( sal_uInt16 index ) const; + + /** returns the documentation string for the field specified by index. + + Each field of a type can have their own documentation. + */ + inline ::rtl::OUString getFieldDoku( sal_uInt16 index ) const; + + /** returns the IDL filename of the field specified by index. + + The IDL filename of a field can differ from the filename of the ype itself + because modules and also constants can be defined in different IDL files. + */ + inline ::rtl::OUString getFieldFileName( sal_uInt16 index ) const; + + /** returns the number of methods of an interface type. + */ + inline sal_uInt32 getMethodCount() const; + + /** returns the name of the method specified by index. + */ + inline ::rtl::OUString getMethodName( sal_uInt16 index ) const; + + /** returns number of parameters of the method specified by index. + */ + inline sal_uInt32 getMethodParamCount( sal_uInt16 index ) const; + + /** returns the full qualified parameter typename. + + @param index indicates the method + @param paramIndex indeciates the parameter which type will be returned. + */ + inline ::rtl::OUString getMethodParamType( sal_uInt16 index, sal_uInt16 paramIndex ) const; + + /** returns the name of a parameter. + + @param index indicates the method + @param paramIndex indiciates the parameter which name will be returned. + */ + inline ::rtl::OUString getMethodParamName( sal_uInt16 index, sal_uInt16 paramIndex ) const; + + /** returns the parameter mode, if it is an in, out or inout parameter. + + @param index indicates the method + @param paramIndex indeciates the parameter which mode will be returned. + */ + inline RTParamMode getMethodParamMode( sal_uInt16 index, sal_uInt16 paramIndex ) const; + + /** returns the number of exceptions which are declared for the method specified by index. + + @param index indicates the method + */ + inline sal_uInt32 getMethodExcCount( sal_uInt16 index ) const; + + /** returns the full qualified exception type of the specified exception. + + @param index indicates the method + @param paramIndex indeciates the exception which typename will be returned. + */ + inline ::rtl::OUString getMethodExcType( sal_uInt16 index, sal_uInt16 excIndex ) const; + + /** returns the full qualified return type of the method specified by index. + */ + inline ::rtl::OUString getMethodReturnType( sal_uInt16 index ) const; + + /** returns the full qualified exception type of the specified exception. + + @param index indicates the method + @param paramIndex indeciates the exception which typename will be returned. + */ + inline RTMethodMode getMethodMode( sal_uInt16 index ) const; + + /** returns the documentation string of the method specified by index. + + @param index indicates the method. + */ + inline ::rtl::OUString getMethodDoku( sal_uInt16 index ) const; + + /** returns the number of references (supported interfaces, exported services). + */ + inline sal_uInt32 getReferenceCount() const; + + /** returns the full qualified typename of the reference specified by index. + + @param index indicates the reference. + */ + inline ::rtl::OUString getReferenceName( sal_uInt16 index ) const; + + /** returns the type of the reference specified by index. + + @param index indicates the reference. + */ + inline RTReferenceType getReferenceType( sal_uInt16 index ) const; + + /** returns the documentation string of the reference specified by index. + + @param index indicates the reference. + */ + inline ::rtl::OUString getReferenceDoku( sal_uInt16 index ) const; + + /** returns the access mode of the reference specified by index. + + The only valid value is RT_ACCESS_OPTIONAL in the context of + references. + @param index indicates the reference. + */ + inline RTFieldAccess getReferenceAccess( sal_uInt16 index ) const; + +protected: + + /// stores the registry type reader Api. + const RegistryTypeReader_Api* m_pApi; + /// stores the handle of an implementation class + TypeReaderImpl m_hImpl; +}; + + + +inline RegistryTypeReader::RegistryTypeReader(const sal_uInt8* buffer, + sal_uInt32 bufferLen, + sal_Bool copyData) + : m_pApi(initRegistryTypeReader_Api()) + , m_hImpl(NULL) + { + m_hImpl = m_pApi->createEntry(buffer, bufferLen, copyData); + } + + +inline RegistryTypeReader::RegistryTypeReader(const RegistryTypeReader& toCopy) + : m_pApi(toCopy.m_pApi) + , m_hImpl(toCopy.m_hImpl) + { m_pApi->acquire(m_hImpl); } + + +inline RegistryTypeReader::~RegistryTypeReader() + { m_pApi->release(m_hImpl); } + +inline RegistryTypeReader& RegistryTypeReader::operator == (const RegistryTypeReader& toAssign) +{ + if (m_hImpl != toAssign.m_hImpl) + { + m_pApi->release(m_hImpl); + m_hImpl = toAssign.m_hImpl; + m_pApi->acquire(m_hImpl); + } + + return *this; +} + +inline sal_uInt16 RegistryTypeReader::getMinorVersion() const + { return m_pApi->getMinorVersion(m_hImpl); } + +inline sal_Bool RegistryTypeReader::isValid() const + { return (m_hImpl != NULL); } + +inline sal_uInt16 RegistryTypeReader::getMajorVersion() const + { return m_pApi->getMajorVersion(m_hImpl); } + +inline RTTypeClass RegistryTypeReader::getTypeClass() const + { return m_pApi->getTypeClass(m_hImpl); } + +inline ::rtl::OUString RegistryTypeReader::getTypeName() const + { + ::rtl::OUString sRet; + m_pApi->getTypeName(m_hImpl, &sRet.pData); + return sRet; + } + +inline ::rtl::OUString RegistryTypeReader::getSuperTypeName() const + { + ::rtl::OUString sRet; + m_pApi->getSuperTypeName(m_hImpl, &sRet.pData); + return sRet; + } + +inline void RegistryTypeReader::getUik(RTUik& uik) const + { m_pApi->getUik(m_hImpl, &uik); } + +inline ::rtl::OUString RegistryTypeReader::getDoku() const + { + ::rtl::OUString sRet; + m_pApi->getDoku(m_hImpl, &sRet.pData); + return sRet; + } + +inline ::rtl::OUString RegistryTypeReader::getFileName() const + { + ::rtl::OUString sRet; + m_pApi->getFileName(m_hImpl, &sRet.pData); + return sRet; + } + +inline sal_uInt32 RegistryTypeReader::getFieldCount() const + { return m_pApi->getFieldCount(m_hImpl); } + +inline ::rtl::OUString RegistryTypeReader::getFieldName( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getFieldName(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline ::rtl::OUString RegistryTypeReader::getFieldType( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getFieldType(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline RTFieldAccess RegistryTypeReader::getFieldAccess( sal_uInt16 index ) const + { return m_pApi->getFieldAccess(m_hImpl, index); } + +inline RTConstValue RegistryTypeReader::getFieldConstValue( sal_uInt16 index ) const + { + RTConstValue ret; + ret.m_type = m_pApi->getFieldConstValue(m_hImpl, index, &ret.m_value); + return ret; + } + +inline ::rtl::OUString RegistryTypeReader::getFieldDoku( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getFieldDoku(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline ::rtl::OUString RegistryTypeReader::getFieldFileName( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getFieldFileName(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline sal_uInt32 RegistryTypeReader::getMethodCount() const + { return m_pApi->getMethodCount(m_hImpl); } + +inline ::rtl::OUString RegistryTypeReader::getMethodName( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getMethodName(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline sal_uInt32 RegistryTypeReader::getMethodParamCount( sal_uInt16 index ) const + { return m_pApi->getMethodParamCount(m_hImpl, index); } + +inline ::rtl::OUString RegistryTypeReader::getMethodParamType( sal_uInt16 index, sal_uInt16 paramIndex ) const + { + ::rtl::OUString sRet; + m_pApi->getMethodParamType(m_hImpl, &sRet.pData, index, paramIndex); + return sRet; + } + +inline ::rtl::OUString RegistryTypeReader::getMethodParamName( sal_uInt16 index, sal_uInt16 paramIndex ) const + { + ::rtl::OUString sRet; + m_pApi->getMethodParamName(m_hImpl, &sRet.pData, index, paramIndex); + return sRet; + } + +inline RTParamMode RegistryTypeReader::getMethodParamMode( sal_uInt16 index, sal_uInt16 paramIndex ) const + { return m_pApi->getMethodParamMode(m_hImpl, index, paramIndex); } + +inline sal_uInt32 RegistryTypeReader::getMethodExcCount( sal_uInt16 index ) const + { return m_pApi->getMethodExcCount(m_hImpl, index); } + +inline ::rtl::OUString RegistryTypeReader::getMethodExcType( sal_uInt16 index, sal_uInt16 excIndex ) const + { + ::rtl::OUString sRet; + m_pApi->getMethodExcType(m_hImpl, &sRet.pData, index, excIndex); + return sRet; + } + +inline ::rtl::OUString RegistryTypeReader::getMethodReturnType( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getMethodReturnType(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline RTMethodMode RegistryTypeReader::getMethodMode( sal_uInt16 index ) const + { return m_pApi->getMethodMode(m_hImpl, index); } + +inline ::rtl::OUString RegistryTypeReader::getMethodDoku( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getMethodDoku(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline sal_uInt32 RegistryTypeReader::getReferenceCount() const + { return m_pApi->getReferenceCount(m_hImpl); } + +inline ::rtl::OUString RegistryTypeReader::getReferenceName( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getReferenceName(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline RTReferenceType RegistryTypeReader::getReferenceType( sal_uInt16 index ) const + { return m_pApi->getReferenceType(m_hImpl, index); } + +inline ::rtl::OUString RegistryTypeReader::getReferenceDoku( sal_uInt16 index ) const + { + ::rtl::OUString sRet; + m_pApi->getReferenceDoku(m_hImpl, &sRet.pData, index); + return sRet; + } + +inline RTFieldAccess RegistryTypeReader::getReferenceAccess( sal_uInt16 index ) const + { return m_pApi->getReferenceAccess(m_hImpl, index); } + +#endif diff --git a/registry/inc/registry/refltype.hxx b/registry/inc/registry/refltype.hxx new file mode 100644 index 000000000000..27634e9dce28 --- /dev/null +++ b/registry/inc/registry/refltype.hxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGISTRY_REFLTYPE_HXX_ +#define _REGISTRY_REFLTYPE_HXX_ + +#include "registry/types.h" +#include <sal/types.h> + +/** specifies the type source of a binary type blob. + + Currently only RT_UNO_IDL type is used. + */ +enum RTTypeSource +{ + RT_UNO_IDL, + RT_CORBA_IDL, + RT_JAVA +}; + +/** specifies a helper class for const values. + + This class is used for easy handling of constants or enum values + as fields in binary type blob. + */ +class RTConstValue +{ +public: + /// stores the type of the constant value. + RTValueType m_type; + /// stores the value of the constant. + RTConstValueUnion m_value; + + /// Default constructor. + RTConstValue() + : m_type(RT_TYPE_NONE) + { + m_value.aDouble = 0.0; + } + + /// Destructor + ~RTConstValue() {} +}; + +/** deprecated. + + An earlier version of UNO used an unique identifier for interfaces. In the + current version of UNO this uik was eliminated and this type is not longer used. + */ +struct RTUik +{ + sal_uInt32 m_Data1; + sal_uInt16 m_Data2; + sal_uInt16 m_Data3; + sal_uInt32 m_Data4; + sal_uInt32 m_Data5; +}; + +/// specifies the calling onvention for type reader/wrter api +#define TYPEREG_CALLTYPE SAL_CALL + +#endif diff --git a/registry/inc/registry/reflwrit.hxx b/registry/inc/registry/reflwrit.hxx new file mode 100644 index 000000000000..0046b8829810 --- /dev/null +++ b/registry/inc/registry/reflwrit.hxx @@ -0,0 +1,355 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGISTRY_REFLWRIT_HXX_ +#define _REGISTRY_REFLWRIT_HXX_ + +#include <registry/refltype.hxx> +#include <registry/regtype.h> +#include <rtl/ustring.hxx> + +/// Implememetation handle +typedef void* TypeWriterImpl; + +/**************************************************************************** + + C-Api + +*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** specifies a collection of function pointers which represents the complete registry type writer C-API. + + This funtions pointers are used by the C++ wrapper to call the C-API. +*/ +struct RegistryTypeWriter_Api +{ + TypeWriterImpl (TYPEREG_CALLTYPE *createEntry) (RTTypeClass, rtl_uString*, rtl_uString*, sal_uInt16, sal_uInt16, sal_uInt16); + void (TYPEREG_CALLTYPE *acquire) (TypeWriterImpl); + void (TYPEREG_CALLTYPE *release) (TypeWriterImpl); + void (TYPEREG_CALLTYPE *setUik) (TypeWriterImpl, const RTUik*); + void (TYPEREG_CALLTYPE *setDoku) (TypeWriterImpl, rtl_uString*); + void (TYPEREG_CALLTYPE *setFileName) (TypeWriterImpl, rtl_uString*); + void (TYPEREG_CALLTYPE *setFieldData) (TypeWriterImpl, sal_uInt16, rtl_uString*, rtl_uString*, rtl_uString*, rtl_uString*, RTFieldAccess, RTValueType, RTConstValueUnion); + void (TYPEREG_CALLTYPE *setMethodData) (TypeWriterImpl, sal_uInt16, rtl_uString*, rtl_uString*, RTMethodMode, sal_uInt16, sal_uInt16, rtl_uString*); + void (TYPEREG_CALLTYPE *setParamData) (TypeWriterImpl, sal_uInt16, sal_uInt16, rtl_uString*, rtl_uString*, RTParamMode); + void (TYPEREG_CALLTYPE *setExcData) (TypeWriterImpl, sal_uInt16, sal_uInt16, rtl_uString*); + const sal_uInt8* (TYPEREG_CALLTYPE *getBlop) (TypeWriterImpl); + sal_uInt32 (TYPEREG_CALLTYPE *getBlopSize) (TypeWriterImpl); + + void (TYPEREG_CALLTYPE *setReferenceData) (TypeWriterImpl, sal_uInt16, rtl_uString*, RTReferenceType, rtl_uString*, RTFieldAccess); +}; + +/** the API initialization function. +*/ +RegistryTypeWriter_Api* TYPEREG_CALLTYPE initRegistryTypeWriter_Api(void); + +#ifdef __cplusplus +} +#endif + +/** RegistryTypeWriter writes/creates a binary type blob. + + This class provides the necessary functions to write type informations + for all kinds of types into a blob. + The class is inline and use a C-Api. + + @deprecated + use typereg::Writer instead +*/ +class RegistryTypeWriter +{ +public: + + /** Constructor. + + @param RTTypeClass specifies the type of the new blob. + @param typeName specifies the full qualified type name with '/' as separator. + @param superTypeName specifies the full qualified type name of the base type + with '/' as separator. + @param fieldCount specifies the number of fields (eg. number of attrbutes/properties, + enum values or constants). + @param methodCount specifies the number of methods. + @param referenceCount specifies the number of references (eg. number of supported interfaces, + exported services ...) + */ + inline RegistryTypeWriter(RTTypeClass RTTypeClass, + const ::rtl::OUString& typeName, + const ::rtl::OUString& superTypeName, + sal_uInt16 fieldCount, + sal_uInt16 methodCount, + sal_uInt16 referenceCount); + + /// Copy constructcor + inline RegistryTypeWriter(const RegistryTypeWriter& toCopy); + + /** Destructor. The Destructor frees the internal data block. + + The pointer (returned by getBlop) will be set to NULL. + */ + inline ~RegistryTypeWriter(); + + /// Assign operator + inline RegistryTypeWriter& operator == (const RegistryTypeWriter& toAssign); + + /** @deprecated + sets the unique identifier for an interface type. + + An earlier version of UNO used an unique identifier for interfaces. In the + current version of UNO this uik was eliminated and this function is + not longer used. + */ + inline void setUik(const RTUik& uik); + + /** sets a documentation string for the type. + + This documentation should be the same as the documentation which is provided + for this type in IDL. + */ + inline void setDoku(const ::rtl::OUString& doku); + + /** sets the IDL filename where this type is defined. + */ + inline void setFileName(const ::rtl::OUString& fileName); + + /** sets the data for a field member of a type blob. + + @param index indicates the index of the field. + @param name specifies the name. + @param typeName specifies the full qualified typename. + @param doku specifies the documentation string of the field. + @param fileName specifies the name of the IDL file where the field is defined. + @param access specifies the access mode of the field. + @param constValue specifies the value of the field. The value is only interesting + for enum values or constants. + */ + inline void setFieldData( sal_uInt16 index, + const ::rtl::OUString& name, + const ::rtl::OUString& typeName, + const ::rtl::OUString& doku, + const ::rtl::OUString& fileName, + RTFieldAccess access, + RTConstValue constValue = RTConstValue()); + + /** sets the data for a method. + + @param index indicates the index of the method. + @param name specifies the name. + @param typeName specifies the full qualified return typename. + @param mode specifies the method mode. + @param paramCount specifies the number of parameters. + @param excCount specifies the number of exceptions. + @param doku specifies the documentation string of the field. + */ + inline void setMethodData(sal_uInt16 index, + const ::rtl::OUString& name, + const ::rtl::OUString& returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + const ::rtl::OUString& doku); + + /** sets the data for the specified parameter of a method. + + @param index indicates the index of the method. + @param paramIndex specifies the index of the parameter. + @param type specifies the full qualified typename. + @param name specifies the name. + @param mode specifies the parameter mode. + */ + inline void setParamData(sal_uInt16 index, + sal_uInt16 paramIndex, + const ::rtl::OUString& type, + const ::rtl::OUString& name, + RTParamMode mode); + + /** sets the data for the specified exception of a mehtod. + + @param index indicates the index of the method. + @param excIndex specifies the index of the exception. + @param type specifies the full qualified typename of the exception. + */ + inline void setExcData(sal_uInt16 index, + sal_uInt16 excIndex, + const ::rtl::OUString& type); + + /** returns a pointer to the new type blob. + + The pointer will be invalid (NULL) if the instance of + the RegistryTypeWriter will be destroyed. + */ + inline const sal_uInt8* getBlop(); + + /** returns the size of the new type blob in bytes. + */ + inline sal_uInt32 getBlopSize(); + + /** sets the data for a reference member. + + @param index indicates the index of the reference. + @param name specifies the name. + @param refType specifies the full qualified typename of the reference. + @param doku specifies the documentation string of the reference. + @param access specifies the access mode of the reference. + */ + inline void setReferenceData( sal_uInt16 index, + const ::rtl::OUString& name, + RTReferenceType refType, + const ::rtl::OUString& doku, + RTFieldAccess access = RT_ACCESS_INVALID); + +protected: + + /// stores the registry type writer Api. + const RegistryTypeWriter_Api* m_pApi; + /// stores the handle of an implementation class + TypeWriterImpl m_hImpl; +}; + + + +inline RegistryTypeWriter::RegistryTypeWriter(RTTypeClass RTTypeClass, + const ::rtl::OUString& typeName, + const ::rtl::OUString& superTypeName, + sal_uInt16 fieldCount, + sal_uInt16 methodCount, + sal_uInt16 referenceCount) + : m_pApi(initRegistryTypeWriter_Api()) + , m_hImpl(NULL) +{ + m_hImpl = m_pApi->createEntry(RTTypeClass, + typeName.pData, + superTypeName.pData, + fieldCount, + methodCount, + referenceCount); +} + + +inline RegistryTypeWriter::RegistryTypeWriter(const RegistryTypeWriter& toCopy) + : m_pApi(toCopy.m_pApi) + , m_hImpl(toCopy.m_hImpl) +{ + m_pApi->acquire(m_hImpl); +} + +inline RegistryTypeWriter::~RegistryTypeWriter() +{ + m_pApi->release(m_hImpl); +} + +inline RegistryTypeWriter& RegistryTypeWriter::operator == (const RegistryTypeWriter& toAssign) +{ + if (m_hImpl != toAssign.m_hImpl) + { + m_pApi->release(m_hImpl); + m_hImpl = toAssign.m_hImpl; + m_pApi->acquire(m_hImpl); + } + + return *this; +} + +inline void RegistryTypeWriter::setFieldData( sal_uInt16 index, + const ::rtl::OUString& name, + const ::rtl::OUString& typeName, + const ::rtl::OUString& doku, + const ::rtl::OUString& fileName, + RTFieldAccess access, + RTConstValue constValue) +{ + m_pApi->setFieldData(m_hImpl, index, name.pData, typeName.pData, doku.pData, fileName.pData, access, constValue.m_type, constValue.m_value); +} + + +inline void RegistryTypeWriter::setMethodData(sal_uInt16 index, + const ::rtl::OUString& name, + const ::rtl::OUString& returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + const ::rtl::OUString& doku) +{ + m_pApi->setMethodData(m_hImpl, index, name.pData, returnTypeName.pData, mode, paramCount, excCount, doku.pData); +} + + +inline void RegistryTypeWriter::setUik(const RTUik& uik) +{ + m_pApi->setUik(m_hImpl, &uik); +} + +inline void RegistryTypeWriter::setDoku(const ::rtl::OUString& doku) +{ + m_pApi->setDoku(m_hImpl, doku.pData); +} + +inline void RegistryTypeWriter::setFileName(const ::rtl::OUString& doku) +{ + m_pApi->setFileName(m_hImpl, doku.pData); +} + +inline void RegistryTypeWriter::setParamData(sal_uInt16 index, + sal_uInt16 paramIndex, + const ::rtl::OUString& type, + const ::rtl::OUString& name, + RTParamMode mode) +{ + m_pApi->setParamData(m_hImpl, index, paramIndex, type.pData, name.pData, mode); +} + +inline void RegistryTypeWriter::setExcData(sal_uInt16 index, + sal_uInt16 excIndex, + const ::rtl::OUString& type) +{ + m_pApi->setExcData(m_hImpl, index, excIndex, type.pData); +} + +inline const sal_uInt8* RegistryTypeWriter::getBlop() +{ + return m_pApi->getBlop(m_hImpl); +} + +inline sal_uInt32 RegistryTypeWriter::getBlopSize() +{ + return m_pApi->getBlopSize(m_hImpl); +} + + +inline void RegistryTypeWriter::setReferenceData( sal_uInt16 index, + const ::rtl::OUString& name, + RTReferenceType refType, + const ::rtl::OUString& doku, + RTFieldAccess access) +{ + m_pApi->setReferenceData(m_hImpl, index, name.pData, refType, doku.pData, access); +} + +#endif diff --git a/registry/inc/registry/registry.h b/registry/inc/registry/registry.h new file mode 100644 index 000000000000..6286af132283 --- /dev/null +++ b/registry/inc/registry/registry.h @@ -0,0 +1,477 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGISTRY_REGISTRY_H_ +#define _REGISTRY_REGISTRY_H_ + +#include <stddef.h> +#include <rtl/ustring.h> +#include <registry/regtype.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** This function creates the specified key. + + If the key already exists in the registry, the function opens the key only. + @param hKey identifies a currently open key. The key which will be opened or created by this + function is a subkey of the key identified by hKey. + @param keyName points to a null terminated string specifying the name of a key. + @param phNewKey points to a variable that receives the handle of the opened or created key. + The memory to store this variable will be allocated and will be freed by the function + reg_closeKey. If the function fails, phNewKey is NULL. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_createKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phNewKey); + + +/** This function opens the specified key. + + @param hKey identifies a currently open key. The key which will be opened by this function + is a subkey of the key identified by hKey + @param keyName points to a null terminated string specifying the name of a key. + @param phNewKey points to a variable that receives the handle of the opened key. + The memory to store this variable will be allocated and will be freed by the function + reg_closeKey. If the function fails, phNewKey is NULL. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_openKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phOpenKey); + + + +/** This function opens all subkeys of the specified key. + + @param hKey identifies a currently open key. The key that subkeys will be opened by this + function is a subkey of the key identified by hKey + @param keyName points to a null terminated string specifying the name of a key whose subkeys + will be opened. + @param pphSubKeys points to a variable that receives an array of all opened subkeys. + The memory to store this variable will be allocated and will be freed by the function + reg_closeSubKeys. If the function fails, pphSubKeys is NULL. + @param pnSubKeys specifies the length of the array (the number of open subkeys). + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_openSubKeys(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle** pphSubKeys, + sal_uInt32* pnSubKeys); + + +/** This function closes all subkeys specified in the array. + + @param phSubKeys points to a variable that containss an array of all opened subkeys. + The allocated memory of pphSubKeys and all open subkeys will be freed. + @param nSubKeys specifies the length of the array (the number of subkeys to closed). + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_closeSubKeys(RegKeyHandle* phSubKeys, + sal_uInt32 nSubKeys); + + +/** This function deletes the specified key. + + @param hKey identifies a currently open key. The key deleted by this function + is a subkey of the key identified by hKey + @param keyName points to a null terminated string specifying the name of a key which will + be deleted. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_deleteKey(RegKeyHandle hKey, + rtl_uString* keyName); + + +/** This function closes the specified key. + + @param hKey identifies a currently open key which will be closed by this function. + The memory of the variable specifying the key will be freed. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_closeKey(RegKeyHandle hKey); + + +/** This function returns the name of a key. + + @param hKey identifies a currently open key which name will be returned. + @param pKeyName contains the keyname if succeeds else an empty string. +*/ +RegError REGISTRY_CALLTYPE reg_getKeyName(RegKeyHandle hKey, rtl_uString** pKeyName); + + +/** This function sets a value of a key. + + @param hKey identifies a currently open key. The key which value will be set by this + function is a subkey of the key identified by hKey. + @param keyName points to a null terminated string specifying the name of a key which value + will be set. If keyName is NULL, then the value of the key specified by + hKey will be set. + @param valueType specifies the type of the value. + @param pData points to a memory block containing the data of the value. + @param valueSize specifies the size of pData in bytes + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_setValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType valueType, + RegValue pData, + sal_uInt32 valueSize); + + +/** This function sets an long list value of a key. + + @param keyName points to a null terminated string specifying the name of a key which value + will be set. If keyName is NULL, then the value of the key specified by + hKey will be set. + @param pValueList points to an array of longs containing the data of the value. + @param len specifies the len of pValueList. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_setLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32* pValueList, + sal_uInt32 len); + + +/** This function sets an ascii list value of a key. + + @param keyName points to a null terminated string specifying the name of a key which value + will be set. If keyName is NULL, then the value of the key specified by + hKey will be set. + @param pValueList points to an array of sal_Char* containing the data of the value. + @param len specifies the len of pValueList. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_setStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char** pValueList, + sal_uInt32 len); + + +/** This function sets an unicode string list value of a key. + + @param keyName points to a null terminated string specifying the name of a key which value + will be set. If keyName is NULL, then the value of the key specified by + hKey will be set. + @param pValueList points to an array of sal_Unicode* containing the data of the value. + @param len specifies the len of pValueList. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_setUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode** pValueList, + sal_uInt32 len); + + +/** This function gets info about type and size of a key value. + + @param hKey identifies a currently open key. The key which value info will be got by this + function is a subkey of the key identified by hKey. + @param keyName points to a null terminated string specifying the name of a key which value + will be got. If keyName is NULL, then the value info of the key specified by + hKey will be got. + @param pValueType returns the type of the value. + @param pValueSize returns the size of the value in bytes + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getValueInfo(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize); + + +/** This function gets the value of a key. + + @param hKey identifies a currently open key. The key which value will be got by this + function is a subkey of the key identified by hKey. + @param keyName points to a null terminated string specifying the name of a key which value + will be got. If keyName is NULL, then the value of the key specified by + hKey will be got. + @param pData points to an allocated memory block receiving the data of the value. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValue pData); + + +/** This function gets the long list value of a key. + + @param keyName points to a null terminated string specifying the name of a key which value + will be got. If keyName is NULL, then the value of the key specified by + hKey will be got. + @param pValueList a Pointer to a long value list which returns the data of the value. + @param pLen returns the length of the value list. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32** pValueList, + sal_uInt32* pLen); + + +/** This function gets the string list value of a key. + + @param keyName points to a null terminated string specifying the name of a key which value + will be got. If keyName is NULL, then the value of the key specified by + hKey will be got. + @param pValueList a Pointer to an ascii value list which returns the data of the value. + @param pLen returns the length of the value list. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char*** pValueList, + sal_uInt32* pLen); + + +/** This function gets the unicode list value of a key. + + @param keyName points to a null terminated string specifying the name of a key which value + will be got. If keyName is NULL, then the value of the key specified by + hKey will be got. + @param pValueList a Pointer to an unicode value list which returns the data of the value. + @param pLen returns the length of the value list. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode*** pValueList, + sal_uInt32* pLen); + + +/** This function frees the memory of a value list. + + @param valueType specifies the type of the list values. + @param pValueList a Pointer to the value list. + @param len specifies the length of the value list. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_freeValueList(RegValueType valueType, + RegValue pValueList, + sal_uInt32 len); + +/** This function used to create a link. + + @obsolete Links are no longer supported. + + @return REG_INVALID_LINK +*/ +RegError REGISTRY_CALLTYPE reg_createLink(RegKeyHandle hKey, + rtl_uString* linkName, + rtl_uString* linkTarget); + +/** This function used to delete a link. + + @obsolete Links are no longer supported. + + @return REG_INVALID_LINK +*/ +RegError REGISTRY_CALLTYPE reg_deleteLink(RegKeyHandle hKey, + rtl_uString* linkName); + +/** This function returns the type of a key. + + The registry differentiates two possible types: + - RG_KEYTYPE represents a real key + - RG_LINKTYPE used to represent a link (no longer used) + @param keyName points to a null terminated string specifying the name of the key which keytype + will be returned. + @param pKeyType returns the type of the key. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getKeyType(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyType* pKeyType); + +/** This function used to return the linktarget of a link. + + @obsolete Links are no longer supported. + + @return REG_INVALID_LINK +*/ +RegError REGISTRY_CALLTYPE reg_getLinkTarget(RegKeyHandle hKey, + rtl_uString* linkName, + rtl_uString** pLinkTarget); + +/** This function resolves a keyname. + + and returns the resolved keyName in pResolvedName. + @param hKey identifies a currently open key. The key specified by keyName is a subkey + of the key identified by hKey. + @param keyName points to a null terminated string specifying the relativ name of a key. + The name of hKey together with keyName will be generated. + @param firstLinkOnly ignored + @return REG_NO_ERROR if succeeds else an error code. + */ +RegError REGISTRY_CALLTYPE reg_getResolvedKeyName(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Bool firstLinkOnly, + rtl_uString** pResolvedName); + +/** This function loads registry information from a file and save it under the + specified keyName. + + @param hKey identifies a currently open key. The key which should store the registry information + is a subkey of this key. + @param keyName points to a null terminated string specifying the name of the key which stores the + registry information. If keyName is NULL the registry information will be saved under + the key specified by hKey. + @param regFileName points to a null terminated string specifying the file which conains the + registry information. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_loadKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName); + + +/** This function saves the registry information under a specified key and all of its subkeys and save + it in a registry file. + + @param hKey identifies a currently open key. The key which information is saved by this + function is a subkey of the key identified by hKey. + @param keyName points to a null terminated string specifying the name of the subkey. + If keyName is NULL the registry information under the key specified by hKey + will be saved in the specified file. + @param regFileName points to a null terminated string specifying the file which will contain the + registry information. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_saveKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName); + + +/** This function merges the registry information from a specified source with the information of the + currently open registry. + + All existing keys will be extended and existing key values will be overwritten. + @param hKey identifies a currently open key. The key which information is merged by this + function is a subkey of the key identified by hKey. + @param keyName points to a null terminated string specifying the name of the key which will be merged. + If keyName is NULL the registry information under the key specified by hKey + is merged with the complete information from the specified file. + @param regFileName points to a null terminated string specifying the file containing the + registry information. + @param bWarnings if TRUE the function returns an error if a key already exists. + @param bReport if TRUE the function reports warnings on stdout if a key already exists. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_mergeKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName, + sal_Bool bWarnings, + sal_Bool bReport); + + +/** This function creates a new registry with the specified name and creates a root key. + + @param registryName points to a null terminated string specifying the name of the new registry. + @param phRegistry points to a handle of the new registry if the function succeeds otherwise NULL. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_createRegistry(rtl_uString* registryName, + RegHandle* phRegistry); + + +/** This function opens the root key of a registry. + + @param hReg identifies a currently open registry whose rootKey will be returned. + @param phRootKey points to a handle of the open root key if the function succeeds otherwise NULL. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_openRootKey(RegHandle hRegistry, + RegKeyHandle* phRootKey); + + +/** This function returns the name of a registry. + + @param hReg identifies a currently open registry whose name will be returned. + @param pName returns the name of the registry if the function succeeds otherwise an empty string. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_getName(RegHandle hRegistry, rtl_uString** pName); + + +/** This function returns the access mode of the registry. + + @param hReg identifies a currently open registry. + @return TRUE if accessmode is read only else FALSE. +*/ +sal_Bool REGISTRY_CALLTYPE reg_isReadOnly(RegHandle hReg); + + +/** This function opens a registry with the specified name. + + @param registryName points to a null terminated string specifying the name of the registry. + @param phRegistry points to a hanle of the opened registry if the function succeeds otherwise NULL. + @param accessMode specifies the accessmode of the registry, REG_READONLY or REG_READWRITE. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_openRegistry(rtl_uString* registryName, + RegHandle* phRegistry, + RegAccessMode accessMode); + + +/** This function closes a registry. + + @param hRegistry identifies a currently open registry which should be closed. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_closeRegistry(RegHandle hRegistry); + + +/** This function destroys a registry. + + @param hRegistry identifies a currently open registry. + @param registryName specifies a registry name of a registry which should be destroyed. If the + name is NULL the registry itselfs will be destroyed. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_destroyRegistry(RegHandle hRegistry, + rtl_uString* registryName); + + +/** This function reports the complete registry information of a key and all of its subkeys. + + All information which are available (keynames, value types, values, ...) + will be printed to stdout for report issues only. + @param hKey identifies a currently open key which content will be reported. + @return REG_NO_ERROR if succeeds else an error code. +*/ +RegError REGISTRY_CALLTYPE reg_dumpRegistry(RegKeyHandle hKey); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/registry/inc/registry/registry.hxx b/registry/inc/registry/registry.hxx new file mode 100644 index 000000000000..7ded0738cd72 --- /dev/null +++ b/registry/inc/registry/registry.hxx @@ -0,0 +1,1258 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGISTRY_REGISTRY_HXX_ +#define _REGISTRY_REGISTRY_HXX_ + +#include <registry/regtype.h> +#include <rtl/ustring.hxx> + +#ifdef __cplusplus +extern "C" { +#endif + +/** specifies a collection of function pointers which represents the complete registry C-API. + + This funtions pointers are used by the C++ wrapper to call the C-API. +*/ +struct Registry_Api +{ + void (REGISTRY_CALLTYPE *acquire) (RegHandle); + void (REGISTRY_CALLTYPE *release) (RegHandle); + sal_Bool (REGISTRY_CALLTYPE *isReadOnly) (RegHandle); + RegError (REGISTRY_CALLTYPE *openRootKey) (RegHandle, RegKeyHandle*); + RegError (REGISTRY_CALLTYPE *getName) (RegHandle, rtl_uString**); + RegError (REGISTRY_CALLTYPE *createRegistry) (rtl_uString*, RegHandle*); + RegError (REGISTRY_CALLTYPE *openRegistry) (rtl_uString*, RegHandle*, RegAccessMode); + RegError (REGISTRY_CALLTYPE *closeRegistry) (RegHandle); + RegError (REGISTRY_CALLTYPE *destroyRegistry) (RegHandle, rtl_uString*); + RegError (REGISTRY_CALLTYPE *loadKey) (RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*); + RegError (REGISTRY_CALLTYPE *saveKey) (RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*); + RegError (REGISTRY_CALLTYPE *mergeKey) (RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*, sal_Bool, sal_Bool); + RegError (REGISTRY_CALLTYPE *dumpRegistry) (RegHandle, RegKeyHandle); + void (REGISTRY_CALLTYPE *acquireKey) (RegKeyHandle); + void (REGISTRY_CALLTYPE *releaseKey) (RegKeyHandle); + sal_Bool (REGISTRY_CALLTYPE *isKeyReadOnly) (RegKeyHandle); + RegError (REGISTRY_CALLTYPE *getKeyName) (RegKeyHandle, rtl_uString**); + RegError (REGISTRY_CALLTYPE *createKey) (RegKeyHandle, rtl_uString*, RegKeyHandle*); + RegError (REGISTRY_CALLTYPE *openKey) (RegKeyHandle, rtl_uString*, RegKeyHandle*); + RegError (REGISTRY_CALLTYPE *openSubKeys) (RegKeyHandle, rtl_uString*, RegKeyHandle**, sal_uInt32*); + RegError (REGISTRY_CALLTYPE *closeSubKeys) (RegKeyHandle*, sal_uInt32); + RegError (REGISTRY_CALLTYPE *deleteKey) (RegKeyHandle, rtl_uString*); + RegError (REGISTRY_CALLTYPE *closeKey) (RegKeyHandle); + RegError (REGISTRY_CALLTYPE *setValue) (RegKeyHandle, rtl_uString*, RegValueType, RegValue, sal_uInt32); + RegError (REGISTRY_CALLTYPE *setLongListValue) (RegKeyHandle, rtl_uString*, sal_Int32*, sal_uInt32); + RegError (REGISTRY_CALLTYPE *setStringListValue) (RegKeyHandle, rtl_uString*, sal_Char**, sal_uInt32); + RegError (REGISTRY_CALLTYPE *setUnicodeListValue)(RegKeyHandle, rtl_uString*, sal_Unicode**, sal_uInt32); + RegError (REGISTRY_CALLTYPE *getValueInfo) (RegKeyHandle, rtl_uString*, RegValueType*, sal_uInt32*); + RegError (REGISTRY_CALLTYPE *getValue) (RegKeyHandle, rtl_uString*, RegValue); + RegError (REGISTRY_CALLTYPE *getLongListValue) (RegKeyHandle, rtl_uString*, sal_Int32**, sal_uInt32*); + RegError (REGISTRY_CALLTYPE *getStringListValue) (RegKeyHandle, rtl_uString*, sal_Char***, sal_uInt32*); + RegError (REGISTRY_CALLTYPE *getUnicodeListValue)(RegKeyHandle, rtl_uString*, sal_Unicode***, sal_uInt32*); + RegError (REGISTRY_CALLTYPE *freeValueList) (RegValueType, RegValue, sal_uInt32); + RegError (REGISTRY_CALLTYPE *createLink) (RegKeyHandle, rtl_uString*, rtl_uString*); + RegError (REGISTRY_CALLTYPE *deleteLink) (RegKeyHandle, rtl_uString*); + RegError (REGISTRY_CALLTYPE *getKeyType) (RegKeyHandle, rtl_uString*, RegKeyType*); + RegError (REGISTRY_CALLTYPE *getLinkTarget) (RegKeyHandle, rtl_uString*, rtl_uString**); + RegError (REGISTRY_CALLTYPE *getResolvedKeyName) (RegKeyHandle, rtl_uString*, sal_Bool, rtl_uString**); + RegError (REGISTRY_CALLTYPE *getKeyNames) (RegKeyHandle, rtl_uString*, rtl_uString***, sal_uInt32*); + RegError (REGISTRY_CALLTYPE *freeKeyNames) (rtl_uString**, sal_uInt32); +}; + +/** the API initialization function. +*/ +Registry_Api* REGISTRY_CALLTYPE initRegistry_Api(void); + +#ifdef __cplusplus +} +#endif + + +class RegistryKey; + +//----------------------------------------------------------------------------- + +/** The Registry provides the functionality to read and write information in a registry file. + + The class is implemented inline and use a C-Api. +*/ +class Registry +{ +public: + /** Default constructor. + */ + inline Registry(); + + /// Copy constructcor + inline Registry(const Registry& toCopy); + + /// Destructor. The Destructor close the registry if it is open. + inline ~Registry(); + + /// Assign operator + inline Registry& operator = (const Registry& toAssign); + + /// checks if the registry points to a valid registry data file. + inline sal_Bool isValid() const; + + /** returns the access mode of the registry. + + @return TRUE if the access mode is readonly else FALSE. + */ + inline sal_Bool isReadOnly() const; + + /** opens the root key of the registry. + + @param rRootKey reference to a RegistryKey which is filled with the rootkey. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError openRootKey(RegistryKey& rRootKey); + + /// returns the name of the current registry data file. + inline ::rtl::OUString getName(); + + /** creates a new registry with the specified name and creates a root key. + + @param registryName specifies the name of the new registry. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError create(const ::rtl::OUString& registryName); + + /** opens a registry with the specified name. + + If the registry already points to a valid registry, the old registry will be closed. + @param registryName specifies a registry name. + @param accessMode specifies the access mode for the registry, REG_READONLY or REG_READWRITE. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError open(const ::rtl::OUString& registryName, + RegAccessMode accessMode); + + /// closes explicitly the current registry data file. + inline RegError close(); + + /** destroys a registry. + + @param registryName specifies a registry name, if the name is an empty string the registry + itselfs will be destroyed. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError destroy(const ::rtl::OUString& registryName); + + /** loads registry information from a specified file and save it under the + specified keyName. + + @param rKey references a currently open key. The key which should store the registry information + is a subkey of this key. + @param keyName specifies the name of the key which stores the registry information. If keyName is + is an empty string the registry information will be saved under the key specified + by rKey. + @param regFileName specifies the file containing the registry information. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError loadKey(RegistryKey& rKey, + const ::rtl::OUString& keyName, + const ::rtl::OUString& regFileName); + + /** saves the registry information of the specified key and all subkeys and save + it in the specified file. + + @param rKey references a currently open key. The key which information is saved by this + function is a subkey of this key. + @param keyName specifies the name of the key which information should be stored. + If keyName is an empty string the registry information under the key specified + by rKey is saved in the specified file. + @param regFileName specifies the file containing the registry information. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError saveKey(RegistryKey& rKey, + const ::rtl::OUString& keyName, + const ::rtl::OUString& regFileName); + + /** merges the registry information of the specified key with the registry + information of the specified file. + + All existing keys will be extended and existing key values will be overwritten. + @param rKey references a currently open key. The key which information is merged by this + function is a subkey of this key + @param keyName specifies the name of the key which will be merged. + If keyName is an empty string the registry information under the key specified + by rKey is merged with the information from the specified file. + @param regFileName specifies the file containing the registry information. + @param bWarnings if TRUE the function returns an error if a key already exists. + @param bReport if TRUE the function reports warnings on stdout if a key already exists. + @return REG_NO_ERROR if succeeds else an error code. If it returns an error the registry will + restore the state before merging. + */ + inline RegError mergeKey(RegistryKey& rKey, + const ::rtl::OUString& keyName, + const ::rtl::OUString& regFileName, + sal_Bool bWarnings = sal_False, + sal_Bool bReport = sal_False); + + /** This function reports the complete registry information of a key and all of its subkeys. + + All information which are available (keynames, value types, values, ...) + will be printed to stdout for report issues only. + @param rKey references a currently open key which content will be reported. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError dumpRegistry(RegistryKey& rKey); + + friend class RegistryKey; + friend class RegistryKeyArray; + friend class RegistryKeyNames; + + /// returns the used registry Api. + const Registry_Api* getApi() { return m_pApi; } +protected: + + /// stores the used and initialized registry Api. + const Registry_Api* m_pApi; + /// stores the handle of the underlying registry file on which most of the functions work. + RegHandle m_hImpl; +}; + + +//----------------------------------------------------------------------------- + +/** RegistryKeyArray represents an array of open keys. + + RegistryKeyArray is a helper class to work with an array of keys. +*/ +class RegistryKeyArray +{ +public: + /// Default constructor + inline RegistryKeyArray(); + + /// Destructor, all subkeys will be closed. + inline ~RegistryKeyArray(); + + /// returns the open key specified by index. + inline RegistryKey getElement(sal_uInt32 index); + + /// returns the length of the array. + inline sal_uInt32 getLength(); + + friend class RegistryKey; +protected: + /** sets the data of the key array. + + @param registry specifies the registry files where the keys are located. + @param phKeys points to an array of open keys. + @param length specifies the length of the array specified by phKeys. + */ + inline void setKeyHandles(Registry& registry, RegKeyHandle* phKeys, sal_uInt32 length); + /// close all subkeys + inline RegError closeKeyHandles(); + + /// stores the number of open subkeys, the number of elements. + sal_uInt32 m_length; + /// stores an array of open subkeys. + RegKeyHandle* m_phKeys; + /// stores the handle to the registry file where the appropriate keys are located. + Registry m_registry; +}; + + +/** RegistryKeyNames represents an array of key names. + + RegistryKeyNames is a helper class to work with an array of key names. +*/ +class RegistryKeyNames +{ +public: + /// Default constructor + inline RegistryKeyNames(); + + /// Destructor, the internal array with key names will be deleted. + inline ~RegistryKeyNames(); + + /// returns the name of the key sepecified by index. + inline ::rtl::OUString getElement(sal_uInt32 index); + + /// returns the length of the array. + inline sal_uInt32 getLength(); + + friend class RegistryKey; +protected: + /** sets the data of the array. + + @param registry specifies the registry files where the keys are located. + @param pKeyNames points to an array of key names. + @param length specifies the length of the array specified by pKeyNames. + */ + inline void setKeyNames(Registry& registry, rtl_uString** pKeyNames, sal_uInt32 length); + /// delete the array of key names. + inline RegError freeKeyNames(); + + /// stores the number of key names, the number of elements. + sal_uInt32 m_length; + /// stores an array of key names. + rtl_uString** m_pKeyNames; + /// stores the handle to the registry file where the appropriate keys are located. + Registry m_registry; +}; + +//----------------------------------------------------------------------------- + +/** RegistryValueList represents a value list of the specified type. + + RegistryValueList is a helper class to work with a list value. +*/ +template<class ValueType> +class RegistryValueList +{ +public: + /// Default constructor + RegistryValueList() + : m_length(0) + , m_pValueList(NULL) + , m_valueType(RG_VALUETYPE_NOT_DEFINED) + {} + + /// Destructor, the internal value list will be freed. + ~RegistryValueList() + { + if (m_pValueList) + { + m_registry.getApi()->freeValueList(m_valueType, m_pValueList, m_length); + } + } + + /// returns the value of the list specified by index. + ValueType getElement(sal_uInt32 index) + { + if (m_registry.isValid() && index < m_length) + { + return m_pValueList[index]; + } else + { + return 0; + } + } + + /// returns the length of the list. + sal_uInt32 getLength() + { + return m_length; + } + + friend class RegistryKey; +protected: + /** sets the data of the value list. + + @param registry specifies the registry files where the appropriate key is located. + @param valueType specifies the type of the list values. + @param pValueList points to a value list. + @param length specifies the length of the list. + */ + void setValueList(Registry& registry, RegValueType valueType, + ValueType* pValueList, sal_uInt32 length) + { + m_length = length; + m_pValueList = pValueList; + m_valueType = valueType; + m_registry = registry; + } + + /// stores the length of the list, the number of elements. + sal_uInt32 m_length; + /// stores the value list. + ValueType* m_pValueList; + /// stores the type of the list elements + RegValueType m_valueType; + /** stores the handle to the registry file where the appropriate key to this + value is located. + */ + Registry m_registry; +}; + +//----------------------------------------------------------------------------- + +/** RegistryKey reads or writes information of the underlying key in a registry. + + Class is inline and use a load on call C-Api. +*/ +class RegistryKey +{ +public: + /// Default constructor + inline RegistryKey(); + + /// Copy constructor + inline RegistryKey(const RegistryKey& toCopy); + + /// Destructor, close the key if it references an open one. + inline ~RegistryKey(); + + /// Assign operator + inline RegistryKey& operator = (const RegistryKey& toAssign); + + /// checks if the key points to a valid registry key. + inline sal_Bool isValid() const; + + /** returns the access mode of the key. + + @return TRUE if access mode is read only else FALSE. + */ + inline sal_Bool isReadOnly() const; + + /// returns the full qualified name of the key beginning with the rootkey. + inline ::rtl::OUString getName(); + + /** creates a new key or opens a key if the specified key already exists. + + The specified keyname is relativ to this key. + @param keyName specifies the name of the key which will be opened or created. + @param rNewKey references a RegistryKey which will be filled with the new or open key. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError createKey(const ::rtl::OUString& keyName, + RegistryKey& rNewKey); + + /** opens the specified key. + + The specified keyname is relativ to this key. + @param keyName specifies the name of the key which will be opened. + @param rOpenKey references a RegistryKey which will be filled with the open key. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError openKey(const ::rtl::OUString& keyName, + RegistryKey& rOpenKey); + + /** opens all subkeys of the specified key. + + The specified keyname is relativ to this key. + @param keyName specifies the name of the key which subkeys will be opened. + @param rSubKeys reference a RegistryKeyArray which will be filled with the open subkeys. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError openSubKeys(const ::rtl::OUString& keyName, + RegistryKeyArray& rSubKeys); + + /** returns an array with the names of all subkeys of the specified key. + + The specified keyname is relativ to this key. + @param keyName specifies the name of the key which subkey names will be returned. + @param rSubKeyNames reference a RegistryKeyNames array which will be filled with the subkey names. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getKeyNames(const ::rtl::OUString& keyName, + RegistryKeyNames& rSubKeyNames); + + /** closes all keys specified in the array. + + @param rSubKeys reference a RegistryKeyArray which contains the open keys. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError closeSubKeys(RegistryKeyArray& rSubKeys); + + /** deletes the specified key. + + @param keyName specifies the name of the key which will be deleted. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError deleteKey(const ::rtl::OUString& keyName); + + /// closes explicitly the current key + inline RegError closeKey(); + + /// releases the current key + inline void releaseKey(); + + /** sets a value of a key. + + @param keyName specifies the name of the key which value will be set. + If keyName is an empty string, the value will be set for the key + specified by hKey. + @param valueType specifies the type of the value. + @param pData points to a memory block containing the data for the value. + @param valueSize specifies the size of pData in bytes + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError setValue(const ::rtl::OUString& keyName, + RegValueType valueType, + RegValue pValue, + sal_uInt32 valueSize); + + /** sets a long list value of a key. + + @param keyName specifies the name of the key which value will be set. + If keyName is an empty string, the value will be set for the key + specified by hKey. + @param pValueList points to an array of longs containing the data for the value. + @param len specifies the length of the list (the array referenced by pValueList). + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError setLongListValue(const ::rtl::OUString& keyName, + sal_Int32* pValueList, + sal_uInt32 len); + + /** sets an ascii list value of a key. + + @param keyName specifies the name of the key which value will be set. + If keyName is an empty string, the value will be set for the key + specified by hKey. + @param pValueList points to an array of sal_Char* containing the data for the value. + @param len specifies the length of the list (the array referenced by pValueList). + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError setStringListValue(const ::rtl::OUString& keyName, + sal_Char** pValueList, + sal_uInt32 len); + + /** sets an unicode string list value of a key. + + @param keyName specifies the name of the key which value will be set. + If keyName is an empty string, the value will be set for the key + specified by hKey. + @param pValueList points to an array of sal_Unicode* containing the data for the value. + @param len specifies the length of the list (the array referenced by pValueList). + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError setUnicodeListValue(const ::rtl::OUString& keyName, + sal_Unicode** pValueList, + sal_uInt32 len); + + /** gets info about type and size of a value. + + @param keyName specifies the name of the key which value info will be returned. + If keyName is an empty string, the value info of the key + specified by hKey will be returned. + @param pValueType returns the type of the value. + @param pValueSize returns the size of the value in bytes or the length of a list value. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getValueInfo(const ::rtl::OUString& keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize); + + /** gets the value of a key. + + @param keyName specifies the name of the key which value will be returned. + If keyName is an empty string, the value is get from the key + specified by hKey. + @param pValue points to an allocated memory block receiving the data of the value. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getValue(const ::rtl::OUString& keyName, + RegValue pValue); + + /** gets a long list value of a key. + + @param keyName specifies the name of the key which value will be returned. + If keyName is an empty string, the value is get from the key + specified by hKey. + @param rValueList references a RegistryValueList which will be filled with the long values. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getLongListValue(const ::rtl::OUString& keyName, + RegistryValueList<sal_Int32>& rValueList); + + /** gets an ascii list value of a key. + + @param keyName specifies the name of the key which value will be returned. + If keyName is an empty string, the value is get from the key + specified by hKey. + @param rValueList references a RegistryValueList which will be filled with the ascii values. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getStringListValue(const ::rtl::OUString& keyName, + RegistryValueList<sal_Char*>& rValueList); + + /** gets a unicode value of a key. + + @param keyName specifies the name of the key which value will be returned. + If keyName is an empty string, the value is get from the key + specified by hKey. + @param rValueList reference a RegistryValueList which will be filled with the unicode values. + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getUnicodeListValue(const ::rtl::OUString& keyName, + RegistryValueList<sal_Unicode*>& rValueList); + + /** used to create a link. + + @obsolete Links are no longer supported. + + @return REG_INVALID_LINK + */ + inline RegError createLink(const ::rtl::OUString& linkName, + const ::rtl::OUString& linkTarget); + + /** used to delete a link. + + @obsolete Links are no longer supported. + + @return REG_INVALID_LINK + */ + inline RegError deleteLink(const ::rtl::OUString& linkName); + + /** returns the type of the specified key. + + @param name specifies the name of the key or link. + @param pKeyType returns the type of the key (always RG_KEYTYPE). + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getKeyType(const ::rtl::OUString& name, + RegKeyType* pKeyType) const; + + /** used to return the target of a link. + + @obsolete Links are no longer supported. + + @return REG_INVALID_LINK + */ + inline RegError getLinkTarget(const ::rtl::OUString& linkName, + ::rtl::OUString& rLinkTarget) const; + + /** resolves a keyname. + + @param keyName specifies the name of the key which will be resolved relativ to this key. + The resolved name will be prefixed with the name of this key. + @param firstLinkOnly ignored + @return REG_NO_ERROR if succeeds else an error code. + */ + inline RegError getResolvedKeyName(const ::rtl::OUString& keyName, + sal_Bool firstLinkOnly, + ::rtl::OUString& rResolvedName) const; + + /// returns the name of the registry in which the key is defined. + inline ::rtl::OUString getRegistryName(); + + /// returns the registry in which the key is defined. + Registry getRegistry() const { return m_registry; } + + friend class Registry; +public: + /** Constructor, which initialize a RegistryKey with registry and an valid key handle. + + This constructor is internal only. + @internal + */ + inline RegistryKey(Registry& registry, + RegKeyHandle hKey); + + /** returns the internal key handle. + + @internal + */ + RegKeyHandle getKeyHandle() const { return m_hImpl; } + +protected: + /** sets the internal registry on which this key should work. + + @internal + */ + inline void setRegistry(Registry& registry); + + /// stores the registry on which this key works + Registry m_registry; + /// stores the current key handle of this key + RegKeyHandle m_hImpl; +}; + + +//----------------------------------------------------------------------------- + +inline RegistryKeyArray::RegistryKeyArray() + : m_length(0) + , m_phKeys(NULL) +{ +} + +inline RegistryKeyArray::~RegistryKeyArray() +{ + if (m_phKeys) + m_registry.m_pApi->closeSubKeys(m_phKeys, m_length); +} + +inline RegistryKey RegistryKeyArray::getElement(sal_uInt32 index) +{ + if (m_registry.isValid() && index < m_length) + return RegistryKey(m_registry, m_phKeys[index]); + else + return RegistryKey(); +} + +inline sal_uInt32 RegistryKeyArray::getLength() +{ + return m_length; +} + +inline void RegistryKeyArray::setKeyHandles(Registry& registry, + RegKeyHandle* phKeys, + sal_uInt32 length) +{ + m_phKeys = phKeys; + m_length = length; + m_registry = registry; +} + +inline RegError RegistryKeyArray::closeKeyHandles() +{ + if (m_registry.isValid() && m_phKeys) + { + RegError ret; + ret = m_registry.m_pApi->closeSubKeys(m_phKeys, m_length); + m_registry = Registry(); + m_length = 0; + m_phKeys = NULL; + return ret; + } else + return(REG_INVALID_KEY); +} + +//----------------------------------------------------------------------------- + +inline RegistryKeyNames::RegistryKeyNames() + : m_length(0) + , m_pKeyNames(NULL) +{ +} + +inline RegistryKeyNames::~RegistryKeyNames() +{ + if (m_pKeyNames) + m_registry.m_pApi->freeKeyNames(m_pKeyNames, m_length); +} + +inline ::rtl::OUString RegistryKeyNames::getElement(sal_uInt32 index) +{ + + if (m_pKeyNames && index < m_length) + return m_pKeyNames[index]; + else + return ::rtl::OUString(); +} + +inline sal_uInt32 RegistryKeyNames::getLength() +{ + return m_length; +} + +inline void RegistryKeyNames::setKeyNames(Registry& registry, + rtl_uString** pKeyNames, + sal_uInt32 length) +{ + m_pKeyNames = pKeyNames; + m_length = length; + m_registry = registry; +} + +inline RegError RegistryKeyNames::freeKeyNames() +{ + if (m_registry.isValid() && m_pKeyNames) + { + RegError ret = REG_NO_ERROR; + ret = m_registry.m_pApi->freeKeyNames(m_pKeyNames, m_length); + m_registry = Registry(); + m_length = 0; + m_pKeyNames = NULL; + return ret; + } else + return REG_INVALID_KEY; +} + +//----------------------------------------------------------------------------- + +inline RegistryKey::RegistryKey() + : m_hImpl(NULL) + { } + +inline RegistryKey::RegistryKey(Registry& registry, RegKeyHandle hKey) + : m_registry(registry) + , m_hImpl(hKey) + { + if (m_hImpl) + m_registry.m_pApi->acquireKey(m_hImpl); + } + +inline RegistryKey::RegistryKey(const RegistryKey& toCopy) + : m_registry(toCopy.m_registry) + , m_hImpl(toCopy.m_hImpl) + { + if (m_hImpl) + m_registry.m_pApi->acquireKey(m_hImpl); + } + +inline void RegistryKey::setRegistry(Registry& registry) + { + m_registry = registry; + } + +inline RegistryKey::~RegistryKey() + { + if (m_hImpl) + m_registry.m_pApi->releaseKey(m_hImpl); + } + +inline RegistryKey& RegistryKey::operator = (const RegistryKey& toAssign) +{ + m_registry = toAssign.m_registry; + + if (toAssign.m_hImpl) + m_registry.m_pApi->acquireKey(toAssign.m_hImpl); + if (m_hImpl) + m_registry.m_pApi->releaseKey(m_hImpl); + m_hImpl = toAssign.m_hImpl; + + return *this; +} + +inline sal_Bool RegistryKey::isValid() const + { return (m_hImpl != NULL); } + +inline sal_Bool RegistryKey::isReadOnly() const + { + if (m_registry.isValid()) + return (m_registry.m_pApi)->isKeyReadOnly(m_hImpl); + else + return sal_False; + } + +inline ::rtl::OUString RegistryKey::getName() + { + ::rtl::OUString sRet; + if (m_registry.isValid()) + m_registry.m_pApi->getKeyName(m_hImpl, &sRet.pData); + return sRet;; + } + +inline RegError RegistryKey::createKey(const ::rtl::OUString& keyName, + RegistryKey& rNewKey) + { + if (rNewKey.isValid()) rNewKey.closeKey(); + if (m_registry.isValid()) + { + RegError ret = m_registry.m_pApi->createKey(m_hImpl, keyName.pData, &rNewKey.m_hImpl); + if (!ret) rNewKey.setRegistry(m_registry); + return ret; + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::openKey(const ::rtl::OUString& keyName, + RegistryKey& rOpenKey) + { + if (rOpenKey.isValid()) rOpenKey.closeKey(); + if (m_registry.isValid()) + { + RegError ret = m_registry.m_pApi->openKey(m_hImpl, keyName.pData, + &rOpenKey.m_hImpl); + if (!ret) rOpenKey.setRegistry(m_registry); + return ret; + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::openSubKeys(const ::rtl::OUString& keyName, + RegistryKeyArray& rSubKeys) + { + if (m_registry.isValid()) + { + RegError ret = REG_NO_ERROR; + RegKeyHandle* pSubKeys; + sal_uInt32 nSubKeys; + ret = m_registry.m_pApi->openSubKeys(m_hImpl, keyName.pData, + &pSubKeys, &nSubKeys); + if ( ret ) + { + return ret; + } else + { + rSubKeys.setKeyHandles(m_registry, pSubKeys, nSubKeys); + return ret; + } + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getKeyNames(const ::rtl::OUString& keyName, + RegistryKeyNames& rSubKeyNames) + { + if (m_registry.isValid()) + { + RegError ret = REG_NO_ERROR; + rtl_uString** pSubKeyNames; + sal_uInt32 nSubKeys; + ret = m_registry.m_pApi->getKeyNames(m_hImpl, keyName.pData, + &pSubKeyNames, &nSubKeys); + if ( ret ) + { + return ret; + } else + { + rSubKeyNames.setKeyNames(m_registry, pSubKeyNames, nSubKeys); + return ret; + } + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::closeSubKeys(RegistryKeyArray& rSubKeys) + { + if (m_registry.isValid()) + return rSubKeys.closeKeyHandles(); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::deleteKey(const ::rtl::OUString& keyName) + { + if (m_registry.isValid()) + return m_registry.m_pApi->deleteKey(m_hImpl, keyName.pData); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::closeKey() + { + if (m_registry.isValid()) + { + RegError ret = m_registry.m_pApi->closeKey(m_hImpl); + if (!ret) + { + m_hImpl = NULL; + m_registry = Registry(); + } + return ret; + } else + return REG_INVALID_KEY; + } + +inline void RegistryKey::releaseKey() +{ + if (m_registry.isValid() && (m_hImpl != 0)) + { + m_registry.m_pApi->releaseKey(m_hImpl), m_hImpl = 0; + } +} + +inline RegError RegistryKey::setValue(const ::rtl::OUString& keyName, + RegValueType valueType, + RegValue pValue, + sal_uInt32 valueSize) + { + if (m_registry.isValid()) + return m_registry.m_pApi->setValue(m_hImpl, keyName.pData, valueType, + pValue, valueSize); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::setLongListValue(const ::rtl::OUString& keyName, + sal_Int32* pValueList, + sal_uInt32 len) + { + if (m_registry.isValid()) + return m_registry.m_pApi->setLongListValue(m_hImpl, keyName.pData, + pValueList, len); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::setStringListValue(const ::rtl::OUString& keyName, + sal_Char** pValueList, + sal_uInt32 len) + { + if (m_registry.isValid()) + return m_registry.m_pApi->setStringListValue(m_hImpl, keyName.pData, + pValueList, len); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::setUnicodeListValue(const ::rtl::OUString& keyName, + sal_Unicode** pValueList, + sal_uInt32 len) + { + if (m_registry.isValid()) + return m_registry.m_pApi->setUnicodeListValue(m_hImpl, keyName.pData, + pValueList, len); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getValueInfo(const ::rtl::OUString& keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize) + { + if (m_registry.isValid()) + return m_registry.m_pApi->getValueInfo(m_hImpl, keyName.pData, pValueType, pValueSize); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getValue(const ::rtl::OUString& keyName, + RegValue pValue) + { + if (m_registry.isValid()) + return m_registry.m_pApi->getValue(m_hImpl, keyName.pData, pValue); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getLongListValue(const ::rtl::OUString& keyName, + RegistryValueList<sal_Int32>& rValueList) + { + if (m_registry.isValid()) + { + RegError ret = REG_NO_ERROR; + sal_Int32* pValueList; + sal_uInt32 length; + ret = m_registry.m_pApi->getLongListValue(m_hImpl, keyName.pData, + &pValueList, &length); + if ( ret ) + { + return ret; + } else + { + rValueList.setValueList(m_registry, RG_VALUETYPE_LONGLIST, + pValueList, length); + return ret; + } + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getStringListValue(const ::rtl::OUString& keyName, + RegistryValueList<sal_Char*>& rValueList) + { + if (m_registry.isValid()) + { + RegError ret = REG_NO_ERROR; + sal_Char** pValueList; + sal_uInt32 length; + ret = m_registry.m_pApi->getStringListValue(m_hImpl, keyName.pData, + &pValueList, &length); + if ( ret ) + { + return ret; + } else + { + rValueList.setValueList(m_registry, RG_VALUETYPE_STRINGLIST, + pValueList, length); + return ret; + } + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getUnicodeListValue(const ::rtl::OUString& keyName, + RegistryValueList<sal_Unicode*>& rValueList) + { + if (m_registry.isValid()) + { + RegError ret = REG_NO_ERROR; + sal_Unicode** pValueList; + sal_uInt32 length; + ret = m_registry.m_pApi->getUnicodeListValue(m_hImpl, keyName.pData, + &pValueList, &length); + if ( ret ) + { + return ret; + } else + { + rValueList.setValueList(m_registry, RG_VALUETYPE_UNICODELIST, + pValueList, length); + return ret; + } + } else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::createLink(const ::rtl::OUString& linkName, + const ::rtl::OUString& linkTarget) + { + if (m_registry.isValid()) + return m_registry.m_pApi->createLink(m_hImpl, linkName.pData, linkTarget.pData); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::deleteLink(const ::rtl::OUString& linkName) + { + if (m_registry.isValid()) + return m_registry.m_pApi->deleteLink(m_hImpl, linkName.pData); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getKeyType(const ::rtl::OUString& keyName, + RegKeyType* pKeyType) const + { + if (m_registry.isValid()) + return m_registry.m_pApi->getKeyType(m_hImpl, keyName.pData, pKeyType); + else + return REG_INVALID_KEY; + } + +inline RegError RegistryKey::getLinkTarget(const ::rtl::OUString& linkName, + ::rtl::OUString& rLinkTarget) const + { + if (m_registry.isValid()) + { + return m_registry.m_pApi->getLinkTarget(m_hImpl, + linkName.pData, + &rLinkTarget.pData); + } else + return REG_INVALID_KEY; + } + + +inline RegError RegistryKey::getResolvedKeyName(const ::rtl::OUString& keyName, + sal_Bool firstLinkOnly, + ::rtl::OUString& rResolvedName) const + { + if (m_registry.isValid()) + return m_registry.m_pApi->getResolvedKeyName(m_hImpl, + keyName.pData, + firstLinkOnly, + &rResolvedName.pData); + else + return REG_INVALID_KEY; + } + +inline ::rtl::OUString RegistryKey::getRegistryName() + { + if (m_registry.isValid()) + { + return m_registry.getName(); + } else + return ::rtl::OUString(); + } + +//----------------------------------------------------------------------------- + +inline Registry::Registry() + : m_pApi(initRegistry_Api()) + , m_hImpl(NULL) + { } + +inline Registry::Registry(const Registry& toCopy) + : m_pApi(toCopy.m_pApi) + , m_hImpl(toCopy.m_hImpl) + { + if (m_hImpl) + m_pApi->acquire(m_hImpl); + } + + +inline Registry::~Registry() + { + if (m_hImpl) + m_pApi->release(m_hImpl); + } + +inline Registry& Registry::operator = (const Registry& toAssign) +{ + if (toAssign.m_hImpl) + toAssign.m_pApi->acquire(toAssign.m_hImpl); + if (m_hImpl) + m_pApi->release(m_hImpl); + + m_pApi = toAssign.m_pApi; + m_hImpl = toAssign.m_hImpl; + + return *this; +} + +inline sal_Bool Registry::isValid() const + { return ( m_hImpl != NULL ); } + +inline sal_Bool Registry::isReadOnly() const + { return m_pApi->isReadOnly(m_hImpl); } + +inline RegError Registry::openRootKey(RegistryKey& rRootKey) + { + rRootKey.setRegistry(*this); + return m_pApi->openRootKey(m_hImpl, &rRootKey.m_hImpl); + } + +inline ::rtl::OUString Registry::getName() + { + ::rtl::OUString sRet; + m_pApi->getName(m_hImpl, &sRet.pData); + return sRet; + } + +inline RegError Registry::create(const ::rtl::OUString& registryName) + { + if (m_hImpl) + m_pApi->release(m_hImpl); + return m_pApi->createRegistry(registryName.pData, &m_hImpl); + } + +inline RegError Registry::open(const ::rtl::OUString& registryName, + RegAccessMode accessMode) + { + if (m_hImpl) + m_pApi->release(m_hImpl); + return m_pApi->openRegistry(registryName.pData, &m_hImpl, accessMode); + } + +inline RegError Registry::close() + { + RegError ret = m_pApi->closeRegistry(m_hImpl); + if (!ret) + m_hImpl = NULL; + return ret; + } + +inline RegError Registry::destroy(const ::rtl::OUString& registryName) + { + RegError ret = m_pApi->destroyRegistry(m_hImpl, registryName.pData); + if ( !ret && (registryName.getLength() == 0) ) + m_hImpl = NULL; + return ret; + } + +inline RegError Registry::loadKey(RegistryKey& rKey, + const ::rtl::OUString& keyName, + const ::rtl::OUString& regFileName) + { return m_pApi->loadKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData); } + +inline RegError Registry::saveKey(RegistryKey& rKey, + const ::rtl::OUString& keyName, + const ::rtl::OUString& regFileName) + { return m_pApi->saveKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData); } + +inline RegError Registry::mergeKey(RegistryKey& rKey, + const ::rtl::OUString& keyName, + const ::rtl::OUString& regFileName, + sal_Bool bWarnings, + sal_Bool bReport) + { return m_pApi->mergeKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData, bWarnings, bReport); } + +inline RegError Registry::dumpRegistry(RegistryKey& rKey) + { return m_pApi->dumpRegistry(m_hImpl, rKey.m_hImpl); } + + +#endif diff --git a/registry/inc/registry/regtype.h b/registry/inc/registry/regtype.h new file mode 100644 index 000000000000..be3cf42de735 --- /dev/null +++ b/registry/inc/registry/regtype.h @@ -0,0 +1,179 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGISTRY_REGTYPE_H_ +#define _REGISTRY_REGTYPE_H_ + +#include <sal/types.h> +#include <sal/udkversion.h> + +// version number of the library. This number is used for the load on call +// mechanism and must be modifed when the library will be upgraded to a new version. +#define LIBRARY_VERSION SAL_UDK_MAJOR + +/// defines the type of a registry handle used in the C API. +typedef void* RegHandle; + +/// defines the type of a registry key handle used in the C API. +typedef void* RegKeyHandle; + +/// defines the type of a registry key value handle used in the C API. +typedef void* RegValue; + +/** defines the open/access mode of the registry. + + Two modes are valid: + -REG_READONLY allows readonly access + -REG_READWRITE allows read and write access + */ +typedef sal_uInt16 RegAccessMode; + +/// Flag to specify the open mode of a registry. This mode allows readonly access. +#define REG_READONLY 0x0001 +/// Flag to specify the open mode of a registry. This mode allows read and write access. +#define REG_READWRITE 0x0002 + +/** defines the type of a registry key. + + The registry differs between normal keys which can contain subkeys or + a value and link keys which navigate over the linktarget to an existing + other key (which are no longer supported). +*/ +enum RegKeyType +{ + /// represents a real key + RG_KEYTYPE, + /// represents a link (which is no longer supported) + RG_LINKTYPE +}; + +/** defines the type of a key value. + + A registry key can contain a value which has one of seven different types. + Three simple types (long, ascii and unicode string) and a list type of + these simple types. Furthermore a binary type which provides the possibilty + to define own data structures and store these types in the registry. The UNO + core reflection data is stored as a binary blob in the type registry. + */ +enum RegValueType +{ + /// The key has no value or the value type is unknown. + RG_VALUETYPE_NOT_DEFINED, + /// The key has a value of type long + RG_VALUETYPE_LONG, + /// The key has a value of type ascii string + RG_VALUETYPE_STRING, + /// The key has a value of type unicode string + RG_VALUETYPE_UNICODE, + /// The key has a value of type binary + RG_VALUETYPE_BINARY, + /// The key has a value of type long list + RG_VALUETYPE_LONGLIST, + /// The key has a value of type ascii string list + RG_VALUETYPE_STRINGLIST, + /// The key has a value of type unicode string list + RG_VALUETYPE_UNICODELIST +}; + +/// specifies the possible error codes which can occur using the registry API. +enum RegError +{ + /// no error. + REG_NO_ERROR, + /// internal registry error. + REG_INTERNAL_ERROR, + + /// registry is not open. + REG_REGISTRY_NOT_OPEN, + /// registry does not exists. + REG_REGISTRY_NOT_EXISTS, + /// registry is open with readonly access rights. + REG_REGISTRY_READONLY, + /// destroy a registry failed. There are may be any open keys. + REG_DESTROY_REGISTRY_FAILED, + /** registry cannot be opened with readwrite access because the registry is already + open with readwrite access anywhere. + */ + REG_CANNOT_OPEN_FOR_READWRITE, + /** registry is in an invalid state or the registry does not point to + a valid registry data file. + */ + REG_INVALID_REGISTRY, + + /// the key or key handle points to an invalid key or closed key. + REG_KEY_NOT_OPEN, + /// the specified keyname points to a nonexisting key. + REG_KEY_NOT_EXISTS, + /// the key with the specified keyname cannot be created. + REG_CREATE_KEY_FAILED, + /// the specified key cannot be deleted. Maybe an open key handle exists to this key. + REG_DELETE_KEY_FAILED, + /** the keyname is invalid. This error will return if the keyname + is NULL but should not be NULL in the context of a called function. + */ + REG_INVALID_KEYNAME, + /// the key is not in a valid state. + REG_INVALID_KEY, + + /// the key has no value + REG_VALUE_NOT_EXISTS, + /// setting the specified value of a key failed. + REG_SET_VALUE_FAILED, + /// deleting of the key value failed. + REG_DELETE_VALUE_FAILED, + /// the key has a invalid value or the value type is unknown. + REG_INVALID_VALUE, + + /// merging a key, the value and all subkeys failed. + REG_MERGE_ERROR, + /** conflicts exists during the merge process of a key. This could happen if + the value of a key already exists and the merge process will replace it. + */ + REG_MERGE_CONFLICT, + + /** a recursion was detected resolving different link targets (no longer + used). + */ + REG_DETECT_RECURSION, + /** the link is invalid and can not be resolved (now used by all + link-related operations, as links are no longer supported). + */ + REG_INVALID_LINK, + /// the specified linkname is not valid (no longer used). + REG_INVALID_LINKNAME, + /// the linknane is not valid (no longer used). + REG_INVALID_LINKTARGET, + /// the link target points to a nonexisting key (no longer used). + REG_LINKTARGET_NOT_EXIST, + /// the reserved buffer for the resolved keyname is to small. + REG_BUFFERSIZE_TOSMALL +}; + +/// specify the calling convention for the registry API +#define REGISTRY_CALLTYPE SAL_CALL + +#endif diff --git a/registry/inc/registry/types.h b/registry/inc/registry/types.h new file mode 100644 index 000000000000..a6898be582d9 --- /dev/null +++ b/registry/inc/registry/types.h @@ -0,0 +1,340 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_registry_types_h +#define INCLUDED_registry_types_h + +#include "sal/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** specifies the typeclass of a binary type blob. + + The general structure of a binary type blob is always the same. It depends + on the typeclass which parts of the blob are filled with data or not. + */ +enum RTTypeClass { + /** specifies that the structure of the given blob is unknown and can't be + read. + */ + RT_TYPE_INVALID, + + /** specifies that the blob represents an interface type. An interface blob + can contain a base interface, attributes and methods. + */ + RT_TYPE_INTERFACE, + + /** specifies that the blob represents a module type. A module blob can + contain a base module and constant members (fields). + */ + RT_TYPE_MODULE, + + /** specifies that the blob represents a struct type. A struct blob can + contain a base struct and members (fields). + */ + RT_TYPE_STRUCT, + + /** specifies that the blob represents an enum type. An enum blob can + contain enum values which are accessible as fields. + */ + RT_TYPE_ENUM, + + /** specifies that the blob represents an exception type. An exception blob + can contain a base exception and members (fields). + */ + RT_TYPE_EXCEPTION, + + /** specifies that the blob represents a typedef type. A typedef blob can + contain a base type. + */ + RT_TYPE_TYPEDEF, + + /** specifies that the blob represents a service type. A service blob can + contain a base service, properties (fields), references to services or + interfaces. + */ + RT_TYPE_SERVICE, + + /** specifies that the blob represents a singleton type (a named object) + which refers exactly one existing service. + */ + RT_TYPE_SINGLETON, + + /// deprecated, not used. + RT_TYPE_OBJECT, + + /** specifies that the blob represents a constants type. A constants blob + can contain constant types as fields. + */ + RT_TYPE_CONSTANTS, + + /** @deprecated + a union type was evaluated but currently not supported. + */ + RT_TYPE_UNION, + + /** + Flag for published entities. + + Used in combination with RT_TYPE_INTERFACE, RT_TYPE_STRUCT, RT_TYPE_ENUM, + RT_TYPE_EXCEPTION, RT_TYPE_TYPEDEF, RT_TYPE_SERVICE, RT_TYPE_SINGLETON, + or RT_TYPE_CONSTANTS to mark an entity as published. + + (The value of this enumerator is chosen so that it is unlikely that its + addition changes the underlying type of this enumeration for any C/C++ + compiler.) + + @internal + + @since UDK 3.2.0 + */ + RT_TYPE_PUBLISHED = 0x4000 +}; + +/** specifies the type for the field access. + + Fields in a type blob are used for different types. Among others they were + used for properties of services and these poperties can have several flags. + + @see RT_ACCESS_INVALID + @see RT_ACCESS_READONLY + @see RT_ACCESS_OPTIONAL + @see RT_ACCESS_MAYBEVOID + @see RT_ACCESS_BOUND + @see RT_ACCESS_CONSTRAINED + @see RT_ACCESS_TRANSIENT + @see RT_ACCESS_MAYBEAMBIGUOUS + @see RT_ACCESS_MAYBEDEFAULT + @see RT_ACCESS_REMOVEABLE + @see RT_ACCESS_ATTRIBUTE + @see RT_ACCESS_PROPERTY + @see RT_ACCESS_CONST + @see RT_ACCESS_READWRITE + @see RT_ACCESS_DEFAULT + @see RT_ACCESS_PARAMETERIZED_TYPE + @see RT_ACCESS_PUBLISHED + */ +typedef sal_uInt16 RTFieldAccess; + +/// specifies a unknown flag +#define RT_ACCESS_INVALID 0x0000 +/// specifies a readonly property/attribute +#define RT_ACCESS_READONLY 0x0001 +/// specifies a property as optional that means that it must not be implemented. +#define RT_ACCESS_OPTIONAL 0x0002 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_MAYBEVOID 0x0004 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_BOUND 0x0008 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_CONSTRAINED 0x0010 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_TRANSIENT 0x0020 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_MAYBEAMBIGUOUS 0x0040 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_MAYBEDEFAULT 0x0080 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_REMOVEABLE 0x0100 +/// @see com::sun::star::beans::PropertyAttribute +#define RT_ACCESS_ATTRIBUTE 0x0200 +/// specifies that the field is a property +#define RT_ACCESS_PROPERTY 0x0400 +/// specifies that the field is a constant or enum value +#define RT_ACCESS_CONST 0x0800 +/// specifies that the property/attribute has read/write access +#define RT_ACCESS_READWRITE 0x1000 +/// only to describe a union default label +#define RT_ACCESS_DEFAULT 0x2000 + +/** + Indicates that a member of a polymorphic struct type template is of a + parameterized type. + + Only valid for fields that represent members of polymorphic struct type + templates. + + @since UDK 3.2.0 + */ +#define RT_ACCESS_PARAMETERIZED_TYPE 0x4000 + +/** + Flag for published individual constants. + + Used in combination with RT_ACCESS_CONST for individual constants (which are + not members of constant groups). + + @since UDK 3.2.0 + */ +#define RT_ACCESS_PUBLISHED 0x8000 + +/** specifies the type of a field value. + + A field can have a value if it repsresents a constant or an enum value. + */ +enum RTValueType { + RT_TYPE_NONE, + RT_TYPE_BOOL, + RT_TYPE_BYTE, + RT_TYPE_INT16, + RT_TYPE_UINT16, + RT_TYPE_INT32, + RT_TYPE_UINT32, + RT_TYPE_INT64, + RT_TYPE_UINT64, + RT_TYPE_FLOAT, + RT_TYPE_DOUBLE, + RT_TYPE_STRING +}; + +/** specifies a variable container for field values. + */ +union RTConstValueUnion { + sal_Bool aBool; + sal_uInt8 aByte; + sal_Int16 aShort; + sal_uInt16 aUShort; + sal_Int32 aLong; + sal_uInt32 aULong; + sal_Int64 aHyper; + sal_uInt64 aUHyper; + float aFloat; + double aDouble; + sal_Unicode const * aString; +}; + +/** specifies the mode of a method. + + A method can be synchron or asynchron (oneway). The const attribute for + methods was removed so that the const values are deprecated. + */ +enum RTMethodMode { + /// indicates an invalid mode + RT_MODE_INVALID, + + /// indicates the asynchronous mode of a method + RT_MODE_ONEWAY, + + /// @deprecated + RT_MODE_ONEWAY_CONST, + + /// indicated the synchronous mode of a method + RT_MODE_TWOWAY, + + /// @deprecated + RT_MODE_TWOWAY_CONST, + + /** + Indicates an extended attribute getter (that has a 'raises' clause) of an + interface type. + + @since UDK 3.2.0 + */ + RT_MODE_ATTRIBUTE_GET, + + /** + Indicates an extended attribute setter (that has a 'raises' clause) of an + interface type. + + @since UDK 3.2.0 + */ + RT_MODE_ATTRIBUTE_SET +}; + +/** specifies the mode of a parameter. + + There are three paramter modes which have impact of the handling of the + paramter in the UNO bridges and the UNO code generation. + */ +enum RTParamMode { + /// indicates an invalid parameter mode + RT_PARAM_INVALID = 0, + + /// indicates a pure in parameter which is used by value + RT_PARAM_IN = 1, + + /// indicates a pure out parameter which is used by reference + RT_PARAM_OUT = 2, + + /// indicates a in and out parameter which is used also by reference + RT_PARAM_INOUT = 3, + + /** + Indicates a rest parameter (currently only valid for service + constructors). + + This value can be combined with any of RT_PARAM_IN, RT_PARAM_OUT, and + RT_PARAM_INOUT (however, service constructors currently only allow + RT_PARAM_IN, anyway). + + @since UDK 3.2.0 + */ + RT_PARAM_REST = 4 +}; + +/** specifies the type of a reference used in a service description. + */ +enum RTReferenceType { + /// the reference type is unknown + RT_REF_INVALID, + + /** the service support the interface that means a implementation of this + service must implement this interface. + */ + RT_REF_SUPPORTS, + + /** @deprecated + the service observes the interface. + */ + RT_REF_OBSERVES, + + /** the service exports the specified service that means this service + provides also the specified service. + */ + RT_REF_EXPORTS, + + /** @deprecated + the service needs the specified service that means in the context of + this service the specified service will be used or must be available. + */ + RT_REF_NEEDS, + + /** + Indicates a type parameter of a polymorphic struct type template. + + @since UDK 3.2.0 + */ + RT_REF_TYPE_PARAMETER +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/registry/inc/registry/version.h b/registry/inc/registry/version.h new file mode 100644 index 000000000000..cabd3639104c --- /dev/null +++ b/registry/inc/registry/version.h @@ -0,0 +1,77 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_registry_version_h +#define INCLUDED_registry_version_h + +#include "sal/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @HTML + +/** + The version of a binary blob that represents a UNOIDL type. + + <p>All values between <code>TYPEREG_VERSION_0</code> and + <code>TYPEREG_MAX_VERSION</code> are valid, where currently unallocated + values represent future versions. Negative values are not valid.</p> + + @see typereg::Reader + @see typereg::Writer + + @since UDK 3.2.0 + */ +enum typereg_Version { + /** + Denotes the original version of UNOIDL type blobs. + */ + TYPEREG_VERSION_0, + + /** + Denotes the updated version of UNOIDL type blobs. + + <p>This version added support for multiple-inheritance interface types, + extended interface type attributes, single-interface–based + services, interface-based singletons, polymorphic struct types, and + published entities.</p> + */ + TYPEREG_VERSION_1, + + /** + Denotes the maximum future version of UNOIDL type blobs. + */ + TYPEREG_MAX_VERSION = SAL_MAX_INT32 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/registry/inc/registry/writer.h b/registry/inc/registry/writer.h new file mode 100644 index 000000000000..5f14766b0f30 --- /dev/null +++ b/registry/inc/registry/writer.h @@ -0,0 +1,269 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_registry_writer_h +#define INCLUDED_registry_writer_h + +#include "registry/types.h" +#include "registry/version.h" + +#include "rtl/ustring.h" +#include "sal/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @HTML + +/** + Creates a type writer working on a binary blob that represents a UNOIDL type. + + <p>Operations on a returned handle are not multi-thread–safe.</p> + + @param version the version of the created type writer; must not be negative + + @param documentation the documentation; must not be null + + @param fileName the file name; must not be null (deprecated, use an empty string) + + @param typeClass the type class of the created type writer + + @param published whether the created type writer is published; for a type + class that cannot be published, this should be false + + @param typeName the type name of the created type writer; must not be null + + @param superTypeCount the number of super types of the created type writer + + @param fieldCount the number of fields of the created type writer + + @param methodCount the number of methods of the created type writer + + @param referenceCount the number of references of the created type writer + + @return a handle on the type writer; if an out-of-memory condition occurs, + null is returned, and no type writer is created + + @since UDK 3.2.0 + */ +void * SAL_CALL typereg_writer_create( + typereg_Version version, rtl_uString const * documentation, + rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published, + rtl_uString const * typeName, sal_uInt16 superTypeCount, + sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount) + SAL_THROW_EXTERN_C(); + +/** + Destroys a type writer. + + @param handle a handle on a type writer obtained from a call to + <code>typereg_writer_create</code>; must not be null + + @since UDK 3.2.0 + */ +void SAL_CALL typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C(); + +/** + Sets the type name of a super type of a type writer. + + @param handle a handle on a type writer; must not be null + + @param index a valid index into the range of super types of the given type + writer + + @param typeName the super type name; must not be null + + @return false iff an out-of-memory condition ocurred, in which case the type + writer is not modified + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_writer_setSuperTypeName( + void * handle, sal_uInt16 index, rtl_uString const * typeName) + SAL_THROW_EXTERN_C(); + +/** + Sets the data of a field of a type writer. + + @param handle a handle on a type writer; must not be null + + @param index a valid index into the range of fields of the given type writer + + @param documentation the documentation of the field; must not be null + + @param fileName the file name of the field; must not be null (deprecated, use an empty string) + + @param flags the flags of the field + + @param name the name of the field; must not be null + + @param typeName the type name of the field; must not be null + + @param valueType the type of the value of the field + + @param valueValue the value of the value of the field + + @return false iff an out-of-memory condition ocurred, in which case the type + writer is not modified + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_writer_setFieldData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name, + rtl_uString const * typeName, RTValueType valueType, + RTConstValueUnion valueValue) + SAL_THROW_EXTERN_C(); + +/** + Sets the data of a method of a type writer. + + @param handle a handle on a type writer; must not be null + + @param index a valid index into the range of methods of the given type writer + + @param documentation the documentation of the method; must not be null + + @param flags the flags of the method + + @param name the name of the method; must not be null + + @param returnTypeName the return type name of the method; must not be null + + @param parameterCount the number of parameters of the method + + @param exceptionCount the number of exceptions of the method + + @return false iff an out-of-memory condition ocurred, in which case the type + writer is not modified + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_writer_setMethodData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + RTMethodMode flags, rtl_uString const * name, + rtl_uString const * returnTypeName, sal_uInt16 parameterCount, + sal_uInt16 exceptionCount) + SAL_THROW_EXTERN_C(); + +/** + Sets the data of a parameter of a method of a type writer. + + @param handle a handle on a type writer; must not be null + + @param methodIndex a valid index into the range of methods of the given type + writer + + @param parameterIndex a valid index into the range of parameters of the given + method + + @param flags the flags of the parameter + + @param name the name of the parameter; must not be null + + @param typeName the type name of the parameter; must not be null + + @return false iff an out-of-memory condition ocurred, in which case the type + writer is not modified + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_writer_setMethodParameterData( + void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex, + RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName) + SAL_THROW_EXTERN_C(); + +/** + Sets an exception type name of a method of a type writer. + + @param handle a handle on a type writer; must not be null + + @param methodIndex a valid index into the range of methods of the given type + writer + + @param exceptionIndex a valid index into the range of exceptions of the given + method + + @param typeName the exception type name; must not be null + + @return false iff an out-of-memory condition ocurred, in which case the type + writer is not modified + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_writer_setMethodExceptionTypeName( + void * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex, + rtl_uString const * typeName) + SAL_THROW_EXTERN_C(); + +/** + Sets the data of a reference of a type writer. + + @param handle a handle on a type writer; must not be null + + @param index a valid index into the range of references of the given type + writer + + @param documentation the documentation of the reference; must not be null + + @param sort the sort of the reference + + @param flags the flags of the reference + + @param typeName the type name of the reference; must not be null + + @return false iff an out-of-memory condition ocurred, in which case the type + writer is not modified + + @since UDK 3.2.0 + */ +sal_Bool SAL_CALL typereg_writer_setReferenceData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName) + SAL_THROW_EXTERN_C(); + +/** + Returns the blob of a type writer. + + @param handle a handle on a type writer; must not be null + + @param size an out-parameter obtaining the size of the blob; must not be null + + @return a (byte-aligned) pointer to the blob; the returned pointer and the + returned <code>size</code> remain valid until the next function is called on + the given type writer; if an out-of-memory condition occurs, null is returned + and <code>size</code> is not modified + */ +void const * SAL_CALL typereg_writer_getBlob(void * handle, sal_uInt32 * size) + SAL_THROW_EXTERN_C(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/registry/inc/registry/writer.hxx b/registry/inc/registry/writer.hxx new file mode 100644 index 000000000000..50bf542024b8 --- /dev/null +++ b/registry/inc/registry/writer.hxx @@ -0,0 +1,303 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_registry_writer_hxx +#define INCLUDED_registry_writer_hxx + +#include "registry/writer.h" +#include "registry/refltype.hxx" +#include "registry/types.h" +#include "registry/version.h" + +#include "rtl/ustring.hxx" +#include "sal/types.h" + +#include <new> + +namespace typereg { + +/// @HTML + +/** + A type writer working on a binary blob that represents a UNOIDL type. + + <p>Instances of this class are not multi-thread–safe.</p> + + @since UDK 3.2.0 + */ +class Writer { +public: + /** + Creates a type writer. + + @param version the version of the created type writer; must not be + negative + + @param documentation the documentation + + @param fileName the file name (deprecated, use an empty string) + + @param typeClass the type class of the created type writer + + @param published whether the created type writer is published; for a type + class that cannot be published, this should be false + + @param typeName the type name of the created type writer + + @param superTypeCount the number of super types of the created type + writer + + @param fieldCount the number of fields of the created type writer + + @param methodCount the number of methods of the created type writer + + @param referenceCount the number of references of the created type writer + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + Writer( + typereg_Version version, rtl::OUString const & documentation, + rtl::OUString const & fileName, RTTypeClass typeClass, bool published, + rtl::OUString const & typeName, sal_uInt16 superTypeCount, + sal_uInt16 fieldCount, sal_uInt16 methodCount, + sal_uInt16 referenceCount): + m_handle( + typereg_writer_create( + version, documentation.pData, fileName.pData, typeClass, + published, typeName.pData, superTypeCount, fieldCount, + methodCount, referenceCount)) + { + if (m_handle == 0) { + throw std::bad_alloc(); + } + } + + /** + Destroys this <code>Writer</code> instance. + */ + ~Writer() { + typereg_writer_destroy(m_handle); + } + + /** + Sets the type name of a super type of this type writer. + + @param index a valid index into the range of super types of this type + writer + + @param typeName the super type name + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + void setSuperTypeName(sal_uInt16 index, rtl::OUString const & typeName) { + if (!typereg_writer_setSuperTypeName(m_handle, index, typeName.pData)) { + throw std::bad_alloc(); + } + } + + /** + Sets the data of a field of this type writer. + + @param index a valid index into the range of fields of this type writer + + @param documentation the documentation of the field + + @param fileName the file name of the field (deprecated, use an empty string) + + @param flags the flags of the field + + @param name the name of the field + + @param typeName the type name of the field + + @param valueType the type of the value of the field + + @param valueValue the value of the value of the field + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + void setFieldData( + sal_uInt16 index, rtl::OUString const & documentation, + rtl::OUString const & fileName, RTFieldAccess flags, rtl::OUString const & name, + rtl::OUString const & typeName, RTConstValue const & value) + { + if (!typereg_writer_setFieldData( + m_handle, index, documentation.pData, fileName.pData, flags, + name.pData, typeName.pData, value.m_type, value.m_value)) + { + throw std::bad_alloc(); + } + } + + /** + Sets the data of a method of this type writer. + + @param index a valid index into the range of methods of this type writer + + @param documentation the documentation of the method + + @param flags the flags of the method + + @param name the name of the method + + @param returnTypeName the return type name of the method + + @param parameterCount the number of parameters of the method + + @param exceptionCount the number of exceptions of the method + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + void setMethodData( + sal_uInt16 index, rtl::OUString const & documentation, + RTMethodMode flags, rtl::OUString const & name, + rtl::OUString const & returnTypeName, sal_uInt16 parameterCount, + sal_uInt16 exceptionCount) + { + if (!typereg_writer_setMethodData( + m_handle, index, documentation.pData, flags, name.pData, + returnTypeName.pData, parameterCount, exceptionCount)) + { + throw std::bad_alloc(); + } + } + + /** + Sets the data of a parameter of a method of this type writer. + + @param methodIndex a valid index into the range of methods of this type + writer + + @param parameterIndex a valid index into the range of parameters of the + given method + + @param flags the flags of the parameter + + @param name the name of the parameter + + @param typeName the type name of the parameter + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + void setMethodParameterData( + sal_uInt16 methodIndex, sal_uInt16 parameterIndex, + RTParamMode flags, rtl::OUString const & name, + rtl::OUString const & typeName) + { + if (!typereg_writer_setMethodParameterData( + m_handle, methodIndex, parameterIndex, flags, name.pData, + typeName.pData)) + { + throw std::bad_alloc(); + } + } + + /** + Sets an exception type name of a method of this type writer. + + @param methodIndex a valid index into the range of methods of this type + writer + + @param exceptionIndex a valid index into the range of exceptions of the + given method + + @param typeName the exception type name + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + void setMethodExceptionTypeName( + sal_uInt16 methodIndex, sal_uInt16 exceptionIndex, + rtl::OUString const & typeName) + { + if (!typereg_writer_setMethodExceptionTypeName( + m_handle, methodIndex, exceptionIndex, typeName.pData)) + { + throw std::bad_alloc(); + } + } + + /** + Sets the data of a reference of this type writer. + + @param handle a handle on a type writer + + @param index a valid index into the range of references of this type + writer + + @param documentation the documentation of the reference + + @param sort the sort of the reference + + @param flags the flags of the reference + + @param typeName the type name of the reference + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + */ + void setReferenceData( + sal_uInt16 index, rtl::OUString const & documentation, + RTReferenceType sort, RTFieldAccess flags, + rtl::OUString const & typeName) + { + if (!typereg_writer_setReferenceData( + m_handle, index, documentation.pData, sort, flags, + typeName.pData)) + { + throw std::bad_alloc(); + } + } + + /** + Returns the blob of this type writer. + + @param size an out-parameter obtaining the size of the blob + + @return a (byte-aligned) pointer to the blob; the returned pointer and + the returned <code>size</code> remain valid until the next function is + called on this type writer + + @exception std::bad_alloc is raised if an out-of-memory condition occurs + (in which case <code>siez</code> is not modified + */ + void const * getBlob(sal_uInt32 * size) { + void const * p = typereg_writer_getBlob(m_handle, size); + if (p == 0) { + throw std::bad_alloc(); + } + return p; + } + +private: + Writer(Writer &); // not implemented + void operator =(Writer); // not implemented + + void * m_handle; +}; + +} + +#endif diff --git a/registry/prj/build.lst b/registry/prj/build.lst new file mode 100644 index 000000000000..624601246e3a --- /dev/null +++ b/registry/prj/build.lst @@ -0,0 +1,7 @@ +rg registry : salhelper store NULL +rg registry usr1 - all rg_mkout NULL +rg registry\inc nmake - all rg_inc NULL +rg registry\prj get - all rg_prj rg_inc NULL +rg registry\source nmake - all rg_src rg_inc NULL +rg registry\util nmake - all rg_utl rg_src NULL +rg registry\tools nmake - all rg_tls rg_utl NULL diff --git a/registry/prj/d.lst b/registry/prj/d.lst new file mode 100644 index 000000000000..644f28e5cfd8 --- /dev/null +++ b/registry/prj/d.lst @@ -0,0 +1,19 @@ +mkdir: %_DEST%\inc%_EXT%\registry + +..\inc\registry\*.h %_DEST%\inc%_EXT%\registry\*.h +..\inc\registry\*.hxx %_DEST%\inc%_EXT%\registry\*.hxx + +..\%__SRC%\lib\ireg.lib %_DEST%\lib%_EXT%\ireg.lib +..\%__SRC%\lib\libreg.*.* %_DEST%\lib%_EXT%\* +..\%__SRC%\bin\reg*.dll %_DEST%\bin%_EXT%\reg*.dll + +..\%__SRC%\bin\checksingleton.exe %_DEST%\bin%_EXT%\checksingleton.exe +..\%__SRC%\bin\regcompare.exe %_DEST%\bin%_EXT%\regcompare.exe +..\%__SRC%\bin\regmerge.exe %_DEST%\bin%_EXT%\regmerge.exe +..\%__SRC%\bin\regview.exe %_DEST%\bin%_EXT%\regview.exe +..\%__SRC%\bin\checksingleton %_DEST%\bin%_EXT%\checksingleton +..\%__SRC%\bin\regcompare %_DEST%\bin%_EXT%\regcompare +..\%__SRC%\bin\regmerge %_DEST%\bin%_EXT%\regmerge +..\%__SRC%\bin\regview %_DEST%\bin%_EXT%\regview + +linklib: libreg.*.* diff --git a/registry/source/keyimpl.cxx b/registry/source/keyimpl.cxx new file mode 100644 index 000000000000..9496aee84d8e --- /dev/null +++ b/registry/source/keyimpl.cxx @@ -0,0 +1,1078 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include "keyimpl.hxx" + +#include "reflcnst.hxx" +#include "rtl/alloc.h" +#include "rtl/memory.h" +#include "rtl/ustrbuf.hxx" + +using rtl::OUString; +using rtl::OUStringBuffer; +using namespace store; + +namespace { static char const VALUE_PREFIX[] = "$VL_"; } + +//********************************************************************* +// ORegKey() +// +ORegKey::ORegKey(const OUString& keyName, ORegistry* pReg) + : m_refCount(1) + , m_name(keyName) + , m_bDeleted(0) + , m_bModified(0) + , m_pRegistry(pReg) +{ +} + +//********************************************************************* +// ~ORegKey() +// +ORegKey::~ORegKey() +{ + OSL_POSTCOND(m_refCount == 0, "registry::ORegKey::dtor(): refcount not zero."); +} + +//********************************************************************* +// acquireKey +// +RegError ORegKey::acquireKey(RegKeyHandle hKey) +{ + return m_pRegistry->acquireKey(hKey); +} + +//********************************************************************* +// releaseKey +// +RegError ORegKey::releaseKey(RegKeyHandle hKey) +{ + return m_pRegistry->releaseKey(hKey); +} + +//********************************************************************* +// createKey +// +RegError ORegKey::createKey(const OUString& keyName, RegKeyHandle* phNewKey) +{ + return m_pRegistry->createKey(this, keyName, phNewKey); +} + + +//********************************************************************* +// openKey +// +RegError ORegKey::openKey(const OUString& keyName, RegKeyHandle* phOpenKey) +{ + return m_pRegistry->openKey(this, keyName, phOpenKey); +} + + +//********************************************************************* +// openSubKeys +// +RegError ORegKey::openSubKeys(const OUString& keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys) +{ + RegError _ret = REG_NO_ERROR; + + *phOpenSubKeys = 0; + *pnSubKeys = 0; + + ORegKey* pKey = this; + if ( keyName.getLength() ) + { + _ret = openKey(keyName, (RegKeyHandle*)&pKey); + if (_ret != REG_NO_ERROR) + return _ret; + } + + sal_uInt32 nSubKeys = pKey->countSubKeys(); + *pnSubKeys = nSubKeys; + + ORegKey** pSubKeys; + pSubKeys = (ORegKey**)rtl_allocateZeroMemory(nSubKeys * sizeof(ORegKey*)); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + nSubKeys = 0; + while ( _err == store_E_None ) + { + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + OUString const sSubKeyName = iter.m_pszName; + + ORegKey* pOpenSubKey = 0; + _ret = pKey->openKey(sSubKeyName, (RegKeyHandle*)&pOpenSubKey); + if (_ret != REG_NO_ERROR) + { + *phOpenSubKeys = NULL; + *pnSubKeys = 0; + rtl_freeMemory(pSubKeys); // @@@ leaking 'pSubKeys[0...nSubkeys-1]' + return _ret; // @@@ leaking 'pKey' + } + + pSubKeys[nSubKeys] = pOpenSubKey; + + nSubKeys++; + } + + _err = rStoreDir.next(iter); + } + + *phOpenSubKeys = (RegKeyHandle*)pSubKeys; + if (keyName.getLength()) + { + (void) releaseKey(pKey); + } + return REG_NO_ERROR; +} + + +//********************************************************************* +// getKeyNames +// +RegError ORegKey::getKeyNames(const OUString& keyName, + rtl_uString*** pSubKeyNames, + sal_uInt32* pnSubKeys) +{ + RegError _ret = REG_NO_ERROR; + + *pSubKeyNames = 0; + *pnSubKeys = 0; + + ORegKey* pKey = this; + if (keyName.getLength()) + { + _ret = openKey(keyName, (RegKeyHandle*)&pKey); + if (_ret != REG_NO_ERROR) + return _ret; + } + + sal_uInt32 nSubKeys = pKey->countSubKeys(); + *pnSubKeys = nSubKeys; + + rtl_uString** pSubKeys = 0; + pSubKeys = (rtl_uString**)rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*)); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + nSubKeys = 0; + + while ( _err == store_E_None ) + { + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + OUString const sSubKeyName = iter.m_pszName; + + OUString sFullKeyName(pKey->getName()); + if (sFullKeyName.getLength() > 1) + sFullKeyName += m_pRegistry->ROOT; + sFullKeyName += sSubKeyName; + + rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData); + + nSubKeys++; + } + + _err = rStoreDir.next(iter); + } + + *pSubKeyNames = pSubKeys; + if (keyName.getLength()) + { + releaseKey(pKey); + } + return REG_NO_ERROR; +} + + +//********************************************************************* +// closeKey +// +RegError ORegKey::closeKey(RegKeyHandle hKey) +{ + return (m_pRegistry->closeKey(hKey)); +} + + +//********************************************************************* +// deleteKey +// +RegError ORegKey::deleteKey(const OUString& keyName) +{ + return (m_pRegistry->deleteKey(this, keyName)); +} + + +//********************************************************************* +// getValueType +// +RegError ORegKey::getValueInfo(const OUString& valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(m_pRegistry->getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + *pValueType = RG_VALUETYPE_NOT_DEFINED; + *pValueSize = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 size; + sal_uInt8 type = *((sal_uInt8*)pBuffer); + readUINT32(pBuffer+VALUE_TYPEOFFSET, size); + + *pValueType = (RegValueType)type; +// if (*pValueType == RG_VALUETYPE_UNICODE) +// { +// *pValueSize = (size / 2) * sizeof(sal_Unicode); +// } else +// { + if (*pValueType > 4) + { + rtl_freeMemory(pBuffer); + pBuffer = (sal_uInt8*)rtl_allocateMemory(4); + rValue.readAt(VALUE_HEADEROFFSET, pBuffer, 4, readBytes); + + readUINT32(pBuffer, size); + } + + *pValueSize = size; +// } + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + + +//********************************************************************* +// setValue +// +RegError ORegKey::setValue(const OUString& valueName, RegValueType vType, RegValue value, sal_uInt32 vSize) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + if (vType > 4) + { + return REG_INVALID_VALUE; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT , sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = vSize; + + sal_uInt8 type = (sal_uInt8)vType; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + + switch (vType) + { + case RG_VALUETYPE_NOT_DEFINED: + rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, value, size); + break; + case RG_VALUETYPE_LONG: + writeINT32(pBuffer+VALUE_HEADEROFFSET, *((sal_Int32*)value)); + break; + case RG_VALUETYPE_STRING: + writeUtf8(pBuffer+VALUE_HEADEROFFSET, (const sal_Char*)value); + break; + case RG_VALUETYPE_UNICODE: + writeString(pBuffer+VALUE_HEADEROFFSET, (const sal_Unicode*)value); + break; + case RG_VALUETYPE_BINARY: + rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, value, size); + break; + default: + OSL_ASSERT(false); + break; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADERSIZE+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// setLongListValue +// +RegError ORegKey::setLongListValue(const OUString& valueName, sal_Int32* pValueList, sal_uInt32 len) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge + + size += len * 4; + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_LONGLIST; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + + for (sal_uInt32 i=0; i < len; i++) + { + writeINT32(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); + offset += 4; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADEROFFSET+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// setStringListValue +// +RegError ORegKey::setStringListValue(const OUString& valueName, sal_Char** pValueList, sal_uInt32 len) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge + + sal_uInt32 i; + for (i=0; i < len; i++) + { + size += 4 + strlen(pValueList[i]) + 1; + } + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_STRINGLIST; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + for (i=0; i < len; i++) + { + sLen = strlen(pValueList[i]) + 1; + writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen); + + offset += 4; + writeUtf8(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); + offset += sLen; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADERSIZE+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// setUnicodeListValue +// +RegError ORegKey::setUnicodeListValue(const OUString& valueName, sal_Unicode** pValueList, sal_uInt32 len) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + + if (m_pRegistry->isReadOnly()) + { + return REG_REGISTRY_READONLY; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) + { + return REG_SET_VALUE_FAILED; + } + + sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge + + sal_uInt32 i; + for (i=0; i < len; i++) + { + size += 4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2); + } + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_UNICODELIST; + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); + rtl_copyMemory(pBuffer, &type, 1); + + writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); + writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + for (i=0; i < len; i++) + { + sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2; + writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen); + + offset += 4; + writeString(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); + offset += sLen; + } + + sal_uInt32 writenBytes; + if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + if (writenBytes != (VALUE_HEADERSIZE+size)) + { + rtl_freeMemory(pBuffer); + return REG_SET_VALUE_FAILED; + } + setModified(); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getValue +// +RegError ORegKey::getValue(const OUString& valueName, RegValue value) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + if (valueType > 4) + { + return REG_INVALID_VALUE; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + switch (valueType) + { + case RG_VALUETYPE_NOT_DEFINED: + rtl_copyMemory(value, pBuffer, valueSize); + break; + case RG_VALUETYPE_LONG: + readINT32(pBuffer, *((sal_Int32*)value)); + break; + case RG_VALUETYPE_STRING: + readUtf8(pBuffer, (sal_Char*)value, valueSize); + break; + case RG_VALUETYPE_UNICODE: + readString(pBuffer, (sal_Unicode*)value, valueSize); + break; + case RG_VALUETYPE_BINARY: + rtl_copyMemory(value, pBuffer, valueSize); + break; + case RG_VALUETYPE_LONGLIST: + case RG_VALUETYPE_STRINGLIST: + case RG_VALUETYPE_UNICODELIST: + rtl_copyMemory(value, pBuffer, valueSize); + break; + } + + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getLongListValue +// +RegError ORegKey::getLongListValue(const OUString& valueName, sal_Int32** pValueList, sal_uInt32* pLen) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + pValueList = NULL; + *pLen = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + + if (valueType != RG_VALUETYPE_LONGLIST) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 len = 0; + readUINT32(pBuffer, len); + + *pLen = len; + sal_Int32* pVList = (sal_Int32*)rtl_allocateZeroMemory(len * sizeof(sal_Int32)); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + + for (sal_uInt32 i=0; i < len; i++) + { + readINT32(pBuffer+offset, pVList[i]); + offset += 4; + } + + *pValueList = pVList; + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getStringListValue +// +RegError ORegKey::getStringListValue(const OUString& valueName, sal_Char*** pValueList, sal_uInt32* pLen) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + pValueList = NULL; + *pLen = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + + if (valueType != RG_VALUETYPE_STRINGLIST) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 len = 0; + readUINT32(pBuffer, len); + + *pLen = len; + sal_Char** pVList = (sal_Char**)rtl_allocateZeroMemory(len * sizeof(sal_Char*)); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + sal_Char *pValue; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; + + pValue = (sal_Char*)rtl_allocateMemory(sLen); + readUtf8(pBuffer+offset, pValue, sLen); + pVList[i] = pValue; + + offset += sLen; + } + + *pValueList = pVList; + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getUnicodeListValue +// +RegError ORegKey::getUnicodeListValue(const OUString& valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (m_pRegistry->isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); + sImplValueName += valueName; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) + { + pValueList = NULL; + *pLen = 0; + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 readBytes; + if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != VALUE_HEADERSIZE) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + + if (valueType != RG_VALUETYPE_UNICODELIST) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + rtl_freeMemory(pBuffer); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + + if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (readBytes != valueSize) + { + pValueList = NULL; + *pLen = 0; + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt32 len = 0; + readUINT32(pBuffer, len); + + *pLen = len; + sal_Unicode** pVList = (sal_Unicode**)rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)); + + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; + sal_uInt32 sLen = 0; + + sal_Unicode *pValue; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; + + pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)); + readString(pBuffer+offset, pValue, sLen); + pVList[i] = pValue; + + offset += sLen; + } + + *pValueList = pVList; + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// getKeyType() +// +RegError ORegKey::getKeyType(const OUString& name, RegKeyType* pKeyType) const +{ + *pKeyType = RG_KEYTYPE; + + REG_GUARD(m_pRegistry->m_mutex); + + if ( name.getLength() ) + { + ORegKey* pThis = const_cast< ORegKey* >(this); + + RegKeyHandle hKey = 0; + RegError _ret = pThis->openKey(name, &hKey); + if (_ret != REG_NO_ERROR) + return _ret; + (void) pThis->releaseKey(hKey); + } + + return REG_NO_ERROR; +} + +RegError ORegKey::getResolvedKeyName(const OUString& keyName, + OUString& resolvedName) +{ + if (keyName.getLength() == 0) + return REG_INVALID_KEYNAME; + + resolvedName = getFullPath(keyName); + return REG_NO_ERROR; +} + +//********************************************************************* +// countSubKeys() +// +sal_uInt32 ORegKey::countSubKeys() +{ + REG_GUARD(m_pRegistry->m_mutex); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir = getStoreDir(); + storeError _err = rStoreDir.first(iter); + sal_uInt32 count = 0; + + while ( _err == store_E_None ) + { + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + count++; + } + + _err = rStoreDir.next(iter); + } + + return count; +} + +OStoreDirectory ORegKey::getStoreDir() +{ + OStoreDirectory rStoreDir; + OUString fullPath; + OUString relativName; + storeAccessMode accessMode = KEY_MODE_OPEN; + + if ( m_name.equals(m_pRegistry->ROOT) ) + { + fullPath = OUString(); + relativName = OUString(); + } else + { + fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1); + relativName = m_name.copy(m_name.lastIndexOf('/') + 1); + } + + if (m_pRegistry->isReadOnly()) + { + accessMode = KEY_MODE_OPENREAD; + } + + rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode); + + return rStoreDir; +} + +OUString ORegKey::getFullPath(OUString const & path) const { + OSL_ASSERT(m_name.getLength() != 0 && path.getLength() != 0); + OUStringBuffer b(m_name); + if (b.charAt(b.getLength() - 1) == '/') { + if (path[0] == '/') { + b.append(path.getStr() + 1, path.getLength() - 1); + } else { + b.append(path); + } + } else { + if (path[0] != '/') { + b.append(sal_Unicode('/')); + } + b.append(path); + } + return b.makeStringAndClear(); +} diff --git a/registry/source/keyimpl.hxx b/registry/source/keyimpl.hxx new file mode 100644 index 000000000000..c2558b4f8394 --- /dev/null +++ b/registry/source/keyimpl.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _KEYIMPL_HXX_ +#define _KEYIMPL_HXX_ + +#include <registry/registry.h> +#include "regimpl.hxx" +#include <rtl/ustring.hxx> + +class ORegKey +{ +public: + + ORegKey(const rtl::OUString& keyName, ORegistry* pReg); + ~ORegKey(); + + sal_uInt32 acquire() + { return ++m_refCount; } + + sal_uInt32 release() + { return --m_refCount; } + + RegError acquireKey(RegKeyHandle hKey); + RegError releaseKey(RegKeyHandle hKey); + + RegError createKey(const rtl::OUString& keyName, RegKeyHandle* phNewKey); + + RegError openKey(const rtl::OUString& keyName, RegKeyHandle* phOpenKey); + + RegError openSubKeys(const rtl::OUString& keyName, + RegKeyHandle** phOpenSubKeys, + sal_uInt32* pnSubKeys); + + RegError getKeyNames(const rtl::OUString& keyName, + rtl_uString*** pSubKeyNames, + sal_uInt32* pnSubKeys); + + RegError closeKey(RegKeyHandle hKey); + + RegError deleteKey(const rtl::OUString& keyName); + + RegError getValueInfo(const rtl::OUString& valueName, + RegValueType* pValueTye, + sal_uInt32* pValueSize) const; + + RegError setValue(const rtl::OUString& valueName, + RegValueType vType, + RegValue value, + sal_uInt32 vSize); + + RegError setLongListValue(const rtl::OUString& valueName, + sal_Int32* pValueList, + sal_uInt32 len); + + RegError setStringListValue(const rtl::OUString& valueName, + sal_Char** pValueList, + sal_uInt32 len); + + RegError setUnicodeListValue(const rtl::OUString& valueName, + sal_Unicode** pValueList, + sal_uInt32 len); + + RegError getValue(const rtl::OUString& valueName, RegValue value) const; + + RegError getLongListValue(const rtl::OUString& valueName, + sal_Int32** pValueList, + sal_uInt32* pLen) const; + + RegError getStringListValue(const rtl::OUString& valueName, + sal_Char*** pValueList, + sal_uInt32* pLen) const; + + RegError getUnicodeListValue(const rtl::OUString& valueName, + sal_Unicode*** pValueList, + sal_uInt32* pLen) const; + + RegError getKeyType(const rtl::OUString& name, + RegKeyType* pKeyType) const; + + RegError getResolvedKeyName(const rtl::OUString& keyName, + rtl::OUString& resolvedName); + + bool isDeleted() const + { return m_bDeleted != 0; } + + void setDeleted (sal_Bool bKeyDeleted) + { m_bDeleted = bKeyDeleted ? 1 : 0; } + + bool isModified() const + { return m_bModified != 0; } + + void setModified (bool bModified = true) + { m_bModified = bModified ? 1 : 0; } + + sal_Bool isReadOnly() const + { return m_pRegistry->isReadOnly(); } + + sal_uInt32 countSubKeys(); + + ORegistry* getRegistry() const + { return m_pRegistry; } + + const store::OStoreFile& getStoreFile() const + { return m_pRegistry->getStoreFile(); } + + store::OStoreDirectory getStoreDir(); + + const rtl::OUString& getName() const + { return m_name; } + + sal_uInt32 getRefCount() const + { return m_refCount; } + + rtl::OUString getFullPath(rtl::OUString const & path) const; + +private: + sal_uInt32 m_refCount; + rtl::OUString m_name; + int m_bDeleted:1; + int m_bModified:1; + ORegistry* m_pRegistry; +}; + +#endif + + diff --git a/registry/source/makefile.mk b/registry/source/makefile.mk new file mode 100644 index 000000000000..9b9cb5ca4fee --- /dev/null +++ b/registry/source/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# 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=registry +TARGET=regcpp + +ENABLE_EXCEPTIONS := TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : ..$/version.mk + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/regimpl.obj \ + $(SLO)$/regkey.obj \ + $(SLO)$/registry.obj \ + $(SLO)$/keyimpl.obj \ + $(SLO)$/reflread.obj \ + $(SLO)$/reflwrit.obj + +# ------------------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/registry/source/reflcnst.hxx b/registry/source/reflcnst.hxx new file mode 100644 index 000000000000..4b64a1ad61ea --- /dev/null +++ b/registry/source/reflcnst.hxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REFLCNST_HXX_ +#define _REFLCNST_HXX_ + +#include <registry/refltype.hxx> +#include <sal/macros.h> + +#include <string.h> + +#define REGTYPE_IEEE_NATIVE 1 + +extern const sal_uInt32 magic; +extern const sal_uInt16 minorVersion; +extern const sal_uInt16 majorVersion; + +#define OFFSET_MAGIC 0 +#define OFFSET_SIZE (OFFSET_MAGIC + sizeof(magic)) +#define OFFSET_MINOR_VERSION (OFFSET_SIZE + sizeof(sal_uInt32)) +#define OFFSET_MAJOR_VERSION (OFFSET_MINOR_VERSION + sizeof(minorVersion)) +#define OFFSET_N_ENTRIES (OFFSET_MAJOR_VERSION + sizeof(sal_uInt16)) +#define OFFSET_TYPE_SOURCE (OFFSET_N_ENTRIES + sizeof(sal_uInt16)) +#define OFFSET_TYPE_CLASS (OFFSET_TYPE_SOURCE + sizeof(sal_uInt16)) +#define OFFSET_THIS_TYPE (OFFSET_TYPE_CLASS + sizeof(sal_uInt16)) +#define OFFSET_UIK (OFFSET_THIS_TYPE + sizeof(sal_uInt16)) +#define OFFSET_DOKU (OFFSET_UIK + sizeof(sal_uInt16)) +#define OFFSET_FILENAME (OFFSET_DOKU + sizeof(sal_uInt16)) + +#define OFFSET_N_SUPERTYPES (OFFSET_FILENAME + sizeof(sal_uInt16)) +#define OFFSET_SUPERTYPES (OFFSET_N_SUPERTYPES + sizeof(sal_uInt16)) + +#define OFFSET_CP_SIZE (OFFSET_SUPERTYPES + sizeof(sal_uInt16)) +#define OFFSET_CP (OFFSET_CP_SIZE + sizeof(sal_uInt16)) + +#define CP_OFFSET_ENTRY_SIZE 0 +#define CP_OFFSET_ENTRY_TAG (CP_OFFSET_ENTRY_SIZE + sizeof(sal_uInt32)) +#define CP_OFFSET_ENTRY_DATA (CP_OFFSET_ENTRY_TAG + sizeof(sal_uInt16)) +#define CP_OFFSET_ENTRY_UIK1 CP_OFFSET_ENTRY_DATA +#define CP_OFFSET_ENTRY_UIK2 (CP_OFFSET_ENTRY_UIK1 + sizeof(sal_uInt32)) +#define CP_OFFSET_ENTRY_UIK3 (CP_OFFSET_ENTRY_UIK2 + sizeof(sal_uInt16)) +#define CP_OFFSET_ENTRY_UIK4 (CP_OFFSET_ENTRY_UIK3 + sizeof(sal_uInt16)) +#define CP_OFFSET_ENTRY_UIK5 (CP_OFFSET_ENTRY_UIK4 + sizeof(sal_uInt32)) + +#define FIELD_OFFSET_ACCESS 0 +#define FIELD_OFFSET_NAME (FIELD_OFFSET_ACCESS + sizeof(sal_uInt16)) +#define FIELD_OFFSET_TYPE (FIELD_OFFSET_NAME + sizeof(sal_uInt16)) +#define FIELD_OFFSET_VALUE (FIELD_OFFSET_TYPE + sizeof(sal_uInt16)) +#define FIELD_OFFSET_DOKU (FIELD_OFFSET_VALUE + sizeof(sal_uInt16)) +#define FIELD_OFFSET_FILENAME (FIELD_OFFSET_DOKU + sizeof(sal_uInt16)) +//#define FIELD_ENTRY_SIZE (FIELD_OFFSET_FILENAME + sizeof(sal_uInt16)) + +#define PARAM_OFFSET_TYPE 0 +#define PARAM_OFFSET_MODE (PARAM_OFFSET_TYPE + sizeof(sal_uInt16)) +#define PARAM_OFFSET_NAME (PARAM_OFFSET_MODE + sizeof(sal_uInt16)) +//#define PARAM_ENTRY_SIZE (PARAM_OFFSET_NAME + sizeof(sal_uInt16)) + +#define METHOD_OFFSET_SIZE 0 +#define METHOD_OFFSET_MODE (METHOD_OFFSET_SIZE + sizeof(sal_uInt16)) +#define METHOD_OFFSET_NAME (METHOD_OFFSET_MODE + sizeof(sal_uInt16)) +#define METHOD_OFFSET_RETURN (METHOD_OFFSET_NAME + sizeof(sal_uInt16)) +#define METHOD_OFFSET_DOKU (METHOD_OFFSET_RETURN + sizeof(sal_uInt16)) +#define METHOD_OFFSET_PARAM_COUNT (METHOD_OFFSET_DOKU + sizeof(sal_uInt16)) +//#define METHOD_OFFSET_PARAM(i) (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (i * PARAM_ENTRY_SIZE)) + +#define REFERENCE_OFFSET_TYPE 0 +#define REFERENCE_OFFSET_NAME (REFERENCE_OFFSET_TYPE + sizeof(sal_uInt16)) +#define REFERENCE_OFFSET_DOKU (REFERENCE_OFFSET_NAME + sizeof(sal_uInt16)) +#define REFERENCE_OFFSET_ACCESS (REFERENCE_OFFSET_DOKU + sizeof(sal_uInt16)) +//#define REFERENCE_ENTRY_SIZE (REFERENCE_OFFSET_ACCESS + sizeof(sal_uInt16)) + +enum CPInfoTag +{ + CP_TAG_INVALID = RT_TYPE_NONE, + CP_TAG_CONST_BOOL = RT_TYPE_BOOL, + CP_TAG_CONST_BYTE = RT_TYPE_BYTE, + CP_TAG_CONST_INT16 = RT_TYPE_INT16, + CP_TAG_CONST_UINT16 = RT_TYPE_UINT16, + CP_TAG_CONST_INT32 = RT_TYPE_INT32, + CP_TAG_CONST_UINT32 = RT_TYPE_UINT32, + CP_TAG_CONST_INT64 = RT_TYPE_INT64, + CP_TAG_CONST_UINT64 = RT_TYPE_UINT64, + CP_TAG_CONST_FLOAT = RT_TYPE_FLOAT, + CP_TAG_CONST_DOUBLE = RT_TYPE_DOUBLE, + CP_TAG_CONST_STRING = RT_TYPE_STRING, + CP_TAG_UTF8_NAME, + CP_TAG_UIK +}; + +inline sal_uInt32 writeBYTE(sal_uInt8* buffer, sal_uInt8 v) +{ + buffer[0] = v; + + return sizeof(sal_uInt8); +} + +inline sal_uInt16 readBYTE(const sal_uInt8* buffer, sal_uInt8& v) +{ + v = buffer[0]; + + return sizeof(sal_uInt8); +} + +inline sal_uInt32 writeINT16(sal_uInt8* buffer, sal_Int16 v) +{ + buffer[0] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_Int16); +} + +inline sal_uInt32 readINT16(const sal_uInt8* buffer, sal_Int16& v) +{ + v = ((buffer[0] << 8) | (buffer[1] << 0)); + + return sizeof(sal_Int16); +} + +inline sal_uInt32 writeUINT16(sal_uInt8* buffer, sal_uInt16 v) +{ + buffer[0] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_uInt16); +} + +inline sal_uInt32 readUINT16(const sal_uInt8* buffer, sal_uInt16& v) +{ + v = ((buffer[0] << 8) | (buffer[1] << 0)); + + return sizeof(sal_uInt16); +} + +inline sal_uInt32 writeINT32(sal_uInt8* buffer, sal_Int32 v) +{ + buffer[0] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_Int32); +} + +inline sal_uInt32 readINT32(const sal_uInt8* buffer, sal_Int32& v) +{ + v = ( + (buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + (buffer[3] << 0) + ); + + return sizeof(sal_Int32); +} + +inline sal_uInt32 writeUINT32(sal_uInt8* buffer, sal_uInt32 v) +{ + buffer[0] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_uInt32); +} + +inline sal_uInt32 readUINT32(const sal_uInt8* buffer, sal_uInt32& v) +{ + v = ( + (buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + (buffer[3] << 0) + ); + + return sizeof(sal_uInt32); +} + +inline sal_uInt32 writeINT64(sal_uInt8* buffer, sal_Int64 v) +{ + buffer[0] = (sal_uInt8)((v >> 56) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 48) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 40) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 32) & 0xFF); + buffer[4] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[5] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[6] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[7] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_Int64); +} + +inline sal_uInt32 readINT64(const sal_uInt8* buffer, sal_Int64& v) +{ + v = ( + ((sal_Int64)buffer[0] << 56) | + ((sal_Int64)buffer[1] << 48) | + ((sal_Int64)buffer[2] << 40) | + ((sal_Int64)buffer[3] << 32) | + ((sal_Int64)buffer[4] << 24) | + ((sal_Int64)buffer[5] << 16) | + ((sal_Int64)buffer[6] << 8) | + ((sal_Int64)buffer[7] << 0) + ); + + return sizeof(sal_Int64); +} + +inline sal_uInt32 writeUINT64(sal_uInt8* buffer, sal_uInt64 v) +{ + buffer[0] = (sal_uInt8)((v >> 56) & 0xFF); + buffer[1] = (sal_uInt8)((v >> 48) & 0xFF); + buffer[2] = (sal_uInt8)((v >> 40) & 0xFF); + buffer[3] = (sal_uInt8)((v >> 32) & 0xFF); + buffer[4] = (sal_uInt8)((v >> 24) & 0xFF); + buffer[5] = (sal_uInt8)((v >> 16) & 0xFF); + buffer[6] = (sal_uInt8)((v >> 8) & 0xFF); + buffer[7] = (sal_uInt8)((v >> 0) & 0xFF); + + return sizeof(sal_uInt64); +} + +inline sal_uInt32 readUINT64(const sal_uInt8* buffer, sal_uInt64& v) +{ + v = ( + ((sal_uInt64)buffer[0] << 56) | + ((sal_uInt64)buffer[1] << 48) | + ((sal_uInt64)buffer[2] << 40) | + ((sal_uInt64)buffer[3] << 32) | + ((sal_uInt64)buffer[4] << 24) | + ((sal_uInt64)buffer[5] << 16) | + ((sal_uInt64)buffer[6] << 8) | + ((sal_uInt64)buffer[7] << 0) + ); + + return sizeof(sal_uInt64); +} + +inline sal_uInt32 writeUtf8(sal_uInt8* buffer, const sal_Char* v) +{ + sal_uInt32 size = strlen(v) + 1; + + memcpy(buffer, v, size); + + return (size); +} + +inline sal_uInt32 readUtf8(const sal_uInt8* buffer, sal_Char* v, sal_uInt32 maxSize) +{ + sal_uInt32 size = SAL_MIN(strlen((const sal_Char*) buffer) + 1, maxSize); + + memcpy(v, buffer, size); + + if (size == maxSize) v[size - 1] = '\0'; + + return (size); +} + + +sal_uInt32 writeFloat(sal_uInt8* buffer, float v); +sal_uInt32 writeDouble(sal_uInt8* buffer, double v); +sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v); +sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize); + +sal_uInt32 UINT16StringLen(const sal_uInt8* wstring); + +#endif + + + + + diff --git a/registry/source/reflread.cxx b/registry/source/reflread.cxx new file mode 100644 index 000000000000..a61b5e5f58fa --- /dev/null +++ b/registry/source/reflread.cxx @@ -0,0 +1,1774 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <memory> +#include <new> + +#include <string.h> +#include <sal/types.h> +#include <osl/endian.h> +#include <registry/reflread.hxx> + +#include "registry/reader.h" +#include "registry/version.h" + +#include "reflcnst.hxx" + +#include <cstddef> + +static sal_Char NULL_STRING[1] = { 0 }; +static sal_Unicode NULL_WSTRING[1] = { 0 }; + +const sal_uInt32 magic = 0x12345678; +const sal_uInt16 minorVersion = 0x0000; +const sal_uInt16 majorVersion = 0x0001; + +#if defined ( GCC ) && ( defined ( SCO ) ) +ORealDynamicLoader* ODynamicLoader<RegistryTypeReader_Api>::m_pLoader = NULL; +#endif + +/************************************************************************** + + class BlopObject + + holds any data in a flat memory buffer + +**************************************************************************/ + +class BlopObject +{ +public: + const sal_uInt8* m_pBuffer; + sal_uInt32 m_bufferLen; + sal_Bool m_isCopied; + + BlopObject(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer); + // throws std::bad_alloc + + ~BlopObject(); + + inline sal_uInt8 readBYTE(sal_uInt32 index) const + { + return m_pBuffer[index]; + } + + inline sal_Int16 readINT16(sal_uInt32 index) const + { + return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0)); + } + + inline sal_uInt16 readUINT16(sal_uInt32 index) const + { + return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0)); + } + + inline sal_Int32 readINT32(sal_uInt32 index) const + { + return ( + (m_pBuffer[index] << 24) | + (m_pBuffer[index+1] << 16) | + (m_pBuffer[index+2] << 8) | + (m_pBuffer[index+3] << 0) + ); + } + + inline sal_uInt32 readUINT32(sal_uInt32 index) const + { + return ( + (m_pBuffer[index] << 24) | + (m_pBuffer[index+1] << 16) | + (m_pBuffer[index+2] << 8) | + (m_pBuffer[index+3] << 0) + ); + } + + inline sal_Int64 readINT64(sal_uInt32 index) const + { + return ( + ((sal_Int64)m_pBuffer[index] << 56) | + ((sal_Int64)m_pBuffer[index+1] << 48) | + ((sal_Int64)m_pBuffer[index+2] << 40) | + ((sal_Int64)m_pBuffer[index+3] << 32) | + ((sal_Int64)m_pBuffer[index+4] << 24) | + ((sal_Int64)m_pBuffer[index+5] << 16) | + ((sal_Int64)m_pBuffer[index+6] << 8) | + ((sal_Int64)m_pBuffer[index+7] << 0) + ); + } + + inline sal_uInt64 readUINT64(sal_uInt32 index) const + { + return ( + ((sal_uInt64)m_pBuffer[index] << 56) | + ((sal_uInt64)m_pBuffer[index+1] << 48) | + ((sal_uInt64)m_pBuffer[index+2] << 40) | + ((sal_uInt64)m_pBuffer[index+3] << 32) | + ((sal_uInt64)m_pBuffer[index+4] << 24) | + ((sal_uInt64)m_pBuffer[index+5] << 16) | + ((sal_uInt64)m_pBuffer[index+6] << 8) | + ((sal_uInt64)m_pBuffer[index+7] << 0) + ); + } +}; + +BlopObject::BlopObject(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer) + : m_bufferLen(len) + , m_isCopied(copyBuffer) +{ + if (m_isCopied) + { + m_pBuffer = 0; + sal_uInt8* newBuffer = new sal_uInt8[len]; + memcpy(newBuffer, buffer, len); + m_pBuffer = newBuffer; + } + else + { + m_pBuffer = buffer; + } +} + +BlopObject::~BlopObject() +{ + if (m_isCopied) + { + delete[] const_cast<sal_uInt8*>(m_pBuffer); + } +} + +/************************************************************************** + + class StringCache + +**************************************************************************/ + +class StringCache +{ +public: + sal_Unicode** m_stringTable; + sal_uInt16 m_numOfStrings; + sal_uInt16 m_stringsCopied; + + StringCache(sal_uInt16 size); // throws std::bad_alloc + ~StringCache(); + + const sal_Unicode* getString(sal_uInt16 index); + sal_uInt16 createString(const sal_uInt8* buffer); // throws std::bad_alloc +}; + +StringCache::StringCache(sal_uInt16 size) + : m_stringTable(NULL) + , m_numOfStrings(size) + , m_stringsCopied(0) +{ + m_stringTable = new sal_Unicode*[m_numOfStrings]; + + for (sal_uInt16 i = 0; i < m_numOfStrings; i++) + { + m_stringTable[i] = NULL; + } +} + +StringCache::~StringCache() +{ + if (m_stringTable) + { + for (sal_uInt16 i = 0; i < m_stringsCopied; i++) + { + delete[] m_stringTable[i]; + } + + delete[] m_stringTable; + } +} + +const sal_Unicode* StringCache::getString(sal_uInt16 index) +{ + if ((index > 0) && (index <= m_stringsCopied)) + return m_stringTable[index - 1]; + else + return NULL; +} + +sal_uInt16 StringCache::createString(const sal_uInt8* buffer) +{ + if (m_stringsCopied < m_numOfStrings) + { + sal_uInt32 len = UINT16StringLen(buffer); + + m_stringTable[m_stringsCopied] = new sal_Unicode[len + 1]; + + readString(buffer, m_stringTable[m_stringsCopied], (len + 1) * sizeof(sal_Unicode)); + + return ++m_stringsCopied; + } + else + return 0; +} + +/************************************************************************** + + class ConstantPool + +**************************************************************************/ + +class ConstantPool : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_Int32* m_pIndex; // index values may be < 0 for cached string constants + + StringCache* m_pStringCache; + + ConstantPool(const sal_uInt8* buffer, sal_uInt16 numEntries) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pIndex(NULL) + , m_pStringCache(NULL) + { + } + + ~ConstantPool(); + + sal_uInt32 parseIndex(); // throws std::bad_alloc + + CPInfoTag readTag(sal_uInt16 index); + + const sal_Char* readUTF8NameConstant(sal_uInt16 index); + sal_Bool readBOOLConstant(sal_uInt16 index); + sal_uInt8 readBYTEConstant(sal_uInt16 index); + sal_Int16 readINT16Constant(sal_uInt16 index); + sal_uInt16 readUINT16Constant(sal_uInt16 index); + sal_Int32 readINT32Constant(sal_uInt16 index); + sal_uInt32 readUINT32Constant(sal_uInt16 index); + sal_Int64 readINT64Constant(sal_uInt16 index); + sal_uInt64 readUINT64Constant(sal_uInt16 index); + float readFloatConstant(sal_uInt16 index); + double readDoubleConstant(sal_uInt16 index); + const sal_Unicode* readStringConstant(sal_uInt16 index); + // throws std::bad_alloc + void readUIK(sal_uInt16 index, RTUik* uik); +}; + +ConstantPool::~ConstantPool() +{ + delete[] m_pIndex; + delete m_pStringCache; +} + +sal_uInt32 ConstantPool::parseIndex() +{ + if (m_pIndex) + { + delete[] m_pIndex; + m_pIndex = NULL; + } + + if (m_pStringCache) + { + delete m_pStringCache; + m_pStringCache = NULL; + } + + sal_uInt32 offset = 0; + sal_uInt16 numOfStrings = 0; + + if (m_numOfEntries) + { + m_pIndex = new sal_Int32[m_numOfEntries]; + + for (int i = 0; i < m_numOfEntries; i++) + { + m_pIndex[i] = offset; + + offset += readUINT32(offset); + + if ( ((CPInfoTag) readUINT16(m_pIndex[i] + CP_OFFSET_ENTRY_TAG)) == + CP_TAG_CONST_STRING ) + { + numOfStrings++; + } + + } + } + + if (numOfStrings) + { + m_pStringCache = new StringCache(numOfStrings); + } + + m_bufferLen = offset; + + return offset; +} + +CPInfoTag ConstantPool::readTag(sal_uInt16 index) +{ + CPInfoTag tag = CP_TAG_INVALID; + + if (m_pIndex && (index > 0) && (index <= m_numOfEntries)) + { + tag = (CPInfoTag) readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG); + } + + return tag; +} + +const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index) +{ + const sal_Char* aName = NULL_STRING; + + if (m_pIndex && (index > 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME) + { + aName = (const sal_Char*) (m_pBuffer + m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aName; +} + +sal_Bool ConstantPool::readBOOLConstant(sal_uInt16 index) +{ + sal_Bool aBool = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BOOL) + { + aBool = (sal_Bool) readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aBool; +} + +sal_uInt8 ConstantPool::readBYTEConstant(sal_uInt16 index) +{ + sal_uInt8 aByte = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BYTE) + { + aByte = readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aByte; +} + +sal_Int16 ConstantPool::readINT16Constant(sal_uInt16 index) +{ + sal_Int16 aINT16 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT16) + { + aINT16 = readINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aINT16; +} + +sal_uInt16 ConstantPool::readUINT16Constant(sal_uInt16 index) +{ + sal_uInt16 asal_uInt16 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT16) + { + asal_uInt16 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return asal_uInt16; +} + +sal_Int32 ConstantPool::readINT32Constant(sal_uInt16 index) +{ + sal_Int32 aINT32 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT32) + { + aINT32 = readINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aINT32; +} + +sal_uInt32 ConstantPool::readUINT32Constant(sal_uInt16 index) +{ + sal_uInt32 aUINT32 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT32) + { + aUINT32 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aUINT32; +} + +sal_Int64 ConstantPool::readINT64Constant(sal_uInt16 index) +{ + sal_Int64 aINT64 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT64) + { + aINT64 = readINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aINT64; +} + +sal_uInt64 ConstantPool::readUINT64Constant(sal_uInt16 index) +{ + sal_uInt64 aUINT64 = sal_False; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT64) + { + aUINT64 = readUINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + return aUINT64; +} + +float ConstantPool::readFloatConstant(sal_uInt16 index) +{ + union + { + float v; + sal_uInt32 b; + } x = { 0.0f }; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_FLOAT) + { +#ifdef REGTYPE_IEEE_NATIVE + x.b = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); +#else +# error no IEEE +#endif + } + } + + return x.v; +} + +double ConstantPool::readDoubleConstant(sal_uInt16 index) +{ + union + { + double v; + struct + { + sal_uInt32 b1; + sal_uInt32 b2; + } b; + } x = { 0.0 }; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_DOUBLE) + { + +#ifdef REGTYPE_IEEE_NATIVE +# ifdef OSL_BIGENDIAN + x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32)); +# else + x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32)); + x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); +# endif +#else +# error no IEEE +#endif + } + } + + return x.v; +} + +const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index) +{ + const sal_Unicode* aString = NULL_WSTRING; + + if (m_pIndex && (index> 0) && (index <= m_numOfEntries) && m_pStringCache) + { + if (m_pIndex[index - 1] >= 0) + { + // create cached string now + + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING) + { + m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); + } + } + + aString = m_pStringCache->getString((sal_uInt16) (m_pIndex[index - 1] * -1)); + } + + return aString; +} + +void ConstantPool::readUIK(sal_uInt16 index, RTUik* uik) +{ + if (index == 0) + { + uik->m_Data1 = 0; + uik->m_Data2 = 0; + uik->m_Data3 = 0; + uik->m_Data4 = 0; + uik->m_Data5 = 0; + } + else if (m_pIndex && (index <= m_numOfEntries)) + { + if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UIK) + { + uik->m_Data1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK1); + uik->m_Data2 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK2); + uik->m_Data3 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK3); + uik->m_Data4 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK4); + uik->m_Data5 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK5); + } + } +} + +/************************************************************************** + + class FieldList + +**************************************************************************/ + +class FieldList : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_uInt16 m_numOfFieldEntries; + sal_uInt16 m_FIELD_ENTRY_SIZE; + ConstantPool* m_pCP; + + FieldList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pCP(pCP) + { + if ( m_numOfEntries > 0 ) + { + m_numOfFieldEntries = readUINT16(0); + m_FIELD_ENTRY_SIZE = m_numOfFieldEntries * sizeof(sal_uInt16); + } else + { + m_numOfFieldEntries = 0; + m_FIELD_ENTRY_SIZE = 0; + } + } + + sal_uInt32 parseIndex(); + + const sal_Char* getFieldName(sal_uInt16 index); + const sal_Char* getFieldType(sal_uInt16 index); + RTFieldAccess getFieldAccess(sal_uInt16 index); + RTValueType getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value); + // throws std::bad_alloc + const sal_Char* getFieldDoku(sal_uInt16 index); + const sal_Char* getFieldFileName(sal_uInt16 index); +}; + +sal_uInt32 FieldList::parseIndex() +{ + return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_FIELD_ENTRY_SIZE)); +} + +const sal_Char* FieldList::getFieldName(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME)); + } + + return aName; +} + +const sal_Char* FieldList::getFieldType(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE)); + } + + return aName; +} + +RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) +{ + RTFieldAccess aAccess = RT_ACCESS_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS); + } + + return aAccess; +} + +RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) +{ + RTValueType ret = RT_TYPE_NONE; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE); + + switch (m_pCP->readTag(cpIndex)) + { + case CP_TAG_CONST_BOOL: + value->aBool = m_pCP->readBOOLConstant(cpIndex); + ret = RT_TYPE_BOOL; + break; + case CP_TAG_CONST_BYTE: + value->aByte = m_pCP->readBYTEConstant(cpIndex); + ret = RT_TYPE_BYTE; + break; + case CP_TAG_CONST_INT16: + value->aShort = m_pCP->readINT16Constant(cpIndex); + ret = RT_TYPE_INT16; + break; + case CP_TAG_CONST_UINT16: + value->aUShort = m_pCP->readUINT16Constant(cpIndex); + ret = RT_TYPE_UINT16; + break; + case CP_TAG_CONST_INT32: + value->aLong = m_pCP->readINT32Constant(cpIndex); + ret = RT_TYPE_INT32; + break; + case CP_TAG_CONST_UINT32: + value->aULong = m_pCP->readUINT32Constant(cpIndex); + ret = RT_TYPE_UINT32; + break; + case CP_TAG_CONST_INT64: + value->aHyper = m_pCP->readINT64Constant(cpIndex); + ret = RT_TYPE_INT64; + break; + case CP_TAG_CONST_UINT64: + value->aUHyper = m_pCP->readUINT64Constant(cpIndex); + ret = RT_TYPE_UINT64; + break; + case CP_TAG_CONST_FLOAT: + value->aFloat = m_pCP->readFloatConstant(cpIndex); + ret = RT_TYPE_FLOAT; + break; + case CP_TAG_CONST_DOUBLE: + value->aDouble = m_pCP->readDoubleConstant(cpIndex); + ret = RT_TYPE_DOUBLE; + break; + case CP_TAG_CONST_STRING: + value->aString = m_pCP->readStringConstant(cpIndex); + ret = RT_TYPE_STRING; + break; + default: + break; + } + } + + return ret; +} + +const sal_Char* FieldList::getFieldDoku(sal_uInt16 index) +{ + const sal_Char* aDoku = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU)); + } + + return aDoku; +} + +const sal_Char* FieldList::getFieldFileName(sal_uInt16 index) +{ + const sal_Char* aFileName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME)); + } + + return aFileName; +} + +/************************************************************************** + + class ReferenceList + +**************************************************************************/ + +class ReferenceList : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_uInt16 m_numOfReferenceEntries; + sal_uInt16 m_REFERENCE_ENTRY_SIZE; + ConstantPool* m_pCP; + + ReferenceList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pCP(pCP) + { + if ( m_numOfEntries > 0 ) + { + m_numOfReferenceEntries = readUINT16(0); + m_REFERENCE_ENTRY_SIZE = m_numOfReferenceEntries * sizeof(sal_uInt16); + } else + { + m_numOfReferenceEntries = 0; + m_REFERENCE_ENTRY_SIZE = 0; + } + } + + sal_uInt32 parseIndex(); + + const sal_Char* getReferenceName(sal_uInt16 index); + RTReferenceType getReferenceType(sal_uInt16 index); + const sal_Char* getReferenceDoku(sal_uInt16 index); + RTFieldAccess getReferenceAccess(sal_uInt16 index); +}; + +sal_uInt32 ReferenceList::parseIndex() +{ + return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_REFERENCE_ENTRY_SIZE)); +} + +const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME)); + } + + return aName; +} + +RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index) +{ + RTReferenceType refType = RT_REF_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE); + } + + return refType; +} + +const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index) +{ + const sal_Char* aDoku = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU)); + } + + return aDoku; +} + +RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index) +{ + RTFieldAccess aAccess = RT_ACCESS_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS); + } + + return aAccess; +} + +/************************************************************************** + + class MethodList + +**************************************************************************/ + +class MethodList : public BlopObject +{ +public: + + sal_uInt16 m_numOfEntries; + sal_uInt16 m_numOfMethodEntries; + sal_uInt16 m_numOfParamEntries; + sal_uInt16 m_PARAM_ENTRY_SIZE; + sal_uInt32* m_pIndex; + ConstantPool* m_pCP; + + MethodList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) + : BlopObject(buffer, 0, sal_False) + , m_numOfEntries(numEntries) + , m_pIndex(NULL) + , m_pCP(pCP) + { + if ( m_numOfEntries > 0 ) + { + m_numOfMethodEntries = readUINT16(0); + m_numOfParamEntries = readUINT16(sizeof(sal_uInt16)); + m_PARAM_ENTRY_SIZE = m_numOfParamEntries * sizeof(sal_uInt16); + } else + { + m_numOfMethodEntries = 0; + m_numOfParamEntries = 0; + m_PARAM_ENTRY_SIZE = 0; + } + } + + ~MethodList(); + + sal_uInt32 parseIndex(); // throws std::bad_alloc + + const sal_Char* getMethodName(sal_uInt16 index); + sal_uInt16 getMethodParamCount(sal_uInt16 index); + const sal_Char* getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex); + const sal_Char* getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex); + RTParamMode getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex); + sal_uInt16 getMethodExcCount(sal_uInt16 index); + const sal_Char* getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex); + const sal_Char* getMethodReturnType(sal_uInt16 index); + RTMethodMode getMethodMode(sal_uInt16 index); + const sal_Char* getMethodDoku(sal_uInt16 index); + +private: + sal_uInt16 calcMethodParamIndex( const sal_uInt16 index ); +}; + +MethodList::~MethodList() +{ + if (m_pIndex) delete[] m_pIndex; +} + +sal_uInt16 MethodList::calcMethodParamIndex( const sal_uInt16 index ) +{ + return (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (index * m_PARAM_ENTRY_SIZE)); +} + +sal_uInt32 MethodList::parseIndex() +{ + if (m_pIndex) + { + delete[] m_pIndex; + m_pIndex = NULL; + } + + sal_uInt32 offset = 0; + + if (m_numOfEntries) + { + offset = 2 * sizeof(sal_uInt16); + m_pIndex = new sal_uInt32[m_numOfEntries]; + + for (int i = 0; i < m_numOfEntries; i++) + { + m_pIndex[i] = offset; + + offset += readUINT16(offset); + } + } + + return offset; +} + +const sal_Char* MethodList::getMethodName(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME)); + } + + return aName; +} + +sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) +{ + sal_uInt16 aCount = 0; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT); + } + + return aCount; +} + +const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && + (index <= m_numOfEntries) && + (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) + { + aName = m_pCP->readUTF8NameConstant( + readUINT16( + m_pIndex[index] + + calcMethodParamIndex(paramIndex) + + PARAM_OFFSET_TYPE)); + } + + return aName; +} + +const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && + (index <= m_numOfEntries) && + (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) + { + aName = m_pCP->readUTF8NameConstant( + readUINT16( + m_pIndex[index] + + calcMethodParamIndex(paramIndex) + + PARAM_OFFSET_NAME)); + } + + return aName; +} + +RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) +{ + RTParamMode aMode = RT_PARAM_INVALID; + + if ((m_numOfEntries > 0) && + (index <= m_numOfEntries) && + (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) + { + aMode = (RTParamMode) readUINT16( + m_pIndex[index] + + calcMethodParamIndex(paramIndex) + + PARAM_OFFSET_MODE); + } + + return aMode; +} + +sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index) +{ + sal_uInt16 aCount = 0; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))); + } + + return aCount; +} + +const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)); + + if (excIndex <= readUINT16(excOffset)) + { + aName = m_pCP->readUTF8NameConstant( + readUINT16( + excOffset + + sizeof(sal_uInt16) + + (excIndex * sizeof(sal_uInt16)))); + } + } + + return aName; +} + +const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index) +{ + const sal_Char* aName = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN)); + } + + return aName; +} + +RTMethodMode MethodList::getMethodMode(sal_uInt16 index) +{ + RTMethodMode aMode = RT_MODE_INVALID; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE); + } + + return aMode; +} + +const sal_Char* MethodList::getMethodDoku(sal_uInt16 index) +{ + const sal_Char* aDoku = NULL; + + if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) + { + aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU)); + } + + return aDoku; +} + +/************************************************************************** + + class TypeRegistryEntry + +**************************************************************************/ + +class TypeRegistryEntry: public BlopObject { +public: + ConstantPool* m_pCP; + FieldList* m_pFields; + MethodList* m_pMethods; + ReferenceList* m_pReferences; + sal_uInt32 m_refCount; + sal_uInt16 m_nSuperTypes; + sal_uInt16 m_offset_SUPERTYPES; + + TypeRegistryEntry( + const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer); + // throws std::bad_alloc + + ~TypeRegistryEntry(); + + typereg_Version getVersion() const; +}; + +TypeRegistryEntry::TypeRegistryEntry( + const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer): + BlopObject(buffer, len, copyBuffer), m_pCP(NULL), m_pFields(NULL), + m_pMethods(NULL), m_pReferences(NULL), m_refCount(1), m_nSuperTypes(0), + m_offset_SUPERTYPES(0) +{ + std::size_t const entrySize = sizeof(sal_uInt16); + sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES); + sal_uInt16 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); + m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; + m_nSuperTypes = readUINT16(offset_N_SUPERTYPES); + + sal_uInt16 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); + sal_uInt16 offset_CP = offset_CP_SIZE + entrySize; + + m_pCP = new ConstantPool(m_pBuffer + offset_CP, readUINT16(offset_CP_SIZE)); + + sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); + + m_pFields = new FieldList( + m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); + + offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); + + m_pMethods = new MethodList( + m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); + + offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); + + m_pReferences = new ReferenceList( + m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); + + m_pReferences->parseIndex(); +} + +TypeRegistryEntry::~TypeRegistryEntry() +{ + delete m_pCP; + delete m_pFields; + delete m_pMethods; + delete m_pReferences; +} + +typereg_Version TypeRegistryEntry::getVersion() const { + // Assumes two's complement arithmetic with modulo-semantics: + return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic); +} + +/************************************************************************** + + C-API + +**************************************************************************/ + +extern "C" { + +sal_Bool typereg_reader_create( + void const * buffer, sal_uInt32 length, sal_Bool copy, + typereg_Version maxVersion, void ** result) + SAL_THROW_EXTERN_C() +{ + if (length < OFFSET_CP || length > SAL_MAX_UINT32) { + *result = 0; + return true; + } + std::auto_ptr< TypeRegistryEntry > entry; + try { + entry.reset( + new TypeRegistryEntry( + static_cast< sal_uInt8 const * >(buffer), + static_cast< sal_uInt32 >(length), copy)); + } catch (std::bad_alloc &) { + return false; + } + if (entry->readUINT32(OFFSET_SIZE) != length) { + *result = 0; + return true; + } + typereg_Version version = entry->getVersion(); + if (version < TYPEREG_VERSION_0 || version > maxVersion) { + *result = 0; + return true; + } + *result = entry.release(); + return true; +} + +static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer) +{ + void * handle; + typereg_reader_create(buffer, len, copyBuffer, TYPEREG_VERSION_0, &handle); + return handle; +} + +void typereg_reader_acquire(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry != NULL) + pEntry->m_refCount++; +} + +void typereg_reader_release(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry != NULL) + { + if (--pEntry->m_refCount == 0) + delete pEntry; + } +} + +typereg_Version typereg_reader_getVersion(void * handle) SAL_THROW_EXTERN_C() { + return handle == 0 + ? TYPEREG_VERSION_0 + : static_cast< TypeRegistryEntry * >(handle)->getVersion(); +} + +static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->readUINT16(OFFSET_MINOR_VERSION); +} + +static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->readUINT16(OFFSET_MAJOR_VERSION); +} + +RTTypeClass typereg_reader_getTypeClass(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_TYPE_INVALID; + + return (RTTypeClass) + (pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED); +} + +sal_Bool typereg_reader_isPublished(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry); + return entry != 0 + && (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0; +} + +void typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pTypeName); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE)); + rtl_string2UString( + pTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + + +static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pSuperTypeName); + return; + } + + if (pEntry->m_nSuperTypes == 0) + { + rtl_uString_new(pSuperTypeName); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16)))); + rtl_string2UString( + pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik) +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry != NULL) + { + pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik); + } +} + +void typereg_reader_getDocumentation(void * hEntry, rtl_uString** pDoku) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU)); + rtl_string2UString( + pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFileName); + return; + } + + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME)); + rtl_string2UString( + pFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + + +sal_uInt16 typereg_reader_getFieldCount(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pFields->m_numOfEntries; +} + +static sal_uInt32 TYPEREG_CALLTYPE getFieldCount(TypeReaderImpl hEntry) +{ + return typereg_reader_getFieldCount(hEntry); +} + +void typereg_reader_getFieldName(void * hEntry, rtl_uString** pFieldName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFieldName); + return; + } + const sal_Char* pTmp = pEntry->m_pFields->getFieldName(index); + rtl_string2UString( + pFieldName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getFieldTypeName(void * hEntry, rtl_uString** pFieldType, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFieldType); + return; + } + + const sal_Char* pTmp = pEntry->m_pFields->getFieldType(index); + rtl_string2UString( + pFieldType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTFieldAccess typereg_reader_getFieldFlags(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_ACCESS_INVALID; + + return pEntry->m_pFields->getFieldAccess(index); +} + +sal_Bool typereg_reader_getFieldValue( + void * hEntry, sal_uInt16 index, RTValueType * type, + RTConstValueUnion * value) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) { + *type = RT_TYPE_NONE; + return true; + } + + try { + *type = pEntry->m_pFields->getFieldConstValue(index, value); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static RTValueType TYPEREG_CALLTYPE getFieldConstValue(TypeReaderImpl hEntry, sal_uInt16 index, RTConstValueUnion* value) +{ + RTValueType t = RT_TYPE_NONE; + typereg_reader_getFieldValue(hEntry, index, &t, value); + return t; +} + +void typereg_reader_getFieldDocumentation(void * hEntry, rtl_uString** pDoku, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pFields->getFieldDoku(index); + rtl_string2UString( + pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getFieldFileName(void * hEntry, rtl_uString** pFieldFileName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pFieldFileName); + return; + } + + const sal_Char* pTmp = pEntry->m_pFields->getFieldFileName(index); + rtl_string2UString( + pFieldFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + + +sal_uInt16 typereg_reader_getMethodCount(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pMethods->m_numOfEntries; +} + +static sal_uInt32 TYPEREG_CALLTYPE getMethodCount(TypeReaderImpl hEntry) +{ + return typereg_reader_getMethodCount(hEntry); +} + +void typereg_reader_getMethodName(void * hEntry, rtl_uString** pMethodName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodName); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodName(index); + rtl_string2UString( + pMethodName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +sal_uInt16 typereg_reader_getMethodParameterCount( + void * hEntry, sal_uInt16 index) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pMethods->getMethodParamCount(index); +} + +static sal_uInt32 TYPEREG_CALLTYPE getMethodParamCount(TypeReaderImpl hEntry, sal_uInt16 index) +{ + return typereg_reader_getMethodParameterCount(hEntry, index); +} + +void typereg_reader_getMethodParameterTypeName(void * hEntry, rtl_uString** pMethodParamType, sal_uInt16 index, sal_uInt16 paramIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodParamType); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex); + rtl_string2UString( + pMethodParamType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getMethodParameterName(void * hEntry, rtl_uString** pMethodParamName, sal_uInt16 index, sal_uInt16 paramIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodParamName); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex); + rtl_string2UString( + pMethodParamName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTParamMode typereg_reader_getMethodParameterFlags(void * hEntry, sal_uInt16 index, sal_uInt16 paramIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_PARAM_INVALID; + + return pEntry->m_pMethods->getMethodParamMode(index, paramIndex); +} + +sal_uInt16 typereg_reader_getMethodExceptionCount( + void * hEntry, sal_uInt16 index) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pMethods->getMethodExcCount(index); +} + +static sal_uInt32 TYPEREG_CALLTYPE getMethodExcCount(TypeReaderImpl hEntry, sal_uInt16 index) +{ + return typereg_reader_getMethodExceptionCount(hEntry, index); +} + +void typereg_reader_getMethodExceptionTypeName(void * hEntry, rtl_uString** pMethodExcpType, sal_uInt16 index, sal_uInt16 excIndex) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodExcpType); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex); + rtl_string2UString( + pMethodExcpType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +void typereg_reader_getMethodReturnTypeName(void * hEntry, rtl_uString** pMethodReturnType, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodReturnType); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodReturnType(index); + rtl_string2UString( + pMethodReturnType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTMethodMode typereg_reader_getMethodFlags(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_MODE_INVALID; + + return pEntry->m_pMethods->getMethodMode(index); +} + +void typereg_reader_getMethodDocumentation(void * hEntry, rtl_uString** pMethodDoku, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pMethodDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pMethods->getMethodDoku(index); + rtl_string2UString( + pMethodDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +sal_uInt16 typereg_reader_getReferenceCount(void * hEntry) SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_pReferences->m_numOfEntries; +} + +static sal_uInt32 TYPEREG_CALLTYPE getReferenceCount(TypeReaderImpl hEntry) +{ + return typereg_reader_getReferenceCount(hEntry); +} + +void typereg_reader_getReferenceTypeName(void * hEntry, rtl_uString** pReferenceName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pReferenceName); + return; + } + + const sal_Char* pTmp = pEntry->m_pReferences->getReferenceName(index); + rtl_string2UString( + pReferenceName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTReferenceType typereg_reader_getReferenceSort(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_REF_INVALID; + + return pEntry->m_pReferences->getReferenceType(index); +} + +void typereg_reader_getReferenceDocumentation(void * hEntry, rtl_uString** pReferenceDoku, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pReferenceDoku); + return; + } + + const sal_Char* pTmp = pEntry->m_pReferences->getReferenceDoku(index); + rtl_string2UString( + pReferenceDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RTFieldAccess typereg_reader_getReferenceFlags(void * hEntry, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return RT_ACCESS_INVALID; + + return pEntry->m_pReferences->getReferenceAccess(index); +} + +sal_uInt16 typereg_reader_getSuperTypeCount(void * hEntry) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) return 0; + + return pEntry->m_nSuperTypes; +} + +void typereg_reader_getSuperTypeName( + void * hEntry, rtl_uString ** pSuperTypeName, sal_uInt16 index) + SAL_THROW_EXTERN_C() +{ + TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; + + if (pEntry == NULL) + { + rtl_uString_new(pSuperTypeName); + return; + } + + OSL_ASSERT(index < pEntry->m_nSuperTypes); + const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16)))); + rtl_string2UString( + pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp), + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS); +} + +RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api(void) +{ + static RegistryTypeReader_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + if (!aApi.acquire) + { + aApi.createEntry = &createEntry; + aApi.acquire = &typereg_reader_acquire; + aApi.release = &typereg_reader_release; + aApi.getMinorVersion = &getMinorVersion; + aApi.getMajorVersion = &getMajorVersion; + aApi.getTypeClass = &typereg_reader_getTypeClass; + aApi.getTypeName = &typereg_reader_getTypeName; + aApi.getSuperTypeName = &getSuperTypeName; + aApi.getUik = &getUik; + aApi.getDoku = &typereg_reader_getDocumentation; + aApi.getFileName = &typereg_reader_getFileName; + aApi.getFieldCount = &getFieldCount; + aApi.getFieldName = &typereg_reader_getFieldName; + aApi.getFieldType = &typereg_reader_getFieldTypeName; + aApi.getFieldAccess = &typereg_reader_getFieldFlags; + aApi.getFieldConstValue = &getFieldConstValue; + aApi.getFieldDoku = &typereg_reader_getFieldDocumentation; + aApi.getFieldFileName = &typereg_reader_getFieldFileName; + aApi.getMethodCount = &getMethodCount; + aApi.getMethodName = &typereg_reader_getMethodName; + aApi.getMethodParamCount = &getMethodParamCount; + aApi.getMethodParamType = &typereg_reader_getMethodParameterTypeName; + aApi.getMethodParamName = &typereg_reader_getMethodParameterName; + aApi.getMethodParamMode = &typereg_reader_getMethodParameterFlags; + aApi.getMethodExcCount = &getMethodExcCount; + aApi.getMethodExcType = &typereg_reader_getMethodExceptionTypeName; + aApi.getMethodReturnType = &typereg_reader_getMethodReturnTypeName; + aApi.getMethodMode = &typereg_reader_getMethodFlags; + aApi.getMethodDoku = &typereg_reader_getMethodDocumentation; + aApi.getReferenceCount = &getReferenceCount; + aApi.getReferenceName = &typereg_reader_getReferenceTypeName; + aApi.getReferenceType = &typereg_reader_getReferenceSort; + aApi.getReferenceDoku = &typereg_reader_getReferenceDocumentation; + aApi.getReferenceAccess = &typereg_reader_getReferenceFlags; + + return (&aApi); + } + else + { + return (&aApi); + } +} + +} diff --git a/registry/source/reflwrit.cxx b/registry/source/reflwrit.cxx new file mode 100644 index 000000000000..442951849b02 --- /dev/null +++ b/registry/source/reflwrit.cxx @@ -0,0 +1,1491 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <new> +#include <sal/types.h> +#include <sal/macros.h> +#include <osl/endian.h> +#include <rtl/alloc.h> +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" + +#include "registry/reflwrit.hxx" +#include "registry/version.h" +#include "registry/writer.h" + +#include "reflcnst.hxx" + +using namespace rtl; + +namespace { + +// Throws std::bad_alloc: +inline rtl::OString toByteString(rtl_uString const * str) { + return rtl::OString( + str->buffer, str->length, RTL_TEXTENCODING_UTF8, + OUSTRING_TO_OSTRING_CVTFLAGS); +} + +} + +static sal_Unicode NULL_WSTRING[1] = { 0 }; + +#if defined ( GCC ) && ( defined ( SCO ) ) +ORealDynamicLoader* ODynamicLoader<RegistryTypeWriter_Api>::m_pLoader = NULL; +#endif + +#define BLOP_OFFSET_MAGIC 0 +#define BLOP_OFFSET_SIZE (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32)) +#define BLOP_OFFSET_MINOR (BLOP_OFFSET_SIZE + sizeof(sal_uInt32)) +#define BLOP_OFFSET_MAJOR (BLOP_OFFSET_MINOR + sizeof(sal_uInt16)) +#define BLOP_OFFSET_N_ENTRIES (BLOP_OFFSET_MAJOR + sizeof(sal_uInt16)) +#define BLOP_OFFSET_TYPE_SOURCE (BLOP_OFFSET_N_ENTRIES + sizeof(sal_uInt16)) +#define BLOP_OFFSET_TYPE_CLASS (BLOP_OFFSET_TYPE_SOURCE + sizeof(sal_uInt16)) +#define BLOP_OFFSET_THIS (BLOP_OFFSET_TYPE_CLASS + sizeof(sal_uInt16)) +#define BLOP_OFFSET_UIK (BLOP_OFFSET_THIS + sizeof(sal_uInt16)) +#define BLOP_OFFSET_DOKU (BLOP_OFFSET_UIK + sizeof(sal_uInt16)) +#define BLOP_OFFSET_FILENAME (BLOP_OFFSET_DOKU + sizeof(sal_uInt16)) +#define BLOP_HEADER_N_ENTRIES 6 + +#define BLOP_OFFSET_N_SUPERTYPES 0 +#define BLOP_OFFSET_SUPERTYPES (BLOP_OFFSET_N_SUPERTYPES + sizeof(sal_uInt16)) + +#define BLOP_FIELD_ENTRY_ACCESS 0 +#define BLOP_FIELD_ENTRY_NAME (BLOP_FIELD_ENTRY_ACCESS + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_TYPE (BLOP_FIELD_ENTRY_NAME + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_VALUE (BLOP_FIELD_ENTRY_TYPE + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_DOKU (BLOP_FIELD_ENTRY_VALUE + sizeof(sal_uInt16)) +#define BLOP_FIELD_ENTRY_FILENAME (BLOP_FIELD_ENTRY_DOKU + sizeof(sal_uInt16)) +#define BLOP_FIELD_N_ENTRIES 6 + +#define BLOP_METHOD_SIZE 0 +#define BLOP_METHOD_MODE (BLOP_METHOD_SIZE + sizeof(sal_uInt16)) +#define BLOP_METHOD_NAME (BLOP_METHOD_MODE + sizeof(sal_uInt16)) +#define BLOP_METHOD_RETURN (BLOP_METHOD_NAME + sizeof(sal_uInt16)) +#define BLOP_METHOD_DOKU (BLOP_METHOD_RETURN + sizeof(sal_uInt16)) +#define BLOP_METHOD_N_ENTRIES 5 + +#define BLOP_PARAM_TYPE 0 +#define BLOP_PARAM_MODE (BLOP_PARAM_TYPE + sizeof(sal_uInt16)) +#define BLOP_PARAM_NAME (BLOP_PARAM_MODE + sizeof(sal_uInt16)) +#define BLOP_PARAM_N_ENTRIES 3 + +#define BLOP_REFERENCE_TYPE 0 +#define BLOP_REFERENCE_NAME (BLOP_REFERENCE_TYPE + sizeof(sal_uInt16)) +#define BLOP_REFERENCE_DOKU (BLOP_REFERENCE_NAME + sizeof(sal_uInt16)) +#define BLOP_REFERENCE_ACCESS (BLOP_REFERENCE_DOKU + sizeof(sal_uInt16)) +#define BLOP_REFERENCE_N_ENTRIES 4 + +sal_uInt32 UINT16StringLen(const sal_uInt8* wstring) +{ + if (!wstring) return 0; + + const sal_uInt8* b = wstring; + + while (b[0] || b[1]) b += sizeof(sal_uInt16); + + return ((b - wstring) / sizeof(sal_uInt16)); +} + +sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v) +{ + sal_uInt32 len = rtl_ustr_getLength(v) + 1; + sal_uInt32 i; + sal_uInt8* buff = buffer; + + for (i = 0; i < len; i++) + { + buff += writeUINT16(buff, (sal_uInt16) v[i]); + } + + return (buff - buffer); +} + +sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize) +{ + sal_uInt32 len = SAL_MIN(UINT16StringLen(buffer) + 1, maxSize / 2); + sal_uInt32 i; + sal_uInt8* buff = (sal_uInt8*)buffer; + + for (i = 0; i < (len - 1); i++) + { + sal_uInt16 aChar; + + buff += readUINT16(buff, aChar); + + v[i] = (sal_Unicode) aChar; + } + + v[len - 1] = L'\0'; + + return (buff - ((sal_uInt8*)buffer)); +} + +sal_uInt32 writeFloat(sal_uInt8* buffer, float v) +{ + union + { + float v; + sal_uInt32 b; + } x; + + x.v = v; + +#ifdef REGTYPE_IEEE_NATIVE + writeUINT32(buffer, x.b); +#else +# error no IEEE +#endif + + return sizeof(sal_uInt32); +} + +sal_uInt32 writeDouble(sal_uInt8* buffer, double v) +{ + union + { + double v; + struct + { + sal_uInt32 b1; + sal_uInt32 b2; + } b; + } x; + + x.v = v; + +#ifdef REGTYPE_IEEE_NATIVE +# ifdef OSL_BIGENDIAN + writeUINT32(buffer, x.b.b1); + writeUINT32(buffer + sizeof(sal_uInt32), x.b.b2); +# else + writeUINT32(buffer, x.b.b2); + writeUINT32(buffer + sizeof(sal_uInt32), x.b.b1); +# endif +#else +# error no IEEE +#endif + + return (sizeof(sal_uInt32) + sizeof(sal_uInt32)); +} + +/************************************************************************** + + buffer write functions + +**************************************************************************/ + + +/************************************************************************** + + struct CPInfo + +**************************************************************************/ + +struct CPInfo +{ + CPInfoTag m_tag; + union + { + const sal_Char* aUtf8; + RTUik* aUik; + RTConstValueUnion aConst; + } m_value; + + sal_uInt16 m_index; + struct CPInfo* m_next; + + CPInfo(CPInfoTag tag, struct CPInfo* prev); + + sal_uInt32 getBlopSize(); + + sal_uInt32 toBlop(sal_uInt8* buffer); +}; + +CPInfo::CPInfo(CPInfoTag tag, struct CPInfo* prev) + : m_tag(tag) + , m_index(0) + , m_next(NULL) +{ + if (prev) + { + m_index = prev->m_index + 1; + prev->m_next = this; + } +} + +sal_uInt32 CPInfo::getBlopSize() +{ + sal_uInt32 size = sizeof(sal_uInt32) /* size */ + sizeof(sal_uInt16) /* tag */; + + switch (m_tag) + { + case CP_TAG_CONST_BOOL: + size += sizeof(sal_uInt8); + break; + case CP_TAG_CONST_BYTE: + size += sizeof(sal_uInt8); + break; + case CP_TAG_CONST_INT16: + size += sizeof(sal_Int16); + break; + case CP_TAG_CONST_UINT16: + size += sizeof(sal_uInt16); + break; + case CP_TAG_CONST_INT32: + size += sizeof(sal_Int32); + break; + case CP_TAG_CONST_UINT32: + size += sizeof(sal_uInt32); + break; + case CP_TAG_CONST_INT64: + size += sizeof(sal_Int64); + break; + case CP_TAG_CONST_UINT64: + size += sizeof(sal_uInt64); + break; + case CP_TAG_CONST_FLOAT: + size += sizeof(sal_uInt32); + break; + case CP_TAG_CONST_DOUBLE: + size += sizeof(sal_uInt32) + sizeof(sal_uInt32); + break; + case CP_TAG_CONST_STRING: + size += (rtl_ustr_getLength(m_value.aConst.aString) + 1) * sizeof(sal_uInt16); + break; + case CP_TAG_UTF8_NAME: + size += strlen(m_value.aUtf8) + 1; + break; + case CP_TAG_UIK: + size += sizeof(sal_uInt32) + sizeof(sal_uInt16) + sizeof(sal_uInt16) + sizeof(sal_uInt32) + sizeof(sal_uInt32); + break; + default: + break; + } + + return size; +} + + +sal_uInt32 CPInfo::toBlop(sal_uInt8* buffer) +{ + sal_uInt8* buff = buffer; + + buff += writeUINT32(buff, getBlopSize()); + buff += writeUINT16(buff, (sal_uInt16) m_tag); + + switch (m_tag) + { + case CP_TAG_CONST_BOOL: + buff += writeBYTE(buff, (sal_uInt8) m_value.aConst.aBool); + break; + case CP_TAG_CONST_BYTE: + buff += writeBYTE(buff, m_value.aConst.aByte); + break; + case CP_TAG_CONST_INT16: + buff += writeINT16(buff, m_value.aConst.aShort); + break; + case CP_TAG_CONST_UINT16: + buff += writeINT16(buff, m_value.aConst.aUShort); + break; + case CP_TAG_CONST_INT32: + buff += writeINT32(buff, m_value.aConst.aLong); + break; + case CP_TAG_CONST_UINT32: + buff += writeUINT32(buff, m_value.aConst.aULong); + break; + case CP_TAG_CONST_INT64: + buff += writeUINT64(buff, m_value.aConst.aHyper); + break; + case CP_TAG_CONST_UINT64: + buff += writeUINT64(buff, m_value.aConst.aUHyper); + break; + case CP_TAG_CONST_FLOAT: + buff += writeFloat(buff, m_value.aConst.aFloat); + break; + case CP_TAG_CONST_DOUBLE: + buff += writeDouble(buff, m_value.aConst.aDouble); + break; + case CP_TAG_CONST_STRING: + buff += writeString(buff, m_value.aConst.aString); + break; + case CP_TAG_UTF8_NAME: + buff += writeUtf8(buff, m_value.aUtf8); + break; + case CP_TAG_UIK: + buff += writeUINT32(buff, m_value.aUik->m_Data1); + buff += writeUINT16(buff, m_value.aUik->m_Data2); + buff += writeUINT16(buff, m_value.aUik->m_Data3); + buff += writeUINT32(buff, m_value.aUik->m_Data4); + buff += writeUINT32(buff, m_value.aUik->m_Data5); + break; + default: + break; + } + + return (buff - buffer); +} + + +/************************************************************************** + + class FieldEntry + +**************************************************************************/ + +class FieldEntry +{ + +public: + + OString m_name; + OString m_typeName; + OString m_doku; + OString m_fileName; + RTFieldAccess m_access; + RTValueType m_constValueType; + RTConstValueUnion m_constValue; + + FieldEntry(); + ~FieldEntry(); + + void setData(const OString& name, + const OString& typeName, + const OString& doku, + const OString& fileName, + RTFieldAccess access, + RTValueType constValueType, + RTConstValueUnion constValue); + // throws std::bad_alloc +}; + +FieldEntry::FieldEntry() + : m_access(RT_ACCESS_INVALID) + , m_constValueType(RT_TYPE_NONE) +{ +} + +FieldEntry::~FieldEntry() +{ + if ( + (m_constValueType == RT_TYPE_STRING) && + m_constValue.aString && + (m_constValue.aString != NULL_WSTRING) + ) + { + delete[] (sal_Unicode*)m_constValue.aString; + } +} + +void FieldEntry::setData(const OString& name, + const OString& typeName, + const OString& doku, + const OString& fileName, + RTFieldAccess access, + RTValueType constValueType, + RTConstValueUnion constValue) +{ + sal_Unicode * newValue = 0; + if (constValueType == RT_TYPE_STRING && constValue.aString != 0) { + sal_Int32 n = rtl_ustr_getLength(constValue.aString) + 1; + newValue = new sal_Unicode[n]; + rtl_copyMemory(newValue, constValue.aString, n * sizeof (sal_Unicode)); + } + + m_name = name; + m_typeName = typeName; + m_doku = doku; + m_fileName = fileName; + + if ( + (m_constValueType == RT_TYPE_STRING) && + m_constValue.aString && + (m_constValue.aString != NULL_WSTRING) + ) + { + delete[] (sal_Unicode*)m_constValue.aString; + } + + m_access = access; + m_constValueType = constValueType; + + if (m_constValueType == RT_TYPE_STRING) + { + if (constValue.aString == NULL) + m_constValue.aString = NULL_WSTRING; + else + { + m_constValue.aString = newValue; + } + } + else + { + m_constValue = constValue; + } +} + +/************************************************************************** + + class ParamEntry + +**************************************************************************/ + +class ParamEntry +{ +public: + + OString m_typeName; + OString m_name; + RTParamMode m_mode; + + ParamEntry(); + ~ParamEntry(); + + void setData(const OString& typeName, + const OString& name, + RTParamMode mode); +}; + +ParamEntry::ParamEntry() + : m_mode(RT_PARAM_INVALID) +{ +} + +ParamEntry::~ParamEntry() +{ +} + +void ParamEntry::setData(const OString& typeName, + const OString& name, + RTParamMode mode) +{ + m_name = name; + m_typeName = typeName; + m_mode = mode; +} + +/************************************************************************** + + class ReferenceEntry + +**************************************************************************/ + +class ReferenceEntry +{ +public: + + OString m_name; + OString m_doku; + RTReferenceType m_type; + RTFieldAccess m_access; + + ReferenceEntry(); + ~ReferenceEntry(); + + void setData(const OString& name, + RTReferenceType refType, + const OString& doku, + RTFieldAccess access); +}; + +ReferenceEntry::ReferenceEntry() + : m_type(RT_REF_INVALID) + , m_access(RT_ACCESS_INVALID) +{ +} + +ReferenceEntry::~ReferenceEntry() +{ +} + +void ReferenceEntry::setData(const OString& name, + RTReferenceType refType, + const OString& doku, + RTFieldAccess access) +{ + m_name = name; + m_doku = doku; + m_type = refType; + m_access = access; +} + +/************************************************************************** + + class MethodEntry + +**************************************************************************/ + +class MethodEntry +{ +public: + + OString m_name; + OString m_returnTypeName; + RTMethodMode m_mode; + sal_uInt16 m_paramCount; + ParamEntry* m_params; + sal_uInt16 m_excCount; + OString* m_excNames; + OString m_doku; + + MethodEntry(); + ~MethodEntry(); + + void setData(const OString& name, + const OString& returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + const OString& doku); + + void setExcName(sal_uInt16 excIndex, const OString& name); + +protected: + + void reallocParams(sal_uInt16 size); + void reallocExcs(sal_uInt16 size); +}; + +MethodEntry::MethodEntry() + : m_mode(RT_MODE_INVALID) + , m_paramCount(0) + , m_params(NULL) + , m_excCount(0) + , m_excNames(NULL) +{ +} + +MethodEntry::~MethodEntry() +{ + if (m_params) + delete[] m_params; + + if (m_excNames) + delete[] m_excNames; +} + +void MethodEntry::setData(const OString& name, + const OString& returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + const OString& doku) +{ + m_name = name; + m_returnTypeName = returnTypeName; + m_doku = doku; + + m_mode = mode; + + reallocParams(paramCount); + reallocExcs(excCount); +} + +void MethodEntry::setExcName(sal_uInt16 excIndex, const OString& name) +{ + if (excIndex < m_excCount) + { + m_excNames[excIndex] = name; + } +} + +void MethodEntry::reallocParams(sal_uInt16 size) +{ + ParamEntry* newParams; + + if (size) + newParams = new ParamEntry[size]; + else + newParams = NULL; + + if (m_paramCount) + { + sal_uInt16 i; + + for (i = 0; i < SAL_MIN(size, m_paramCount); i++) + { + newParams[i].setData(m_params[i].m_typeName, m_params[i].m_name, m_params[i].m_mode); + } + + delete[] m_params; + } + + m_paramCount = size; + m_params = newParams; +} + +void MethodEntry::reallocExcs(sal_uInt16 size) +{ + OString* newExcNames; + + if (size) + newExcNames = new OString[size]; + else + newExcNames = NULL; + + sal_uInt16 i; + + for (i = 0; i < SAL_MIN(size, m_excCount); i++) + { + newExcNames[i] = m_excNames[i]; + } + + delete[] m_excNames; + + m_excCount = size; + m_excNames = newExcNames; +} + + +/************************************************************************** + + class TypeRegistryEntry + +**************************************************************************/ + +class TypeWriter +{ + +public: + + sal_uInt32 m_refCount; + typereg_Version m_version; + RTTypeClass m_typeClass; + OString m_typeName; + sal_uInt16 m_nSuperTypes; + OString* m_superTypeNames; + RTUik* m_pUik; + OString m_doku; + OString m_fileName; + sal_uInt16 m_fieldCount; + FieldEntry* m_fields; + sal_uInt16 m_methodCount; + MethodEntry* m_methods; + sal_uInt16 m_referenceCount; + ReferenceEntry* m_references; + + sal_uInt8* m_blop; + sal_uInt32 m_blopSize; + + TypeWriter(typereg_Version version, + rtl::OString const & documentation, + rtl::OString const & fileName, + RTTypeClass RTTypeClass, + bool published, + const OString& typeName, + sal_uInt16 superTypeCount, + sal_uInt16 FieldCount, + sal_uInt16 methodCount, + sal_uInt16 referenceCount); + + ~TypeWriter(); + + void setSuperType(sal_uInt16 index, OString const & name); + + void createBlop(); // throws std::bad_alloc +}; + +TypeWriter::TypeWriter(typereg_Version version, + rtl::OString const & documentation, + rtl::OString const & fileName, + RTTypeClass RTTypeClass, + bool published, + const OString& typeName, + sal_uInt16 superTypeCount, + sal_uInt16 fieldCount, + sal_uInt16 methodCount, + sal_uInt16 referenceCount) + : m_refCount(1) + , m_version(version) + , m_typeClass( + static_cast< enum RTTypeClass >( + RTTypeClass | (published ? RT_TYPE_PUBLISHED : 0))) + , m_typeName(typeName) + , m_nSuperTypes(superTypeCount) + , m_pUik(NULL) + , m_doku(documentation) + , m_fileName(fileName) + , m_fieldCount(fieldCount) + , m_methodCount(methodCount) + , m_referenceCount(referenceCount) + , m_blop(NULL) + , m_blopSize(0) +{ + if (m_nSuperTypes > 0) + { + m_superTypeNames = new OString[m_nSuperTypes]; + } else + { + m_superTypeNames = NULL; + } + + if (m_fieldCount) + m_fields = new FieldEntry[fieldCount]; + + if (m_methodCount) + m_methods = new MethodEntry[methodCount]; + + if (m_referenceCount) + m_references = new ReferenceEntry[referenceCount]; +} + +TypeWriter::~TypeWriter() +{ + if (m_superTypeNames) + delete[] m_superTypeNames; + + if (m_blop) + delete[] m_blop; + + if (m_fieldCount) + delete[] m_fields; + + if (m_methodCount) + delete[] m_methods; + + if (m_referenceCount) + delete[] m_references; + + if (m_pUik) + delete m_pUik; +} + +void TypeWriter::setSuperType(sal_uInt16 index, OString const & name) +{ + m_superTypeNames[index] = name; +} + +void TypeWriter::createBlop() +{ + //TODO: Fix memory leaks that occur when std::bad_alloc is thrown + + sal_uInt8* pBlopFields = NULL; + sal_uInt8* pBlopMethods = NULL; + sal_uInt8* pBlopReferences = NULL; + sal_uInt8* pBuffer = NULL; + sal_uInt32 blopFieldsSize = 0; + sal_uInt32 blopMethodsSize = 0; + sal_uInt32 blopReferenceSize = 0; + + CPInfo root(CP_TAG_INVALID, NULL); + sal_uInt16 cpIndexThisName = 0; + sal_uInt16* cpIndexSuperNames = NULL; + sal_uInt16 cpIndexUik = 0; + sal_uInt16 cpIndexDoku = 0; + sal_uInt16 cpIndexFileName = 0; + CPInfo* pInfo = NULL; + + sal_uInt16 entrySize = sizeof(sal_uInt16); + sal_uInt32 blopHeaderEntrySize = BLOP_OFFSET_N_ENTRIES + entrySize + (BLOP_HEADER_N_ENTRIES * entrySize); + sal_uInt32 blopFieldEntrySize = BLOP_FIELD_N_ENTRIES * entrySize; + sal_uInt32 blopMethodEntrySize = BLOP_METHOD_N_ENTRIES * entrySize; + sal_uInt32 blopParamEntrySize = BLOP_PARAM_N_ENTRIES * entrySize; + sal_uInt32 blopReferenceEntrySize = BLOP_REFERENCE_N_ENTRIES * entrySize; + + sal_uInt32 blopSize = blopHeaderEntrySize; + + // create CP entry for this name + pInfo = new CPInfo(CP_TAG_UTF8_NAME, &root); + pInfo->m_value.aUtf8 = m_typeName.getStr(); + cpIndexThisName = pInfo->m_index; + + // nSuperTypes + blopSize += entrySize; + + // create CP entry for super names + if (m_nSuperTypes) + { + blopSize += m_nSuperTypes * entrySize; + + cpIndexSuperNames = new sal_uInt16[m_nSuperTypes]; + + for (sal_uInt32 i=0; i < m_nSuperTypes; i++) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_superTypeNames[i].getStr(); + cpIndexSuperNames[i] = pInfo->m_index; + } + } + + // create CP entry for uik + if (m_pUik != NULL) + { + pInfo = new CPInfo(CP_TAG_UIK, pInfo); + pInfo->m_value.aUik = m_pUik; + cpIndexUik = pInfo->m_index; + } + + // create CP entry for doku + if (m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_doku.getStr(); + cpIndexDoku = pInfo->m_index; + } + + // create CP entry for idl source filename + if (m_fileName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fileName.getStr(); + cpIndexFileName = pInfo->m_index; + } + + // fields blop + blopSize += sizeof(sal_uInt16); // fieldCount + nFieldEntries + + if (m_fieldCount) + { + sal_uInt16 cpIndexName = 0; + sal_uInt16 cpIndexTypeName = 0; + sal_uInt16 cpIndexValue = 0; + sal_uInt16 cpIndexDoku2 = 0; + sal_uInt16 cpIndexFileName2 = 0; + + // nFieldEntries + n fields + blopFieldsSize = sizeof(sal_uInt16) + (m_fieldCount * blopFieldEntrySize); + + blopSize += blopFieldsSize; + + pBlopFields = new sal_uInt8[blopFieldsSize]; + pBuffer = pBlopFields; + + pBuffer += writeUINT16(pBuffer, BLOP_FIELD_N_ENTRIES); + + for (sal_uInt16 i = 0; i < m_fieldCount; i++) + { + cpIndexName = 0; + cpIndexTypeName = 0; + cpIndexValue = 0; + cpIndexDoku2 = 0; + cpIndexFileName2 = 0; + + pBuffer += writeUINT16(pBuffer, m_fields[i].m_access); + + if (m_fields[i].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + + if (m_fields[i].m_typeName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_typeName.getStr(); + cpIndexTypeName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexTypeName); + + if (m_fields[i].m_constValueType != RT_TYPE_NONE) + { + pInfo = new CPInfo((CPInfoTag)m_fields[i].m_constValueType, pInfo); + pInfo->m_value.aConst = m_fields[i].m_constValue; + cpIndexValue = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexValue); + + if (m_fields[i].m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_doku.getStr(); + cpIndexDoku2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexDoku2); + + if (m_fields[i].m_fileName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_fields[i].m_fileName.getStr(); + cpIndexFileName2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexFileName2); + } + } + + // methods blop + blopSize += sizeof(sal_uInt16); // methodCount + + if (m_methodCount) + { + sal_uInt16* pMethodEntrySize = new sal_uInt16[m_methodCount]; + sal_uInt16 cpIndexName = 0; + sal_uInt16 cpIndexReturn = 0; + sal_uInt16 cpIndexDoku2 = 0; + + // nMethodEntries + nParamEntries + blopMethodsSize = (2 * sizeof(sal_uInt16)); + + for (sal_uInt16 i = 0; i < m_methodCount; i++) + { + pMethodEntrySize[i] = (sal_uInt16) + ( blopMethodEntrySize + // header + sizeof(sal_uInt16) + // parameterCount + (m_methods[i].m_paramCount * blopParamEntrySize) + // exceptions + sizeof(sal_uInt16) + // exceptionCount + (m_methods[i].m_excCount * sizeof(sal_uInt16)) ); // exceptions + + blopMethodsSize += pMethodEntrySize[i]; + } + + pBlopMethods = new sal_uInt8[blopMethodsSize]; + + blopSize += blopMethodsSize; + + pBuffer = pBlopMethods; + + pBuffer += writeUINT16(pBuffer, BLOP_METHOD_N_ENTRIES); + pBuffer += writeUINT16(pBuffer, BLOP_PARAM_N_ENTRIES ); + + for (sal_uInt16 i = 0; i < m_methodCount; i++) + { + cpIndexReturn = 0; + cpIndexDoku2 = 0; + + pBuffer += writeUINT16(pBuffer, pMethodEntrySize[i]); + pBuffer += writeUINT16( + pBuffer, + sal::static_int_cast< sal_uInt16 >(m_methods[i].m_mode)); + + if (m_methods[i].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + + if (m_methods[i].m_returnTypeName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_returnTypeName.getStr(); + cpIndexReturn = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexReturn); + + if (m_methods[i].m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_doku.getStr(); + cpIndexDoku2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexDoku2); + + sal_uInt16 j; + + pBuffer += writeUINT16(pBuffer, m_methods[i].m_paramCount); + + for (j = 0; j < m_methods[i].m_paramCount; j++) + { + if (m_methods[i].m_params[j].m_typeName.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_typeName.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + + pBuffer += writeUINT16( + pBuffer, + sal::static_int_cast< sal_uInt16 >( + m_methods[i].m_params[j].m_mode)); + + if (m_methods[i].m_params[j].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + } + + pBuffer += writeUINT16(pBuffer, m_methods[i].m_excCount); + + for (j = 0; j < m_methods[i].m_excCount; j++) + { + if (m_methods[i].m_excNames[j].getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_methods[i].m_excNames[j].getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + cpIndexName = 0; + } + } + + delete[] pMethodEntrySize; + } + + // reference blop + blopSize += entrySize; // referenceCount + + if (m_referenceCount) + { + sal_uInt16 cpIndexName = 0; + sal_uInt16 cpIndexDoku2 = 0; + + // nReferenceEntries + n references + blopReferenceSize = entrySize + (m_referenceCount * blopReferenceEntrySize); + + blopSize += blopReferenceSize; + + pBlopReferences = new sal_uInt8[blopReferenceSize]; + pBuffer = pBlopReferences; + + pBuffer += writeUINT16(pBuffer, BLOP_REFERENCE_N_ENTRIES); + + for (sal_uInt16 i = 0; i < m_referenceCount; i++) + { + pBuffer += writeUINT16( + pBuffer, + sal::static_int_cast< sal_uInt16 >(m_references[i].m_type)); + + cpIndexName = 0; + cpIndexDoku2 = 0; + + if (m_references[i].m_name.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_references[i].m_name.getStr(); + cpIndexName = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexName); + + if (m_references[i].m_doku.getLength()) + { + pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); + pInfo->m_value.aUtf8 = m_references[i].m_doku.getStr(); + cpIndexDoku2 = pInfo->m_index; + } + pBuffer += writeUINT16(pBuffer, cpIndexDoku2); + + pBuffer += writeUINT16(pBuffer, m_references[i].m_access); + } + } + + + // get CP infos blop-length + pInfo = root.m_next; + sal_uInt32 cpBlopSize = 0; + sal_uInt16 cpCount = 0; + + while (pInfo) + { + cpBlopSize += pInfo->getBlopSize(); + cpCount++; + pInfo = pInfo->m_next; + } + + blopSize += cpBlopSize; + blopSize += sizeof(sal_uInt16); // constantPoolCount + + // write all in flat buffer + + sal_uInt8 * blop = new sal_uInt8[blopSize]; + + pBuffer = blop; + + // Assumes two's complement arithmetic with modulo-semantics: + pBuffer += writeUINT32(pBuffer, magic + m_version); + pBuffer += writeUINT32(pBuffer, blopSize); + pBuffer += writeUINT16(pBuffer, minorVersion); + pBuffer += writeUINT16(pBuffer, majorVersion); + pBuffer += writeUINT16(pBuffer, BLOP_HEADER_N_ENTRIES); + + pBuffer += writeUINT16(pBuffer, (sal_uInt16)RT_UNO_IDL); + pBuffer += writeUINT16(pBuffer, (sal_uInt16)m_typeClass); + pBuffer += writeUINT16(pBuffer, cpIndexThisName); + pBuffer += writeUINT16(pBuffer, cpIndexUik); + pBuffer += writeUINT16(pBuffer, cpIndexDoku); + pBuffer += writeUINT16(pBuffer, cpIndexFileName); + + // write supertypes + pBuffer += writeUINT16(pBuffer, m_nSuperTypes); + if (m_nSuperTypes) + { + for (sal_uInt32 i=0; i < m_nSuperTypes; i++) + { + pBuffer += writeUINT16(pBuffer, cpIndexSuperNames[i]); + } + delete[] cpIndexSuperNames; + } + + pBuffer += writeUINT16(pBuffer, cpCount); + + // write and delete CP infos + pInfo = root.m_next; + + while (pInfo) + { + CPInfo* pNextInfo = pInfo->m_next; + + pBuffer += pInfo->toBlop(pBuffer); + delete pInfo; + + pInfo = pNextInfo; + } + + // write fields + pBuffer += writeUINT16(pBuffer, m_fieldCount); + if (blopFieldsSize) + { + memcpy(pBuffer, pBlopFields, blopFieldsSize); + pBuffer += blopFieldsSize; + } + + // write methods + pBuffer += writeUINT16(pBuffer, m_methodCount); + if (blopMethodsSize) + { + memcpy(pBuffer, pBlopMethods, blopMethodsSize); + pBuffer += blopMethodsSize; + } + + // write references + pBuffer += writeUINT16(pBuffer, m_referenceCount); + if (blopReferenceSize) + { + memcpy(pBuffer, pBlopReferences, blopReferenceSize); + pBuffer += blopReferenceSize; + } + + delete[] pBlopFields; + delete[] pBlopMethods; + delete[] pBlopReferences; + + delete[] m_blop; + m_blop = blop; + m_blopSize = blopSize; +} + + +/************************************************************************** + + C-API + +**************************************************************************/ + +extern "C" { + +static void TYPEREG_CALLTYPE acquire(TypeWriterImpl hEntry) +{ + TypeWriter* pEntry = (TypeWriter*) hEntry; + + if (pEntry != NULL) + pEntry->m_refCount++; +} + +static void TYPEREG_CALLTYPE release(TypeWriterImpl hEntry) +{ + TypeWriter* pEntry = (TypeWriter*) hEntry; + + if (pEntry != NULL) + { + if (--pEntry->m_refCount == 0) + delete pEntry; + } +} + +static void TYPEREG_CALLTYPE setUik(TypeWriterImpl hEntry, const RTUik* uik) +{ + TypeWriter* pEntry = (TypeWriter*) hEntry; + + if (pEntry != NULL) + { + if (pEntry->m_pUik) + { + pEntry->m_pUik->m_Data1 = uik->m_Data1; + pEntry->m_pUik->m_Data2 = uik->m_Data2; + pEntry->m_pUik->m_Data3 = uik->m_Data3; + pEntry->m_pUik->m_Data4 = uik->m_Data4; + pEntry->m_pUik->m_Data5 = uik->m_Data5; + } + else + pEntry->m_pUik = new RTUik(*uik); + } +} + +static void TYPEREG_CALLTYPE setDoku(TypeWriterImpl hEntry, rtl_uString* doku) +{ + static_cast< TypeWriter * >(hEntry)->m_doku = toByteString(doku); +} + +static void TYPEREG_CALLTYPE setFileName(TypeWriterImpl hEntry, rtl_uString* fileName) +{ + static_cast< TypeWriter * >(hEntry)->m_fileName = toByteString(fileName); +} + +sal_Bool typereg_writer_setFieldData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name, + rtl_uString const * typeName, RTValueType valueType, + RTConstValueUnion valueValue) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_fields[index].setData( + toByteString(name), toByteString(typeName), + toByteString(documentation), toByteString(fileName), flags, + valueType, valueValue); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setFieldData(TypeWriterImpl hEntry, + sal_uInt16 index, + rtl_uString* name, + rtl_uString* typeName, + rtl_uString* doku, + rtl_uString* fileName, + RTFieldAccess access, + RTValueType valueType, + RTConstValueUnion constValue) +{ + typereg_writer_setFieldData( + hEntry, index, doku, fileName, access, name, typeName, valueType, + constValue); +} + +sal_Bool typereg_writer_setMethodData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + RTMethodMode flags, rtl_uString const * name, + rtl_uString const * returnTypeName, sal_uInt16 parameterCount, + sal_uInt16 exceptionCount) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_methods[index].setData( + toByteString(name), toByteString(returnTypeName), flags, + parameterCount, exceptionCount, toByteString(documentation)); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setMethodData(TypeWriterImpl hEntry, + sal_uInt16 index, + rtl_uString* name, + rtl_uString* returnTypeName, + RTMethodMode mode, + sal_uInt16 paramCount, + sal_uInt16 excCount, + rtl_uString* doku) +{ + typereg_writer_setMethodData( + hEntry, index, doku, mode, name, returnTypeName, paramCount, excCount); +} + +sal_Bool typereg_writer_setMethodParameterData( + void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex, + RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)-> + m_methods[methodIndex].m_params[parameterIndex].setData( + toByteString(typeName), toByteString(name), flags); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setParamData(TypeWriterImpl hEntry, + sal_uInt16 index, + sal_uInt16 paramIndex, + rtl_uString* type, + rtl_uString* name, + RTParamMode mode) +{ + typereg_writer_setMethodParameterData( + hEntry, index, paramIndex, mode, name, type); +} + +sal_Bool typereg_writer_setMethodExceptionTypeName( + void * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex, + rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_methods[methodIndex].setExcName( + exceptionIndex, toByteString(typeName)); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setExcData(TypeWriterImpl hEntry, + sal_uInt16 index, + sal_uInt16 excIndex, + rtl_uString* type) +{ + typereg_writer_setMethodExceptionTypeName(hEntry, index, excIndex, type); +} + +void const * typereg_writer_getBlob(void * handle, sal_uInt32 * size) + SAL_THROW_EXTERN_C() +{ + TypeWriter * writer = static_cast< TypeWriter * >(handle); + if (writer->m_blop == 0) { + try { + writer->createBlop(); + } catch (std::bad_alloc &) { + return 0; + } + } + *size = writer->m_blopSize; + return writer->m_blop; +} + +static const sal_uInt8* TYPEREG_CALLTYPE getBlop(TypeWriterImpl hEntry) +{ + sal_uInt32 size; + return static_cast< sal_uInt8 const * >( + typereg_writer_getBlob(hEntry, &size)); +} + +static sal_uInt32 TYPEREG_CALLTYPE getBlopSize(TypeWriterImpl hEntry) +{ + sal_uInt32 size; + typereg_writer_getBlob(hEntry, &size); + return size; +} + +sal_Bool typereg_writer_setReferenceData( + void * handle, sal_uInt16 index, rtl_uString const * documentation, + RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->m_references[index].setData( + toByteString(typeName), sort, toByteString(documentation), flags); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static void TYPEREG_CALLTYPE setReferenceData(TypeWriterImpl hEntry, + sal_uInt16 index, + rtl_uString* name, + RTReferenceType refType, + rtl_uString* doku, + RTFieldAccess access) +{ + typereg_writer_setReferenceData(hEntry, index, doku, refType, access, name); +} + +void * typereg_writer_create( + typereg_Version version, rtl_uString const * documentation, + rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published, + rtl_uString const * typeName, sal_uInt16 superTypeCount, + sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount) + SAL_THROW_EXTERN_C() +{ + try { + return new TypeWriter( + version, toByteString(documentation), toByteString(fileName), + typeClass, published, toByteString(typeName), superTypeCount, + fieldCount, methodCount, referenceCount); + } catch (std::bad_alloc &) { + return 0; + } +} + +void typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C() { + delete static_cast< TypeWriter * >(handle); +} + +sal_Bool typereg_writer_setSuperTypeName( + void * handle, sal_uInt16 index, rtl_uString const * typeName) + SAL_THROW_EXTERN_C() +{ + try { + static_cast< TypeWriter * >(handle)->setSuperType( + index, toByteString(typeName)); + } catch (std::bad_alloc &) { + return false; + } + return true; +} + +static TypeWriterImpl TYPEREG_CALLTYPE createEntry( + RTTypeClass typeClass, rtl_uString * typeName, rtl_uString * superTypeName, + sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount) +{ + rtl::OUString empty; + sal_uInt16 superTypeCount = rtl_uString_getLength(superTypeName) == 0 + ? 0 : 1; + TypeWriterImpl t = typereg_writer_create( + TYPEREG_VERSION_0, empty.pData, empty.pData, typeClass, false, typeName, + superTypeCount, fieldCount, methodCount, referenceCount); + if (superTypeCount > 0) { + typereg_writer_setSuperTypeName(t, 0, superTypeName); + } + return t; +} + +RegistryTypeWriter_Api* TYPEREG_CALLTYPE initRegistryTypeWriter_Api(void) +{ + static RegistryTypeWriter_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0}; + if (!aApi.acquire) + { + aApi.createEntry = &createEntry; + aApi.acquire = &acquire; + aApi.release = &release; + aApi.setUik = &setUik; + aApi.setDoku = &setDoku; + aApi.setFileName = &setFileName; + aApi.setFieldData = &setFieldData; + aApi.setMethodData = &setMethodData; + aApi.setParamData = &setParamData; + aApi.setExcData = &setExcData; + aApi.getBlop = &getBlop; + aApi.getBlopSize = &getBlopSize; + aApi.setReferenceData = &setReferenceData; + + return (&aApi); + } + else + { + return (&aApi); + } +} + +} diff --git a/registry/source/regimpl.cxx b/registry/source/regimpl.cxx new file mode 100644 index 000000000000..2d3322c25b13 --- /dev/null +++ b/registry/source/regimpl.cxx @@ -0,0 +1,1760 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include "regimpl.hxx" + +#include <memory> +#include <string.h> +#include <stdio.h> + +#if defined(UNX) || defined(OS2) +#include <unistd.h> +#endif +#ifdef __MINGW32__ +#include <unistd.h> +#endif + +#ifndef __REGISTRY_REFLREAD_HXX__ +#include <registry/reflread.hxx> +#endif + +#ifndef __REGISTRY_REFLWRIT_HXX__ +#include <registry/reflwrit.hxx> +#endif + +#include "registry/reader.hxx" +#include "registry/refltype.hxx" +#include "registry/types.h" +#include "registry/version.h" + +#include "reflcnst.hxx" +#include "keyimpl.hxx" + +#include <osl/thread.h> +#include <rtl/alloc.h> +#include <rtl/memory.h> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/file.hxx> + +using namespace rtl; +using namespace osl; +using namespace store; + +#if defined ( GCC ) && ( defined ( SCO ) ) +sal_helper::ORealDynamicLoader* sal_helper::ODynamicLoader<RegistryTypeReader_Api>::m_pLoader = NULL; +#endif + +namespace { + +void printString(rtl::OUString const & s) { + printf("\""); + for (sal_Int32 i = 0; i < s.getLength(); ++i) { + sal_Unicode c = s[i]; + if (c == '"' || c == '\\') { + printf("\\%c", static_cast< char >(c)); + } else if (s[i] >= ' ' && s[i] <= '~') { + printf("%c", static_cast< char >(c)); + } else { + printf("\\u%04X", static_cast< unsigned int >(c)); + } + } + printf("\""); +} + +void printFieldOrReferenceFlag( + RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first) +{ + if ((*flags & flag) != 0) { + if (!*first) { + printf("|"); + } + *first = false; + printf("%s", name); + *flags &= ~flag; + } +} + +void printFieldOrReferenceFlags(RTFieldAccess flags) { + if (flags == 0) { + printf("none"); + } else { + bool first = true; + printFieldOrReferenceFlag( + &flags, RT_ACCESS_READONLY, "readonly", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_OPTIONAL, "optional", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_MAYBEVOID, "maybevoid", &first); + printFieldOrReferenceFlag(&flags, RT_ACCESS_BOUND, "bound", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_CONSTRAINED, "constrained", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_TRANSIENT, "transient", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_MAYBEAMBIGUOUS, "maybeambiguous", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_MAYBEDEFAULT, "maybedefault", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_REMOVEABLE, "removeable", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_ATTRIBUTE, "attribute", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_PROPERTY, "property", &first); + printFieldOrReferenceFlag(&flags, RT_ACCESS_CONST, "const", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_READWRITE, "readwrite", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_PARAMETERIZED_TYPE, "parameterized type", &first); + printFieldOrReferenceFlag( + &flags, RT_ACCESS_PUBLISHED, "published", &first); + if (flags != 0) { + if (!first) { + printf("|"); + } + printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags)); + } + } +} + +void dumpType(typereg::Reader const & reader, rtl::OString const & indent) { + if (reader.isValid()) { + printf("version: %ld\n", static_cast< long >(reader.getVersion())); + printf("%sdocumentation: ", indent.getStr()); + printString(reader.getDocumentation()); + printf("\n"); + printf("%sfile name: ", indent.getStr()); + printString(reader.getFileName()); + printf("\n"); + printf("%stype class: ", indent.getStr()); + if (reader.isPublished()) { + printf("published "); + } + switch (reader.getTypeClass()) { + case RT_TYPE_INTERFACE: + printf("interface"); + break; + + case RT_TYPE_MODULE: + printf("module"); + break; + + case RT_TYPE_STRUCT: + printf("struct"); + break; + + case RT_TYPE_ENUM: + printf("enum"); + break; + + case RT_TYPE_EXCEPTION: + printf("exception"); + break; + + case RT_TYPE_TYPEDEF: + printf("typedef"); + break; + + case RT_TYPE_SERVICE: + printf("service"); + break; + + case RT_TYPE_SINGLETON: + printf("singleton"); + break; + + case RT_TYPE_CONSTANTS: + printf("constants"); + break; + + default: + printf( + "<invalid (%ld)>", static_cast< long >(reader.getTypeClass())); + break; + } + printf("\n"); + printf("%stype name: ", indent.getStr()); + printString(reader.getTypeName()); + printf("\n"); + printf( + "%ssuper type count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getSuperTypeCount())); + {for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) { + printf( + "%ssuper type name %u: ", indent.getStr(), + static_cast< unsigned int >(i)); + printString(reader.getSuperTypeName(i)); + printf("\n"); + }} + printf( + "%sfield count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getFieldCount())); + {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { + printf( + "%sfield %u:\n", indent.getStr(), + static_cast< unsigned int >(i)); + printf("%s documentation: ", indent.getStr()); + printString(reader.getFieldDocumentation(i)); + printf("\n"); + printf("%s file name: ", indent.getStr()); + printString(reader.getFieldFileName(i)); + printf("\n"); + printf("%s flags: ", indent.getStr()); + printFieldOrReferenceFlags(reader.getFieldFlags(i)); + printf("\n"); + printf("%s name: ", indent.getStr()); + printString(reader.getFieldName(i)); + printf("\n"); + printf("%s type name: ", indent.getStr()); + printString(reader.getFieldTypeName(i)); + printf("\n"); + printf("%s value: ", indent.getStr()); + RTConstValue value(reader.getFieldValue(i)); + switch (value.m_type) { + case RT_TYPE_NONE: + printf("none"); + break; + + case RT_TYPE_BOOL: + printf("boolean %s", value.m_value.aBool ? "true" : "false"); + break; + + case RT_TYPE_BYTE: + printf( + "byte 0x%02X", + static_cast< unsigned int >(value.m_value.aByte)); + break; + + case RT_TYPE_INT16: + printf("short %d", static_cast< int >(value.m_value.aShort)); + break; + + case RT_TYPE_UINT16: + printf( + "unsigned short %u", + static_cast< unsigned int >(value.m_value.aUShort)); + break; + + case RT_TYPE_INT32: + printf("long %ld", static_cast< long >(value.m_value.aLong)); + break; + + case RT_TYPE_UINT32: + printf( + "unsigned long %lu", + static_cast< unsigned long >(value.m_value.aULong)); + break; + + case RT_TYPE_INT64: + // TODO: no portable way to print hyper values + printf("hyper"); + break; + + case RT_TYPE_UINT64: + // TODO: no portable way to print unsigned hyper values + printf("unsigned hyper"); + break; + + case RT_TYPE_FLOAT: + // TODO: no portable way to print float values + printf("float"); + break; + + case RT_TYPE_DOUBLE: + // TODO: no portable way to print double values + printf("double"); + break; + + case RT_TYPE_STRING: + printf("string "); + printString(value.m_value.aString); + break; + + default: + printf("<invalid (%ld)>", static_cast< long >(value.m_type)); + break; + } + printf("\n"); + }} + printf( + "%smethod count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getMethodCount())); + {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) { + printf( + "%smethod %u:\n", indent.getStr(), + static_cast< unsigned int >(i)); + printf("%s documentation: ", indent.getStr()); + printString(reader.getMethodDocumentation(i)); + printf("\n"); + printf("%s flags: ", indent.getStr()); + switch (reader.getMethodFlags(i)) { + case RT_MODE_ONEWAY: + printf("oneway"); + break; + + case RT_MODE_TWOWAY: + printf("synchronous"); + break; + + case RT_MODE_ATTRIBUTE_GET: + printf("attribute get"); + break; + + case RT_MODE_ATTRIBUTE_SET: + printf("attribute set"); + break; + + default: + printf( + "<invalid (%ld)>", + static_cast< long >(reader.getMethodFlags(i))); + break; + } + printf("\n"); + printf("%s name: ", indent.getStr()); + printString(reader.getMethodName(i)); + printf("\n"); + printf("%s return type name: ", indent.getStr()); + printString(reader.getMethodReturnTypeName(i)); + printf("\n"); + printf( + "%s parameter count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getMethodParameterCount(i))); + for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j) + { + printf( + "%s parameter %u:\n", indent.getStr(), + static_cast< unsigned int >(j)); + printf("%s flags: ", indent.getStr()); + RTParamMode flags = reader.getMethodParameterFlags(i, j); + bool rest = (flags & RT_PARAM_REST) != 0; + switch (flags & ~RT_PARAM_REST) { + case RT_PARAM_IN: + printf("in"); + break; + + case RT_PARAM_OUT: + printf("out"); + break; + + case RT_PARAM_INOUT: + printf("inout"); + break; + + default: + printf("<invalid (%ld)>", static_cast< long >(flags)); + rest = false; + break; + } + if (rest) { + printf("|rest"); + } + printf("\n"); + printf("%s name: ", indent.getStr()); + printString(reader.getMethodParameterName(i, j)); + printf("\n"); + printf("%s type name: ", indent.getStr()); + printString(reader.getMethodParameterTypeName(i, j)); + printf("\n"); + } + printf( + "%s exception count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getMethodExceptionCount(i))); + for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j) + { + printf( + "%s exception type name %u: ", indent.getStr(), + static_cast< unsigned int >(j)); + printString(reader.getMethodExceptionTypeName(i, j)); + printf("\n"); + } + }} + printf( + "%sreference count: %u\n", indent.getStr(), + static_cast< unsigned int >(reader.getReferenceCount())); + {for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) { + printf( + "%sreference %u:\n", indent.getStr(), + static_cast< unsigned int >(i)); + printf("%s documentation: ", indent.getStr()); + printString(reader.getReferenceDocumentation(i)); + printf("\n"); + printf("%s flags: ", indent.getStr()); + printFieldOrReferenceFlags(reader.getReferenceFlags(i)); + printf("\n"); + printf("%s sort: ", indent.getStr()); + switch (reader.getReferenceSort(i)) { + case RT_REF_SUPPORTS: + printf("supports"); + break; + + case RT_REF_EXPORTS: + printf("exports"); + break; + + case RT_REF_TYPE_PARAMETER: + printf("type parameter"); + break; + + default: + printf( + "<invalid (%ld)>", + static_cast< long >(reader.getReferenceSort(i))); + break; + } + printf("\n"); + printf("%s type name: ", indent.getStr()); + printString(reader.getReferenceTypeName(i)); + printf("\n"); + }} + } else { + printf("<invalid>\n"); + } +} + +} + +//********************************************************************* +// ORegistry() +// +ORegistry::ORegistry() + : m_refCount(1) + , m_readOnly(sal_False) + , m_isOpen(sal_False) + , ROOT( RTL_CONSTASCII_USTRINGPARAM("/") ) +{ +} + +//********************************************************************* +// ~ORegistry() +// +ORegistry::~ORegistry() +{ + ORegKey* pRootKey = m_openKeyTable[ROOT]; + if (pRootKey != 0) + (void) releaseKey(pRootKey); + + if (m_file.isValid()) + m_file.close(); +} + + +//********************************************************************* +// initRegistry +// +RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode) +{ + OStoreFile rRegFile; + storeAccessMode sAccessMode = REG_MODE_OPEN; + storeError errCode; + + if (accessMode & REG_CREATE) + { + sAccessMode = REG_MODE_CREATE; + } else + if (accessMode & REG_READONLY) + { + sAccessMode = REG_MODE_OPENREAD; + m_readOnly = sal_True; + } + + if (0 == regName.getLength() && + store_AccessCreate == sAccessMode) + { + errCode = rRegFile.createInMemory(); + } + else + { + errCode = rRegFile.create(regName, sAccessMode, REG_PAGESIZE); + } + + if (errCode) + { + switch (errCode) + { + case store_E_NotExists: + return REG_REGISTRY_NOT_EXISTS; + case store_E_LockingViolation: + return REG_CANNOT_OPEN_FOR_READWRITE; + default: + return REG_INVALID_REGISTRY; + } + } else + { + OStoreDirectory rStoreDir; + storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode); + + if ( _err == store_E_None ) + { + m_file = rRegFile; + m_name = regName; + m_isOpen = sal_True; + + m_openKeyTable[ROOT] = new ORegKey(ROOT, this); + return REG_NO_ERROR; + } else + return REG_INVALID_REGISTRY; + } +} + + +//********************************************************************* +// closeRegistry +// +RegError ORegistry::closeRegistry() +{ + REG_GUARD(m_mutex); + + if (m_file.isValid()) + { + (void) releaseKey(m_openKeyTable[ROOT]); + m_file.close(); + m_isOpen = sal_False; + return REG_NO_ERROR; + } else + { + return REG_REGISTRY_NOT_EXISTS; + } +} + + +//********************************************************************* +// destroyRegistry +// +RegError ORegistry::destroyRegistry(const OUString& regName) +{ + REG_GUARD(m_mutex); + + if (regName.getLength()) + { + ORegistry* pReg = new ORegistry(); + + if (!pReg->initRegistry(regName, REG_READWRITE)) + { + delete pReg; + + OUString systemName; + if ( FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None ) + systemName = regName; + + OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) ); + if (unlink(name) != 0) + { + return REG_DESTROY_REGISTRY_FAILED; + } + } else + { + return REG_DESTROY_REGISTRY_FAILED; + } + } else + { + if (m_refCount != 1 || isReadOnly()) + { + return REG_DESTROY_REGISTRY_FAILED; + } + + if (m_file.isValid()) + { + releaseKey(m_openKeyTable[ROOT]); + m_file.close(); + m_isOpen = sal_False; + + if (m_name.getLength()) + { + OUString systemName; + if ( FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None ) + systemName = m_name; + + OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) ); + if (unlink(name.getStr()) != 0) + { + return REG_DESTROY_REGISTRY_FAILED; + } + } + } else + { + return REG_REGISTRY_NOT_EXISTS; + } + } + + return REG_NO_ERROR; +} + +//********************************************************************* +// acquireKey +// +RegError ORegistry::acquireKey (RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + REG_GUARD(m_mutex); + pKey->acquire(); + + return REG_NO_ERROR; +} + +//********************************************************************* +// releaseKey +// +RegError ORegistry::releaseKey (RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + REG_GUARD(m_mutex); + if (pKey->release() == 0) + { + m_openKeyTable.erase(pKey->getName()); + delete pKey; + } + return REG_NO_ERROR; +} + +//********************************************************************* +// createKey +// +RegError ORegistry::createKey(RegKeyHandle hKey, const OUString& keyName, + RegKeyHandle* phNewKey) +{ + ORegKey* pKey; + + *phNewKey = NULL; + + if ( !keyName.getLength() ) + return REG_INVALID_KEYNAME; + + REG_GUARD(m_mutex); + + if (hKey) + pKey = (ORegKey*)hKey; + else + pKey = m_openKeyTable[ROOT]; + + OUString sFullKeyName = pKey->getFullPath(keyName); + + if (m_openKeyTable.count(sFullKeyName) > 0) + { + *phNewKey = m_openKeyTable[sFullKeyName]; + ((ORegKey*)*phNewKey)->acquire(); + ((ORegKey*)*phNewKey)->setDeleted(sal_False); + return REG_NO_ERROR; + } + + OStoreDirectory rStoreDir; + OUStringBuffer sFullPath(sFullKeyName.getLength()); + OUString token; + + sFullPath.append((sal_Unicode)'/'); + + sal_Int32 nIndex = 0; + do + { + token = sFullKeyName.getToken( 0, '/', nIndex ); + if (token.getLength()) + { + if (rStoreDir.create(pKey->getStoreFile(), sFullPath.getStr(), token, KEY_MODE_CREATE)) + { + return REG_CREATE_KEY_FAILED; + } + + sFullPath.append(token); + sFullPath.append((sal_Unicode)'/'); + } + } while( nIndex != -1 ); + + + pKey = new ORegKey(sFullKeyName, this); + *phNewKey = pKey; + m_openKeyTable[sFullKeyName] = pKey; + + return REG_NO_ERROR; +} + + +//********************************************************************* +// openKey +// +RegError ORegistry::openKey(RegKeyHandle hKey, const OUString& keyName, + RegKeyHandle* phOpenKey) +{ + ORegKey* pKey; + + *phOpenKey = NULL; + + if ( !keyName.getLength() ) + { + return REG_INVALID_KEYNAME; + } + + REG_GUARD(m_mutex); + + if (hKey) + pKey = (ORegKey*)hKey; + else + pKey = m_openKeyTable[ROOT]; + + OUString path(pKey->getFullPath(keyName)); + KeyMap::iterator i(m_openKeyTable.find(path)); + if (i == m_openKeyTable.end()) { + sal_Int32 n = path.lastIndexOf('/') + 1; + switch (OStoreDirectory().create( + pKey->getStoreFile(), path.copy(0, n), path.copy(n), + isReadOnly() ? KEY_MODE_OPENREAD : KEY_MODE_OPEN)) + { + case store_E_NotExists: + return REG_KEY_NOT_EXISTS; + case store_E_WrongFormat: + return REG_INVALID_KEY; + default: + break; + } + + std::auto_ptr< ORegKey > p(new ORegKey(path, this)); + i = m_openKeyTable.insert(std::make_pair(path, p.get())).first; + p.release(); + } else { + i->second->acquire(); + } + *phOpenKey = i->second; + return REG_NO_ERROR; +} + + +//********************************************************************* +// closeKey +// +RegError ORegistry::closeKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + + REG_GUARD(m_mutex); + + OUString const aKeyName (pKey->getName()); + if (!(m_openKeyTable.count(aKeyName) > 0)) + return REG_KEY_NOT_OPEN; + + if (pKey->isModified()) + { + ORegKey * pRootKey = getRootKey(); + if (pKey != pRootKey) + { + // propagate "modified" state to RootKey. + pRootKey->setModified(); + } + else + { + // closing modified RootKey, flush registry file. + OSL_TRACE("registry::ORegistry::closeKey(): flushing modified RootKey"); + (void) m_file.flush(); + } + pKey->setModified(false); + (void) releaseKey(pRootKey); + } + + return releaseKey(pKey); +} + +//********************************************************************* +// deleteKey +// +RegError ORegistry::deleteKey(RegKeyHandle hKey, const OUString& keyName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if ( !keyName.getLength() ) + return REG_INVALID_KEYNAME; + + REG_GUARD(m_mutex); + + if (!pKey) + pKey = m_openKeyTable[ROOT]; + + OUString sFullKeyName(pKey->getFullPath(keyName)); + return eraseKey(m_openKeyTable[ROOT], sFullKeyName); +} + +RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName) +{ + RegError _ret = REG_NO_ERROR; + + if ( !keyName.getLength() ) + { + return REG_INVALID_KEYNAME; + } + + OUString sFullKeyName(pKey->getName()); + OUString sFullPath(sFullKeyName); + OUString sRelativKey; + sal_Int32 lastIndex = keyName.lastIndexOf('/'); + + if ( lastIndex >= 0 ) + { + sRelativKey += keyName.copy(lastIndex + 1); + + if (sFullKeyName.getLength() > 1) + sFullKeyName += keyName; + else + sFullKeyName += (keyName+1); + + sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1); + } else + { + if (sFullKeyName.getLength() > 1) + sFullKeyName += ROOT; + + sRelativKey += keyName; + sFullKeyName += keyName; + + if (sFullPath.getLength() > 1) + sFullPath += ROOT; + } + + ORegKey* pOldKey = 0; + _ret = pKey->openKey(keyName, (RegKeyHandle*)&pOldKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = deleteSubkeysAndValues(pOldKey); + if (_ret != REG_NO_ERROR) + { + pKey->closeKey(pOldKey); + return _ret; + } + + OUString tmpName(sRelativKey); + tmpName += ROOT; + + OStoreFile sFile(pKey->getStoreFile()); + if ( sFile.isValid() && sFile.remove(sFullPath, tmpName) ) + { + return REG_DELETE_KEY_FAILED; + } + pOldKey->setModified(); + + // set flag deleted !!! + pOldKey->setDeleted(sal_True); + + return pKey->closeKey(pOldKey); +} + +//********************************************************************* +// deleteSubKeysAndValues +// +RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey) +{ + OStoreDirectory::iterator iter; + RegError _ret = REG_NO_ERROR; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + while ( _err == store_E_None ) + { + OUString const keyName = iter.m_pszName; + + if (iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + _ret = eraseKey(pKey, keyName); + if (_ret) + return _ret; + } + else + { + OUString sFullPath(pKey->getName()); + + if (sFullPath.getLength() > 1) + sFullPath += ROOT; + + if ( ((OStoreFile&)pKey->getStoreFile()).remove(sFullPath, keyName) ) + { + return REG_DELETE_VALUE_FAILED; + } + pKey->setModified(); + } + + _err = rStoreDir.next(iter); + } + + return REG_NO_ERROR; +} + + +//********************************************************************* +// loadKey +// +RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName, + sal_Bool bWarnings, sal_Bool bReport) +{ + RegError _ret = REG_NO_ERROR; + ORegKey* pKey = static_cast< ORegKey* >(hKey); + + std::auto_ptr< ORegistry > pReg (new ORegistry()); + _ret = pReg->initRegistry(regFileName, REG_READONLY); + if (_ret != REG_NO_ERROR) + return _ret; + ORegKey* pRootKey = pReg->getRootKey(); + + REG_GUARD(m_mutex); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pRootKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + while ( _err == store_E_None ) + { + OUString const keyName = iter.m_pszName; + + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport); + } + else + { + _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport); + } + + if (_ret == REG_MERGE_ERROR) + break; + if (_ret == REG_MERGE_CONFLICT && bWarnings) + break; + + _err = rStoreDir.next(iter); + } + + rStoreDir = OStoreDirectory(); + (void) pReg->releaseKey(pRootKey); + return _ret; +} + + +//********************************************************************* +// saveKey +// +RegError ORegistry::saveKey(RegKeyHandle hKey, const OUString& regFileName, + sal_Bool bWarnings, sal_Bool bReport) +{ + RegError _ret = REG_NO_ERROR; + ORegKey* pKey = static_cast< ORegKey* >(hKey); + + std::auto_ptr< ORegistry > pReg (new ORegistry()); + _ret = pReg->initRegistry(regFileName, REG_CREATE); + if (_ret != REG_NO_ERROR) + return _ret; + ORegKey* pRootKey = pReg->getRootKey(); + + REG_GUARD(m_mutex); + + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + while ( _err == store_E_None ) + { + OUString const keyName = iter.m_pszName; + + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + _ret = loadAndSaveKeys(pRootKey, pKey, keyName, + pKey->getName().getLength(), + bWarnings, bReport); + } + else + { + _ret = loadAndSaveValue(pRootKey, pKey, keyName, + pKey->getName().getLength(), + bWarnings, bReport); + } + + if (_ret != REG_NO_ERROR) + break; + + _err = rStoreDir.next(iter); + } + + (void) pReg->releaseKey(pRootKey); + return _ret; +} + + +//********************************************************************* +// loadAndSaveValue() +// +RegError ORegistry::loadAndSaveValue(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const OUString& valueName, + sal_uInt32 nCut, + sal_Bool bWarnings, + sal_Bool bReport) +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + RegValueType valueType; + sal_uInt32 valueSize; + sal_uInt32 nSize; + storeAccessMode sourceAccess = VALUE_MODE_OPEN; + OUString sTargetPath(pTargetKey->getName()); + OUString sSourcePath(pSourceKey->getName()); + + if (pSourceKey->isReadOnly()) + { + sourceAccess = VALUE_MODE_OPENREAD; + } + + if (nCut) + { + sTargetPath = sSourcePath.copy(nCut); + } else + { + if (sTargetPath.getLength() > 1) + { + if (sSourcePath.getLength() > 1) + sTargetPath += sSourcePath; + } else + sTargetPath = sSourcePath; + } + + if (sTargetPath.getLength() > 1) sTargetPath += ROOT; + if (sSourcePath.getLength() > 1) sSourcePath += ROOT; + + if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess)) + { + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 rwBytes; + if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != VALUE_HEADERSIZE) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + RegError _ret = REG_NO_ERROR; + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + rtl_freeMemory(pBuffer); + + nSize = VALUE_HEADERSIZE + valueSize; + pBuffer = (sal_uInt8*)rtl_allocateMemory(nSize); + + if (rValue.readAt(0, pBuffer, nSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != nSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + OStoreFile rTargetFile(pTargetKey->getStoreFile()); + + if (!rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_OPEN)) + { + if (valueType == RG_VALUETYPE_BINARY) + { + _ret = checkBlop( + rValue, sTargetPath, valueSize, pBuffer+VALUE_HEADEROFFSET, + bReport); + if (_ret) + { + if (_ret == REG_MERGE_ERROR || + (_ret == REG_MERGE_CONFLICT && bWarnings)) + { + rtl_freeMemory(pBuffer); + return _ret; + } + } else + { + rtl_freeMemory(pBuffer); + return _ret; + } + } + } + + // write + if (rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_CREATE)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rValue.writeAt(0, pBuffer, nSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + if (rwBytes != nSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + pTargetKey->setModified(); + + rtl_freeMemory(pBuffer); + return _ret; +} + + +//********************************************************************* +// checkblop() +// +RegError ORegistry::checkBlop(OStoreStream& rValue, + const OUString& sTargetPath, + sal_uInt32 srcValueSize, + sal_uInt8* pSrcBuffer, + sal_Bool bReport) +{ + RegistryTypeReader reader(pSrcBuffer, srcValueSize, sal_False); + + if (reader.getTypeClass() == RT_TYPE_INVALID) + { + return REG_INVALID_VALUE; + } + + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + RegValueType valueType; + sal_uInt32 valueSize; + sal_uInt32 rwBytes; + OString targetPath( OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8) ); + + if (!rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes) && + (rwBytes == VALUE_HEADERSIZE)) + { + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + rtl_freeMemory(pBuffer); + + if (valueType == RG_VALUETYPE_BINARY) + { + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (!rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes) && + (rwBytes == valueSize)) + { + RegistryTypeReader reader2(pBuffer, valueSize, sal_False); + + if ((reader.getTypeClass() != reader2.getTypeClass()) + || reader2.getTypeClass() == RT_TYPE_INVALID) + { + rtl_freeMemory(pBuffer); + + if (bReport) + { + fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n", + targetPath.getStr()); + } + return REG_MERGE_ERROR; + } + + if (reader.getTypeClass() == RT_TYPE_MODULE) + { + if (reader.getFieldCount() > 0 && + reader2.getFieldCount() > 0) + { + mergeModuleValue(rValue, reader, reader2); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; + } else + if (reader2.getFieldCount() > 0) + { + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; + } else + { + rtl_freeMemory(pBuffer); + return REG_MERGE_CONFLICT; + } + } else + { + rtl_freeMemory(pBuffer); + + if (bReport) + { + fprintf(stdout, "WARNING: value of key \"%s\" already exists.\n", + targetPath.getStr()); + } + return REG_MERGE_CONFLICT; + } + } else + { + rtl_freeMemory(pBuffer); + if (bReport) + { + fprintf(stdout, "ERROR: values of key \"%s\" contains bad data.\n", + targetPath.getStr()); + } + return REG_MERGE_ERROR; + } + } else + { + rtl_freeMemory(pBuffer); + if (bReport) + { + fprintf(stdout, "ERROR: values of key \"%s\" has different types.\n", + targetPath.getStr()); + } + return REG_MERGE_ERROR; + } + } else + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } +} + +static sal_uInt32 checkTypeReaders(RegistryTypeReader& reader1, + RegistryTypeReader& reader2, + std::set< OUString >& nameSet) +{ + sal_uInt32 count=0; + sal_uInt16 i; + for (i=0 ; i < reader1.getFieldCount(); i++) + { + nameSet.insert(reader1.getFieldName(i)); + count++; + } + for (i=0 ; i < reader2.getFieldCount(); i++) + { + if (nameSet.find(reader2.getFieldName(i)) == nameSet.end()) + { + nameSet.insert(reader2.getFieldName(i)); + count++; + } + } + return count; +} + +//********************************************************************* +// mergeModuleValue() +// +RegError ORegistry::mergeModuleValue(OStoreStream& rTargetValue, + RegistryTypeReader& reader, + RegistryTypeReader& reader2) +{ + sal_uInt16 index = 0; + + std::set< OUString > nameSet; + sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet); + + if (count != reader.getFieldCount()) + { + RegistryTypeWriter writer(reader.getTypeClass(), + reader.getTypeName(), + reader.getSuperTypeName(), + (sal_uInt16)count, + 0, + 0); + + sal_uInt16 i; + for (i=0 ; i < reader.getFieldCount(); i++) + { + writer.setFieldData(index, + reader.getFieldName(i), + reader.getFieldType(i), + reader.getFieldDoku(i), + reader.getFieldFileName(i), + reader.getFieldAccess(i), + reader.getFieldConstValue(i)); + index++; + } + for (i=0 ; i < reader2.getFieldCount(); i++) + { + if (nameSet.find(reader2.getFieldName(i)) == nameSet.end()) + { + writer.setFieldData(index, + reader2.getFieldName(i), + reader2.getFieldType(i), + reader2.getFieldDoku(i), + reader2.getFieldFileName(i), + reader2.getFieldAccess(i), + reader2.getFieldConstValue(i)); + index++; + } + } + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_BINARY; + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + aBlopSize); + + rtl_copyMemory(pBuffer, &type, 1); + writeUINT32(pBuffer+VALUE_TYPEOFFSET, aBlopSize); + rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, pBlop, aBlopSize); + + sal_uInt32 rwBytes; + if (rTargetValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+aBlopSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + if (rwBytes != VALUE_HEADERSIZE+aBlopSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + rtl_freeMemory(pBuffer); + } + return REG_NO_ERROR; +} + +//********************************************************************* +// loadAndSaveKeys() +// +RegError ORegistry::loadAndSaveKeys(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const OUString& keyName, + sal_uInt32 nCut, + sal_Bool bWarnings, + sal_Bool bReport) +{ + RegError _ret = REG_NO_ERROR; + OUString sRelPath(pSourceKey->getName().copy(nCut)); + OUString sFullPath; + + if(pTargetKey->getName().getLength() > 1) + sFullPath += pTargetKey->getName(); + sFullPath += sRelPath; + if (sRelPath.getLength() > 1 || sFullPath.getLength() == 0) + sFullPath += ROOT; + + OUString sFullKeyName = sFullPath; + sFullKeyName += keyName; + + OStoreDirectory rStoreDir; + if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, KEY_MODE_CREATE)) + { + return REG_CREATE_KEY_FAILED; + } + + if (m_openKeyTable.count(sFullKeyName) > 0) + { + m_openKeyTable[sFullKeyName]->setDeleted(sal_False); + } + + ORegKey* pTmpKey = 0; + _ret = pSourceKey->openKey(keyName, (RegKeyHandle*)&pTmpKey); + if (_ret != REG_NO_ERROR) + return _ret; + + OStoreDirectory::iterator iter; + OStoreDirectory rTmpStoreDir(pTmpKey->getStoreDir()); + storeError _err = rTmpStoreDir.first(iter); + + while ( _err == store_E_None) + { + OUString const sName = iter.m_pszName; + + if (iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + _ret = loadAndSaveKeys(pTargetKey, pTmpKey, + sName, nCut, bWarnings, bReport); + } else + { + _ret = loadAndSaveValue(pTargetKey, pTmpKey, + sName, nCut, bWarnings, bReport); + } + + if (_ret == REG_MERGE_ERROR) + break; + if (_ret == REG_MERGE_CONFLICT && bWarnings) + break; + + _err = rTmpStoreDir.next(iter); + } + + pSourceKey->releaseKey(pTmpKey); + return _ret; +} + + +//********************************************************************* +// getRootKey() +// +ORegKey* ORegistry::getRootKey() +{ + m_openKeyTable[ROOT]->acquire(); + return m_openKeyTable[ROOT]; +} + + +//********************************************************************* +// dumpRegistry() +// +RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const +{ + ORegKey *pKey = (ORegKey*)hKey; + OUString sName; + RegError _ret = REG_NO_ERROR; + OStoreDirectory::iterator iter; + OStoreDirectory rStoreDir(pKey->getStoreDir()); + storeError _err = rStoreDir.first(iter); + + OString regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) ); + OString keyName( OUStringToOString( pKey->getName(), RTL_TEXTENCODING_UTF8 ) ); + fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr()); + + while ( _err == store_E_None ) + { + sName = iter.m_pszName; + + if (iter.m_nAttrib & STORE_ATTRIB_ISDIR) + { + _ret = dumpKey(pKey->getName(), sName, 1); + } else + { + _ret = dumpValue(pKey->getName(), sName, 1); + } + + if (_ret) + { + return _ret; + } + + _err = rStoreDir.next(iter); + } + + return REG_NO_ERROR; +} + +//********************************************************************* +// dumpValue() +// +RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const +{ + OStoreStream rValue; + sal_uInt8* pBuffer; + sal_uInt32 valueSize; + RegValueType valueType; + OUString sFullPath(sPath); + OString sIndent; + storeAccessMode accessMode = VALUE_MODE_OPEN; + + if (isReadOnly()) + { + accessMode = VALUE_MODE_OPENREAD; + } + + for (int i= 0; i < nSpc; i++) sIndent += " "; + + if (sFullPath.getLength() > 1) + { + sFullPath += ROOT; + } + if (rValue.create(m_file, sFullPath, sName, accessMode)) + { + return REG_VALUE_NOT_EXISTS; + } + + pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); + + sal_uInt32 rwBytes; + if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != (VALUE_HEADERSIZE)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + sal_uInt8 type = *((sal_uInt8*)pBuffer); + valueType = (RegValueType)type; + readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); + + pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if (rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes)) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + if (rwBytes != valueSize) + { + rtl_freeMemory(pBuffer); + return REG_INVALID_VALUE; + } + + const sal_Char* indent = sIndent.getStr(); + switch (valueType) + { + case 0: + fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent); + break; + case 1: + { + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONG\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = ", indent); + + sal_Int32 value; + readINT32(pBuffer, value); + fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value)); + } + break; + case 2: + { + sal_Char* value = (sal_Char*)rtl_allocateMemory(valueSize); + readUtf8(pBuffer, value, valueSize); + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRING\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = \"%s\"\n", indent, value); + rtl_freeMemory(value); + } + break; + case 3: + { + sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode); + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODE\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = ", indent); + + sal_Unicode* value = new sal_Unicode[size]; + readString(pBuffer, value, size); + + OString uStr = OUStringToOString(value, RTL_TEXTENCODING_UTF8); + fprintf(stdout, "L\"%s\"\n", uStr.getStr()); + delete[] value; + } + break; + case 4: + { + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_BINARY\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf(stdout, "%s Data = ", indent); + dumpType( + typereg::Reader( + pBuffer, valueSize, false, TYPEREG_VERSION_1), + sIndent + " "); + } + break; + case 5: + { + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + sal_uInt32 len = 0; + + readUINT32(pBuffer, len); + + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONGLIST\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf( + stdout, "%s Len = %lu\n", indent, + sal::static_int_cast< unsigned long >(len)); + fprintf(stdout, "%s Data = ", indent); + + sal_Int32 longValue; + for (sal_uInt32 i=0; i < len; i++) + { + readINT32(pBuffer+offset, longValue); + + if (offset > 4) + fprintf(stdout, "%s ", indent); + + fprintf( + stdout, "%lu = %ld\n", + sal::static_int_cast< unsigned long >(i), + sal::static_int_cast< long >(longValue)); + offset += 4; // 4 Bytes fuer sal_Int32 + } + } + break; + case 6: + { + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + sal_uInt32 sLen = 0; + sal_uInt32 len = 0; + + readUINT32(pBuffer, len); + + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRINGLIST\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf( + stdout, "%s Len = %lu\n", indent, + sal::static_int_cast< unsigned long >(len)); + fprintf(stdout, "%s Data = ", indent); + + sal_Char *pValue; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes + + pValue = (sal_Char*)rtl_allocateMemory(sLen); + readUtf8(pBuffer+offset, pValue, sLen); + + if (offset > 8) + fprintf(stdout, "%s ", indent); + + fprintf( + stdout, "%lu = \"%s\"\n", + sal::static_int_cast< unsigned long >(i), pValue); + offset += sLen; + } + } + break; + case 7: + { + sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays + sal_uInt32 sLen = 0; + sal_uInt32 len = 0; + + readUINT32(pBuffer, len); + + fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODELIST\n", indent); + fprintf( + stdout, "%s Size = %lu\n", indent, + sal::static_int_cast< unsigned long >(valueSize)); + fprintf( + stdout, "%s Len = %lu\n", indent, + sal::static_int_cast< unsigned long >(len)); + fprintf(stdout, "%s Data = ", indent); + + sal_Unicode *pValue; + OString uStr; + for (sal_uInt32 i=0; i < len; i++) + { + readUINT32(pBuffer+offset, sLen); + + offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes + + pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)); + readString(pBuffer+offset, pValue, sLen); + + if (offset > 8) + fprintf(stdout, "%s ", indent); + + uStr = OUStringToOString(pValue, RTL_TEXTENCODING_UTF8); + fprintf( + stdout, "%lu = L\"%s\"\n", + sal::static_int_cast< unsigned long >(i), + uStr.getStr()); + + offset += sLen; + + rtl_freeMemory(pValue); + } + } + break; + } + + fprintf(stdout, "\n"); + + rtl_freeMemory(pBuffer); + return REG_NO_ERROR; +} + +//********************************************************************* +// dumpKey() +// +RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const +{ + OStoreDirectory rStoreDir; + OUString sFullPath(sPath); + OString sIndent; + storeAccessMode accessMode = KEY_MODE_OPEN; + RegError _ret = REG_NO_ERROR; + + if (isReadOnly()) + { + accessMode = KEY_MODE_OPENREAD; + } + + for (int i= 0; i < nSpace; i++) sIndent += " "; + + if (sFullPath.getLength() > 1) + sFullPath += ROOT; + + storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode); + + if (_err == store_E_NotExists) + return REG_KEY_NOT_EXISTS; + else + if (_err == store_E_WrongFormat) + return REG_INVALID_KEY; + + fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr()); + + OUString sSubPath(sFullPath); + OUString sSubName; + sSubPath += sName; + + OStoreDirectory::iterator iter; + + _err = rStoreDir.first(iter); + + while ( _err == store_E_None) + { + sSubName = iter.m_pszName; + + if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) + { + _ret = dumpKey(sSubPath, sSubName, nSpace+2); + } else + { + _ret = dumpValue(sSubPath, sSubName, nSpace+2); + } + + if (_ret) + { + return _ret; + } + + _err = rStoreDir.next(iter); + } + + return REG_NO_ERROR; +} diff --git a/registry/source/regimpl.hxx b/registry/source/regimpl.hxx new file mode 100644 index 000000000000..7523bb586749 --- /dev/null +++ b/registry/source/regimpl.hxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _REGIMPL_HXX_ +#define _REGIMPL_HXX_ + +#include <set> +#include <hash_map> + +#include <registry/registry.h> +#include <rtl/ustring.hxx> +#include <osl/mutex.hxx> +#include <store/store.hxx> + +#define REG_PAGESIZE 512 + +#define REG_MODE_CREATE store_AccessCreate +#define REG_MODE_OPEN store_AccessReadWrite +#define REG_MODE_OPENREAD store_AccessReadOnly + +#define KEY_MODE_CREATE store_AccessCreate +#define KEY_MODE_OPEN store_AccessReadWrite +#define KEY_MODE_OPENREAD store_AccessReadOnly + + +#define VALUE_MODE_CREATE store_AccessCreate +#define VALUE_MODE_OPEN store_AccessReadWrite +#define VALUE_MODE_OPENREAD store_AccessReadOnly + +// 5 Bytes = 1 (Byte fuer den Typ) + 4 (Bytes fuer die Groesse der Daten) +#define VALUE_HEADERSIZE 5 +#define VALUE_TYPEOFFSET 1 +#define VALUE_HEADEROFFSET 5 + +#define REG_CREATE 0x0004 // allow write accesses + +#define REG_GUARD(mutex) \ + osl::Guard< osl::Mutex > aGuard( mutex ); + +// @@@ using namespace rtl; +// @@@ using namespace osl; + +class ORegKey; +class RegistryTypeReader; + +class ORegistry +{ +public: + ORegistry(); + + sal_uInt32 acquire() + { return ++m_refCount; } + + sal_uInt32 release() + { return --m_refCount; } + + RegError initRegistry(const rtl::OUString& name, + RegAccessMode accessMode); + + RegError closeRegistry(); + + RegError destroyRegistry(const rtl::OUString& name); + + RegError acquireKey(RegKeyHandle hKey); + RegError releaseKey(RegKeyHandle hKey); + + RegError createKey(RegKeyHandle hKey, + const rtl::OUString& keyName, + RegKeyHandle* phNewKey); + + RegError openKey(RegKeyHandle hKey, + const rtl::OUString& keyName, + RegKeyHandle* phOpenKey); + + RegError closeKey(RegKeyHandle hKey); + + RegError deleteKey(RegKeyHandle hKey, const rtl::OUString& keyName); + + RegError loadKey(RegKeyHandle hKey, + const rtl::OUString& regFileName, + sal_Bool bWarings=sal_False, + sal_Bool bReport=sal_False); + + RegError saveKey(RegKeyHandle hKey, + const rtl::OUString& regFileName, + sal_Bool bWarings=sal_False, + sal_Bool bReport=sal_False); + + RegError dumpRegistry(RegKeyHandle hKey) const; + + ~ORegistry(); + + sal_Bool isReadOnly() const + { return m_readOnly; } + + sal_Bool isOpen() const + { return m_isOpen; } + + ORegKey* getRootKey(); + + const store::OStoreFile& getStoreFile() + { return m_file; } + + const rtl::OUString& getName() const + { return m_name; } + + friend class ORegKey; + +private: + RegError eraseKey(ORegKey* pKey, const rtl::OUString& keyName); + + RegError deleteSubkeysAndValues(ORegKey* pKey); + + RegError loadAndSaveValue(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const rtl::OUString& valueName, + sal_uInt32 nCut, + sal_Bool bWarnings=sal_False, + sal_Bool bReport=sal_False); + + RegError checkBlop(store::OStoreStream& rValue, + const rtl::OUString& sTargetPath, + sal_uInt32 srcValueSize, + sal_uInt8* pSrcBuffer, + sal_Bool bReport=sal_False); + + RegError mergeModuleValue(store::OStoreStream& rTargetValue, + RegistryTypeReader& reader, + RegistryTypeReader& reader2); + + RegError loadAndSaveKeys(ORegKey* pTargetKey, + ORegKey* pSourceKey, + const rtl::OUString& keyName, + sal_uInt32 nCut, + sal_Bool bWarnings=sal_False, + sal_Bool bReport=sal_False); + + RegError dumpValue(const rtl::OUString& sPath, + const rtl::OUString& sName, + sal_Int16 nSpace) const; + + RegError dumpKey(const rtl::OUString& sPath, + const rtl::OUString& sName, + sal_Int16 nSpace) const; + + typedef std::hash_map< rtl::OUString, ORegKey*, rtl::OUStringHash > KeyMap; + + sal_uInt32 m_refCount; + osl::Mutex m_mutex; + sal_Bool m_readOnly; + sal_Bool m_isOpen; + rtl::OUString m_name; + store::OStoreFile m_file; + KeyMap m_openKeyTable; + + const rtl::OUString ROOT; +}; + +#endif + diff --git a/registry/source/registry.cxx b/registry/source/registry.cxx new file mode 100644 index 000000000000..ea858f062f51 --- /dev/null +++ b/registry/source/registry.cxx @@ -0,0 +1,632 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <registry/registry.h> +#include <registry/registry.hxx> +#include <osl/process.h> + +#include "keyimpl.hxx" +#include "regimpl.hxx" +#include "regkey.hxx" + +#if defined(WIN32) || defined(WNT) || defined(OS2) +#include <io.h> +#endif + +#include <string.h> +#if defined(UNX) +#include <stdlib.h> +#include <unistd.h> +#endif + +#if defined ( GCC ) && ( defined ( SCO ) ) +ORealDynamicLoader* ODynamicLoader<Registry_Api>::m_pLoader = NULL; +#endif + +extern "C" { + +//********************************************************************* +// acquire +// +static void REGISTRY_CALLTYPE acquire(RegHandle hReg) +{ + ORegistry* pReg = (ORegistry*) hReg; + + if (pReg != NULL) + pReg->acquire(); +} + + +//********************************************************************* +// release +// +static void REGISTRY_CALLTYPE release(RegHandle hReg) +{ + ORegistry* pReg = (ORegistry*) hReg; + + if (pReg) + { + if (pReg->release() == 0) + { + delete pReg; + hReg = NULL; + } + } +} + + +//********************************************************************* +// getName +// +static RegError REGISTRY_CALLTYPE getName(RegHandle hReg, rtl_uString** pName) +{ + ORegistry* pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if ( pReg->isOpen() ) + { + rtl_uString_assign(pName, pReg->getName().pData); + return REG_NO_ERROR; + } else + { + rtl_uString_new(pName); + return REG_REGISTRY_NOT_OPEN; + } + } + + rtl_uString_new(pName); + return REG_INVALID_REGISTRY; +} + + +//********************************************************************* +// isReadOnly +// +static sal_Bool REGISTRY_CALLTYPE isReadOnly(RegHandle hReg) +{ + if (hReg) + return ((ORegistry*)hReg)->isReadOnly(); + else + return sal_False; +} + + +//********************************************************************* +// createRegistry +// +static RegError REGISTRY_CALLTYPE createRegistry(rtl_uString* registryName, + RegHandle* phRegistry) +{ + RegError ret; + + ORegistry* pReg = new ORegistry(); + if ((ret = pReg->initRegistry(registryName, REG_CREATE))) + { + *phRegistry = NULL; + return ret; + } + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// openRootKey +// +static RegError REGISTRY_CALLTYPE openRootKey(RegHandle hReg, + RegKeyHandle* phRootKey) +{ + ORegistry* pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + } else + { + phRootKey = NULL; + return REG_INVALID_REGISTRY; + } + + *phRootKey = pReg->getRootKey(); + + return REG_NO_ERROR; +} + + +//********************************************************************* +// openRegistry +// +static RegError REGISTRY_CALLTYPE openRegistry(rtl_uString* registryName, + RegHandle* phRegistry, + RegAccessMode accessMode) +{ + RegError _ret; + + ORegistry* pReg = new ORegistry(); + if ((_ret = pReg->initRegistry(registryName, accessMode))) + { + *phRegistry = NULL; + delete pReg; + return _ret; + } + + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// closeRegistry +// +static RegError REGISTRY_CALLTYPE closeRegistry(RegHandle hReg) +{ + ORegistry *pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + RegError ret = REG_NO_ERROR; + if (pReg->release() == 0) + { + delete(pReg); + hReg = NULL; + } + else + ret = pReg->closeRegistry(); + + return ret; + } else + { + return REG_INVALID_REGISTRY; + } +} + + +//********************************************************************* +// destroyRegistry +// +static RegError REGISTRY_CALLTYPE destroyRegistry(RegHandle hReg, + rtl_uString* registryName) +{ + ORegistry *pReg; + + if (hReg) + { + pReg = (ORegistry*)hReg; + if (!pReg->isOpen()) + return REG_INVALID_REGISTRY; + + RegError ret = pReg->destroyRegistry(registryName); + if (!ret) + { + if (!registryName->length) + { + delete(pReg); + hReg = NULL; + } + } + return ret; + } else + { + return REG_INVALID_REGISTRY; + } +} + + +//********************************************************************* +// loadRegKey +// +static RegError REGISTRY_CALLTYPE loadKey(RegHandle hReg, + RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + + ORegKey* pNewKey = 0; + RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret == REG_NO_ERROR) + { + pKey->releaseKey(pNewKey); + pKey->deleteKey(keyName); + } + + _ret = pKey->createKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = pReg->loadKey(pNewKey, regFileName); + if (_ret != REG_NO_ERROR) + { + pKey->releaseKey(pNewKey); + pKey->deleteKey(keyName); + return _ret; + } + + return pKey->closeKey(pNewKey); +} + +//********************************************************************* +// saveKey +// +static RegError REGISTRY_CALLTYPE saveKey(RegHandle hReg, + RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + ORegKey* pNewKey = 0; + RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = pReg->saveKey(pNewKey, regFileName); + if (_ret != REG_NO_ERROR) + { + (void) pKey->releaseKey(pNewKey); + return _ret; + } + + return pKey->releaseKey(pNewKey); +} + +//********************************************************************* +// mergeKey +// +static RegError REGISTRY_CALLTYPE mergeKey(RegHandle hReg, + RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName, + sal_Bool bWarnings, + sal_Bool bReport) +{ + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + if (keyName->length) + { + ORegKey* pNewKey = 0; + RegError _ret = pKey->createKey(keyName, (RegKeyHandle*)&pNewKey); + if (_ret != REG_NO_ERROR) + return _ret; + + _ret = pReg->loadKey(pNewKey, regFileName, bWarnings, bReport); + if (_ret == REG_MERGE_ERROR || (_ret == REG_MERGE_CONFLICT && bWarnings)) + { + if (pNewKey != pKey) + (void) pKey->closeKey(pNewKey); + else + (void) pKey->releaseKey(pNewKey); + return _ret; + } + + return (pNewKey != pKey) ? pKey->closeKey(pNewKey) : pKey->releaseKey(pNewKey); + } + + return pReg->loadKey(pKey, regFileName, bWarnings, bReport); +} + +//********************************************************************* +// dumpRegistry +// +static RegError REGISTRY_CALLTYPE dumpRegistry(RegHandle hReg, + RegKeyHandle hKey) +{ + ORegistry* pReg = static_cast< ORegistry* >(hReg); + if (!pReg) + return REG_INVALID_REGISTRY; + if (!pReg->isOpen()) + return REG_REGISTRY_NOT_OPEN; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + if (pKey->getRegistry() != pReg) + return REG_INVALID_KEY; + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pReg->dumpRegistry(hKey); +} + +//********************************************************************* +// initRegistry_Api +// +Registry_Api* REGISTRY_CALLTYPE initRegistry_Api(void) +{ + static Registry_Api aApi= {&acquire, + &release, + &isReadOnly, + &openRootKey, + &getName, + &createRegistry, + &openRegistry, + &closeRegistry, + &destroyRegistry, + &loadKey, + &saveKey, + &mergeKey, + &dumpRegistry, + &acquireKey, + &releaseKey, + &isKeyReadOnly, + &getKeyName, + &createKey, + &openKey, + &openSubKeys, + &closeSubKeys, + &deleteKey, + &closeKey, + &setValue, + &setLongListValue, + &setStringListValue, + &setUnicodeListValue, + &getValueInfo, + &getValue, + &getLongListValue, + &getStringListValue, + &getUnicodeListValue, + &freeValueList, + &createLink, + &deleteLink, + &getKeyType, + &getLinkTarget, + &getResolvedKeyName, + &getKeyNames, + &freeKeyNames}; + + return (&aApi); +} + +} + +//********************************************************************* +// reg_loadRegKey +// +RegError REGISTRY_CALLTYPE reg_loadKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return loadKey(pKey->getRegistry(), hKey, keyName, regFileName); +} + +//********************************************************************* +// reg_saveKey +// +RegError REGISTRY_CALLTYPE reg_saveKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return saveKey(pKey->getRegistry(), hKey, keyName, regFileName); +} + +//********************************************************************* +// reg_mergeKey +// +RegError REGISTRY_CALLTYPE reg_mergeKey(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString* regFileName, + sal_Bool bWarnings, + sal_Bool bReport) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return mergeKey(pKey->getRegistry(), hKey, keyName, regFileName, bWarnings, bReport); +} + +//********************************************************************* +// reg_createRegistry +// +RegError REGISTRY_CALLTYPE reg_createRegistry(rtl_uString* registryName, + RegHandle* phRegistry) +{ + RegError ret; + + ORegistry* pReg = new ORegistry(); + if ((ret = pReg->initRegistry(registryName, REG_CREATE))) + { + *phRegistry = NULL; + return ret; + } + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// reg_openRootKey +// +RegError REGISTRY_CALLTYPE reg_openRootKey(RegHandle hRegistry, + RegKeyHandle* phRootKey) +{ + return openRootKey(hRegistry, phRootKey); +} + + +//********************************************************************* +// reg_getName +// +RegError REGISTRY_CALLTYPE reg_getName(RegHandle hRegistry, rtl_uString** pName) +{ + return getName(hRegistry, pName); +} + + +//********************************************************************* +// reg_isReadOnly +// +sal_Bool REGISTRY_CALLTYPE reg_isReadOnly(RegHandle hRegistry) +{ + return isReadOnly(hRegistry); +} + + +//********************************************************************* +// reg_openRegistry +// +RegError REGISTRY_CALLTYPE reg_openRegistry(rtl_uString* registryName, + RegHandle* phRegistry, + RegAccessMode accessMode) +{ + RegError _ret; + + ORegistry* pReg = new ORegistry(); + if ((_ret = pReg->initRegistry(registryName, accessMode))) + { + *phRegistry = NULL; + return _ret; + } + + *phRegistry = pReg; + + return REG_NO_ERROR; +} + +//********************************************************************* +// reg_closeRegistry +// +RegError REGISTRY_CALLTYPE reg_closeRegistry(RegHandle hRegistry) +{ + ORegistry* pReg; + + if (hRegistry) + { + pReg = (ORegistry*)hRegistry; + delete(pReg); + return REG_NO_ERROR; + } else + { + return REG_REGISTRY_NOT_OPEN; + } +} + + +//********************************************************************* +// reg_destroyRegistry +// +RegError REGISTRY_CALLTYPE reg_destroyRegistry(RegHandle hRegistry, + rtl_uString* registryName) +{ + return destroyRegistry(hRegistry, registryName); +} + + +//********************************************************************* +// reg_dumpRegistry +// +RegError REGISTRY_CALLTYPE reg_dumpRegistry(RegKeyHandle hKey) +{ + ORegKey *pKey; + + if (hKey) + pKey = (ORegKey*)hKey; + else + return REG_INVALID_KEY; + + return dumpRegistry(pKey->getRegistry(), hKey); +} + + diff --git a/registry/source/regkey.cxx b/registry/source/regkey.cxx new file mode 100644 index 000000000000..c65de7e3e2ca --- /dev/null +++ b/registry/source/regkey.cxx @@ -0,0 +1,1022 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include "regkey.hxx" + +#include <registry/registry.hxx> +#include <rtl/alloc.h> +#include "regimpl.hxx" +#include "keyimpl.hxx" + +using rtl::OUString; + +//********************************************************************* +// acquireKey +// +void REGISTRY_CALLTYPE acquireKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (pKey != 0) + { + ORegistry* pReg = pKey->getRegistry(); + (void) pReg->acquireKey(pKey); + } +} + + +//********************************************************************* +// releaseKey +// +void REGISTRY_CALLTYPE releaseKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (pKey != 0) + { + ORegistry* pReg = pKey->getRegistry(); + (void) pReg->releaseKey(pKey); + } +} + + +//********************************************************************* +// isKeyReadOnly +// +sal_Bool REGISTRY_CALLTYPE isKeyReadOnly(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + return (pKey != 0) ? pKey->isReadOnly() : sal_False; +} + + +//********************************************************************* +// getKeyName +// +RegError REGISTRY_CALLTYPE getKeyName(RegKeyHandle hKey, rtl_uString** pKeyName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (pKey) + { + rtl_uString_assign( pKeyName, pKey->getName().pData ); + return REG_NO_ERROR; + } else + { + rtl_uString_new(pKeyName); + return REG_INVALID_KEY; + } +} + + +//********************************************************************* +// createKey +// +RegError REGISTRY_CALLTYPE createKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phNewKey) +{ + *phNewKey = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + return pKey->createKey(keyName, phNewKey); +} + +//********************************************************************* +// openKey +// +RegError REGISTRY_CALLTYPE openKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phOpenKey) +{ + *phOpenKey = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->openKey(keyName, phOpenKey); +} + +//********************************************************************* +// openSubKeys +// +RegError REGISTRY_CALLTYPE openSubKeys(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle** pphSubKeys, + sal_uInt32* pnSubKeys) +{ + *pphSubKeys = NULL; + *pnSubKeys = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->openSubKeys(keyName, pphSubKeys, pnSubKeys); +} + +//********************************************************************* +// closeSubKeys +// +RegError REGISTRY_CALLTYPE closeSubKeys(RegKeyHandle* phSubKeys, + sal_uInt32 nSubKeys) +{ + if (phSubKeys == 0 || nSubKeys == 0) + return REG_INVALID_KEY; + + ORegistry* pReg = ((ORegKey*)(phSubKeys[0]))->getRegistry(); + for (sal_uInt32 i = 0; i < nSubKeys; i++) + { + (void) pReg->closeKey(phSubKeys[i]); + } + rtl_freeMemory(phSubKeys); + + return REG_NO_ERROR; +} + +//********************************************************************* +// deleteKey +// +RegError REGISTRY_CALLTYPE deleteKey(RegKeyHandle hKey, + rtl_uString* keyName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + return pKey->deleteKey(keyName); +} + +//********************************************************************* +// closeKey +// +RegError REGISTRY_CALLTYPE closeKey(RegKeyHandle hKey) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + return pKey->closeKey(hKey); +} + +//********************************************************************* +// setValue +// +RegError REGISTRY_CALLTYPE setValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType valueType, + RegValue pData, + sal_uInt32 valueSize) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setValue(valueName, valueType, pData, valueSize); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setValue(valueName, valueType, pData, valueSize); +} + +//********************************************************************* +// setLongValueList +// +RegError REGISTRY_CALLTYPE setLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32* pValueList, + sal_uInt32 len) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setLongListValue(valueName, pValueList, len); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2 != REG_NO_ERROR) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setLongListValue(valueName, pValueList, len); +} + +//********************************************************************* +// setStringValueList +// +RegError REGISTRY_CALLTYPE setStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char** pValueList, + sal_uInt32 len) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setStringListValue(valueName, pValueList, len); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2 != REG_NO_ERROR) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setStringListValue(valueName, pValueList, len); +} + +//********************************************************************* +// setUnicodeValueList +// +RegError REGISTRY_CALLTYPE setUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode** pValueList, + sal_uInt32 len) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + if (pKey->isReadOnly()) + return REG_REGISTRY_READONLY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->setUnicodeListValue(valueName, pValueList, len); + if (_ret1 != REG_NO_ERROR) + { + RegError _ret2 = pKey->closeKey(pSubKey); + if (_ret2 != REG_NO_ERROR) + return _ret2; + else + return _ret1; + } + + return pKey->closeKey(pSubKey); + } + + return pKey->setUnicodeListValue(valueName, pValueList, len); +} + +//********************************************************************* +// getValueInfo +// +RegError REGISTRY_CALLTYPE getValueInfo(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize) +{ + *pValueType = RG_VALUETYPE_NOT_DEFINED; + *pValueSize = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + RegValueType valueType; + sal_uInt32 valueSize; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret != REG_NO_ERROR) + return _ret; + + if (pSubKey->getValueInfo(valueName, &valueType, &valueSize) != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return REG_INVALID_VALUE; + } + + *pValueType = valueType; + *pValueSize = valueSize; + + return pKey->releaseKey(pSubKey); + } + + + if (pKey->getValueInfo(valueName, &valueType, &valueSize) != REG_NO_ERROR) + { + return REG_INVALID_VALUE; + } + + *pValueType = valueType; + *pValueSize = valueSize; + + return REG_NO_ERROR; +} + +//********************************************************************* +// getValueInfo +// +RegError REGISTRY_CALLTYPE getValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValue pValue) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getValue(valueName, pValue); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getValue(valueName, pValue); +} + +//********************************************************************* +// getLongValueList +// +RegError REGISTRY_CALLTYPE getLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32** pValueList, + sal_uInt32* pLen) +{ + OSL_PRECOND((pValueList != 0) && (pLen != 0), "registry::getLongListValue(): invalid parameter"); + *pValueList = 0, *pLen = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getLongListValue(valueName, pValueList, pLen); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getLongListValue(valueName, pValueList, pLen); +} + +//********************************************************************* +// getStringValueList +// +RegError REGISTRY_CALLTYPE getStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char*** pValueList, + sal_uInt32* pLen) +{ + OSL_PRECOND((pValueList != 0) && (pLen != 0), "registry::getStringListValue(): invalid parameter"); + *pValueList = 0, *pLen = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getStringListValue(valueName, pValueList, pLen); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getStringListValue(valueName, pValueList, pLen); +} + +//********************************************************************* +// getUnicodeListValue +// +RegError REGISTRY_CALLTYPE getUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode*** pValueList, + sal_uInt32* pLen) +{ + OSL_PRECOND((pValueList != 0) && (pLen != 0), "registry::getUnicodeListValue(): invalid parameter"); + *pValueList = 0, *pLen = 0; + + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString valueName( RTL_CONSTASCII_USTRINGPARAM("value") ); + if (keyName->length) + { + ORegKey* pSubKey = 0; + RegError _ret1 = pKey->openKey(keyName, (RegKeyHandle*)&pSubKey); + if (_ret1 != REG_NO_ERROR) + return _ret1; + + _ret1 = pSubKey->getUnicodeListValue(valueName, pValueList, pLen); + if (_ret1 != REG_NO_ERROR) + { + (void) pKey->releaseKey(pSubKey); + return _ret1; + } + + return pKey->releaseKey(pSubKey); + } + + return pKey->getUnicodeListValue(valueName, pValueList, pLen); +} + +//********************************************************************* +// freeValueList +// +RegError REGISTRY_CALLTYPE freeValueList(RegValueType valueType, + RegValue pValueList, + sal_uInt32 len) +{ + switch (valueType) + { + case 5: + { + rtl_freeMemory(pValueList); + } + break; + case 6: + { + sal_Char** pVList = (sal_Char**)pValueList; + for (sal_uInt32 i=0; i < len; i++) + { + rtl_freeMemory(pVList[i]); + } + + rtl_freeMemory(pVList); + } + break; + case 7: + { + sal_Unicode** pVList = (sal_Unicode**)pValueList; + for (sal_uInt32 i=0; i < len; i++) + { + rtl_freeMemory(pVList[i]); + } + + rtl_freeMemory(pVList); + } + break; + default: + return REG_INVALID_VALUE; + } + + pValueList = NULL; + return REG_NO_ERROR; +} + +//********************************************************************* +// createLink +// +RegError REGISTRY_CALLTYPE createLink(RegKeyHandle, rtl_uString*, rtl_uString*) +{ + return REG_INVALID_LINK; // links are no longer supported +} + +//********************************************************************* +// deleteLink +// +RegError REGISTRY_CALLTYPE deleteLink(RegKeyHandle, rtl_uString*) +{ + return REG_INVALID_LINK; // links are no longer supported +} + +//********************************************************************* +// getKeyType +// +RegError REGISTRY_CALLTYPE getKeyType(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyType* pKeyType) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->getKeyType(keyName, pKeyType); +} + +//********************************************************************* +// getLinkTarget +// +RegError REGISTRY_CALLTYPE getLinkTarget( + RegKeyHandle, rtl_uString*, rtl_uString**) +{ + return REG_INVALID_LINK; // links are no longer supported +} + +//********************************************************************* +// getName +// +RegError REGISTRY_CALLTYPE getResolvedKeyName(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Bool, + rtl_uString** pResolvedName) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + OUString resolvedName; + RegError _ret = pKey->getResolvedKeyName(keyName, resolvedName); + if (_ret == REG_NO_ERROR) + rtl_uString_assign(pResolvedName, resolvedName.pData); + return _ret; +} + +//********************************************************************* +// getKeyNames +// +RegError REGISTRY_CALLTYPE getKeyNames(RegKeyHandle hKey, + rtl_uString* keyName, + rtl_uString*** pSubKeyNames, + sal_uInt32* pnSubKeys) +{ + ORegKey* pKey = static_cast< ORegKey* >(hKey); + if (!pKey) + return REG_INVALID_KEY; + + if (pKey->isDeleted()) + return REG_INVALID_KEY; + + return pKey->getKeyNames(keyName, pSubKeyNames, pnSubKeys); +} + +//********************************************************************* +// freeKeyNames +// +RegError REGISTRY_CALLTYPE freeKeyNames(rtl_uString** pKeyNames, + sal_uInt32 nKeys) +{ + for (sal_uInt32 i=0; i < nKeys; i++) + { + rtl_uString_release(pKeyNames[i]); + } + + rtl_freeMemory(pKeyNames); + + return REG_NO_ERROR; +} + +//********************************************************************* +// C API +// + +//********************************************************************* +// reg_createKey +// +RegError REGISTRY_CALLTYPE reg_createKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phNewKey) +{ + if (!hKey) + return REG_INVALID_KEY; + + return createKey(hKey, keyName, phNewKey); +} + +//********************************************************************* +// reg_openKey +// +RegError REGISTRY_CALLTYPE reg_openKey(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle* phOpenKey) +{ + if (!hKey) + return REG_INVALID_KEY; + + return openKey(hKey, keyName, phOpenKey); +} + +//********************************************************************* +// reg_openSubKeys +// +RegError REGISTRY_CALLTYPE reg_openSubKeys(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyHandle** pphSubKeys, + sal_uInt32* pnSubKeys) +{ + if (!hKey) + return REG_INVALID_KEY; + + return openSubKeys(hKey, keyName, pphSubKeys, pnSubKeys); +} + +//********************************************************************* +// reg_closeSubKeys +// +RegError REGISTRY_CALLTYPE reg_closeSubKeys(RegKeyHandle* pphSubKeys, + sal_uInt32 nSubKeys) +{ + if (!pphSubKeys) + return REG_INVALID_KEY; + + return closeSubKeys(pphSubKeys, nSubKeys); +} + +//********************************************************************* +// reg_deleteKey +// +RegError REGISTRY_CALLTYPE reg_deleteKey(RegKeyHandle hKey, + rtl_uString* keyName) +{ + if (!hKey) + return REG_INVALID_KEY; + + return deleteKey(hKey, keyName); +} + +//********************************************************************* +// reg_closeKey +// +RegError REGISTRY_CALLTYPE reg_closeKey(RegKeyHandle hKey) +{ + if (!hKey) + return REG_INVALID_KEY; + + return closeKey(hKey); +} + + +//********************************************************************* +// reg_getKeyName +// +RegError REGISTRY_CALLTYPE reg_getKeyName(RegKeyHandle hKey, rtl_uString** pKeyName) +{ + if (hKey) + { + rtl_uString_assign( pKeyName, ((ORegKey*)hKey)->getName().pData ); + return REG_NO_ERROR; + } else + { + rtl_uString_new( pKeyName ); + return REG_INVALID_KEY; + } +} + +//********************************************************************* +// reg_setValue +// +RegError REGISTRY_CALLTYPE reg_setValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType valueType, + RegValue pData, + sal_uInt32 valueSize) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setValue(hKey, keyName, valueType, pData, valueSize); +} + +//********************************************************************* +// reg_setLongListValue +// +RegError REGISTRY_CALLTYPE reg_setLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32* pValueList, + sal_uInt32 len) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setLongListValue(hKey, keyName, pValueList, len); +} + +//********************************************************************* +// reg_setStringListValue +// +RegError REGISTRY_CALLTYPE reg_setStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char** pValueList, + sal_uInt32 len) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setStringListValue(hKey, keyName, pValueList, len); +} + +//********************************************************************* +// reg_setUnicodeListValue +// +RegError REGISTRY_CALLTYPE reg_setUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode** pValueList, + sal_uInt32 len) +{ + if (!hKey) + return REG_INVALID_KEY; + + return setUnicodeListValue(hKey, keyName, pValueList, len); +} + +//********************************************************************* +// reg_getValueInfo +// +RegError REGISTRY_CALLTYPE reg_getValueInfo(RegKeyHandle hKey, + rtl_uString* keyName, + RegValueType* pValueType, + sal_uInt32* pValueSize) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getValueInfo(hKey, keyName, pValueType, pValueSize); +} + +//********************************************************************* +// reg_getValueInfo +// +RegError REGISTRY_CALLTYPE reg_getValue(RegKeyHandle hKey, + rtl_uString* keyName, + RegValue pData) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getValue(hKey, keyName, pData); +} + +//********************************************************************* +// reg_getLongListValue +// +RegError REGISTRY_CALLTYPE reg_getLongListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Int32** pValueList, + sal_uInt32* pLen) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getLongListValue(hKey, keyName, pValueList, pLen); +} + +//********************************************************************* +// reg_getStringListValue +// +RegError REGISTRY_CALLTYPE reg_getStringListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Char*** pValueList, + sal_uInt32* pLen) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getStringListValue(hKey, keyName, pValueList, pLen); +} + +//********************************************************************* +// reg_getUnicodeListValue +// +RegError REGISTRY_CALLTYPE reg_getUnicodeListValue(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Unicode*** pValueList, + sal_uInt32* pLen) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getUnicodeListValue(hKey, keyName, pValueList, pLen); +} + +//********************************************************************* +// reg_freeValueList +// +RegError REGISTRY_CALLTYPE reg_freeValueList(RegValueType valueType, + RegValue pValueList, + sal_uInt32 len) +{ + if (pValueList) + return freeValueList(valueType, pValueList, len); + else + return REG_INVALID_VALUE; +} + +//********************************************************************* +// reg_createLink +// +RegError REGISTRY_CALLTYPE reg_createLink(RegKeyHandle hKey, + rtl_uString* linkName, + rtl_uString* linkTarget) +{ + if (!hKey) + return REG_INVALID_KEY; + + return createLink(hKey, linkName, linkTarget); +} + +//********************************************************************* +// reg_deleteLink +// +RegError REGISTRY_CALLTYPE reg_deleteLink(RegKeyHandle hKey, + rtl_uString* linkName) +{ + if (!hKey) + return REG_INVALID_KEY; + + return deleteLink(hKey, linkName); +} + +//********************************************************************* +// reg_getKeyType +// +RegError REGISTRY_CALLTYPE reg_getKeyType(RegKeyHandle hKey, + rtl_uString* keyName, + RegKeyType* pKeyType) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getKeyType(hKey, keyName, pKeyType); +} + +//********************************************************************* +// reg_getLinkTarget +// +RegError REGISTRY_CALLTYPE reg_getLinkTarget(RegKeyHandle hKey, + rtl_uString* linkName, + rtl_uString** pLinkTarget) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getLinkTarget(hKey, linkName, pLinkTarget); +} + +//********************************************************************* +// reg_getResolvedKeyName +// +RegError REGISTRY_CALLTYPE reg_getResolvedKeyName(RegKeyHandle hKey, + rtl_uString* keyName, + sal_Bool firstLinkOnly, + rtl_uString** pResolvedName) +{ + if (!hKey) + return REG_INVALID_KEY; + + return getResolvedKeyName(hKey, keyName, firstLinkOnly, pResolvedName); +} diff --git a/registry/source/regkey.hxx b/registry/source/regkey.hxx new file mode 100644 index 000000000000..4a9e711e28af --- /dev/null +++ b/registry/source/regkey.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_REGISTRY_SOURCE_REGKEY_HXX +#define INCLUDED_REGISTRY_SOURCE_REGKEY_HXX + +#include "sal/config.h" +#include "registry/regtype.h" +#include "rtl/ustring.h" +#include "sal/types.h" + +extern "C" { + +void REGISTRY_CALLTYPE acquireKey(RegKeyHandle); +void REGISTRY_CALLTYPE releaseKey(RegKeyHandle); +sal_Bool REGISTRY_CALLTYPE isKeyReadOnly(RegKeyHandle); +RegError REGISTRY_CALLTYPE getKeyName(RegKeyHandle, rtl_uString**); +RegError REGISTRY_CALLTYPE createKey(RegKeyHandle, rtl_uString*, RegKeyHandle*); +RegError REGISTRY_CALLTYPE openKey(RegKeyHandle, rtl_uString*, RegKeyHandle*); +RegError REGISTRY_CALLTYPE openSubKeys( + RegKeyHandle, rtl_uString*, RegKeyHandle**, sal_uInt32*); +RegError REGISTRY_CALLTYPE closeSubKeys(RegKeyHandle*, sal_uInt32); +RegError REGISTRY_CALLTYPE deleteKey(RegKeyHandle, rtl_uString*); +RegError REGISTRY_CALLTYPE closeKey(RegKeyHandle); +RegError REGISTRY_CALLTYPE setValue( + RegKeyHandle, rtl_uString*, RegValueType, RegValue, sal_uInt32); +RegError REGISTRY_CALLTYPE setLongListValue( + RegKeyHandle, rtl_uString*, sal_Int32*, sal_uInt32); +RegError REGISTRY_CALLTYPE setStringListValue( + RegKeyHandle, rtl_uString*, sal_Char**, sal_uInt32); +RegError REGISTRY_CALLTYPE setUnicodeListValue( + RegKeyHandle, rtl_uString*, sal_Unicode**, sal_uInt32); +RegError REGISTRY_CALLTYPE getValueInfo( + RegKeyHandle, rtl_uString*, RegValueType*, sal_uInt32*); +RegError REGISTRY_CALLTYPE getValue(RegKeyHandle, rtl_uString*, RegValue); +RegError REGISTRY_CALLTYPE getLongListValue( + RegKeyHandle, rtl_uString*, sal_Int32**, sal_uInt32*); +RegError REGISTRY_CALLTYPE getStringListValue( + RegKeyHandle, rtl_uString*, sal_Char***, sal_uInt32*); +RegError REGISTRY_CALLTYPE getUnicodeListValue( + RegKeyHandle, rtl_uString*, sal_Unicode***, sal_uInt32*); +RegError REGISTRY_CALLTYPE freeValueList(RegValueType, RegValue, sal_uInt32); +RegError REGISTRY_CALLTYPE createLink(RegKeyHandle, rtl_uString*, rtl_uString*); +RegError REGISTRY_CALLTYPE deleteLink(RegKeyHandle, rtl_uString*); +RegError REGISTRY_CALLTYPE getKeyType(RegKeyHandle, rtl_uString*, RegKeyType*); +RegError REGISTRY_CALLTYPE getLinkTarget( + RegKeyHandle, rtl_uString*, rtl_uString**); +RegError REGISTRY_CALLTYPE getResolvedKeyName( + RegKeyHandle, rtl_uString*, sal_Bool, rtl_uString**); +RegError REGISTRY_CALLTYPE getKeyNames( + RegKeyHandle, rtl_uString*, rtl_uString***, sal_uInt32*); +RegError REGISTRY_CALLTYPE freeKeyNames(rtl_uString**, sal_uInt32); + +} + +#endif diff --git a/registry/test/makefile.mk b/registry/test/makefile.mk new file mode 100644 index 000000000000..4d4ce3068648 --- /dev/null +++ b/registry/test/makefile.mk @@ -0,0 +1,90 @@ +#************************************************************************* +# +# 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=registry +TARGET=regtest + +USE_LDUMP2=TRUE + +ENABLE_EXCEPTIONS := TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + + +# ------------------------------------------------------------------ +CDEFS += -DDLL_VERSION=$(EMQ)"$(DLLPOSTFIX)$(EMQ)" + +CXXFILES= \ + testregcpp.cxx \ + testmerge.cxx + + +LIB1TARGET= $(SLB)$/$(TARGET).lib + +LIB1OBJFILES= \ + $(SLO)$/testregcpp.obj \ + $(SLO)$/testmerge.obj + + +SHL1TARGET= rgt$(DLLPOSTFIX) +SHL1IMPLIB= rgt +SHL1STDLIBS= \ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) \ + $(STDLIBCPP) + +SHL1LIBS= $(LIB1TARGET) +SHL1DEPN= $(LIB1TARGET) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) + +DEF1DEPN =$(MISC)$/rgt$(DLLPOSTFIX).flt $(SLOFILES) +DEFLIB1NAME =$(TARGET) +DEF1DES =Registry Runtime - TestDll + +# --- Targets ------------------------------------------------------ + +#all: \ +# ALLTAR + +.INCLUDE : target.mk + +# --- SO2-Filter-Datei --- + + +$(MISC)$/rgt$(DLLPOSTFIX).flt: + @echo ------------------------------ + @echo Making: $@ + @echo WEP>$@ + @echo LIBMAIN>>$@ + @echo LibMain>>$@ + + diff --git a/registry/test/regcompare/makefile.mk b/registry/test/regcompare/makefile.mk new file mode 100644 index 000000000000..169b516060ba --- /dev/null +++ b/registry/test/regcompare/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# 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 := registry +TARGET := test_regcompare + +.INCLUDE: settings.mk +.INCLUDE: target.mk + +ALLTAR: test + +test .PHONY: $(MISC)$/$(TARGET)$/psa.urd $(MISC)$/$(TARGET)$/psb.urd \ + $(MISC)$/$(TARGET)$/usa.urd $(MISC)$/$(TARGET)$/usb.urd \ + $(MISC)$/$(TARGET)$/pe.urd $(MISC)$/$(TARGET)$/ue.urd \ + $(MISC)$/$(TARGET)$/other1.urd $(MISC)$/$(TARGET)$/other2.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/psa.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/psb.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/usa.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/usb.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/pe.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/ue.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/other1.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/other2.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/psa.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/psb.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/usa.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/usb.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/pe.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/ue.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/other1.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/psa.urd -r2 $(MISC)$/$(TARGET)$/other2.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/psa.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/psb.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/usa.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/usb.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/pe.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/ue.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/other1.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/other2.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/psa.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/psb.urd + $(EXECTEST) -SUCCESS $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/usa.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/usb.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/pe.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/ue.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/other1.urd + $(EXECTEST) -FAILURE $(BIN)/regcompare$(EXECPOST) -f -t -u \ + -r1 $(MISC)$/$(TARGET)$/usa.urd -r2 $(MISC)$/$(TARGET)$/other2.urd + +$(MISC)$/$(TARGET)$/%.urd: %.idl + $(IDLC) -O$(MISC)$/$(TARGET) -cid -we $< diff --git a/registry/test/regcompare/other1.idl b/registry/test/regcompare/other1.idl new file mode 100644 index 000000000000..75473015bc82 --- /dev/null +++ b/registry/test/regcompare/other1.idl @@ -0,0 +1 @@ +module M { enum X { V }; }; diff --git a/registry/test/regcompare/other2.idl b/registry/test/regcompare/other2.idl new file mode 100644 index 000000000000..f6c94ef66548 --- /dev/null +++ b/registry/test/regcompare/other2.idl @@ -0,0 +1 @@ +enum X { V }; diff --git a/registry/test/regcompare/pe.idl b/registry/test/regcompare/pe.idl new file mode 100644 index 000000000000..c597b29f048d --- /dev/null +++ b/registry/test/regcompare/pe.idl @@ -0,0 +1 @@ +module M { published enum N { V }; }; diff --git a/registry/test/regcompare/psa.idl b/registry/test/regcompare/psa.idl new file mode 100644 index 000000000000..b8079c9add9d --- /dev/null +++ b/registry/test/regcompare/psa.idl @@ -0,0 +1 @@ +module M { published struct N { long m; }; }; diff --git a/registry/test/regcompare/psb.idl b/registry/test/regcompare/psb.idl new file mode 100644 index 000000000000..03d02b302c96 --- /dev/null +++ b/registry/test/regcompare/psb.idl @@ -0,0 +1 @@ +module M { published struct N { short m; }; }; diff --git a/registry/test/regcompare/ue.idl b/registry/test/regcompare/ue.idl new file mode 100644 index 000000000000..0face3356b23 --- /dev/null +++ b/registry/test/regcompare/ue.idl @@ -0,0 +1 @@ +module M { enum N { V }; }; diff --git a/registry/test/regcompare/usa.idl b/registry/test/regcompare/usa.idl new file mode 100644 index 000000000000..80fe2c2f4c2e --- /dev/null +++ b/registry/test/regcompare/usa.idl @@ -0,0 +1 @@ +module M { struct N { long m; }; }; diff --git a/registry/test/regcompare/usb.idl b/registry/test/regcompare/usb.idl new file mode 100644 index 000000000000..08e7e9daa9d4 --- /dev/null +++ b/registry/test/regcompare/usb.idl @@ -0,0 +1 @@ +module M { struct N { short m; }; }; diff --git a/registry/test/regdiagnose.h b/registry/test/regdiagnose.h new file mode 100644 index 000000000000..475e315cd32d --- /dev/null +++ b/registry/test/regdiagnose.h @@ -0,0 +1,44 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + + +#ifndef REG_DIAGNOSE_H +#define REG_DIAGNOSE_H + +#include <osl/diagnose.h> + +#define REG_ENSURE(c, m) _REG_ENSURE(c, OSL_THIS_FILE, __LINE__, m) + +#define _REG_ENSURE(c, f, l, m) \ + do \ + { \ + if (!(c) && _OSL_GLOBAL osl_assertFailedLine(f, l, m)) \ + _OSL_GLOBAL osl_breakDebug(); \ + } while (0) + + +#endif // REG_DIAGNOSE_H diff --git a/registry/test/testmerge.cxx b/registry/test/testmerge.cxx new file mode 100644 index 000000000000..35c32f751fa6 --- /dev/null +++ b/registry/test/testmerge.cxx @@ -0,0 +1,422 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <iostream> +#include <stdio.h> +#include <string.h> + +#include "registry/registry.hxx" +#include "registry/reflread.hxx" +#include "registry/reflwrit.hxx" +#include "regdiagnose.h" +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> + + +using namespace std; +using namespace rtl; + +sal_Int32 lValue1 = 123456789; +sal_Int32 lValue2 = 54321; +sal_Int32 lValue3 = 111333111; +sal_Int32 lValue4 = 333111333; +sal_Char* sValue = (sal_Char*)"string Value"; +OUString wValue = rtl::OUString::createFromAscii( "unicode Value" ); + + +void test_generateMerge1() +{ + Registry *myRegistry = new Registry(); + + RegistryKey rootKey, key1, key2, key3, key4, key5, key6, key7, key8, key9; + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("merge1.rdb")), "testGenerateMerge1 error 1"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "testGenerateMerge1 error 2"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("MergeKey1"), key1), "testGenerateMerge1 error 3"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey1"), key2), "testGenerateMerge1 error 4"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey1/KeyWithLongValue"), key3), "testGenerateMerge1 error 5"); + REG_ENSURE(!key3.setValue(OUString(), RG_VALUETYPE_LONG, &lValue1, sizeof(sal_Int32)), "testGenerateMerge1 error 5a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey2"), key4), "testGenerateMerge1 error 6"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey2/KeyWithStringValue"), key5), "testGenerateMerge1 error 7"); + REG_ENSURE(!key5.setValue(OUString(), RG_VALUETYPE_STRING, sValue, strlen(sValue)+1), "testGenerateMerge1 error 7a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey3"), key6), "testGenerateMerge1 error 8"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey3/KeyWithUnicodeValue"), key7), "testGenerateMerge1 error 9"); + REG_ENSURE(!key7.setValue(OUString(), RG_VALUETYPE_UNICODE, (void*)wValue.getStr(), ((wValue.getLength()+1)*sizeof(sal_Unicode))), "testGenerateMerge1 error 9a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey4"), key8), "testGenerateMerge1 error 10"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1/MK1SubKey4/KeyWithBinaryValue"), key9), "testGenerateMerge1 error 11"); + REG_ENSURE(!key9.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)"abcdefghijklmnopqrstuvwxyz", 27), "testGenerateMerge1 error 11a"); + + + REG_ENSURE(!key1.closeKey() && + !key2.closeKey() && + !key3.closeKey() && + !key4.closeKey() && + !key5.closeKey() && + !key6.closeKey() && + !key7.closeKey() && + !key8.closeKey() && + !key9.closeKey(), "testGenerateMerge1 error 12"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("MergeKey1u2"), key1), "testGenerateMerge1 error 13"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey11"), key2), "testGenerateMerge1 error 14"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey11/KeyWithLongValue"), key3), "testGenerateMerge1 error 15"); + REG_ENSURE(!key3.setValue(OUString(), RG_VALUETYPE_LONG, &lValue2, sizeof(sal_Int32)), "testGenerateMerge1 error 15a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey12"), key4), "testGenerateMerge1 error 16"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey12/KeyWithStringValue"), key5), "testGenerateMerge1 error 17"); + REG_ENSURE(!key5.setValue(OUString(), RG_VALUETYPE_STRING, sValue, strlen(sValue)+1), "testGenerateMerge1 error 17a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey13"), key6), "testGenerateMerge1 error 18"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey13/KeyWithUnicodeValue"), key7), "testGenerateMerge1 error 19"); + REG_ENSURE(!key7.setValue(OUString(), RG_VALUETYPE_UNICODE, (void*)wValue.getStr(), ((wValue.getLength()+1)*sizeof(sal_Unicode))), "testGenerateMerge1 error 19a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2"), key8), "testGenerateMerge1 error 20"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2/KeyWithLongValue"), key9), "testGenerateMerge1 error 21"); + REG_ENSURE(!key9.setValue(OUString(), RG_VALUETYPE_LONG, &lValue3, sizeof(sal_Int32)), "testGenerateMerge1 error 21a"); + + REG_ENSURE(!rootKey.closeKey() && + !key1.closeKey() && + !key2.closeKey() && + !key3.closeKey() && + !key4.closeKey() && + !key5.closeKey() && + !key6.closeKey() && + !key7.closeKey() && + !key8.closeKey() && + !key9.closeKey(), "testGenerateMerge1 error 22"); + + + delete myRegistry; + + cout << "test_generateMerge1() Ok!\n"; + return; +} + +void test_generateMerge2() +{ + Registry *myRegistry = new Registry(); + + RegistryKey rootKey, key1, key2, key3, key4, key5, key6, key7, key8, key9; + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("merge2.rdb")), "testGenerateMerge2 error 1"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "testGenerateMerge2 error 2"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("MergeKey2"), key1), "testGenerateMerge2 error 3"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey1"), key2), "testGenerateMerge2 error 4"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey1/KeyWithBinaryValue"), key3), "testGenerateMerge2 error 5"); + REG_ENSURE(!key3.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)"1234567890", 11), "testGenerateMerge1 error 5a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey2"), key4), "testGenerateMerge2 error 6"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey2/KeyWithUnicodeValue"), key5), "testGenerateMerge2 error 7"); + REG_ENSURE(!key5.setValue(OUString(), RG_VALUETYPE_UNICODE, (void*)wValue.getStr(), ((wValue.getLength()+1)*sizeof(sal_Unicode))), "testGenerateMerge1 error 7a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey3"), key6), "testGenerateMerge2 error 8"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey3/KeyWithStringValue"), key7), "testGenerateMerge2 error 9"); + REG_ENSURE(!key7.setValue(OUString(), RG_VALUETYPE_STRING, sValue, strlen(sValue)+1), "testGenerateMerge1 error 9a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey4"), key8), "testGenerateMerge2 error 10"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey2/MK2SubKey4/KeyWithLongValue"), key9), "testGenerateMerge2 error 11"); + REG_ENSURE(!key9.setValue(OUString(), RG_VALUETYPE_LONG, &lValue1, sizeof(sal_Int32)), "testGenerateMerge1 error 11a"); + + REG_ENSURE(!key1.closeKey() && + !key2.closeKey() && + !key3.closeKey() && + !key4.closeKey() && + !key5.closeKey() && + !key6.closeKey() && + !key7.closeKey() && + !key8.closeKey() && + !key9.closeKey(), "testGenerateMerge2 error 12"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("MergeKey1u2"), key1), "testGenerateMerge2 error 13"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey21"), key2), "testGenerateMerge2 error 14"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey21/KeyWithBinaryValue"), key3), "testGenerateMerge2 error 15"); + REG_ENSURE(!key3.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)"a1b2c3d4e5f6g7h8i9", 19), "testGenerateMerge1 error 15a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey22"), key4), "testGenerateMerge2 error 16"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey22/KeyWithLongValue"), key5), "testGenerateMerge2 error 17"); + REG_ENSURE(!key5.setValue(OUString(), RG_VALUETYPE_LONG, &lValue2, sizeof(sal_Int32)), "testGenerateMerge1 error 17a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey23"), key6), "testGenerateMerge2 error 18"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey23/KeyWithStringValue"), key7), "testGenerateMerge2 error 19"); + REG_ENSURE(!key7.setValue(OUString(), RG_VALUETYPE_STRING, sValue, strlen(sValue)+1), "testGenerateMerge1 error 19a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2"), key8), "testGenerateMerge2 error 20"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2/KeyWithLongValue"), key9), "testGenerateMerge2 error 21"); + REG_ENSURE(!key9.setValue(OUString(), RG_VALUETYPE_LONG, &lValue4, sizeof(sal_Int32)), "testGenerateMerge1 error 21a"); + + REG_ENSURE(!rootKey.closeKey() && + !key1.closeKey() && + !key2.closeKey() && + !key3.closeKey() && + !key4.closeKey() && + !key5.closeKey() && + !key6.closeKey() && + !key7.closeKey() && + !key8.closeKey() && + !key9.closeKey(), "testGenerateMerge2 error 22"); + + + delete myRegistry; + + cout << "test_generateMerge2() Ok!\n"; + return; +} + +void test_merge() +{ + Registry *myRegistry = new Registry(); + + RegistryKey rootKey, key1, mkey1, key2, mkey2, key1u2, mkey1u2; + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("mergetest.rdb")), "testMerge error 1"); + REG_ENSURE(myRegistry->getName().equals(OUString::createFromAscii("mergetest.rdb")), "testMerge error 1.a)"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "testMerge error 2"); + REG_ENSURE(!myRegistry->loadKey(rootKey, OUString::createFromAscii("/stardiv/IchbineinMergeKey"), + OUString::createFromAscii("merge1.rdb")), "testMerge error 3"); + REG_ENSURE(!myRegistry->mergeKey(rootKey, OUString::createFromAscii("/stardiv/IchbineinMergeKey"), + OUString::createFromAscii("merge2.rdb")), "testMerge error 4"); + + /////////////////////////////////////////////////////////////////////////// + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/stardiv/IchbineinMergeKey"), key1), "testMerge error 5"); + + REG_ENSURE(!key1.openKey(OUString::createFromAscii("MergeKey1"), mkey1), "testMerge error 6"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 7"); + + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey1"), mkey1), "testMerge error 8"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 9"); + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey1/KeyWithLongValue"), mkey1), "testMerge error 10"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 11"); + + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey2"), mkey1), "testMerge error 12"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 13"); + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey2/KeyWithStringValue"), mkey1), "testMerge error 14"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 15"); + + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey3"), mkey1), "testMerge error 16"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 17"); + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey3/KeyWithUnicodeValue"), mkey1), "testMerge error 18"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 19"); + + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey4"), mkey1), "testMerge error 20"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 21"); + REG_ENSURE(!key1.openKey(OUString::createFromAscii("/MergeKey1/MK1SubKey4/KeyWithBinaryValue"), mkey1), "testMerge error 22"); + REG_ENSURE(!mkey1.closeKey(), "testMerge error 23"); + + REG_ENSURE(!key1.closeKey(), "testMerge error 24"); + + /////////////////////////////////////////////////////////////////////////// + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/stardiv/IchbineinMergeKey"), key2), "testMerge error 25"); + + REG_ENSURE(!key2.openKey(OUString::createFromAscii("MergeKey2"), mkey2), "testMerge error 26"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 27"); + + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey1"), mkey2), "testMerge error 28"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 29"); + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey1/KeyWithBinaryValue"), mkey2), "testMerge error 30"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 31"); + + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey2"), mkey2), "testMerge error 31"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 33"); + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey2/KeyWithUnicodeValue"), mkey2), "testMerge error 34"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 35"); + + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey3"), mkey2), "testMerge error 36"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 37"); + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey3/KeyWithStringValue"), mkey2), "testMerge error 38"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 39"); + + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey4"), mkey2), "testMerge error 40"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 41"); + REG_ENSURE(!key2.openKey(OUString::createFromAscii("/MergeKey2/MK2SubKey4/KeyWithLongValue"), mkey2), "testMerge error 42"); + REG_ENSURE(!mkey2.closeKey(), "testMerge error 43"); + + REG_ENSURE(!key2.closeKey(), "testMerge error 44"); + + /////////////////////////////////////////////////////////////////////////// + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/stardiv/IchbineinMergeKey"), key1u2), "testMerge error 40"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("MergeKey1u2"), mkey1u2), "testMerge error 41"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 42"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey11"), mkey1u2), "testMerge error 43"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 44"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey11/KeyWithLongValue"), mkey1u2), "testMerge error 45"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 46"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey12"), mkey1u2), "testMerge error 47"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 48"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey12/KeyWithStringValue"), mkey1u2), "testMerge error 49"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 50"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey13"), mkey1u2), "testMerge error 51"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 52"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK1SubKey13/KeyWithUnicodeValue"), mkey1u2), "testMerge error 53"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 54"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey21"), mkey1u2), "testMerge error 55"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 56"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey21/KeyWithBinaryValue"), mkey1u2), "testMerge error 57"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 58"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey22"), mkey1u2), "testMerge error 59"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 60"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey22/KeyWithLongValue"), mkey1u2), "testMerge error 61"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 62"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey23"), mkey1u2), "testMerge error 63"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 64"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK2SubKey23/KeyWithStringValue"), mkey1u2), "testMerge error 65"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 66"); + + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2"), mkey1u2), "testMerge error 67"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 68"); + REG_ENSURE(!key1u2.openKey(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2/KeyWithLongValue"), mkey1u2), "testMerge error 69"); + REG_ENSURE(!mkey1u2.closeKey(), "testMerge error 70"); + + REG_ENSURE(!key1u2.closeKey(), "testMerge error 71"); + + /////////////////////////////////////////////////////////////////////////// + + RegValueType valueType; + sal_uInt32 valueSize; + sal_Int32 int32Value; + sal_uInt8 *Value; + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/stardiv/IchbineinMergeKey"), key1), "testMerge error 72"); + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1/MK1SubKey1/KeyWithLongValue"), &valueType, &valueSize), "testMerge error 73"); + REG_ENSURE(valueType == RG_VALUETYPE_LONG && valueSize == sizeof(sal_Int32), "testMerge error 74"); + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1/MK1SubKey1/KeyWithLongValue"), (RegValue)&int32Value), "testMerge error 74.a)"); + REG_ENSURE(int32Value == lValue1, "testMerge error 74.b)"); + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1/MK1SubKey2/KeyWithStringValue"), &valueType, &valueSize), "testMerge error 75"); + REG_ENSURE(valueType == RG_VALUETYPE_STRING && valueSize == strlen(sValue)+1, "testMerge error 76"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1/MK1SubKey2/KeyWithStringValue"), (RegValue)Value), "testMerge error 76.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, sValue) == 0, "testMerge error 76.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1/MK1SubKey3/KeyWithUnicodeValue"), &valueType, &valueSize), "testMerge error 77"); + REG_ENSURE(valueType == RG_VALUETYPE_UNICODE && valueSize == (wValue.getLength()+1)*sizeof(sal_Unicode), "testMerge error 78"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1/MK1SubKey3/KeyWithUnicodeValue"), (RegValue)Value), "testMerge error 78.a)"); + REG_ENSURE(wValue.equals( (const sal_Unicode*)Value ), "testMerge error 78.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1/MK1SubKey4/KeyWithBinaryValue"), &valueType, &valueSize), "testMerge error 79"); + REG_ENSURE(valueType == RG_VALUETYPE_BINARY && valueSize == 27, "testMerge error 80"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1/MK1SubKey4/KeyWithBinaryValue"), (RegValue)Value), "testMerge error 80.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, "abcdefghijklmnopqrstuvwxyz") == 0, "testMerge error 80.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey2/MK2SubKey1/KeyWithBinaryValue"), &valueType, &valueSize), "testMerge error 81"); + REG_ENSURE(valueType == RG_VALUETYPE_BINARY && valueSize == 11, "testMerge error 82"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey2/MK2SubKey1/KeyWithBinaryValue"), (RegValue)Value), "testMerge error 82.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, "1234567890") == 0, "testMerge error 82.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey2/MK2SubKey2/KeyWithUnicodeValue"), &valueType, &valueSize), "testMerge error 83"); + REG_ENSURE(valueType == RG_VALUETYPE_UNICODE&& valueSize == (wValue.getLength()+1)*sizeof(sal_Unicode), "testMerge error 84"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey2/MK2SubKey2/KeyWithUnicodeValue"), (RegValue)Value), "testMerge error 84.a)"); + REG_ENSURE(wValue.equals( (const sal_Unicode*)Value ), "testMerge error 84.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey2/MK2SubKey3/KeyWithStringValue"), &valueType, &valueSize), "testMerge error 85"); + REG_ENSURE(valueType == RG_VALUETYPE_STRING && valueSize == strlen(sValue)+1, "testMerge error 86"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey2/MK2SubKey3/KeyWithStringValue"), (RegValue)Value), "testMerge error 86.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, sValue) == 0, "testMerge error 86.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey2/MK2SubKey4/KeyWithLongValue"), &valueType, &valueSize), "testMerge error 87"); + REG_ENSURE(valueType == RG_VALUETYPE_LONG && valueSize == sizeof(sal_Int32), "testMerge error 88"); + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey2/MK2SubKey4/KeyWithLongValue"), (RegValue)&int32Value), "testMerge error 88.a)"); + REG_ENSURE(int32Value == lValue1, "testMerge error 88.b)"); + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK1SubKey11/KeyWithLongValue"), &valueType, &valueSize), "testMerge error 89"); + REG_ENSURE(valueType == RG_VALUETYPE_LONG && valueSize == sizeof(sal_Int32), "testMerge error 90"); + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK1SubKey11/KeyWithLongValue"), (RegValue)&int32Value), "testMerge error 90.a)"); + REG_ENSURE(int32Value == lValue2, "testMerge error 90.b)"); + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK1SubKey12/KeyWithStringValue"), &valueType, &valueSize), "testMerge error 91"); + REG_ENSURE(valueType == RG_VALUETYPE_STRING && valueSize == strlen(sValue)+1, "testMerge error 92"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK1SubKey12/KeyWithStringValue"), (RegValue)Value), "testMerge error 92.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, sValue) == 0, "testMerge error 92.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK1SubKey13/KeyWithUnicodeValue"), &valueType, &valueSize), "testMerge error 93"); + REG_ENSURE(valueType == RG_VALUETYPE_UNICODE && valueSize == (wValue.getLength()+1)*sizeof(sal_Unicode), "testMerge error 94"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK1SubKey13/KeyWithUnicodeValue"), (RegValue)Value), "testMerge error 94.a)"); + REG_ENSURE(wValue.equals( (const sal_Unicode*)Value ), "testMerge error 94.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK2SubKey21/KeyWithBinaryValue"), &valueType, &valueSize), "testMerge error 95"); + REG_ENSURE(valueType == RG_VALUETYPE_BINARY && valueSize == 19, "testMerge error 96"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK2SubKey21/KeyWithBinaryValue"), (RegValue)Value), "testMerge error 96.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, "a1b2c3d4e5f6g7h8i9") == 0, "testMerge error 96.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK2SubKey22/KeyWithLongValue"), &valueType, &valueSize), "testMerge error 97"); + REG_ENSURE(valueType == RG_VALUETYPE_LONG && valueSize == sizeof(sal_Int32), "testMerge error 98"); + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK2SubKey22/KeyWithLongValue"), (RegValue)&int32Value), "testMerge error 98.a)"); + REG_ENSURE(int32Value == lValue2, "testMerge error 98.b)"); + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK2SubKey23/KeyWithStringValue"), &valueType, &valueSize), "testMerge error 99"); + REG_ENSURE(valueType == RG_VALUETYPE_STRING && valueSize == strlen(sValue)+1, "testMerge error 100"); + Value = new sal_uInt8[valueSize]; + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK2SubKey23/KeyWithStringValue"), (RegValue)Value), "testMerge error 100.a)"); + REG_ENSURE(strcmp((const sal_Char*)Value, sValue) == 0, "testMerge error 100.b)"); + delete [] Value; + + REG_ENSURE(!key1.getValueInfo(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2/KeyWithLongValue"), &valueType, &valueSize), "testMerge error 101"); + REG_ENSURE(valueType == RG_VALUETYPE_LONG && valueSize == sizeof(sal_Int32), "testMerge error 102"); + REG_ENSURE(!key1.getValue(OUString::createFromAscii("/MergeKey1u2/MK12SubKey1u2/KeyWithLongValue"), (RegValue)&int32Value), "testMerge error 102.a)"); + REG_ENSURE(int32Value == lValue4, "testMerge error 102.b)"); + + + REG_ENSURE(!key1.closeKey(), "testMerge error 24"); + + /////////////////////////////////////////////////////////////////////////// + + REG_ENSURE(!rootKey.closeKey(), "testMerge error 10"); + + REG_ENSURE(!myRegistry->destroy( OUString::createFromAscii("merge1.rdb") ), "test_registry_CppApi error 11"); + REG_ENSURE(!myRegistry->destroy( OUString::createFromAscii("merge2.rdb") ), "test_registry_CppApi error 12"); + REG_ENSURE(!myRegistry->destroy( OUString() ), "test_registry_CppApi error 13"); + + delete myRegistry; + + cout << "test_merge() Ok!\n"; + return; +} + + diff --git a/registry/test/testregcpp.cxx b/registry/test/testregcpp.cxx new file mode 100644 index 000000000000..398936c40e3e --- /dev/null +++ b/registry/test/testregcpp.cxx @@ -0,0 +1,707 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <iostream> +#include <stdio.h> +#include <string.h> + +#include "registry/registry.hxx" +#include "registry/reflread.hxx" +#include "registry/reflwrit.hxx" +#include "regdiagnose.h" +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> + +using namespace std; +using namespace rtl; + +void test_coreReflection() +{ + Registry *myRegistry = new Registry(); + + RegistryKey rootKey, key1, key2, key3, key4 ,key5, key6, key7, key8; + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("ucrtest.rdb")), "testCoreReflection error 1"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "testCoreReflection error 2"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("UCR"), key1), "testCoreReflection error 3"); + REG_ENSURE(!key1.createKey(OUString::createFromAscii("ModuleA"), key2), "testCoreReflection error 4"); + REG_ENSURE(!key2.createKey(OUString::createFromAscii("StructA"), key3), "testCoreReflection error 5"); + REG_ENSURE(!key2.createKey(OUString::createFromAscii("EnumA"), key4), "testCoreReflection error 6"); + REG_ENSURE(!key2.createKey(OUString::createFromAscii("XInterfaceA"), key5), "testCoreReflection error 7"); + REG_ENSURE(!key2.createKey(OUString::createFromAscii("ExceptionA"), key6), "testCoreReflection error 8"); + REG_ENSURE(!key2.createKey(OUString::createFromAscii("ServiceA"), key7), "testCoreReflection error 8a"); + REG_ENSURE(!key2.createKey(OUString::createFromAscii("ConstantsA"), key8), "testCoreReflection error 8b"); + + { + RegistryTypeWriter writer(RT_TYPE_MODULE, + OUString::createFromAscii("ModuleA"), + OUString(), 11, 0, 0); + + RTConstValue aConst; + + writer.setDoku(OUString::createFromAscii("Hallo ich bin ein Modul")); + writer.setFileName(OUString::createFromAscii("DummyFile")); + + aConst.m_type = RT_TYPE_BOOL; + aConst.m_value.aBool = sal_True; + writer.setFieldData(0, OUString::createFromAscii("aConstBool"), + OUString::createFromAscii("boolean"), + OUString::createFromAscii("ich bin ein boolean"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_BYTE; + aConst.m_value.aByte = 127; + writer.setFieldData(1, OUString::createFromAscii("aConstByte"), + OUString::createFromAscii("byte"), + OUString::createFromAscii("ich bin ein byte"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_INT16; + aConst.m_value.aShort = -10; + writer.setFieldData(2, OUString::createFromAscii("aConstShort"), + OUString::createFromAscii("short"), + OUString::createFromAscii("ich bin ein short"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_UINT16; + aConst.m_value.aUShort = 10; + writer.setFieldData(3, OUString::createFromAscii("aConstUShort"), + OUString::createFromAscii("unsigned short"), + OUString::createFromAscii("ich bin ein unsigned short"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_INT32; + aConst.m_value.aLong = -100000; + writer.setFieldData(4, OUString::createFromAscii("aConstLong"), + OUString::createFromAscii("long"), + OUString::createFromAscii("ich bin ein long"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_UINT32; + aConst.m_value.aULong = 100000; + writer.setFieldData(5, OUString::createFromAscii("aConstULong"), + OUString::createFromAscii("unsigned long"), + OUString::createFromAscii("ich bin ein unsigned long"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_INT64; + aConst.m_value.aHyper = -100000000; + writer.setFieldData(6, OUString::createFromAscii("aConstHyper"), + OUString::createFromAscii("hyper"), + OUString::createFromAscii("ich bin ein hyper"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_UINT64; + aConst.m_value.aUHyper = 100000000; + writer.setFieldData(7, OUString::createFromAscii("aConstULong"), + OUString::createFromAscii("unsigned long"), + OUString::createFromAscii("ich bin ein unsigned long"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_FLOAT; + aConst.m_value.aFloat = -2e-10f; + writer.setFieldData(8, OUString::createFromAscii("aConstFloat"), + OUString::createFromAscii("float"), + OUString::createFromAscii("ich bin ein float"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_DOUBLE; + aConst.m_value.aDouble = -2e-100; writer.setFieldData(9, OUString::createFromAscii("aConstDouble"), + OUString::createFromAscii("double"), + OUString::createFromAscii("ich bin ein double"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_STRING; + OUString tmpStr(OUString::createFromAscii( "dies ist ein unicode string" )); + aConst.m_value.aString = tmpStr.getStr(); + + writer.setFieldData(10, OUString::createFromAscii("aConstString"), + OUString::createFromAscii("string"), + OUString::createFromAscii("ich bin ein string"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key2.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9"); + + sal_uInt8* readBlop = (sal_uInt8*)rtl_allocateMemory(aBlopSize); + REG_ENSURE(!key2.getValue(OUString(), (void*)readBlop) , "testCoreReflection error 9a"); + + RegistryTypeReader reader(readBlop, aBlopSize, sal_True); + + if (reader.isValid()) + { + REG_ENSURE(reader.getTypeName().equals(OUString::createFromAscii("ModuleA")), "testCoreReflection error 9a2"); + + RTConstValue aReadConst = reader.getFieldConstValue(4); + REG_ENSURE( aReadConst.m_type == RT_TYPE_INT32, "testCoreReflection error 9a3"); + REG_ENSURE( aReadConst.m_value.aLong == -100000, "testCoreReflection error 9a4"); + + aReadConst = reader.getFieldConstValue(6); + REG_ENSURE( aReadConst.m_type == RT_TYPE_INT64, "testCoreReflection error 9a5"); + REG_ENSURE( aReadConst.m_value.aHyper == -100000000, "testCoreReflection error 9a6"); + + aReadConst = reader.getFieldConstValue(10); + OString aConstStr = OUStringToOString(aConst.m_value.aString, RTL_TEXTENCODING_ASCII_US); + REG_ENSURE(aConstStr.equals("dies ist ein unicode string"), "testCoreReflection error 9b"); + } + + } + + { + RegistryTypeWriter writer(RT_TYPE_STRUCT, + OUString::createFromAscii("ModuleA/StructA"), + OUString(), 3, 0, 0); + + writer.setDoku(OUString::createFromAscii("Hallo ich bin eine Struktur")); + writer.setFileName(OUString::createFromAscii("DummyFile")); + + writer.setFieldData(0, OUString::createFromAscii("asal_uInt32"), + OUString::createFromAscii("unsigned long"), + OUString(), OUString(), RT_ACCESS_READWRITE); + writer.setFieldData(1, OUString::createFromAscii("aXInterface"), + OUString::createFromAscii("stardiv/uno/XInterface"), + OUString(), OUString(), RT_ACCESS_READWRITE); + writer.setFieldData(2, OUString::createFromAscii("aSequence"), + OUString::createFromAscii("[]ModuleA/EnumA"), + OUString(), OUString(), RT_ACCESS_READWRITE); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key3.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9a"); + } + + { + RegistryTypeWriter writer(RT_TYPE_ENUM, + OUString::createFromAscii("ModuleA/EnumA"), + OUString(), 2, 0, 0); + + RTConstValue aConst; + + aConst.m_type = RT_TYPE_UINT32; + aConst.m_value.aULong = 10; + + writer.setDoku(OUString::createFromAscii("Hallo ich bin ein Enum")); + writer.setFileName(OUString::createFromAscii("DummyFile")); + + writer.setFieldData(0, OUString::createFromAscii("ENUM_VAL_1"), + OUString(), OUString::createFromAscii("ich bin ein enum value"), + OUString(), RT_ACCESS_CONST, aConst); + + aConst.m_value.aULong = 10; + writer.setFieldData(1, OUString::createFromAscii("ENUM_VAL_2"), + OUString(), OUString(), OUString(), RT_ACCESS_CONST, aConst); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key4.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9b"); + } + + { + RegistryTypeWriter writer(RT_TYPE_INTERFACE, + OUString::createFromAscii("ModuleA/XInterfaceA"), + OUString::createFromAscii("stardiv/uno/XInterface"), + 4, 1, 0); + RTConstValue aConst; + + RTUik aUik = {1,2,3,4,5}; + + writer.setUik(aUik); + writer.setDoku(OUString::createFromAscii("Hallo ich bin ein Interface")); + writer.setFileName(OUString::createFromAscii("DummyFile")); + + writer.setFieldData(0, OUString::createFromAscii("aString"), + OUString::createFromAscii("string"), OUString(), OUString(), RT_ACCESS_READWRITE); + writer.setFieldData(1, OUString::createFromAscii("aStruct"), + OUString::createFromAscii("ModuleA/StructA"), + OUString(), OUString(), RT_ACCESS_READONLY); + writer.setFieldData(2, OUString::createFromAscii("aEnum"), + OUString::createFromAscii("ModuleA/EnumA"), OUString(), OUString(), RT_ACCESS_BOUND); + aConst.m_type = RT_TYPE_UINT16; + aConst.m_value.aUShort = 12; + writer.setFieldData(3, OUString::createFromAscii("aConstUShort"), + OUString::createFromAscii("unsigned short"), OUString(), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + + writer.setMethodData(0, OUString::createFromAscii("methodA"), + OUString::createFromAscii("double"), RT_MODE_TWOWAY, 2, 1, + OUString::createFromAscii("Hallo ich bin die methodA")); + writer.setParamData(0, 0, OUString::createFromAscii("ModuleA/StructA"), + OUString::createFromAscii("aStruct"), RT_PARAM_IN); + writer.setParamData(0, 1, OUString::createFromAscii("unsigned short"), + OUString::createFromAscii("aShort"), RT_PARAM_INOUT); + writer.setExcData(0, 0, OUString::createFromAscii("ModuleA/ExceptionA")); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key5.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9c"); + + sal_uInt8* readBlop = (sal_uInt8*)rtl_allocateMemory(aBlopSize); + REG_ENSURE(!key5.getValue(OUString(), (void*)readBlop) , "testCoreReflection error 9c1"); + + RegistryTypeReader reader(readBlop, aBlopSize, sal_True); + + if (reader.isValid()) + { + REG_ENSURE(reader.getTypeName().equals(OUString::createFromAscii("ModuleA/XInterfaceA")), "testCoreReflection error 9c2"); + + RTUik retUik; + reader.getUik(retUik); + REG_ENSURE(retUik.m_Data1 = 1, "testCoreReflection error 9c3"); + REG_ENSURE(retUik.m_Data2 = 2, "testCoreReflection error 9c4"); + REG_ENSURE(retUik.m_Data3 = 3, "testCoreReflection error 9c5"); + REG_ENSURE(retUik.m_Data4 = 4, "testCoreReflection error 9c6"); + REG_ENSURE(retUik.m_Data5 = 5, "testCoreReflection error 9c7"); + } + + } + + { + RegistryTypeWriter writer(RT_TYPE_EXCEPTION, + OUString::createFromAscii("ModuleA/ExceptionA"), + OUString(), 1, 0, 0); + + writer.setDoku(OUString::createFromAscii("Hallo ich bin eine Exception")); + + writer.setFieldData(0, OUString::createFromAscii("aSource"), + OUString::createFromAscii("stardiv/uno/XInterface"), + OUString::createFromAscii("ich bin ein interface member"), + OUString(), RT_ACCESS_READWRITE); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key6.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9d"); + } + + { + RegistryTypeWriter writer(RT_TYPE_SERVICE, + OUString::createFromAscii("ModuleA/ServiceA"), + OUString(), 1, 0, 4); + + writer.setDoku(OUString::createFromAscii("Hallo ich bin ein Service")); + writer.setFileName(OUString::createFromAscii("DummyFile")); + + writer.setFieldData(0, OUString::createFromAscii("aProperty"), + OUString::createFromAscii("stardiv/uno/XInterface"), + OUString::createFromAscii("ich bin eine property"), + OUString(), RT_ACCESS_READWRITE); + + writer.setReferenceData(0, OUString::createFromAscii("ModuleA/XInterfaceA"), RT_REF_SUPPORTS, + OUString::createFromAscii("Hallo ich eine Reference auf ein supported interface"), + RT_ACCESS_OPTIONAL); + writer.setReferenceData(1, OUString::createFromAscii("ModuleA/XInterfaceA"), RT_REF_OBSERVES, + OUString::createFromAscii("Hallo ich eine Reference auf ein observed interface")); + writer.setReferenceData(2, OUString::createFromAscii("ModuleA/ServiceB"), RT_REF_EXPORTS, + OUString::createFromAscii("Hallo ich eine Reference auf einen exported service")); + writer.setReferenceData(3, OUString::createFromAscii("ModuleA/ServiceB"), RT_REF_NEEDS, + OUString::createFromAscii("Hallo ich eine Reference auf einen needed service")); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key7.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9e"); + sal_uInt8* readBlop = (sal_uInt8*)rtl_allocateMemory(aBlopSize); + REG_ENSURE(!key7.getValue(OUString(), (void*)readBlop) , "testCoreReflection error 9e2"); + + RegistryTypeReader reader(readBlop, aBlopSize, sal_True); + + if (reader.isValid()) + { + REG_ENSURE(reader.getTypeName().equals(OUString::createFromAscii("ModuleA/ServiceA")), "testCoreReflection error 9e3"); + + sal_uInt32 referenceCount = reader.getReferenceCount(); + REG_ENSURE( referenceCount == 4, "testCoreReflection error 9e4"); + + OUString refName = reader.getReferenceName(0); + REG_ENSURE(refName.equals(OUString::createFromAscii("ModuleA/XInterfaceA")), "testCoreReflection error 9e5"); + } + } + + { + RegistryTypeWriter writer(RT_TYPE_CONSTANTS, + OUString::createFromAscii("ModuleA/ConstansA"), + OUString(), 3, 0, 0); + + RTConstValue aConst; + + writer.setDoku(OUString::createFromAscii("Hallo ich bin eine Constants Group")); + writer.setFileName(OUString::createFromAscii("DummyFile")); + + aConst.m_type = RT_TYPE_BOOL; + aConst.m_value.aBool = sal_True; + writer.setFieldData(0, OUString::createFromAscii("ConstantsA_aConstBool"), + OUString::createFromAscii("boolean"), + OUString::createFromAscii("ich bin ein boolean"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_BYTE; + aConst.m_value.aByte = 127; + writer.setFieldData(1, OUString::createFromAscii("ConstantsA_aConstByte"), + OUString::createFromAscii("byte"), + OUString::createFromAscii("ich bin ein byte"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + aConst.m_type = RT_TYPE_INT16; + aConst.m_value.aShort = -10; + writer.setFieldData(2, OUString::createFromAscii("ConstantsA_aConstShort"), + OUString::createFromAscii("short"), + OUString::createFromAscii("ich bin ein short"), + OUString::createFromAscii("DummyFile"), RT_ACCESS_CONST, aConst); + + const sal_uInt8* pBlop = writer.getBlop(); + sal_uInt32 aBlopSize = writer.getBlopSize(); + + REG_ENSURE(!key8.setValue(OUString(), RG_VALUETYPE_BINARY, (void*)pBlop, aBlopSize), "testCoreReflection error 9f"); + } + +// REG_ENSURE(!myRegistry->destroy(NULL), "testCoreReflection error 10"); + delete myRegistry; + + cout << "test_coreReflection() Ok!\n"; +} + +void test_registry_CppApi() +{ + Registry *myRegistry = new Registry(); + + RegistryKey rootKey, key1, key2, key3, key4 ,key5, key6, key7, key8, key9; + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("test.rdb")), "test_registry_CppApi error 1"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "test_registry_CppApi error 2"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("myFirstKey"), key1), "test_registry_CppApi error 3"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("mySecondKey"), key2), "test_registry_CppApi error 4"); + REG_ENSURE(!key1.createKey(OUString::createFromAscii("X"), key3), "test_registry_CppApi error 5"); + REG_ENSURE(!key1.createKey(OUString::createFromAscii("mySecondSubKey"), key4), "test_registry_CppApi error 6"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("myThirdKey"), key5), "test_registry_CppApi error 6a"); + + REG_ENSURE(!key5.createKey(OUString::createFromAscii("1"), key4), "test_registry_CppApi error 6b"); + REG_ENSURE(!key4.createKey(OUString::createFromAscii("2"), key3), "test_registry_CppApi error 6c"); + REG_ENSURE(!key5.openKey(OUString::createFromAscii("1"), key4), "test_registry_CppApi error 6d"); + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/myThirdKey/1"), key4), "test_registry_CppApi error 6e"); + REG_ENSURE(key4.getName().equals(OUString::createFromAscii("/myThirdKey/1")), "test_registry_CppApi error 6f"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("myFourthKey"), key6), "test_registry_CppApi error 7"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("myFifthKey"), key6), "test_registry_CppApi error 7a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("mySixthKey"), key6), "test_registry_CppApi error 7b"); + + // Link Test + // + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/myFourthKey/X"), key7), "test_registry_CppApi error 7c)");; + REG_ENSURE(!key6.createLink(OUString::createFromAscii("myFirstLink"), OUString::createFromAscii("/myFourthKey/X")), "test_registry_CppApi error 7d"); + REG_ENSURE(!key6.createKey(OUString::createFromAscii("mySixthSubKey"), key7), "test_registry_CppApi error 7e"); + + OUString linkTarget; + REG_ENSURE(!key6.getLinkTarget(OUString::createFromAscii("myFirstLink"), linkTarget), "test_registry_CppApi error 7f"); + REG_ENSURE(linkTarget.equals(OUString::createFromAscii("/myFourthKey/X")), "test_registry_CppApi error 7g"); + + RegistryKeyNames* pSubKeyNames = new RegistryKeyNames(); + sal_uInt32 nSubKeys=0; + + REG_ENSURE(!rootKey.getKeyNames(OUString::createFromAscii("mySixthKey"), *pSubKeyNames), "test_registry_CppApi error 7h)"); + REG_ENSURE(pSubKeyNames->getLength() == 2, "test_registry_CppApi error 7i)"); + + for (sal_uInt32 i=0; i < pSubKeyNames->getLength(); i++) + { + if (pSubKeyNames->getElement(i).equals(OUString::createFromAscii("/mySixthKey/myFirstLink"))) + { + RegKeyType keyType; + REG_ENSURE(!rootKey.getKeyType(pSubKeyNames->getElement(i), &keyType), "test_registry_CppApi error 7j"); + REG_ENSURE(keyType == RG_LINKTYPE, "test_registry_CppApi error 7k"); + } + } + + REG_ENSURE(!key7.closeKey(), "test_registry_CppApi error 7k1"); + delete pSubKeyNames; + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/mySixthKey/myFirstLink"), key6), "test_registry_CppApi error 7l"); +// REG_ENSURE(key6.getName().equals(OUString::createFromAscii("/myFourthKey/X")), "test_registry_CppApi error 7m"); + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("myFifthKey"), key6), "test_registry_CppApi error 7m1"); + REG_ENSURE(!key6.createLink(OUString::createFromAscii("mySecondLink"), + OUString::createFromAscii("/mySixthKey/myFirstLink")), "test_registry_CppApi error 7m2"); + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/myFifthKey/mySecondLink"), key6), "test_registry_CppApi error 7m3"); +// REG_ENSURE(key6.getName().equals(OUString::createFromAscii("/myFourthKey/X")), "test_registry_CppApi error 7m4"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/myFifthKey/mySecondLink/myFirstLinkSubKey"), key7), "test_registry_CppApi error 7m5"); + REG_ENSURE(key7.getName().equals(OUString::createFromAscii("/myFourthKey/X/myFirstLinkSubKey")), "test_registry_CppApi error 7m6"); + + REG_ENSURE(!key7.createLink(OUString::createFromAscii("myThirdLink"), OUString::createFromAscii("/myFifthKey/mySecondLink")), "test_registry_CppApi error 7m7"); + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/myFourthKey/X/myFirstLinkSubKey/myThirdLink"), key7), "test_registry_CppApi error 7m8"); +// REG_ENSURE(!key7.openKey(OUString::createFromAscii("/myFirstLinkSubKey/myThirdLink/myFirstLinkSubKey/myThirdLink"), key6), "test_registry_CppApi error 7m9"); +// REG_ENSURE(key7.getName().equals(OUString::createFromAscii("/myFourthKey/X")), "test_registry_CppApi error 7m10"); + REG_ENSURE(!key7.closeKey(), "test_registry_CppApi error 7m11"); + + REG_ENSURE(!rootKey.deleteLink(OUString::createFromAscii("/myFifthKey/mySecondLink")), "test_registry_CppApi error 7m12"); + + REG_ENSURE(!rootKey.createLink(OUString::createFromAscii("/myFifthKey/mySecondLink"), + OUString::createFromAscii("/myFourthKey/X/myFirstLinkSubKey/myThirdLink")), + "test_registry_CppApi error 7m13"); + +// REG_ENSURE(rootKey.openKey(OUString::createFromAscii("/myFourthKey/X/myFirstLinkSubKey/myThirdLink"), key7) == REG_DETECT_RECURSION, +// "test_registry_CppApi error 7m14"); + +// REG_ENSURE(key7.closeKey() == REG_INVALID_KEY, "test_registry_CppApi error 7m11"); + + RegistryKeyNames subKeyNames; + nSubKeys=0; + + REG_ENSURE(!rootKey.getKeyNames(OUString::createFromAscii("mySixthKey"), subKeyNames), "test_registry_CppApi error 7n"); + + nSubKeys = subKeyNames.getLength(); + REG_ENSURE(nSubKeys == 2, "test_registry_CppApi error 7n1"); + REG_ENSURE(subKeyNames.getElement(0).equals(OUString::createFromAscii("/mySixthKey/myFirstLink")), "test_registry_CppApi error 7p1)"); + REG_ENSURE(subKeyNames.getElement(1).equals(OUString::createFromAscii("/mySixthKey/mySixthSubKey")), "test_registry_CppApi error 7p2"); + + + RegistryKeyArray subKeys; + nSubKeys=0; + + REG_ENSURE(!rootKey.openSubKeys(OUString::createFromAscii("myFirstKey"), subKeys), "test_registry_CppApi error 7o"); + + nSubKeys = subKeys.getLength(); + REG_ENSURE(nSubKeys == 2, "test_registry_CppApi error 7o1"); + REG_ENSURE(subKeys.getElement(0).getName().equals(OUString::createFromAscii("/myFirstKey/mySecondSubKey")), "test_registry_CppApi error 7p1)"); + REG_ENSURE(subKeys.getElement(1).getName().equals(OUString::createFromAscii("/myFirstKey/X")), "test_registry_CppApi error 7p2"); + + REG_ENSURE(!rootKey.closeSubKeys(subKeys), "test_registry_CppApi error 7q)"); + + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/TEST"), key8), "test_registry_CppApi error 8"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/TEST/Child1"), key8), "test_registry_CppApi error 8a"); + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("/TEST/Child2"), key8), "test_registry_CppApi error 8a1"); + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/TEST"), key9), "test_registry_CppApi error 8b"); + REG_ENSURE(!key8.closeKey() && !key9.closeKey(), "test_registry_CppApi error 8b1"); + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/TEST"), key8), "test_registry_CppApi error 8b"); + REG_ENSURE(!key8.closeKey(), "test_registry_CppApi error 8c"); + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("TEST"), key8), "test_registry_CppApi error 8c"); + REG_ENSURE(!key8.closeKey(), "test_registry_CppApi error 8d"); + + + sal_Char* Value=(sal_Char*)"Mein erster Value"; + REG_ENSURE(!rootKey.setValue(OUString::createFromAscii("mySecondKey"), RG_VALUETYPE_STRING, Value, 18), "test_registry_CppApi error 9"); + + RegValueType valueType; + sal_uInt32 valueSize; + sal_Char* readValue; + REG_ENSURE(!rootKey.getValueInfo(OUString::createFromAscii("mySecondKey"), &valueType, &valueSize), "test_registry_CppApi error 9a"); + + readValue = (sal_Char*)rtl_allocateMemory(valueSize); + REG_ENSURE(!key2.getValue(OUString(), readValue), "test_registry_CppApi error 10"); + + REG_ENSURE(valueType == RG_VALUETYPE_STRING, "test_registry_CppApi error 11"); + REG_ENSURE(valueSize == 18, "test_registry_CppApi error 12"); + REG_ENSURE(strcmp(readValue, Value) == 0, "test_registry_CppApi error 13"); + rtl_freeMemory(readValue); + + const sal_Char* pList[3]; + const sal_Char* n1= "Hallo"; + const sal_Char* n2= "jetzt komm"; + const sal_Char* n3= "ich"; + + pList[0]=n1; + pList[1]=n2; + pList[2]=n3; + + REG_ENSURE(!rootKey.setStringListValue(OUString::createFromAscii("myFourthKey"), (sal_Char**)pList, 3), "test_registry_CppApi error 13a"); + + RegistryValueList<sal_Char*> valueList; + REG_ENSURE(!rootKey.getStringListValue(OUString::createFromAscii("myFourthKey"), valueList), "test_registry_CppApi error 13b"); + + REG_ENSURE(strcmp(n1, valueList.getElement(0)) == 0, "test_registry_CppApi error 13c"); + REG_ENSURE(strcmp(n2, valueList.getElement(1)) == 0, "test_registry_CppApi error 13d"); + REG_ENSURE(strcmp(n3, valueList.getElement(2)) == 0, "test_registry_CppApi error 13e"); + + REG_ENSURE(!rootKey.getValueInfo(OUString::createFromAscii("myFourthKey"), &valueType, &valueSize), "test_registry_CppApi error 13e1"); + REG_ENSURE(valueType == RG_VALUETYPE_STRINGLIST, "test_registry_CppApi error 13e2"); + REG_ENSURE(valueSize == 3, "test_registry_CppApi error 13e3"); + + sal_Int32 pLong[3]; + pLong[0] = 123; + pLong[1] = 456; + pLong[2] = 789; + + REG_ENSURE(!rootKey.setLongListValue(OUString::createFromAscii("myFifthKey"), pLong, 3), "test_registry_CppApi error 13f"); + + RegistryValueList<sal_Int32> longList; + REG_ENSURE(!rootKey.getLongListValue(OUString::createFromAscii("myFifthKey"), longList), "test_registry_CppApi error 13g"); + + REG_ENSURE(pLong[0] == longList.getElement(0), "test_registry_CppApi error 13h"); + REG_ENSURE(pLong[1] == longList.getElement(1), "test_registry_CppApi error 13i"); + REG_ENSURE(pLong[2] == longList.getElement(2), "test_registry_CppApi error 13j"); + + + OUString sWTestValue(OUString::createFromAscii( "Mein erster Unicode Value" )); + const sal_Unicode* wTestValue= sWTestValue.getStr(); + REG_ENSURE(!rootKey.setValue(OUString::createFromAscii("mySixthKey"), RG_VALUETYPE_UNICODE, (void*)wTestValue, + (rtl_ustr_getLength(wTestValue)+1)*sizeof(sal_Unicode)), "test_registry_CppApi error 13j1"); + + REG_ENSURE(!rootKey.getValueInfo(OUString::createFromAscii("mySixthKey"), &valueType, &valueSize), "test_registry_CppApi error 13j2"); + sal_Unicode* pTmpValue = (sal_Unicode*)rtl_allocateMemory(valueSize); + REG_ENSURE(!rootKey.getValue(OUString::createFromAscii("mySixthKey"), pTmpValue), "test_registry_CppApi error 13j3"); + REG_ENSURE(rtl_ustr_getLength(wTestValue) == rtl_ustr_getLength(pTmpValue), "test_registry_CppApi error 13j4"); + REG_ENSURE(rtl_ustr_compare(wTestValue, pTmpValue) == 0, "test_registry_CppApi error 13j4"); + + const sal_Unicode* pUnicode[3]; + OUString w1(OUString::createFromAscii( "Hallo" )); + OUString w2(OUString::createFromAscii( "jetzt komm" )); + OUString w3(OUString::createFromAscii( "ich als unicode" )); + + pUnicode[0]=w1.getStr(); + pUnicode[1]=w2.getStr(); + pUnicode[2]=w3.getStr(); + + REG_ENSURE(!rootKey.setUnicodeListValue(OUString::createFromAscii("mySixthKey"), (sal_Unicode**)pUnicode, 3), "test_registry_CppApi error 13k"); + + RegistryValueList<sal_Unicode*> unicodeList; + REG_ENSURE(!rootKey.getUnicodeListValue(OUString::createFromAscii("mySixthKey"), unicodeList), "test_registry_CppApi error 13l"); + + REG_ENSURE(rtl_ustr_compare(w1, unicodeList.getElement(0)) == 0, "test_registry_CppApi error 13m"); + REG_ENSURE(rtl_ustr_compare(w2, unicodeList.getElement(1)) == 0, "test_registry_CppApi error 13n"); + REG_ENSURE(rtl_ustr_compare(w3, unicodeList.getElement(2)) == 0, "test_registry_CppApi error 13o"); + + REG_ENSURE(!key6.closeKey(), "test_registry_CppApi error 14"); + + REG_ENSURE(!key1.closeKey() && + !key3.closeKey() && + !key4.closeKey(), "test_registry_CppApi error 14"); + + REG_ENSURE(!rootKey.deleteKey(OUString::createFromAscii("myFirstKey")), "test_registry_CppApi error 15"); + + REG_ENSURE(!key2.closeKey(), "test_registry_CppApi error 16"); + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("mySecondKey"), key2), "test_registry_CppApi error 17"); + + REG_ENSURE(!key5.closeKey(), "test_registry_CppApi error 18"); + + REG_ENSURE(!rootKey.deleteKey(OUString::createFromAscii("myThirdKey")), "test_registry_CppApi error 19"); + + REG_ENSURE(rootKey.openKey(OUString::createFromAscii("myThirdKey"), key5), "test_registry_CppApi error 20"); + + REG_ENSURE(!key2.closeKey() && + !rootKey.closeKey(), "test_registry_CppApi error 21"); + + REG_ENSURE(!myRegistry->close(), "test_registry_CppApi error 22"); + + // Test loadkey + RegistryKey rootKey2, key21, key22, key23, key24 , key25; + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("test2.rdb")), "test_registry_CppApi error 23"); + REG_ENSURE(!myRegistry->openRootKey(rootKey2), "test_registry_CppApi error 24"); + + REG_ENSURE(!rootKey2.createKey(OUString::createFromAscii("reg2FirstKey"), key21), "test_registry_CppApi error 25"); + REG_ENSURE(!rootKey2.createKey(OUString::createFromAscii("reg2SecondKey"), key22), "test_registry_CppApi error 26"); + REG_ENSURE(!key21.createKey(OUString::createFromAscii("reg2FirstSubKey"), key23), "test_registry_CppApi error 27"); + REG_ENSURE(!key21.createKey(OUString::createFromAscii("reg2SecondSubKey"), key24), "test_registry_CppApi error 28"); + REG_ENSURE(!rootKey2.createKey(OUString::createFromAscii("reg2ThirdKey"), key25), "test_registry_CppApi error 29"); + + sal_uInt32 nValue= 123456789; + REG_ENSURE(!key23.setValue(OUString(), RG_VALUETYPE_LONG, &nValue, sizeof(sal_uInt32)), "test_registry_CppApi error 30"); + + REG_ENSURE(!key21.closeKey() && + !key22.closeKey() && + !key23.closeKey() && + !key24.closeKey() && + !key25.closeKey() && + !rootKey2.closeKey(), "test_registry_CppApi error 31"); + + REG_ENSURE(!myRegistry->close(), "test_registry_CppApi error 32"); + + REG_ENSURE(!myRegistry->open(OUString::createFromAscii("test.rdb"), REG_READWRITE), "test_registry_CppApi error 33"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "test_registry_CppApi error 34"); + + REG_ENSURE(!myRegistry->loadKey(rootKey, OUString::createFromAscii("allFromTest2"), + OUString::createFromAscii("test2.rdb")), "test_registry_CppApi error 35"); + REG_ENSURE(!myRegistry->saveKey(rootKey, OUString::createFromAscii("allFromTest2"), + OUString::createFromAscii("test3.rdb")), "test_registry_CppApi error 36"); + + REG_ENSURE(!rootKey.createKey(OUString::createFromAscii("allFromTest3"), key1), "test_registry_CppApi error 37"); + REG_ENSURE(!key1.createKey(OUString::createFromAscii("myFirstKey2"), key2), "test_registry_CppApi error 38"); + REG_ENSURE(!key1.createKey(OUString::createFromAscii("mySecondKey2"), key3), "test_registry_CppApi error 39"); + + REG_ENSURE(!myRegistry->mergeKey(rootKey, OUString::createFromAscii("allFromTest3"), + OUString::createFromAscii("test3.rdb")), "test_registry_CppApi error 40"); + REG_ENSURE(!myRegistry->mergeKey(rootKey, OUString::createFromAscii("allFromTest3"), + OUString::createFromAscii("ucrtest.rdb"), sal_True), "test_registry_CppApi error 40.a)"); + +// REG_ENSURE(myRegistry->mergeKey(rootKey, OUString::createFromAscii("allFromTest3"), OUString::createFromAscii("ucrtest.rdb"), sal_True) +// == REG_NO_ERROR/*REG_MERGE_CONFLICT*/, "test_registry_CppApi error 40.b)"); + + REG_ENSURE(!key1.closeKey() && + !key2.closeKey(), "test_registry_CppApi error 41"); + + const sal_Unicode* wValue= OUString::createFromAscii( "Mein erster Unicode Value" ).getStr(); + REG_ENSURE(!key3.setValue(OUString(), RG_VALUETYPE_UNICODE, (void*)wValue, + (rtl_ustr_getLength(wValue)+1)*sizeof(sal_Unicode)), "test_registry_CppApi error 42"); + + REG_ENSURE(!key3.closeKey(), "test_registry_CppApi error 43"); + + REG_ENSURE(!rootKey.openKey(OUString::createFromAscii("/allFromTest3/reg2FirstKey/reg2FirstSubKey"), key1), + "test_registry_CppApi error 43.a)"); + REG_ENSURE(!rootKey.deleteKey(OUString::createFromAscii("/allFromTest3/reg2FirstKey/reg2FirstSubKey")), "test_registry_CppApi error 44"); + REG_ENSURE(key1.getValueInfo(OUString(), &valueType, &valueSize) == REG_INVALID_KEY, + "test_registry_CppApi error 44.a)"); + REG_ENSURE(!key1.closeKey(), "test_registry_CppApi error 44.b)"); + + REG_ENSURE(!rootKey.closeKey(), "test_registry_CppApi error 45"); + + REG_ENSURE(!myRegistry->close(), "test_registry_CppApi error 46"); + + REG_ENSURE(!myRegistry->open(OUString::createFromAscii("test.rdb"), REG_READWRITE), "test_registry_CppApi error 47"); + + REG_ENSURE(!myRegistry->destroy(OUString::createFromAscii("test2.rdb")), "test_registry_CppApi error 48"); +// REG_ENSURE(!myRegistry->destroy("test3.rdb"), "test_registry_CppApi error 49"); + + Registry *myRegistry2 = new Registry(*myRegistry); + + REG_ENSURE(myRegistry->destroy(OUString()), "test_registry_CppApi error 50"); + + delete(myRegistry2); + + REG_ENSURE(!myRegistry->create(OUString::createFromAscii("destroytest.rdb")), "test_registry_CppApi error 51"); + REG_ENSURE(!myRegistry->close(), "test_registry_CppApi error 52"); + REG_ENSURE(!myRegistry->open(OUString::createFromAscii("destroytest.rdb"), REG_READONLY), "test_registry_CppApi error 53"); + REG_ENSURE(!myRegistry->openRootKey(rootKey), "test_registry_CppApi error 54"); + + REG_ENSURE(myRegistry->mergeKey(rootKey, OUString::createFromAscii("allFromTest3"), + OUString::createFromAscii("test3.rdb")), "test_registry_CppApi error 55"); + REG_ENSURE(!myRegistry->destroy(OUString::createFromAscii("test3.rdb")), "test_registry_CppApi error 56"); + + REG_ENSURE(!rootKey.closeKey(), "test_registry_CppApi error 57"); + REG_ENSURE(!myRegistry->close(), "test_registry_CppApi error 58"); + REG_ENSURE(!myRegistry->open(OUString::createFromAscii("destroytest.rdb"), REG_READWRITE), "test_registry_CppApi error 59"); + REG_ENSURE(!myRegistry->destroy(OUString()), "test_registry_CppApi error 60"); + + REG_ENSURE(!myRegistry->open(OUString::createFromAscii("test.rdb"), REG_READWRITE), "test_registry_CppApi error 61"); + REG_ENSURE(!myRegistry->destroy(OUString::createFromAscii("ucrtest.rdb")), "test_registry_CppApi error 62"); + REG_ENSURE(!myRegistry->destroy(OUString()), "test_registry_CppApi error 63"); + delete(myRegistry); + + cout << "test_registry_CppApi() Ok!\n"; + + return; +} + + diff --git a/registry/tools/checksingleton.cxx b/registry/tools/checksingleton.cxx new file mode 100644 index 000000000000..4353721ad0b0 --- /dev/null +++ b/registry/tools/checksingleton.cxx @@ -0,0 +1,483 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <stdio.h> +#include <string.h> + +#include "registry/registry.hxx" +#include "registry/reflread.hxx" +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> +#include <osl/process.h> +#include <osl/diagnose.h> +#include <osl/thread.h> +#include <osl/file.hxx> + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +using namespace ::rtl; +using namespace ::osl; + +sal_Bool isFileUrl(const OString& fileName) +{ + if (fileName.indexOf("file://") == 0 ) + return sal_True; + return sal_False; +} + +OUString convertToFileUrl(const OString& fileName) +{ + if ( isFileUrl(fileName) ) + { + return OStringToOUString(fileName, osl_getThreadTextEncoding()); + } + + OUString uUrlFileName; + OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); + if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 ) + { + OUString uWorkingDir; + if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } else + { + if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } + + return uUrlFileName; +} + +#define U2S( s ) \ + OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr() +#define S2U( s ) \ + OStringToOUString(s, RTL_TEXTENCODING_UTF8) + +struct LessString +{ + sal_Bool operator()(const OUString& str1, const OUString& str2) const + { + return (str1 < str2); + } +}; + +class Options +{ +public: + Options() + : m_bForceOutput(sal_False) + {} + ~Options() + {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False); + + OString prepareHelp(); + OString prepareVersion(); + + const OString& getProgramName() + { return m_program; } + const OString& getIndexReg() + { return m_indexRegName; } + const OString& getTypeReg() + { return m_typeRegName; } + sal_Bool hasBase() + { return m_base.getLength() > 0; } + const OString& getBase() + { return m_base; } + sal_Bool forceOutput() + { return m_bForceOutput; } +protected: + OString m_program; + OString m_indexRegName; + OString m_typeRegName; + OString m_base; + sal_Bool m_bForceOutput; +}; + +sal_Bool Options::initOptions(int ac, char* av[], sal_Bool bCmdFile) +{ + sal_Bool bRet = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + bRet = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for (; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'r': + case 'R': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + fprintf(stderr, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + s = av[i] + 2; + } + m_typeRegName = OString(s); + break; + case 'o': + case 'O': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + fprintf(stderr, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + s = av[i] + 2; + } + m_indexRegName = OString(s); + break; + case 'b': + case 'B': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + fprintf(stderr, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + s = av[i] + 2; + } + m_base = OString(s); + break; + case 'f': + case 'F': + if (av[i][2] != '\0') + { + fprintf(stderr, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + } + m_bForceOutput = sal_True; + break; + case 'h': + case '?': + if (av[i][2] != '\0') + { + fprintf(stderr, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + } else + { + fprintf(stdout, "%s", prepareHelp().getStr()); + exit(0); + } + break; + default: + fprintf(stderr, "%s: unknown option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + bRet = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + bRet = initOptions(rargc, rargv, bCmdFile); + + for (long j=0; j < rargc; j++) + { + free(rargv[j]); + } + } + } else + { + fprintf(stderr, "%s: unknown option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + } + } + } + + return bRet; +} + +OString Options::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " -r<filename> -o<filename> [-options] | @<filename>\n"; + help += " -o<filename> = filename specifies the name of the new singleton index registry.\n"; + help += " -r<filename> = filename specifies the name of the type registry.\n"; + help += " @<filename> = filename specifies a command file.\n"; + help += "Options:\n"; + help += " -b<name> = name specifies the name of a start key. The types will be searched\n"; + help += " under this key in the type registry.\n"; + help += " -f = force the output of all found singletons.\n"; + help += " -h|-? = print this help message and exit.\n"; + help += prepareVersion(); + + return help; +} + +OString Options::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 1.0\n\n"; + return version; +} + +static Options options; + +static sal_Bool checkSingletons(RegistryKey& singletonKey, RegistryKey& typeKey) +{ + RegValueType valueType = RG_VALUETYPE_NOT_DEFINED; + sal_uInt32 size = 0; + OUString tmpName; + sal_Bool bRet = sal_False; + + RegError e = typeKey.getValueInfo(tmpName, &valueType, &size); + + if ( e != REG_VALUE_NOT_EXISTS && e != REG_INVALID_VALUE && valueType == RG_VALUETYPE_BINARY) + { + RegistryKey entryKey; + RegValue value = rtl_allocateMemory(size); + + typeKey.getValue(tmpName, value); + + RegistryTypeReader reader((sal_uInt8*)value, size, sal_False); + + if ( reader.isValid() && reader.getTypeClass() == RT_TYPE_SINGLETON ) + { + OUString singletonName = reader.getTypeName().replace('/', '.'); + if ( singletonKey.createKey(singletonName, entryKey) ) + { + fprintf(stderr, "%s: could not create SINGLETONS entry for \"%s\"\n", + options.getProgramName().getStr(), U2S( singletonName )); + } else + { + bRet = sal_True; + OUString value2 = reader.getSuperTypeName(); + + if ( entryKey.setValue(tmpName, RG_VALUETYPE_UNICODE, + (RegValue)value2.getStr(), sizeof(sal_Unicode)* (value2.getLength()+1)) ) + { + fprintf(stderr, "%s: could not create data entry for singleton \"%s\"\n", + options.getProgramName().getStr(), U2S( singletonName )); + } + + if ( options.forceOutput() ) + { + fprintf(stderr, "%s: create SINGLETON entry for \"%s\" -> \"%s\"\n", + options.getProgramName().getStr(), U2S( singletonName ), U2S(value2)); + } + } + } + + rtl_freeMemory(value); + } + + RegistryKeyArray subKeys; + + typeKey.openSubKeys(tmpName, subKeys); + + sal_uInt32 length = subKeys.getLength(); + RegistryKey elementKey; + for (sal_uInt32 i = 0; i < length; i++) + { + elementKey = subKeys.getElement(i); + if ( checkSingletons(singletonKey, elementKey) ) + { + bRet = sal_True; + } + } + return bRet; +} + +#if (defined UNX) || (defined OS2) || (defined __MINGW32__) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + if ( !options.initOptions(argc, argv) ) + { + exit(1); + } + + OUString indexRegName( convertToFileUrl(options.getIndexReg()) ); + OUString typeRegName( convertToFileUrl(options.getTypeReg()) ); + + Registry indexReg; + Registry typeReg; + + if ( indexReg.open(indexRegName, REG_READWRITE) ) + { + if ( indexReg.create(indexRegName) ) + { + fprintf(stderr, "%s: open registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getIndexReg().getStr()); + exit(2); + } + } + if ( typeReg.open(typeRegName, REG_READONLY) ) + { + fprintf(stderr, "%s: open registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getTypeReg().getStr()); + exit(3); + } + + RegistryKey indexRoot, typeRoot; + if ( indexReg.openRootKey(indexRoot) ) + { + fprintf(stderr, "%s: open root key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getIndexReg().getStr()); + exit(4); + } + if ( typeReg.openRootKey(typeRoot) ) + { + fprintf(stderr, "%s: open root key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getTypeReg().getStr()); + exit(5); + } + + RegistryKey singletonKey, typeKey; + if ( options.hasBase() ) + { + if ( typeRoot.openKey(S2U(options.getBase()), typeKey) ) + { + fprintf(stderr, "%s: open base key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getTypeReg().getStr()); + exit(6); + } + } else + { + typeKey = typeRoot; + } + + if ( indexRoot.createKey(OUString::createFromAscii("SINGLETONS"), singletonKey) ) + { + fprintf(stderr, "%s: open/create SINGLETONS key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getIndexReg().getStr()); + exit(7); + } + + sal_Bool bSingletonsExist = checkSingletons(singletonKey, typeKey); + + indexRoot.releaseKey(); + typeRoot.releaseKey(); + typeKey.releaseKey(); + singletonKey.releaseKey(); + if ( indexReg.close() ) + { + fprintf(stderr, "%s: closing registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getIndexReg().getStr()); + exit(9); + } + if ( !bSingletonsExist ) + { + if ( indexReg.destroy(OUString()) ) + { + fprintf(stderr, "%s: destroy registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getIndexReg().getStr()); + exit(10); + } + } + if ( typeReg.close() ) + { + fprintf(stderr, "%s: closing registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getTypeReg().getStr()); + exit(11); + } +} + + diff --git a/registry/tools/makefile.mk b/registry/tools/makefile.mk new file mode 100644 index 000000000000..bb7d448b86e6 --- /dev/null +++ b/registry/tools/makefile.mk @@ -0,0 +1,80 @@ +#************************************************************************* +# +# 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=registry +TARGET=regmerge +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS := TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +.INCLUDE : ..$/version.mk + +# --- Files -------------------------------------------------------- +CDEFS += -DDLL_VERSION=$(EMQ)"$(DLLPOSTFIX)$(EMQ)" + +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJ)$/regmerge.obj +APP1RPATH= UREBIN + +APP1STDLIBS=\ + $(SALLIB) \ + $(REGLIB) + +APP2TARGET= regview +APP2OBJS= $(OBJ)$/regview.obj +APP2RPATH= UREBIN + +APP2STDLIBS=\ + $(SALLIB) \ + $(REGLIB) + +APP3TARGET= regcompare +APP3OBJS= $(OBJ)$/regcompare.obj +APP3RPATH= SDK + +APP3STDLIBS=\ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) + +APP4TARGET= checksingleton +APP4OBJS= $(OBJ)$/checksingleton.obj + +APP4STDLIBS=\ + $(SALLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) + +OBJFILES = $(APP1OBJS) $(APP2OBJS) $(APP3OBJS) $(APP4OBJS) + +.INCLUDE : target.mk diff --git a/registry/tools/regcompare.cxx b/registry/tools/regcompare.cxx new file mode 100644 index 000000000000..4e95d884de30 --- /dev/null +++ b/registry/tools/regcompare.cxx @@ -0,0 +1,2399 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <stdio.h> +#include <string.h> + +#include <set> +#include <vector> +#include "registry/registry.hxx" +#include "registry/reader.hxx" +#include "registry/version.h" +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> +#include <osl/process.h> +#include <osl/diagnose.h> +#include <osl/thread.h> +#include <osl/file.hxx> + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +using namespace ::rtl; +using namespace ::osl; + +OUString shortName(const OUString& fullName) +{ + return fullName.copy(fullName.lastIndexOf('/') + 1); +} + +sal_Bool isFileUrl(const OString& fileName) +{ + if (fileName.indexOf("file://") == 0 ) + return sal_True; + return sal_False; +} + +OUString convertToFileUrl(const OString& fileName) +{ + if ( isFileUrl(fileName) ) + { + return OStringToOUString(fileName, osl_getThreadTextEncoding()); + } + + OUString uUrlFileName; + OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); + if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 ) + { + OUString uWorkingDir; + if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } else + { + if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } + + return uUrlFileName; +} + +#define U2S( s ) \ + OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr() +#define S2U( s ) \ + OStringToOUString(s, RTL_TEXTENCODING_UTF8) + +struct LessString +{ + sal_Bool operator()(const OUString& str1, const OUString& str2) const + { + return (str1 < str2); + } +}; + +typedef ::std::set< OUString > StringSet; + +class Options +{ +public: + Options() + : m_bFullCheck(sal_False) + , m_bForceOutput(sal_False) + , m_bUnoTypeCheck(sal_False) + , m_checkUnpublished(false) + {} + ~Options() + {} + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False); + + OString prepareHelp(); + OString prepareVersion(); + + const OString& getProgramName() + { return m_program; } + const OString& getRegName1() + { return m_regName1; } + const OString& getRegName2() + { return m_regName2; } + sal_Bool isStartKeyValid() + { return (m_startKey.getLength() > 0); }; + const OString& getStartKey() + { return m_startKey; } + sal_Bool existsExcludeKeys() + { return !m_excludeKeys.empty(); }; + StringSet& getExcludeKeys() + { return m_excludeKeys; } + sal_Bool matchedWithExcludeKey( const OUString& keyName); + sal_Bool fullCheck() + { return m_bFullCheck; } + sal_Bool forceOutput() + { return m_bForceOutput; } + sal_Bool unoTypeCheck() + { return m_bUnoTypeCheck; } + bool checkUnpublished() const { return m_checkUnpublished; } +protected: + OString m_program; + OString m_regName1; + OString m_regName2; + OString m_startKey; + StringSet m_excludeKeys; + sal_Bool m_bFullCheck; + sal_Bool m_bForceOutput; + sal_Bool m_bUnoTypeCheck; + bool m_checkUnpublished; +}; + +sal_Bool Options::initOptions(int ac, char* av[], sal_Bool bCmdFile) +{ + sal_Bool bRet = sal_True; + sal_uInt16 i=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stdout, "%s", prepareHelp().getStr()); + bRet = sal_False; + } + + i = 1; + } else + { + i = 0; + } + + char *s=NULL; + for (; i < ac; i++) + { + if (av[i][0] == '-') + { + switch (av[i][1]) + { + case 'r': + case 'R': + { + sal_Bool bFirst = sal_True; + if (av[i][2] == '2') + { + bFirst = sal_False; + } else if (av[i][2] != '1') + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + } + if (av[i][3] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + s = av[i] + 2; + } + + if ( bFirst ) + { + m_regName1 = OString(s); + } else + { + m_regName2 = OString(s); + } + } + break; + case 's': + case 'S': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + s = av[i] + 2; + } + m_startKey = OString(s); + break; + case 'x': + case 'X': + if (av[i][2] == '\0') + { + if (i < ac - 1 && av[i+1][0] != '-') + { + i++; + s = av[i]; + } else + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + s = av[i] + 2; + } + m_excludeKeys.insert(S2U(s)); + break; + case 'c': + case 'C': + if (av[i][2] != '\0') + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + } + m_bFullCheck = sal_True; + break; + case 'f': + case 'F': + if (av[i][2] != '\0') + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + } + m_bForceOutput = sal_True; + break; + case 't': + case 'T': + if (av[i][2] != '\0') + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + } + m_bUnoTypeCheck = sal_True; + break; + case 'u': + case 'U': + if (av[i][2] != '\0') + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + } + m_checkUnpublished = true; + break; + case 'h': + case '?': + if (av[i][2] != '\0') + { + fprintf(stdout, "%s: invalid option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + } else + { + fprintf(stdout, "%s", prepareHelp().getStr()); + exit(0); + } + break; + default: + fprintf(stdout, "%s: unknown option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + break; + } + } else + { + if (av[i][0] == '@') + { + FILE* cmdFile = fopen(av[i]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stdout, "%s", prepareHelp().getStr()); + bRet = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]; + + while ( fscanf(cmdFile, "%s", buffer) != EOF ) + { + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + bRet = initOptions(rargc, rargv, bCmdFile); + + for (long j=0; j < rargc; j++) + { + free(rargv[j]); + } + } + } else + { + fprintf(stdout, "%s: unknown option '%s'\n", m_program.getStr(), av[i]); + bRet = sal_False; + } + } + } + + if ( bRet ) + { + if ( m_regName1.getLength() == 0 ) + { + fprintf(stdout, "%s: missing option '-r1'\n", m_program.getStr()); + bRet = sal_False; + } + if ( m_regName2.getLength() == 0 ) + { + fprintf(stdout, "%s: missing option '-r2'\n", m_program.getStr()); + bRet = sal_False; + } + } + + return bRet; +} + +OString Options::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + " -r1<filename> -r2<filename> [-options] | @<filename>\n"; + help += " -r1<filename> = filename specifies the name of the first registry.\n"; + help += " -r2<filename> = filename specifies the name of the second registry.\n"; + help += " @<filename> = filename specifies a command file.\n"; + help += "Options:\n"; + help += " -s<name> = name specifies the name of a start key. If no start key\n"; + help += " |S<name> is specified the comparison starts with the root key.\n"; + help += " -x<name> = name specifies the name of a key which won't be compared. All\n"; + help += " |X<name> subkeys won't be compared also. This option can be used more than once.\n"; + help += " -f|F = force the detailed output of any diffenrences. Default\n"; + help += " is that only the number of differences is returned.\n"; + help += " -c|C = make a complete check, that means any differences will be\n"; + help += " detected. Default is only a compatibility check that means\n"; + help += " only UNO typelibrary entries will be checked.\n"; + help += " -t|T = make an UNO type compatiblity check. This means that registry 2\n"; + help += " will be checked against registry 1. If a interface in r2 contains\n"; + help += " more methods or the methods are in a different order as in r1, r2 is\n"; + help += " incompatible to r1. But if a service in r2 supports more properties as\n"; + help += " in r1 and the new properties are 'optonal' it is compatible.\n"; + help += " -u|U = additionally check types that are unpublished in registry 1.\n"; + help += " -h|-? = print this help message and exit.\n"; + help += prepareVersion(); + + return help; +} + +OString Options::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 1.0\n\n"; + return version; +} + +sal_Bool Options::matchedWithExcludeKey( const OUString& keyName) +{ + if ( m_excludeKeys.empty() ) + return sal_False; + + StringSet::const_iterator iter = m_excludeKeys.begin(); + StringSet::const_iterator end = m_excludeKeys.end(); + + while ( iter != end ) + { + if ( keyName.indexOf(*iter) == 0) + return sal_True; + + ++iter; + } + + return sal_False; +} + +static Options options; + +static char const * getTypeClass(RTTypeClass typeClass) +{ + switch (typeClass) + { + case RT_TYPE_INTERFACE: + return "INTERFACE"; + case RT_TYPE_MODULE: + return "MODULE"; + case RT_TYPE_STRUCT: + return "STRUCT"; + case RT_TYPE_ENUM: + return "ENUM"; + case RT_TYPE_EXCEPTION: + return "EXCEPTION"; + case RT_TYPE_TYPEDEF: + return "TYPEDEF"; + case RT_TYPE_SERVICE: + return "SERVICE"; + case RT_TYPE_OBJECT: + return "OBJECT"; + case RT_TYPE_CONSTANTS: + return "CONSTANTS"; + default: + return "INVALID"; + } +} + +static OString getFieldAccess(RTFieldAccess fieldAccess) +{ + OString ret; + if ( (fieldAccess & RT_ACCESS_INVALID) == RT_ACCESS_INVALID ) + { + ret += OString("INVALID"); + } + if ( (fieldAccess & RT_ACCESS_READONLY) == RT_ACCESS_READONLY ) + { + ret += OString(ret.getLength() > 0 ? ",READONLY" : "READONLY"); + } + if ( (fieldAccess & RT_ACCESS_OPTIONAL) == RT_ACCESS_OPTIONAL ) + { + ret += OString(ret.getLength() > 0 ? ",OPTIONAL" : "OPTIONAL"); + } + if ( (fieldAccess & RT_ACCESS_MAYBEVOID) == RT_ACCESS_MAYBEVOID ) + { + ret += OString(ret.getLength() > 0 ? ",MAYBEVOID" : "MAYBEVOID"); + } + if ( (fieldAccess & RT_ACCESS_BOUND) == RT_ACCESS_BOUND ) + { + ret += OString(ret.getLength() > 0 ? ",BOUND" : "BOUND"); + } + if ( (fieldAccess & RT_ACCESS_CONSTRAINED) == RT_ACCESS_CONSTRAINED ) + { + ret += OString(ret.getLength() > 0 ? ",CONSTRAINED" : "CONSTRAINED"); + } + if ( (fieldAccess & RT_ACCESS_TRANSIENT) == RT_ACCESS_TRANSIENT ) + { + ret += OString(ret.getLength() > 0 ? ",TRANSIENT" : "TRANSIENT"); + } + if ( (fieldAccess & RT_ACCESS_MAYBEAMBIGUOUS) == RT_ACCESS_MAYBEAMBIGUOUS ) + { + ret += OString(ret.getLength() > 0 ? ",MAYBEAMBIGUOUS" : "MAYBEAMBIGUOUS"); + } + if ( (fieldAccess & RT_ACCESS_MAYBEDEFAULT) == RT_ACCESS_MAYBEDEFAULT ) + { + ret += OString(ret.getLength() > 0 ? ",MAYBEDEFAULT" : "MAYBEDEFAULT"); + } + if ( (fieldAccess & RT_ACCESS_REMOVEABLE) == RT_ACCESS_REMOVEABLE ) + { + ret += OString(ret.getLength() > 0 ? ",REMOVEABLE" : "REMOVEABLE"); + } + if ( (fieldAccess & RT_ACCESS_ATTRIBUTE) == RT_ACCESS_ATTRIBUTE ) + { + ret += OString(ret.getLength() > 0 ? ",ATTRIBUTE" : "ATTRIBUTE"); + } + if ( (fieldAccess & RT_ACCESS_PROPERTY) == RT_ACCESS_PROPERTY ) + { + ret += OString(ret.getLength() > 0 ? ",PROPERTY" : "PROPERTY"); + } + if ( (fieldAccess & RT_ACCESS_CONST) == RT_ACCESS_CONST ) + { + ret += OString(ret.getLength() > 0 ? ",CONST" : "CONST"); + } + if ( (fieldAccess & RT_ACCESS_READWRITE) == RT_ACCESS_READWRITE ) + { + ret += OString(ret.getLength() > 0 ? ",READWRITE" : "READWRITE"); + } + return ret; +} + +static char const * getConstValueType(RTConstValue& constValue) +{ + switch (constValue.m_type) + { + case RT_TYPE_BOOL: + return "sal_Bool"; + case RT_TYPE_BYTE: + return "sal_uInt8"; + case RT_TYPE_INT16: + return "sal_Int16"; + case RT_TYPE_UINT16: + return "sal_uInt16"; + case RT_TYPE_INT32: + return "sal_Int32"; + case RT_TYPE_UINT32: + return "sal_uInt32"; +// case RT_TYPE_INT64: +// return "sal_Int64"; +// case RT_TYPE_UINT64: +// return "sal_uInt64"; + case RT_TYPE_FLOAT: + return "float"; + case RT_TYPE_DOUBLE: + return "double"; + case RT_TYPE_STRING: + return "sal_Unicode*"; + default: + return "NONE"; + } +} +static void printConstValue(RTConstValue& constValue) +{ + switch (constValue.m_type) + { + case RT_TYPE_NONE: + fprintf(stdout, "none"); + break; + case RT_TYPE_BOOL: + fprintf(stdout, "%s", constValue.m_value.aBool ? "TRUE" : "FALSE"); + break; + case RT_TYPE_BYTE: + fprintf(stdout, "%d", constValue.m_value.aByte); + break; + case RT_TYPE_INT16: + fprintf(stdout, "%d", constValue.m_value.aShort); + break; + case RT_TYPE_UINT16: + fprintf(stdout, "%d", constValue.m_value.aUShort); + break; + case RT_TYPE_INT32: + fprintf( + stdout, "%ld", + sal::static_int_cast< long >(constValue.m_value.aLong)); + break; + case RT_TYPE_UINT32: + fprintf( + stdout, "%lu", + sal::static_int_cast< unsigned long >( + constValue.m_value.aULong)); + break; +// case RT_TYPE_INT64: +// fprintf(stdout, "%d", constValue.m_value.aHyper); +// case RT_TYPE_UINT64: +// fprintf(stdout, "%d", constValue.m_value.aUHyper); + case RT_TYPE_FLOAT: + fprintf(stdout, "%f", constValue.m_value.aFloat); + break; + case RT_TYPE_DOUBLE: + fprintf(stdout, "%f", constValue.m_value.aDouble); + break; + case RT_TYPE_STRING: + fprintf( + stdout, "%s", + (rtl::OUStringToOString( + constValue.m_value.aString, RTL_TEXTENCODING_UTF8). + getStr())); + break; + default: + break; + } +} + +static sal_uInt32 checkConstValue(const OUString& keyName, + RTTypeClass typeClass, + sal_Bool& bDump, + RTConstValue& constValue1, + RTConstValue& constValue2, + sal_uInt16 index1) +{ + switch (constValue1.m_type) + { + case RT_TYPE_INVALID: + break; + case RT_TYPE_BOOL: + if (constValue1.m_value.aBool != constValue2.m_value.aBool) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %s != Value2 = %s\n", index1, + constValue1.m_value.aBool ? "TRUE" : "FALSE", + constValue2.m_value.aBool ? "TRUE" : "FALSE"); + } + return 1; + } + break; + case RT_TYPE_BYTE: + if (constValue1.m_value.aByte != constValue2.m_value.aByte) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %d != Value2 = %d\n", index1, + constValue1.m_value.aByte, constValue2.m_value.aByte); + } + return 1; + } + break; + case RT_TYPE_INT16: + if (constValue1.m_value.aShort != constValue2.m_value.aShort) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %d != Value2 = %d\n", index1, + constValue1.m_value.aShort, constValue2.m_value.aShort); + } + return 1; + } + break; + case RT_TYPE_UINT16: + if (constValue1.m_value.aUShort != constValue2.m_value.aUShort) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %d != Value2 = %d\n", index1, + constValue1.m_value.aUShort, constValue2.m_value.aUShort); + } + return 1; + } + break; + case RT_TYPE_INT32: + if (constValue1.m_value.aLong != constValue2.m_value.aLong) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %ld != Value2 = %ld\n", index1, + sal::static_int_cast< long >(constValue1.m_value.aLong), + sal::static_int_cast< long >(constValue2.m_value.aLong)); + } + return 1; + } + break; + case RT_TYPE_UINT32: + if (constValue1.m_value.aULong != constValue2.m_value.aULong) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %lu != Value2 = %lu\n", index1, + sal::static_int_cast< unsigned long >(constValue1.m_value.aULong), + sal::static_int_cast< unsigned long >(constValue2.m_value.aULong)); + } + return 1; + } + break; + case RT_TYPE_INT64: + if (constValue1.m_value.aHyper != constValue2.m_value.aHyper) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf( + stdout, " Field %d: Value1 = %s != Value2 = %s\n", + index1, + rtl::OUStringToOString( + rtl::OUString::valueOf(constValue1.m_value.aHyper), + RTL_TEXTENCODING_ASCII_US).getStr(), + rtl::OUStringToOString( + rtl::OUString::valueOf(constValue2.m_value.aHyper), + RTL_TEXTENCODING_ASCII_US).getStr()); + } + return 1; + } + break; + case RT_TYPE_UINT64: + if (constValue1.m_value.aUHyper != constValue2.m_value.aUHyper) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf( + stdout, " Field %d: Value1 = %s != Value2 = %s\n", + index1, + rtl::OUStringToOString( + rtl::OUString::valueOf( + static_cast< sal_Int64 >( + constValue1.m_value.aUHyper)), + RTL_TEXTENCODING_ASCII_US).getStr(), + rtl::OUStringToOString( + rtl::OUString::valueOf( + static_cast< sal_Int64 >( + constValue2.m_value.aUHyper)), + RTL_TEXTENCODING_ASCII_US).getStr()); + // printing the unsigned values as signed should be + // acceptable... + } + return 1; + } + break; + case RT_TYPE_FLOAT: + if (constValue1.m_value.aFloat != constValue2.m_value.aFloat) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %f != Value2 = %f\n", index1, + constValue1.m_value.aFloat, constValue2.m_value.aFloat); + } + return 1; + } + break; + case RT_TYPE_DOUBLE: + if (constValue1.m_value.aDouble != constValue2.m_value.aDouble) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Value1 = %f != Value2 = %f\n", index1, + constValue1.m_value.aDouble, constValue2.m_value.aDouble); + } + return 1; + } + break; + default: + OSL_ASSERT(false); + break; + } + return 0; +} + +static sal_uInt32 checkField(const OUString& keyName, + RTTypeClass typeClass, + sal_Bool& bDump, + typereg::Reader& reader1, + typereg::Reader& reader2, + sal_uInt16 index1, + sal_uInt16 index2) +{ + sal_uInt32 nError = 0; + if ( reader1.getFieldName(index1) != + reader2.getFieldName(index2) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Name1 = %s != Name2 = %s\n", index1, + U2S(reader1.getFieldName(index1)), U2S(reader2.getFieldName(index2))); + } + nError++; + } + if ( reader1.getFieldTypeName(index1) != + reader2.getFieldTypeName(index2) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Type1 = %s != Type2 = %s\n", index1, + U2S(reader1.getFieldTypeName(index1)), U2S(reader2.getFieldTypeName(index2))); + } + nError++; + } else + { + RTConstValue constValue1 = reader1.getFieldValue(index1); + RTConstValue constValue2 = reader2.getFieldValue(index2); + if ( constValue1.m_type != constValue2.m_type ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Access1 = %s != Access2 = %s\n", index1, + getConstValueType(constValue1), getConstValueType(constValue2)); + fprintf(stdout, " Field %d: Value1 = ", index1); + printConstValue(constValue1); + fprintf(stdout, " != Value2 = "); + printConstValue(constValue1); + fprintf(stdout, "\n;"); + } + nError++; + } else + { + nError += checkConstValue(keyName, typeClass, bDump, constValue1, constValue2, index1); + } + } + + if ( reader1.getFieldFlags(index1) != reader2.getFieldFlags(index2) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: FieldAccess1 = %s != FieldAccess2 = %s\n", index1, + getFieldAccess(reader1.getFieldFlags(index1)).getStr(), + getFieldAccess(reader1.getFieldFlags(index2)).getStr()); + } + nError++; + } + + if ( options.fullCheck() && + (reader1.getFieldDocumentation(index1) != reader2.getFieldDocumentation(index2)) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Field %d: Doku1 = %s\n Doku2 = %s\n", index1, + U2S(reader1.getFieldDocumentation(index1)), U2S(reader2.getFieldDocumentation(index2))); + } + nError++; + } + return nError; +} + +static char const * getMethodMode(RTMethodMode methodMode) +{ + switch ( methodMode ) + { + case RT_MODE_ONEWAY: + return "ONEWAY"; + case RT_MODE_ONEWAY_CONST: + return "ONEWAY,CONST"; + case RT_MODE_TWOWAY: + return "NONE"; + case RT_MODE_TWOWAY_CONST: + return "CONST"; + default: + return "INVALID"; + } +} + +static char const * getParamMode(RTParamMode paramMode) +{ + switch ( paramMode ) + { + case RT_PARAM_IN: + return "IN"; + case RT_PARAM_OUT: + return "OUT"; + case RT_PARAM_INOUT: + return "INOUT"; + default: + return "INVALID"; + } +} + +static sal_uInt32 checkMethod(const OUString& keyName, + RTTypeClass typeClass, + sal_Bool& bDump, + typereg::Reader& reader1, + typereg::Reader& reader2, + sal_uInt16 index) +{ + sal_uInt32 nError = 0; + if ( reader1.getMethodName(index) != + reader2.getMethodName(index) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method1 %d: Name1 = %s != Name2 = %s\n", index, + U2S(reader1.getMethodName(index)), + U2S(reader2.getMethodName(index))); + } + nError++; + } + + if ( reader1.getMethodReturnTypeName(index) != + reader2.getMethodReturnTypeName(index) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method1 %d: ReturnType1 = %s != ReturnType2 = %s\n", index, + U2S(reader1.getMethodReturnTypeName(index)), + U2S(reader2.getMethodReturnTypeName(index))); + } + nError++; + } + + sal_uInt16 nParams1 = (sal_uInt16)reader1.getMethodParameterCount(index); + sal_uInt16 nParams2 = (sal_uInt16)reader2.getMethodParameterCount(index); + if ( nParams1 != nParams2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d : nParameters1 = %d != nParameters2 = %d\n", index, nParams1, nParams2); + } + nError++; + } + sal_uInt16 i=0; + for (i=0; i < nParams1 && i < nParams2; i++) + { + if ( reader1.getMethodParameterTypeName(index, i) != reader2.getMethodParameterTypeName(index, i) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d, Parameter %d: Type1 = %s != Type2 = %s\n", index, i, + U2S(reader1.getMethodParameterTypeName(index, i)), + U2S(reader2.getMethodParameterTypeName(index, i))); + } + nError++; + } + if ( options.fullCheck() && + (reader1.getMethodParameterName(index, i) != reader2.getMethodParameterName(index, i)) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d, Parameter %d: Name1 = %s != Name2 = %s\n", index, i, + U2S(reader1.getMethodParameterName(index, i)), + U2S(reader2.getMethodParameterName(index, i))); + } + nError++; + } + if ( reader1.getMethodParameterFlags(index, i) != reader2.getMethodParameterFlags(index, i) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d, Parameter %d: Mode1 = %s != Mode2 = %s\n", index, i, + getParamMode(reader1.getMethodParameterFlags(index, i)), + getParamMode(reader2.getMethodParameterFlags(index, i))); + } + nError++; + } + } + if ( i < nParams1 && options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Registry1: Method %d contains %d more parameters\n", index, nParams1 - i); + } + if ( i < nParams2 && options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Registry2: Method %d contains %d more parameters\n", index, nParams2 - i); + } + + sal_uInt16 nExcep1 = (sal_uInt16)reader1.getMethodExceptionCount(index); + sal_uInt16 nExcep2 = (sal_uInt16)reader2.getMethodExceptionCount(index); + if ( nExcep1 != nExcep2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " nExceptions1 = %d != nExceptions2 = %d\n", nExcep1, nExcep2); + } + nError++; + } + for (i=0; i < nExcep1 && i < nExcep2; i++) + { + if ( reader1.getMethodExceptionTypeName(index, i) != reader2.getMethodExceptionTypeName(index, i) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d, Exception %d: Name1 = %s != Name2 = %s\n", index, i, + U2S(reader1.getMethodExceptionTypeName(index, i)), + U2S(reader2.getMethodExceptionTypeName(index, i))); + } + nError++; + } + } + if ( i < nExcep1 && options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Registry1: Method %d contains %d more exceptions\n", index, nExcep1 - i); + } + if ( i < nExcep2 && options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Registry2: Method %d contains %d more exceptions\n", index, nExcep2 - i); + } + + if ( reader1.getMethodFlags(index) != reader2.getMethodFlags(index) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d: Mode1 = %s != Mode2 = %s\n", index, + getMethodMode(reader1.getMethodFlags(index)), + getMethodMode(reader2.getMethodFlags(index))); + } + nError++; + } + + if ( options.fullCheck() && + (reader1.getMethodDocumentation(index) != reader2.getMethodDocumentation(index)) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Method %d: Doku1 = %s\n Doku2 = %s\n", index, + U2S(reader1.getMethodDocumentation(index)), + U2S(reader2.getMethodDocumentation(index))); + } + nError++; + } + return nError; +} + +static char const * getReferenceType(RTReferenceType refType) +{ + switch (refType) + { + case RT_REF_SUPPORTS: + return "RT_REF_SUPPORTS"; + case RT_REF_OBSERVES: + return "RT_REF_OBSERVES"; + case RT_REF_EXPORTS: + return "RT_REF_EXPORTS"; + case RT_REF_NEEDS: + return "RT_REF_NEEDS"; + default: + return "RT_REF_INVALID"; + } +} + +static sal_uInt32 checkReference(const OUString& keyName, + RTTypeClass typeClass, + sal_Bool& bDump, + typereg::Reader& reader1, + typereg::Reader& reader2, + sal_uInt16 index1, + sal_uInt16 index2) +{ + sal_uInt32 nError = 0; + if ( reader1.getReferenceTypeName(index1) != + reader2.getReferenceTypeName(index2) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Reference %d: Name1 = %s != Name2 = %s\n", index1, + U2S(reader1.getReferenceTypeName(index1)), + U2S(reader2.getReferenceTypeName(index2))); + } + nError++; + } + if ( reader1.getReferenceTypeName(index1) != + reader2.getReferenceTypeName(index2) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Reference %d: Type1 = %s != Type2 = %s\n", index1, + getReferenceType(reader1.getReferenceSort(index1)), + getReferenceType(reader2.getReferenceSort(index2))); + } + nError++; + } + if ( options.fullCheck() && + (reader1.getReferenceDocumentation(index1) != reader2.getReferenceDocumentation(index2)) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Reference %d: Doku1 = %s\n Doku2 = %s\n", index1, + U2S(reader1.getReferenceDocumentation(index1)), + U2S(reader2.getReferenceDocumentation(index2))); + } + nError++; + } + if ( reader1.getReferenceFlags(index1) != + reader2.getReferenceFlags(index2) ) + { + if ( options.forceOutput() && !options.unoTypeCheck() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Reference %d: Access1 = %s != Access2 = %s\n", index1, + getFieldAccess(reader1.getReferenceFlags(index1)).getStr(), + getFieldAccess(reader1.getReferenceFlags(index2)).getStr()); + } + nError++; + } + return nError; +} + +static sal_uInt32 checkFieldsWithoutOrder(const OUString& keyName, + RTTypeClass typeClass, + sal_Bool& bDump, + typereg::Reader& reader1, + typereg::Reader& reader2) +{ + sal_uInt32 nError = 0; + + sal_uInt16 nFields1 = (sal_uInt16)reader1.getFieldCount(); + sal_uInt16 nFields2 = (sal_uInt16)reader2.getFieldCount(); + sal_uInt16 i=0, j=0; + + if ( nFields1 > nFields2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " %s1 contains %d more properties as %s2\n", + getTypeClass(typeClass), nFields1-nFields2, getTypeClass(typeClass)); + } + } + + sal_Bool bFound = sal_False; + ::std::set< sal_uInt16 > moreProps; + + for (i=0; i < nFields1; i++) + { + for (j=0; j < nFields2; j++) + { + if (!checkField(keyName, typeClass, bDump, reader1, reader2, i, j)) + { + bFound = sal_True; + moreProps.insert(j); + break; + } + } + if (!bFound) + { + if (options.forceOutput()) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " incompatible change: Field %d ('%s') of r1 is not longer a property of this %s in r2\n", + i, U2S(shortName(reader1.getFieldName(i))), getTypeClass(typeClass)); + } + nError++; + } else + { + bFound = sal_False; + } + } + + if ( typeClass == RT_TYPE_SERVICE && !moreProps.empty() ) + { + for (j=0; j < nFields2; j++) + { + if ( moreProps.find(j) == moreProps.end() ) + { + if ( (reader2.getFieldFlags(j) & RT_ACCESS_OPTIONAL) != RT_ACCESS_OPTIONAL ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " incompatible change: Field %d ('%s') of r2 is a new property compared to this %s in r1 and is not 'optional'\n", + j, U2S(shortName(reader2.getFieldName(j))), getTypeClass(typeClass)); + } + nError++; + } + } + } + } + + return nError; +} + +static sal_uInt32 checkBlob(const OUString& keyName, typereg::Reader& reader1, sal_uInt32 size1, + typereg::Reader& reader2, sal_uInt32 size2) +{ + sal_uInt32 nError = 0; + sal_Bool bDump = sal_True; + + if ( options.fullCheck() && (size1 != size2) ) + { + if ( options.forceOutput() ) + { + fprintf( + stdout, " Size1 = %lu Size2 = %lu\n", + sal::static_int_cast< unsigned long >(size1), + sal::static_int_cast< unsigned long >(size2)); + } + } + if (reader1.isPublished()) { + if (!reader2.isPublished()) { + if (options.forceOutput()) { + if (bDump) { + fprintf(stdout, "?: %s\n", U2S(keyName)); + bDump = false; + } + fprintf(stdout, " published in 1 but unpublished in 2\n"); + } + ++nError; + } + } else if (!options.checkUnpublished()) { + return nError; + } + if ( reader1.getTypeClass() != reader2.getTypeClass() ) + { + if ( options.forceOutput() ) + { + if (bDump) { + fprintf(stdout, "?: %s\n", U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " TypeClass1 = %s != TypeClass2 = %s\n", + getTypeClass(reader1.getTypeClass()), + getTypeClass(reader2.getTypeClass())); + } + return ++nError; + } + + RTTypeClass typeClass = reader1.getTypeClass(); + + if ( reader1.getTypeName() != reader2.getTypeName() ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " TypeName1 = %s != TypeName2 = %s\n", + U2S(reader1.getTypeName()), U2S(reader2.getTypeName())); + } + nError++; + } + if ( (typeClass == RT_TYPE_INTERFACE || + typeClass == RT_TYPE_STRUCT || + typeClass == RT_TYPE_EXCEPTION) ) + { + if (reader1.getSuperTypeCount() != reader2.getSuperTypeCount()) { + if (bDump) { + fprintf( + stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = false; + } + fprintf( + stdout, " SuperTypeCount1 = %d != SuperTypeCount2 = %d\n", + static_cast< int >(reader1.getSuperTypeCount()), + static_cast< int >(reader2.getSuperTypeCount())); + ++nError; + } else { + for (sal_Int16 i = 0; i < reader1.getSuperTypeCount(); ++i) { + if (reader1.getSuperTypeName(i) != reader2.getSuperTypeName(i)) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " SuperTypeName1 = %s != SuperTypeName2 = %s\n", + U2S(reader1.getSuperTypeName(i)), U2S(reader2.getSuperTypeName(i))); + } + nError++; + } + } + } + } + sal_uInt16 nFields1 = (sal_uInt16)reader1.getFieldCount(); + sal_uInt16 nFields2 = (sal_uInt16)reader2.getFieldCount(); + sal_Bool bCheckNormal = sal_True; + + if ( (typeClass == RT_TYPE_SERVICE || + typeClass == RT_TYPE_MODULE || + typeClass == RT_TYPE_CONSTANTS) && options.unoTypeCheck() ) + { + bCheckNormal = sal_False; + } + + if ( bCheckNormal ) + { + if ( nFields1 != nFields2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " nFields1 = %d != nFields2 = %d\n", nFields1, nFields2); + } + nError++; + } + sal_uInt16 i; + for (i=0; i < nFields1 && i < nFields2; i++) + { + nError += checkField(keyName, typeClass, bDump, reader1, reader2, i, i); + } + if ( i < nFields1 && options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Registry1 contains %d more fields\n", nFields1 - i); + } + if ( i < nFields2 && options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Registry2 contains %d more fields\n", nFields2 - i); + } + } else + { + nError += checkFieldsWithoutOrder(keyName, typeClass, bDump, reader1, reader2); + } + + if ( typeClass == RT_TYPE_INTERFACE ) + { + sal_uInt16 nMethods1 = (sal_uInt16)reader1.getMethodCount(); + sal_uInt16 nMethods2 = (sal_uInt16)reader2.getMethodCount(); + if ( nMethods1 != nMethods2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " nMethods1 = %d != nMethods2 = %d\n", nMethods1, nMethods2); + } + nError++; + } + sal_uInt16 i; + for (i=0; i < nMethods1 && i < nMethods2; i++) + { + nError += checkMethod(keyName, typeClass, bDump, reader1, reader2, i); + } + if ( i < nMethods1 && options.forceOutput() ) + { + fprintf(stdout, " Registry1 contains %d more methods\n", nMethods1 - i); + } + if ( i < nMethods2 && options.forceOutput() ) + { + fprintf(stdout, " Registry2 contains %d more methods\n", nMethods2 - i); + } + } + if ( typeClass == RT_TYPE_SERVICE ) + { + sal_uInt16 nReference1 = (sal_uInt16)reader1.getReferenceCount(); + sal_uInt16 nReference2 = (sal_uInt16)reader2.getReferenceCount(); + + if ( !bCheckNormal ) + { + sal_uInt16 i=0, j=0; + + if ( nReference1 > nReference2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " service1 contains %d more references as service2\n", + nReference1-nReference2); + } + } + + sal_Bool bFound = sal_False; + ::std::set< sal_uInt16 > moreReferences; + + for (i=0; i < nReference1; i++) + { + for (j=0; j < nReference2; j++) + { + if (!checkReference(keyName, typeClass, bDump, reader1, reader2, i, j)) + { + bFound = sal_True; + moreReferences.insert(j); + break; + } + } + if (!bFound) + { + if (options.forceOutput()) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " incompatible change: Reference %d ('%s') in 'r1' is not longer a reference of this service in 'r2'\n", + i, U2S(shortName(reader1.getReferenceTypeName(i)))); + } + nError++; + } else + { + bFound = sal_False; + } + } + + if ( !moreReferences.empty() ) + { + for (j=0; j < nReference2; j++) + { + if ( moreReferences.find(j) == moreReferences.end() ) + { + if ( (reader2.getReferenceFlags(j) & RT_ACCESS_OPTIONAL) != RT_ACCESS_OPTIONAL ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " incompatible change: Reference %d ('%s') of r2 is a new reference compared to this service in r1 and is not 'optional'\n", + j, U2S(shortName(reader2.getReferenceTypeName(j)))); + } + nError++; + } + } + } + } + } else + { + if ( nReference1 != nReference2 ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " nReferences1 = %d != nReferences2 = %d\n", nReference1, nReference2); + } + nError++; + } + sal_uInt16 i; + for (i=0; i < nReference1 && i < nReference2; i++) + { + nError += checkReference(keyName, typeClass, bDump, reader1, reader2, i, i); + } + if ( i < nReference1 && options.forceOutput() ) + { + fprintf(stdout, " Registry1 contains %d more references\n", nReference1 - i); + } + if ( i < nReference2 && options.forceOutput() ) + { + fprintf(stdout, " Registry2 contains %d more references\n", nReference2 - i); + } + } + } + + if ( options.fullCheck() && (reader1.getDocumentation() != reader2.getDocumentation()) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Doku1 = %s\n Doku2 = %s\n", + U2S(reader1.getDocumentation()), U2S(reader2.getDocumentation())); + } + nError++; + } +/* + if ( nError && + (!keyName.compareTo(OUString::createFromAscii("/UCR/drafts"), 11) || + !keyName.compareTo(OUString::createFromAscii("/drafts"), 7)) ) + { + if ( options.forceOutput() ) + { + if ( bDump ) + { + fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName)); + bDump = sal_False; + } + fprintf(stdout, " Note: \"drafts\" type changed incompatible, no effect to the final API\n"); + } + return 0; + } +*/ + return nError; +} + +static sal_uInt32 checkValueDifference(RegistryKey& key1, RegValueType valueType1, sal_uInt32 size1, + RegistryKey& key2, RegValueType valueType2, sal_uInt32 size2) +{ + OUString tmpName; + sal_uInt32 nError = 0; + + if ( valueType1 == valueType2 ) + { + sal_Bool bEqual = sal_True; + switch (valueType1) + { + case RG_VALUETYPE_LONGLIST: + { + RegistryValueList<sal_Int32> valueList1; + RegistryValueList<sal_Int32> valueList2; + key1.getLongListValue(tmpName, valueList1); + key2.getLongListValue(tmpName, valueList2); + sal_uInt32 length1 = valueList1.getLength(); + sal_uInt32 length2 = valueList1.getLength(); + if ( length1 != length2 ) + { + bEqual = sal_False; + break; + } + for (sal_uInt32 i=0; i<length1; i++) + { + if ( valueList1.getElement(i) != valueList2.getElement(i) ) + { + bEqual = sal_False; + break; + } + } + } + break; + case RG_VALUETYPE_STRINGLIST: + { + RegistryValueList<sal_Char*> valueList1; + RegistryValueList<sal_Char*> valueList2; + key1.getStringListValue(tmpName, valueList1); + key2.getStringListValue(tmpName, valueList2); + sal_uInt32 length1 = valueList1.getLength(); + sal_uInt32 length2 = valueList1.getLength(); + if ( length1 != length2 ) + { + bEqual = sal_False; + break; + } + for (sal_uInt32 i=0; i<length1; i++) + { + if ( strcmp(valueList1.getElement(i), valueList2.getElement(i)) != 0 ) + { + bEqual = sal_False; + break; + } + } + } + break; + case RG_VALUETYPE_UNICODELIST: + { + RegistryValueList<sal_Unicode*> valueList1; + RegistryValueList<sal_Unicode*> valueList2; + key1.getUnicodeListValue(tmpName, valueList1); + key2.getUnicodeListValue(tmpName, valueList2); + sal_uInt32 length1 = valueList1.getLength(); + sal_uInt32 length2 = valueList1.getLength(); + if ( length1 != length2 ) + { + bEqual = sal_False; + break; + } + for (sal_uInt32 i=0; i<length1; i++) + { + if ( rtl_ustr_compare(valueList1.getElement(i), valueList2.getElement(i)) != 0 ) + { + bEqual = sal_False; + break; + } + } + } + break; + default: + break; + } + + if ( bEqual) + { + RegValue value1 = rtl_allocateMemory(size1); + RegValue value2 = rtl_allocateMemory(size2); + + key1.getValue(tmpName, value1); + key2.getValue(tmpName, value2); + + bEqual = (rtl_compareMemory(value1, value2, size1) == 0 ); + + if ( !bEqual && valueType1 == RG_VALUETYPE_BINARY && valueType2 == RG_VALUETYPE_BINARY ) + { + typereg::Reader reader1( + value1, size1, false, TYPEREG_VERSION_1); + typereg::Reader reader2( + value2, size2, false, TYPEREG_VERSION_1); + + if ( reader1.isValid() && reader2.isValid() ) + { + return checkBlob(key1.getName(), reader1, size1, reader2, size2); + } + } + + rtl_freeMemory(value1); + rtl_freeMemory(value2); + + if ( bEqual ) + { + return 0; + } else + { + if ( options.forceOutput() ) + { + fprintf(stdout, "Difference: key values of key \"%s\" are different\n", + U2S(key1.getName())); + } + nError++; + } + } + } + + if ( options.forceOutput() ) + { + switch (valueType1) + { + case RG_VALUETYPE_NOT_DEFINED: + fprintf(stdout, " Registry 1: key has no value\n"); + break; + case RG_VALUETYPE_LONG: + case RG_VALUETYPE_STRING: + case RG_VALUETYPE_UNICODE: + { + RegValue value1 = rtl_allocateMemory(size1); + key1.getValue(tmpName, value1); + + switch (valueType1) + { + case RG_VALUETYPE_LONG: + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_LONG\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size1)); + fprintf(stdout, " Data = %p\n", value1); + break; + case RG_VALUETYPE_STRING: + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_STRING\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size1)); + fprintf(stdout, " Data = \"%s\"\n", (sal_Char*)value1); + break; + case RG_VALUETYPE_UNICODE: + { + OUString uStrValue((sal_Unicode*)value1); + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_UNICODE\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size1)); + fprintf(stdout, " Data = \"%s\"\n", U2S(uStrValue)); + } + break; + default: + OSL_ASSERT(false); + break; + } + + rtl_freeMemory(value1); + } + break; + case RG_VALUETYPE_BINARY: + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_BINARY\n"); + break; + case RG_VALUETYPE_LONGLIST: + { + RegistryValueList<sal_Int32> valueList; + key1.getLongListValue(tmpName, valueList); + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_LONGLIST\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size1)); + sal_uInt32 length = valueList.getLength(); + for (sal_uInt32 i=0; i<length; i++) + { + fprintf( + stdout, " Data[%lu] = %ld\n", + sal::static_int_cast< unsigned long >(i), + sal::static_int_cast< long >(valueList.getElement(i))); + } + } + break; + case RG_VALUETYPE_STRINGLIST: + { + RegistryValueList<sal_Char*> valueList; + key1.getStringListValue(tmpName, valueList); + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_STRINGLIST\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size1)); + sal_uInt32 length = valueList.getLength(); + for (sal_uInt32 i=0; i<length; i++) + { + fprintf( + stdout, " Data[%lu] = \"%s\"\n", + sal::static_int_cast< unsigned long >(i), + valueList.getElement(i)); + } + } + break; + case RG_VALUETYPE_UNICODELIST: + { + RegistryValueList<sal_Unicode*> valueList; + key1.getUnicodeListValue(tmpName, valueList); + fprintf(stdout, " Registry 1: Value: Type = RG_VALUETYPE_UNICODELIST\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size1)); + sal_uInt32 length = valueList.getLength(); + OUString uStrValue; + for (sal_uInt32 i=0; i<length; i++) + { + uStrValue = OUString(valueList.getElement(i)); + fprintf( + stdout, " Data[%lu] = \"%s\"\n", + sal::static_int_cast< unsigned long >(i), U2S(uStrValue)); + } + } + break; + } + + switch (valueType2) + { + case RG_VALUETYPE_NOT_DEFINED: + fprintf(stdout, " Registry 2: key has no value\n"); + break; + case RG_VALUETYPE_LONG: + case RG_VALUETYPE_STRING: + case RG_VALUETYPE_UNICODE: + { + RegValue value2 = rtl_allocateMemory(size2); + key2.getValue(tmpName, value2); + + switch (valueType2) + { + case RG_VALUETYPE_LONG: + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_LONG\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size2)); + fprintf(stdout, " Data = %p\n", value2); + break; + case RG_VALUETYPE_STRING: + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_STRING\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size2)); + fprintf(stdout, " Data = \"%s\"\n", (sal_Char*)value2); + break; + case RG_VALUETYPE_UNICODE: + { + OUString uStrValue((sal_Unicode*)value2); + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_UNICODE\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size2)); + fprintf(stdout, " Data = \"%s\"\n", U2S(uStrValue)); + } + break; + default: + OSL_ASSERT(false); + break; + } + + rtl_freeMemory(value2); + } + break; + case RG_VALUETYPE_BINARY: + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_BINARY\n"); + break; + case RG_VALUETYPE_LONGLIST: + { + RegistryValueList<sal_Int32> valueList; + key2.getLongListValue(tmpName, valueList); + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_LONGLIST\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size2)); + sal_uInt32 length = valueList.getLength(); + for (sal_uInt32 i=0; i<length; i++) + { + fprintf( + stdout, " Data[%lu] = %ld\n", + sal::static_int_cast< unsigned long >(i), + sal::static_int_cast< long >(valueList.getElement(i))); + } + } + break; + case RG_VALUETYPE_STRINGLIST: + { + RegistryValueList<sal_Char*> valueList; + key2.getStringListValue(tmpName, valueList); + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_STRINGLIST\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size2)); + sal_uInt32 length = valueList.getLength(); + for (sal_uInt32 i=0; i<length; i++) + { + fprintf( + stdout, " Data[%lu] = \"%s\"\n", + sal::static_int_cast< unsigned long >(i), + valueList.getElement(i)); + } + } + break; + case RG_VALUETYPE_UNICODELIST: + { + RegistryValueList<sal_Unicode*> valueList; + key2.getUnicodeListValue(tmpName, valueList); + fprintf(stdout, " Registry 2: Value: Type = RG_VALUETYPE_UNICODELIST\n"); + fprintf( + stdout, " Size = %lu\n", + sal::static_int_cast< unsigned long >(size2)); + sal_uInt32 length = valueList.getLength(); + OUString uStrValue; + for (sal_uInt32 i=0; i<length; i++) + { + uStrValue = OUString(valueList.getElement(i)); + fprintf( + stdout, " Data[%lu] = \"%s\"\n", + sal::static_int_cast< unsigned long >(i), U2S(uStrValue)); + } + } + break; + } + } + return nError; +} + +static bool hasPublishedChildren(RegistryKey & key) { + RegistryKeyNames subKeyNames; + key.getKeyNames(rtl::OUString(), subKeyNames); + for (sal_uInt32 i = 0; i < subKeyNames.getLength(); ++i) { + rtl::OUString keyName(subKeyNames.getElement(i)); + if (!options.matchedWithExcludeKey(keyName)) { + keyName = keyName.copy(keyName.lastIndexOf('/') + 1); + RegistryKey subKey; + if (!key.openKey(keyName, subKey)) { + if (options.forceOutput()) { + fprintf( + stdout, + ("WARNING: could not open key \"%s\" in registry" + " \"%s\"\n"), + U2S(subKeyNames.getElement(i)), + options.getRegName1().getStr()); + } + } + if (subKey.isValid()) { + RegValueType type; + sal_uInt32 size; + if (subKey.getValueInfo(rtl::OUString(), &type, &size) + != REG_NO_ERROR) + { + if (options.forceOutput()) { + fprintf( + stdout, + ("WARNING: could not read key \"%s\" in registry" + " \"%s\"\n"), + U2S(subKeyNames.getElement(i)), + options.getRegName1().getStr()); + } + } else if (type == RG_VALUETYPE_BINARY) { + char * value = new char[size]; + bool published = false; + if (subKey.getValue(rtl::OUString(), value) != REG_NO_ERROR) + { + if (options.forceOutput()) { + fprintf( + stdout, + ("WARNING: could not read key \"%s\" in" + " registry \"%s\"\n"), + U2S(subKeyNames.getElement(i)), + options.getRegName1().getStr()); + } + } else { + published = typereg::Reader( + value, size, false, TYPEREG_VERSION_1). + isPublished(); + } + delete[] value; + if (published) { + return true; + } + } + } + } + } + return false; +} + +static sal_uInt32 checkDifferences( + RegistryKey& key, StringSet& keys, RegistryKeyNames& subKeyNames1, + RegistryKeyNames& subKeyNames2) +{ + sal_uInt32 nError = 0; + sal_uInt32 length1 = subKeyNames1.getLength(); + sal_uInt32 length2 = subKeyNames2.getLength(); + sal_uInt32 i,j; + + for (i=0; i<length1; i++) + { + sal_Bool bFound = sal_False; + for (j=0; j<length2; j++) + { + if ( subKeyNames1.getElement(i) == subKeyNames2.getElement(j) ) + { + bFound = sal_True; + keys.insert(subKeyNames1.getElement(i)); + break; + } + } + if ( !bFound ) + { + if ( options.fullCheck() ) + { + if ( options.forceOutput() ) + { + fprintf(stdout, "EXISTENCE: key \"%s\" exists only in registry \"%s\"\n", + U2S(subKeyNames1.getElement(i)), options.getRegName1().getStr()); + } + nError++; + } + else + { + rtl::OUString keyName(subKeyNames1.getElement(i)); + if (!options.matchedWithExcludeKey(keyName)) { + keyName = keyName.copy(keyName.lastIndexOf('/') + 1); + RegistryKey subKey; + if (key.openKey(keyName, subKey)) { + if (options.forceOutput()) { + fprintf( + stdout, + ("ERROR: could not open key \"%s\" in registry" + " \"%s\"\n"), + U2S(subKeyNames1.getElement(i)), + options.getRegName1().getStr()); + } + ++nError; + } + if (subKey.isValid()) { + RegValueType type; + sal_uInt32 size; + if (subKey.getValueInfo(rtl::OUString(), &type, &size) + != REG_NO_ERROR) + { + if (options.forceOutput()) { + fprintf( + stdout, + ("ERROR: could not read key \"%s\" in" + " registry \"%s\"\n"), + U2S(subKeyNames1.getElement(i)), + options.getRegName1().getStr()); + } + ++nError; + } else if (type == RG_VALUETYPE_BINARY) { + char * value = new char[size]; + if (subKey.getValue(rtl::OUString(), value) + != REG_NO_ERROR) + { + if (options.forceOutput()) { + fprintf( + stdout, + ("ERROR: could not read key \"%s\" in" + " registry \"%s\"\n"), + U2S(subKeyNames1.getElement(i)), + options.getRegName1().getStr()); + } + ++nError; + } else { + typereg::Reader reader( + value, size, false, TYPEREG_VERSION_1); + if (reader.getTypeClass() == RT_TYPE_MODULE) { + if (options.checkUnpublished() + || hasPublishedChildren(subKey)) + { + if (options.forceOutput()) { + fprintf( + stdout, + ("EXISTENCE: module \"%s\"" + " %sexists only in registry" + " 1\n"), + U2S(subKeyNames1.getElement( + i)), + (options.checkUnpublished() + ? "" + : "with published children ")); + } + ++nError; + } + } else if (options.checkUnpublished() + || reader.isPublished()) + { + if (options.forceOutput()) { + fprintf( + stdout, + ("EXISTENCE: %spublished key \"%s\"" + " exists only in registry 1\n"), + reader.isPublished() ? "" : "un", + U2S(subKeyNames1.getElement(i))); + } + ++nError; + } + } + delete[] value; + } + } + } + } + } + } + + for (i=0; i<length2; i++) + { + sal_Bool bFound = sal_False; + for (j=0; j<length1; j++) + { + if ( subKeyNames2.getElement(i) == subKeyNames1.getElement(j) ) + { + bFound = sal_True; + keys.insert(subKeyNames2.getElement(i)); + break; + } + } + if ( !bFound && options.fullCheck() ) + { + if ( options.forceOutput() ) + { + fprintf(stdout, "EXISTENCE: key \"%s\" exists only in registry \"%s\"\n", + U2S(subKeyNames2.getElement(i)), options.getRegName2().getStr()); + } + nError++; + } + } + return nError; +} + +static sal_uInt32 compareKeys(RegistryKey& key1, RegistryKey& key2) +{ + sal_uInt32 nError = 0; + + RegValueType valueType1 = RG_VALUETYPE_NOT_DEFINED; + RegValueType valueType2 = RG_VALUETYPE_NOT_DEFINED; + sal_uInt32 size1 = 0; + sal_uInt32 size2 = 0; + OUString tmpName; + RegError e1 = key1.getValueInfo(tmpName, &valueType1, &size1); + RegError e2 = key2.getValueInfo(tmpName, &valueType2, &size2); + + if ( e1 == e2 && e1 != REG_VALUE_NOT_EXISTS && e1 != REG_INVALID_VALUE ) + { + nError += checkValueDifference(key1, valueType1, size1, key2, valueType2, size2); + } else + { + if ( e1 != REG_INVALID_VALUE || e2 != REG_INVALID_VALUE ) + { + if ( options.forceOutput() ) + { + fprintf(stdout, "VALUES: key values of key \"%s\" are different\n", U2S(key1.getName())); + } + nError++; + } + } + + RegistryKeyNames subKeyNames1; + RegistryKeyNames subKeyNames2; + + key1.getKeyNames(tmpName, subKeyNames1); + key2.getKeyNames(tmpName, subKeyNames2); + + StringSet keys; + nError += checkDifferences(key1, keys, subKeyNames1, subKeyNames2); + + StringSet::iterator iter = keys.begin(); + StringSet::iterator end = keys.end(); + + RegistryKey subKey1, subKey2; + OUString keyName; + while ( iter != end ) + { + keyName = OUString(*iter); + if ( options.matchedWithExcludeKey(keyName) ) + { + ++iter; + continue; + } + + sal_Int32 nPos = keyName.lastIndexOf( '/' ); + keyName = keyName.copy( nPos != -1 ? nPos+1 : 0 ); + if ( key1.openKey(keyName, subKey1) ) + { + if ( options.forceOutput() ) + { + fprintf(stdout, "ERROR: could not open key \"%s\" in registry \"%s\"\n", + U2S(*iter), options.getRegName1().getStr()); + } + nError++; + } + if ( key2.openKey(keyName, subKey2) ) + { + if ( options.forceOutput() ) + { + fprintf(stdout, "ERROR: could not open key \"%s\" in registry \"%s\"\n", + U2S(*iter), options.getRegName2().getStr()); + } + nError++; + } + if ( subKey1.isValid() && subKey2.isValid() ) + { + nError += compareKeys(subKey1, subKey2); + } + subKey1.releaseKey(); + subKey2.releaseKey(); + ++iter; + } + + return nError; +} + +#if (defined UNX) || (defined OS2) || defined __MINGW32__ +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + if ( !options.initOptions(argc, argv) ) + { + exit(1); + } + + OUString regName1( convertToFileUrl(options.getRegName1()) ); + OUString regName2( convertToFileUrl(options.getRegName2()) ); + + Registry reg1; + Registry reg2; + + if ( reg1.open(regName1, REG_READONLY) ) + { + fprintf(stdout, "%s: open registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName1().getStr()); + exit(2); + } + if ( reg2.open(regName2, REG_READONLY) ) + { + fprintf(stdout, "%s: open registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName2().getStr()); + exit(3); + } + + RegistryKey key1, key2; + if ( reg1.openRootKey(key1) ) + { + fprintf(stdout, "%s: open root key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName1().getStr()); + exit(4); + } + if ( reg2.openRootKey(key2) ) + { + fprintf(stdout, "%s: open root key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName2().getStr()); + exit(5); + } + if ( options.isStartKeyValid() ) + { + if ( options.matchedWithExcludeKey( S2U(options.getStartKey()) ) ) + { + fprintf(stdout, "%s: start key is equal to one of the exclude keys\n", + options.getProgramName().getStr()); + exit(6); + } + RegistryKey sk1, sk2; + if ( key1.openKey(S2U(options.getStartKey()), sk1) ) + { + fprintf(stdout, "%s: open start key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName1().getStr()); + exit(7); + } + if ( key2.openKey(S2U(options.getStartKey()), sk2) ) + { + fprintf(stdout, "%s: open start key of registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName2().getStr()); + exit(8); + } + + key1 = sk1; + key2 = sk2; + } + + sal_uInt32 nError = compareKeys(key1, key2); + if ( nError ) + { + if ( options.unoTypeCheck() ) + { + fprintf(stdout, "%s: registries are incompatible: %lu differences!\n", + options.getProgramName().getStr(), + sal::static_int_cast< unsigned long >(nError)); + } else + { + fprintf(stdout, "%s: registries contain %lu differences!\n", + options.getProgramName().getStr(), + sal::static_int_cast< unsigned long >(nError)); + } + } else + { + if ( options.unoTypeCheck() ) + { + fprintf(stdout, "%s: registries are compatible!\n", + options.getProgramName().getStr()); + } else + { + fprintf(stdout, "%s: registries are equal!\n", + options.getProgramName().getStr()); + } + } + + key1.releaseKey(); + key2.releaseKey(); + if ( reg1.close() ) + { + fprintf(stdout, "%s: closing registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName1().getStr()); + exit(9); + } + if ( reg2.close() ) + { + fprintf(stdout, "%s: closing registry \"%s\" failed\n", + options.getProgramName().getStr(), options.getRegName2().getStr()); + exit(10); + } + + return nError > 0 ? 11 : 0; +} + + diff --git a/registry/tools/regmerge.cxx b/registry/tools/regmerge.cxx new file mode 100644 index 000000000000..06786a9b993e --- /dev/null +++ b/registry/tools/regmerge.cxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <stdio.h> +#include <string.h> + +#include "registry/registry.hxx" +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> +#include <osl/process.h> +#include <osl/diagnose.h> +#include <osl/thread.h> +#include <osl/file.hxx> + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +using namespace ::rtl; +using namespace ::osl; + +sal_Bool isFileUrl(const OString& fileName) +{ + if (fileName.indexOf("file://") == 0 ) + return sal_True; + return sal_False; +} + +OUString convertToFileUrl(const OString& fileName) +{ + if ( isFileUrl(fileName) ) + { + return OStringToOUString(fileName, osl_getThreadTextEncoding()); + } + + OUString uUrlFileName; + OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); + if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 ) + { + OUString uWorkingDir; + if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } else + { + if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } + + return uUrlFileName; +} + +int realargc; +char* realargv[2048]; + +static void dumpHelp() +{ + fprintf(stderr, "using: regmerge [-v|--verbose] mergefile mergeKeyName regfile_1 ... regfile_n\n"); + fprintf(stderr, " regmerge @regcmds\nOptions:\n"); + fprintf(stderr, " -v, --verbose : verbose output on stdout.\n"); + fprintf(stderr, " mergefile : specifies the merged registry file. If this file doesn't exists,\n"); + fprintf(stderr, " it is created.\n"); + fprintf(stderr, " mergeKeyName : specifies the merge key, everything is merged under this key.\n"); + fprintf(stderr, " If this key doesn't exists, it is created.\n"); + fprintf(stderr, " regfile_1..n : specifies one or more registry files which are merged.\n"); +} + +static bool checkCommandFile(char* cmdfile) +{ + FILE *commandfile; + char option[256]; + bool bVerbose = false; + + commandfile = fopen(cmdfile+1, "r"); + if( commandfile == NULL ) + { + fprintf(stderr, "ERROR: Can't open command file \"%s\"\n", cmdfile); + } else + { + while ( fscanf(commandfile, "%s", option) != EOF ) + { + if (option[0]== '@') + { + bool bRet = checkCommandFile(option); + // ensure that the option will not be overwritten + if ( !bRet ) + bVerbose = bRet; + } else { + if (option[0]== '-') { + if (strncmp(option, "-v", 2) == 0 || + strncmp(option, "--verbose", 9) == 0) + { + bVerbose = true; + } else { + fprintf(stderr, "ERROR: unknown option \"%s\"\n", option); + dumpHelp(); + exit(-1); + } + }else + { + realargv[realargc]= strdup(option); + realargc++; + } + } + if (realargc == 2047) + { + fprintf(stderr, "ERROR: more than 2048 arguments.\n"); + break; + } + } + fclose(commandfile); + } + + return bVerbose; +} + +static bool checkCommandArgs(int argc, char **argv) +{ + bool bVerbose = false; + + realargc = 0; + + for (int i=0; i<argc; i++) + { + if (argv[i][0]== '@') + { + bool bRet = checkCommandFile(argv[i]); + // ensure that the option will not be overwritten + if ( !bRet ) + bVerbose = bRet; + } else { + if (argv[i][0]== '-') { + if (strncmp(argv[i], "-v", 2) == 0 || + strncmp(argv[i], "--verbose", 9) == 0) + { + bVerbose = true; + } else { + fprintf(stderr, "ERROR: unknown option \"%s\"\n", argv[i]); + dumpHelp(); + exit(-1); + } + } else + { + realargv[realargc]= strdup(argv[i]); + realargc++; + } + } + } + + return bVerbose; +} + +static void cleanCommandArgs() +{ + for (int i=0; i<realargc; i++) + { + free(realargv[i]); + } +} + + + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + bool bVerbose = checkCommandArgs(argc, argv); + + if (realargc < 4) + { + dumpHelp(); + cleanCommandArgs(); + exit(1); + } + + ::rtl::OUString regName( convertToFileUrl(realargv[1]) ); + + Registry reg; + if (reg.open(regName, REG_READWRITE) != REG_NO_ERROR) + { + if (reg.create(regName) != REG_NO_ERROR) + { + if (bVerbose) + fprintf(stderr, "open registry \"%s\" failed\n", realargv[1]); + cleanCommandArgs(); + exit(-1); + } + } + + RegistryKey rootKey; + if (reg.openRootKey(rootKey) == REG_NO_ERROR) + { + ::rtl::OUString mergeKeyName( ::rtl::OUString::createFromAscii(realargv[2]) ); + ::rtl::OUString targetRegName; + for (int i = 3; i < realargc; i++) + { + targetRegName = convertToFileUrl(realargv[i]); + RegError _ret = reg.mergeKey(rootKey, mergeKeyName, targetRegName, sal_False, bVerbose); + if (_ret != REG_NO_ERROR) + { + if (_ret == REG_MERGE_CONFLICT) + { + if (bVerbose) + fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n", + realargv[i], realargv[2], realargv[1]); + } else + { + if (bVerbose) + fprintf(stderr, "ERROR: merging registry \"%s\" under key \"%s\" in registry \"%s\" failed.\n", + realargv[i], realargv[2], realargv[1]); + exit(-2); + } + } else + { + if (bVerbose) + fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n", + realargv[i], realargv[2], realargv[1]); + } + } + + rootKey.releaseKey(); + } else + { + if (bVerbose) + fprintf(stderr, "open root key of registry \"%s\" failed\n", + realargv[1]); + exit(-4); + } + + if (reg.close() != REG_NO_ERROR) + { + if (bVerbose) + fprintf(stderr, "closing registry \"%s\" failed\n", realargv[1]); + cleanCommandArgs(); + exit(-5); + } + + cleanCommandArgs(); + return(0); +} + + diff --git a/registry/tools/regview.cxx b/registry/tools/regview.cxx new file mode 100644 index 000000000000..4e478e8985db --- /dev/null +++ b/registry/tools/regview.cxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <stdio.h> + +#include "registry/registry.h" +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> +#include <osl/process.h> +#include <osl/diagnose.h> +#include <osl/thread.h> +#include <osl/file.hxx> + +#ifdef SAL_UNX +#define SEPARATOR '/' +#else +#define SEPARATOR '\\' +#endif + +using namespace ::rtl; +using namespace ::osl; + +sal_Bool isFileUrl(const OString& fileName) +{ + if (fileName.indexOf("file://") == 0 ) + return sal_True; + return sal_False; +} + +OUString convertToFileUrl(const OString& fileName) +{ + if ( isFileUrl(fileName) ) + { + return OStringToOUString(fileName, osl_getThreadTextEncoding()); + } + + OUString uUrlFileName; + OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); + if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 ) + { + OUString uWorkingDir; + if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } else + { + if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } + + return uUrlFileName; +} + + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + RegHandle hReg; + RegKeyHandle hRootKey, hKey; + + if (argc < 2 || argc > 3) + { + fprintf(stderr, "using: regview registryfile [keyName]\n"); + exit(1); + } + + OUString regName( convertToFileUrl(argv[1]) ); + if (reg_openRegistry(regName.pData, &hReg, REG_READONLY)) + { + fprintf(stderr, "open registry \"%s\" failed\n", argv[1]); + exit(1); + } + + if (!reg_openRootKey(hReg, &hRootKey)) + { + if (argc == 3) + { + OUString keyName( OUString::createFromAscii(argv[2]) ); + if (!reg_openKey(hRootKey, keyName.pData, &hKey)) + { + if (reg_dumpRegistry(hKey)) + { + fprintf(stderr, "dumping registry \"%s\" failed\n", argv[1]); + } + + if (reg_closeKey(hKey)) + { + fprintf(stderr, "closing key \"%s\" of registry \"%s\" failed\n", + argv[2], argv[1]); + } + } else + { + fprintf(stderr, "key \"%s\" not exists in registry \"%s\"\n", + argv[2], argv[1]); + } + } else + { + if (reg_dumpRegistry(hRootKey)) + { + fprintf(stderr, "dumping registry \"%s\" failed\n", argv[1]); + } + } + + if (reg_closeKey(hRootKey)) + { + fprintf(stderr, "closing root key of registry \"%s\" failed\n", argv[1]); + } + } else + { + fprintf(stderr, "open root key of registry \"%s\" failed\n", argv[1]); + } + + if (reg_closeRegistry(hReg)) + { + fprintf(stderr, "closing registry \"%s\" failed\n", argv[1]); + exit(1); + } + + return(0); +} + + diff --git a/registry/util/makefile.mk b/registry/util/makefile.mk new file mode 100644 index 000000000000..1fb4cdc0fe38 --- /dev/null +++ b/registry/util/makefile.mk @@ -0,0 +1,76 @@ +#************************************************************************* +# +# 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=registry +TARGET=reg + +UNIXVERSIONNAMES=UDK + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +USE_LDUMP2=TRUE +#USE_DEFFILE=TRUE +LDUMP2=LDUMP3 + +DOCPPFILES= $(INC)$/registry$/registry.hxx \ + $(INC)$/registry$/registry.h \ + $(INC)$/registry$/regtype.h \ + $(INC)$/registry$/reflread.hxx \ + $(INC)$/registry$/reflwrit.hxx \ + $(INC)$/registry$/refltype.hxx \ + +LIB1TARGET= $(SLB)$/$(TARGET).lib + +LIB1FILES= $(SLB)$/$(TARGET)cpp.lib + +SHL1TARGET= $(TARGET) +SHL1IMPLIB= ireg +SHL1STDLIBS= \ + $(SALLIB) \ + $(STORELIB) + +SHL1VERSIONMAP= $(TARGET).map + +SHL1LIBS= $(LIB1TARGET) +SHL1DEPN= $(LIB1TARGET) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) +DEF1DES = RegistryRuntime +SHL1RPATH=URELIB + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +makedocpp: $(DOCPPFILES) + docpp -H -m -f -u -d $(OUT)$/doc$/$(PRJNAME) $(DOCPPFILES) + diff --git a/registry/util/reg.map b/registry/util/reg.map new file mode 100644 index 000000000000..92913e755eb5 --- /dev/null +++ b/registry/util/reg.map @@ -0,0 +1,88 @@ +UDK_3_0_0 { + global: + initRegistry_Api; + initRegistryTypeWriter_Api; + initRegistryTypeReader_Api; + reg_createKey; + reg_openKey; + reg_openSubKeys; + reg_closeSubKeys; + reg_deleteKey; + reg_closeKey; + reg_getKeyName; + reg_setValue; + reg_setLongListValue; + reg_setStringListValue; + reg_setUnicodeListValue; + reg_getValueInfo; + reg_getValue; + reg_getLongListValue; + reg_getStringListValue; + reg_getUnicodeListValue; + reg_freeValueList; + reg_createLink; + reg_deleteLink; + reg_getKeyType; + reg_getLinkTarget; + reg_getResolvedKeyName; + reg_loadKey; + reg_saveKey; + reg_mergeKey; + reg_createRegistry; + reg_openRootKey; + reg_getName; + reg_isReadOnly; + reg_openRegistry; + reg_closeRegistry; + reg_destroyRegistry; + reg_dumpRegistry; + local: + *; +}; + +UDK_3.1 { + global: + typereg_reader_create; + typereg_reader_acquire; + typereg_reader_release; + typereg_reader_getVersion; + typereg_reader_getDocumentation; + typereg_reader_getFileName; + typereg_reader_getTypeClass; + typereg_reader_isPublished; + typereg_reader_getTypeName; + typereg_reader_getSuperTypeCount; + typereg_reader_getSuperTypeName; + typereg_reader_getFieldCount; + typereg_reader_getFieldDocumentation; + typereg_reader_getFieldFileName; + typereg_reader_getFieldFlags; + typereg_reader_getFieldName; + typereg_reader_getFieldTypeName; + typereg_reader_getFieldValue; + typereg_reader_getMethodCount; + typereg_reader_getMethodDocumentation; + typereg_reader_getMethodFlags; + typereg_reader_getMethodName; + typereg_reader_getMethodReturnTypeName; + typereg_reader_getMethodParameterCount; + typereg_reader_getMethodParameterFlags; + typereg_reader_getMethodParameterName; + typereg_reader_getMethodParameterTypeName; + typereg_reader_getMethodExceptionCount; + typereg_reader_getMethodExceptionTypeName; + typereg_reader_getReferenceCount; + typereg_reader_getReferenceDocumentation; + typereg_reader_getReferenceFlags; + typereg_reader_getReferenceSort; + typereg_reader_getReferenceTypeName; + typereg_writer_create; + typereg_writer_destroy; + typereg_writer_setSuperTypeName; + typereg_writer_setFieldData; + typereg_writer_setMethodData; + typereg_writer_setMethodParameterData; + typereg_writer_setMethodExceptionTypeName; + typereg_writer_setReferenceData; + typereg_writer_getBlob; +} UDK_3_0_0; diff --git a/registry/version.mk b/registry/version.mk new file mode 100644 index 000000000000..d4b56a318921 --- /dev/null +++ b/registry/version.mk @@ -0,0 +1,39 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +# target +REGISTRY_TARGET=reg + +# the major +REGISTRY_MAJOR=2 +# the minor +REGISTRY_MINOR=0 +# the micro +REGISTRY_MICRO=0 + +# this is a c++ compatible library +REGISTRY_CPP=0 diff --git a/registry/workben/makefile.mk b/registry/workben/makefile.mk new file mode 100644 index 000000000000..2813d696516a --- /dev/null +++ b/registry/workben/makefile.mk @@ -0,0 +1,86 @@ +#************************************************************************* +# +# 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=registry +TARGET=regtest +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS := TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +CDEFS += -DDLL_VERSION=$(EMQ)"$(DLLPOSTFIX)$(EMQ)" + +RGTLIB = rgt.lib +.IF "$(GUI)"=="UNX" || "$(GUI)"=="OS2" +RGTLIB = -lrgt$(DLLPOSTFIX) +.ENDIF + + +CXXFILES= regtest.cxx \ + test.cxx \ + regspeed.cxx + + +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJ)$/regtest.obj + +APP1STDLIBS=\ + $(SALLIB) \ + $(REGLIB) + +APP2TARGET= test +APP2OBJS= $(OBJ)$/test.obj +APP2RPATH=NONE +.IF "$(GUI)"=="UNX" && "$(OS)"!="MACOSX" + +.IF "$(OS)"=="LINUX" +APP2LINKFLAGS=-Wl,-rpath,\''$$ORIGIN:$$ORIGIN/../lib'\' +.ENDIF + +.IF "$(OS)"=="SOLARIS" +APP2LINKFLAGS=-R\''$$ORIGIN/../lib:$$ORIGIN'\' +.ENDIF + +.ENDIF # "$(OS)"=="UNX" + +APP2STDLIBS=\ + $(RGTLIB) + +APP3TARGET= regspeed +APP3OBJS= $(OBJ)$/regspeed.obj + +APP3STDLIBS=\ + $(SALLIB) \ + $(REGLIB) + +.INCLUDE : target.mk diff --git a/registry/workben/regspeed.cxx b/registry/workben/regspeed.cxx new file mode 100644 index 000000000000..21a67c89ed35 --- /dev/null +++ b/registry/workben/regspeed.cxx @@ -0,0 +1,271 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <sys/timeb.h> +#include <sys/types.h> + +#include "registry/registry.h" +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> + +using namespace std; + +/***************************************************************** + MyTimer +*****************************************************************/ +#ifndef UNX +class MyTimer +{ +public: + void start() { _ftime( &m_start ); }; + void stop() + { + _ftime( &m_stop ); + m_diff = difftime(m_stop.time, m_start.time); + if (m_stop.millitm > m_start.millitm) + { + m_diff += ((double)(m_stop.millitm - m_start.millitm)) / 1000; + } + else + { + m_diff -= 1; + m_diff += ((double)(1000 - (m_start.millitm - m_stop.millitm))) / 1000; + } + printf(" %.4f Sekunden\n", m_diff); + }; + +protected: +#ifdef OS2 + struct timeb m_start, m_stop; +#else + struct _timeb m_start, m_stop; +#endif + double m_diff; +}; +#else +extern "C" int ftime(struct timeb *pt); + +class MyTimer +{ +public: + void start() { ftime( &m_start ); }; + void stop() + { + ftime( &m_stop ); + m_diff = difftime(m_stop.time, m_start.time); + if (m_stop.millitm > m_start.millitm) + { + m_diff += ((double)(m_stop.millitm - m_start.millitm)) / 1000; + } + else + { + m_diff -= 1; + m_diff += ((double)(1000 - (m_start.millitm - m_stop.millitm))) / 1000; + } + printf(" %.4f Sekunden\n", m_diff); + }; + +protected: + struct timeb m_start, m_stop; + double m_diff; +}; +#endif + +using namespace rtl; + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + RegHandle hReg; + RegKeyHandle hRootKey, hKey, hSubKey, hSubSubKey; + OUString sName1(RTL_CONSTASCII_USTRINGPARAM("regkey")); + OUString sName2(RTL_CONSTASCII_USTRINGPARAM("regSubkey")); + OUString sName3(RTL_CONSTASCII_USTRINGPARAM("regSubSubkey")); + OUString keyName1; + OUString keyName2; + OUString keyName3; + int S1 = 10; + int S2 = 10; + int S3 = 10; + MyTimer aTimer; + + if (argc < 4) + { + cerr << "using regspeed count1 count2 count3\n"; + exit(1); + } + + S1 = atoi(argv[1]); + S2 = atoi(argv[2]); + S3 = atoi(argv[3]); + + OUString speedReg( RTL_CONSTASCII_USTRINGPARAM("speed.reg")); + if (reg_createRegistry(speedReg.pData, &hReg)) + { + cout << "creating registry \"test.reg\" failed\n"; + } else + { + if (reg_openRootKey(hReg, &hRootKey)) + { + cout << "open root key \"test.reg\" failed\n"; + } else + { + printf("\n %d keys anlegen, oeffnen und schliessen dauert ... ", (S1 * S2 * S3)); + aTimer.start(); + + for (sal_Int32 i=0; i < S1; i++) + { + keyName1 = sName1; + keyName1 += OUString().valueOf(i); + if (reg_createKey(hRootKey, keyName1.pData, &hKey)) + cout << "creating key \"" << OUStringToOString(keyName1, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + for (sal_Int32 j=0; j < S2; j++) + { + keyName2 = sName2; + keyName2 += OUString().valueOf(j); + if (reg_createKey(hKey, keyName2.pData, &hSubKey)) + cout << "creating key \"" << OUStringToOString(keyName2, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + for (sal_Int32 n=0; n < S3; n++) + { + keyName3 = sName3; + keyName3 += OUString().valueOf(n); + if (reg_createKey(hSubKey, keyName3.pData, &hSubSubKey)) + cout << "creating key \"" << OUStringToOString(keyName3, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + if (reg_closeKey(hSubSubKey)) + cout << "closing key \"" << OUStringToOString(keyName3, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + } + + if (reg_closeKey(hSubKey)) + cout << "closing key \"" << OUStringToOString(keyName2, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + } + + if (reg_closeKey(hKey)) + cout << "closing key \"" << OUStringToOString(keyName1, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + } + + aTimer.stop(); + + printf("\n %d keys oeffnen und schliessen dauert ... ", (S1 * S2 * S3)); + aTimer.start(); + + for (sal_Int32 i=0; i < S1; i++) + { + keyName1 = OUString::createFromAscii("/"); + keyName1 += sName1; + keyName1 += OUString().valueOf(i); + if (reg_openKey(hRootKey, keyName1.pData, &hKey)) + cout << "open key \"" << OUStringToOString(keyName1, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + for (sal_Int32 j=0; j < S2; j++) + { + keyName2 = OUString::createFromAscii("/"); + keyName2 += sName1; + keyName2 += OUString().valueOf(i); + keyName2 += OUString::createFromAscii("/"); + keyName2 += sName2; + keyName2 += OUString().valueOf(j); + if (reg_openKey(hRootKey, keyName2.pData, &hSubKey)) + cout << "open key \"" << OUStringToOString(keyName2, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + for (sal_Int32 n=0; n < S3; n++) + { + keyName3 = OUString::createFromAscii("/"); + keyName3 += sName1; + keyName3 += OUString().valueOf(i); + keyName3 += OUString::createFromAscii("/"); + keyName3 += sName2; + keyName3 += OUString().valueOf(j); + keyName3 += OUString::createFromAscii("/"); + keyName3 += sName3; + keyName3 += OUString().valueOf(n); + if (reg_openKey(hRootKey, keyName3.pData, &hSubSubKey)) + cout << "open key \"" << OUStringToOString(keyName3, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + if (reg_closeKey(hSubSubKey)) + cout << "open key \"" << OUStringToOString(keyName3, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + } + + if (reg_closeKey(hSubKey)) + cout << "closing key \"" << OUStringToOString(keyName2, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + } + + if (reg_closeKey(hKey)) + cout << "closing key \"" << OUStringToOString(keyName1, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + } + + aTimer.stop(); + + printf("\n 1 key oeffnen und schliessen dauert ... "); + aTimer.start(); + + if (reg_openKey(hRootKey, keyName3.pData, &hSubSubKey)) + cout << "open key \"" << OUStringToOString(keyName3, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + if (reg_closeKey(hSubSubKey)) + cout << "open key \"" << OUStringToOString(keyName3, RTL_TEXTENCODING_ASCII_US).getStr() + << "\" failed\n"; + + aTimer.stop(); + + } + + if (reg_closeKey(hRootKey)) + cout << "closing root key failed\n"; + if (reg_closeRegistry(hReg)) + cout << "\t41. closing registry \"test.reg\" failed\n"; + } + + return(0); +} + + diff --git a/registry/workben/regtest.cxx b/registry/workben/regtest.cxx new file mode 100644 index 000000000000..ace25ed64d86 --- /dev/null +++ b/registry/workben/regtest.cxx @@ -0,0 +1,340 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <iostream> +#include <stdio.h> + +#include "registry/registry.h" +#include <rtl/ustring.hxx> +#include <rtl/alloc.h> + +using namespace std; +using namespace rtl; + +#if (defined UNX) || (defined OS2) +int main() +#else +int _cdecl main() +#endif +{ + RegHandle hReg; + RegKeyHandle hRootKey, hKey1, hKey2, hKey3, hKey4, hKey5; + + cout << "\n Simple Registry Test !!! \n\n"; + + if (reg_createRegistry(OUString::createFromAscii("test4.rdb").pData, &hReg)) + cout << "\t0. creating registry \"test4.rdb\" failed\n"; + else + cout << "0. registry test4.rdb is created\n"; + + if (reg_openRootKey(hReg, &hRootKey)) + cout << "1. open root key \"test4.rdb\" failed\n"; + else + cout << "1. root key of \"test4.rdb\" is opened\n"; + + if (reg_createKey(hRootKey, OUString::createFromAscii("myFirstKey").pData, &hKey1)) + cout << "\t2. creating key \"myFirstKey\" failed\n"; + else + cout << "2. key \"myFirstKey\" is created\n"; + if (reg_createKey(hRootKey, OUString::createFromAscii("mySecondKey").pData, &hKey2)) + cout << "\t3. creating key \"mySecondKey\" failed\n"; + else + cout << "3. key \"mySecondKey\" is created\n"; + if (reg_createKey(hKey1, OUString::createFromAscii("myFirstSubKey").pData, &hKey3)) + cout << "\t4. creating subkey \"myFirstSubKey\" failed\n"; + else + cout << "4. subkey \"myFirstSubKey\" is created\n"; + if (reg_createKey(hKey1, OUString::createFromAscii("mySecondSubKey").pData, &hKey4)) + cout << "\t5. creating subkey \"mySecondSubKey\" failed\n"; + else + cout << "5. subkey \"mySecondSubKey\" is created\n"; + if (reg_createKey(hRootKey, OUString::createFromAscii("myThirdKey").pData, &hKey5)) + cout << "\t6. creating key \"myThirdKey\" is created\n\n"; + else + cout << "6. key \"myThirdKey\" is created\n\n"; + + + RegKeyHandle* phSubKeys; + sal_uInt32 nSubKeys; + if (reg_openSubKeys(hRootKey, OUString::createFromAscii("myFirstKey").pData, &phSubKeys, &nSubKeys)) + cout << "\t7. open subkeys of \"myfirstKey\" failed\n"; + else + cout << "7. open " << nSubKeys << "subkeys of \"myfirstKey\"\n"; + + OUString keyName; + if (reg_getKeyName(phSubKeys[0], &keyName.pData)) + cout << "\tname of subkey 1 = " << OUStringToOString(keyName, RTL_TEXTENCODING_ASCII_US).getStr() << "\n"; + if (reg_getKeyName(phSubKeys[1], &keyName.pData)) + cout << "\tname of subkey 2 = " << OUStringToOString(keyName, RTL_TEXTENCODING_ASCII_US).getStr() << "\n"; + + if (reg_closeSubKeys(phSubKeys, nSubKeys)) + cout << "\t8. close subkeys of \"myfirstKey\" failed\n\n"; + else + cout << "8. close " << nSubKeys << "subkeys of \"myfirstKey\"\n\n"; + + + char* Value=(char*)"Mein erster Value"; + if (reg_setValue(hRootKey, OUString::createFromAscii("mySecondKey").pData, RG_VALUETYPE_STRING, Value, 18)) + cout << "\t9. setValue of key \"mySecondKey\" failed\n"; + else + cout << "9. setValue (string Value) of key \"mySecondKey\"\n"; + + RegValueType valueType; + sal_uInt32 valueSize; + sal_Char* readValue; + if (reg_getValueInfo(hRootKey, OUString::createFromAscii("mySecondKey").pData, &valueType, &valueSize)) + cout << "\t10. getValueInfo of key \"mySecondKey\" failed\n"; + else + cout << "10. getValueInfo of key \"mySecondKey\"\n"; + + readValue = (sal_Char*)rtl_allocateMemory(valueSize); + if (reg_getValue(hKey2, OUString().pData, readValue)) + cout << "\t11. getValue of key \"mySecondKey\" failed\n"; + else + { + cout << "11. getValue of key \"mySecondKey\"\n"; + + cout << "read Value,\n\tvalueType = " << (long)valueType + << "\n\tvalueSize = " << valueSize + << "\n\tvalue = " << readValue << "\n\n"; + } + rtl_freeMemory(readValue); + + if (reg_closeKey(hKey1) || + reg_closeKey(hKey3) || + reg_closeKey(hKey4)) + cout << "\t12. closing \"myFirstKey\" \"myfistSubKey\" \"mySecondSubKey\" failed\n"; + else + cout << "12. keys \"myFirstKey\" \"myfistSubKey\" \"mySecondSubKey\" are closed\n"; + + if (reg_deleteKey(hRootKey, OUString::createFromAscii("myFirstKey").pData)) + cout << "13.\t delete key \"myFirstKey\" failed\n"; + else + cout << "13. key \"myFirstKey\" is deleted\n"; + + if (reg_closeKey(hKey2)) + cout << "\t14. closing key \"mySecondKey\" failed\n"; + else + cout << "14. key \"mySecondKey\" is closed\n"; + + if (reg_openKey(hRootKey, OUString::createFromAscii("mySecondKey").pData, &hKey2)) + cout << "\n15. open key \"mySecondKey\" failed\n"; + else + cout << "15. key \"mySecondKey\" is opended\n"; + + if (reg_closeKey(hKey5)) + cout << "\t15. closing key \"myThirdSubKey\" failed\n"; + else + cout << "15. key \"myThirdSubKey\" is closed\n"; + if (reg_deleteKey(hRootKey, OUString::createFromAscii("myThirdKey").pData)) + cout << "\t16. delete key \"myThirdKey\" failed\n"; + else + cout << "16. key \"myThirdKey\" is deleted\n"; + + if (reg_openKey(hRootKey, OUString::createFromAscii("myThirdKey").pData, &hKey5)) + cout << "\t17. open key \"myThirdKey\" failed\n"; + else + cout << "17. key \"myThirdKey\" is opened\n"; + + cout << "\n close open keys\n\n"; + + if (reg_closeKey(hKey2)) + cout << "\t18. closing key \"mySecondKey\" failed\n"; + else + cout << "18. key \"mySecondKey\" is closed\n"; + + if (reg_closeKey(hRootKey)) + cout << "\t19. closing root key failed\n"; + else + cout << "19. root key is closed\n"; + + if (reg_closeRegistry(hReg)) + cout << "\t20. closing registry \"test4.rdb\" failed\n"; + else + cout << "20. registry \"test4.rdb\" is closed\n"; + + // Test loadkey + cout << "\nTest load key\n\n"; + + RegHandle hReg2; + RegKeyHandle hRootKey2, h2Key1, h2Key2, h2Key3, h2Key4, h2Key5; + + if (reg_createRegistry(OUString::createFromAscii("test5.rdb").pData, &hReg2)) + cout << "\t21. creating registry \"test5.rdb\" failed\n"; + else + cout << "21. registry \"test5.rdb\" is created\n"; + + if (reg_openRootKey(hReg2, &hRootKey2)) + cout << "\t22. open root key of \"test5.rdb\" failed\n"; + else + cout << "22. root key of \"test5.rdb\" is opened\n"; + + if (reg_createKey(hRootKey2, OUString::createFromAscii("reg2FirstKey").pData, &h2Key1)) + cout << "\t23. creating key \"reg2FirstKey\" failed\n"; + else + cout << "23. key \"reg2FirstKey\" is created\n"; + if (reg_createKey(hRootKey2, OUString::createFromAscii("reg2SecondKey").pData, &h2Key2)) + cout << "\t24. creating key \"reg2SecondKey\" failed\n"; + else + cout << "24. key \"reg2SecondKey\" is created\n"; + if (reg_createKey(h2Key1, OUString::createFromAscii("reg2FirstSubKey").pData, &h2Key3)) + cout << "\t25. creating key \"reg2FirstSubKey\" failed\n"; + else + cout << "25. key \"reg2FirstSubKey\" is created\n"; + if (reg_createKey(h2Key1, OUString::createFromAscii("reg2SecondSubKey").pData, &h2Key4)) + cout << "\26. creating key \"reg2SecondSubKey\" failed\n"; + else + cout << "26. key \"reg2SecondSubKey\" is created\n"; + if (reg_createKey(hRootKey2, OUString::createFromAscii("reg2ThirdKey").pData, &h2Key5)) + cout << "\n27. creating key \"reg2ThirdKey\" failed\n"; + else + cout << "27. key \"reg2ThirdKey\" is created\n"; + + sal_uInt32 nValue= 123456789; + if (reg_setValue(h2Key3, OUString().pData, RG_VALUETYPE_LONG, &nValue, sizeof(sal_uInt32))) + cout << "\t27.b) setValue of key \"reg2FirstSubKey\" failed\n"; + else + cout << "27.b). setValue (long Value) of key \"reg2FirstSubKey\"\n"; + + if (reg_closeKey(h2Key1) || + reg_closeKey(h2Key2) || + reg_closeKey(h2Key3) || + reg_closeKey(h2Key4) || + reg_closeKey(h2Key5)) + cout << "\n\t28. closing keys of \"test5.rdb\" failed\n"; + else + cout << "\n28. all keys of \"test5.rdb\" closed\n"; + + if (reg_closeKey(hRootKey2)) + cout << "\t29. root key of \"test5.rdb\" failed\n"; + else + cout << "29. root key of \"test5.rdb\" is closed\n"; + + if (reg_closeRegistry(hReg2)) + cout << "\t30. registry test5.rdb is closed\n"; + else + cout << "30. registry test5.rdb is closed\n"; + + if (reg_openRegistry(OUString::createFromAscii("test4.rdb").pData, &hReg, REG_READWRITE)) + cout << "\t31. registry test4.rdb is opened\n"; + else + cout << "31. registry test4.rdb is opened\n"; + + if (reg_openRootKey(hReg, &hRootKey)) + cout << "\t32. open root key of \"test4.rdb\" is failed\n"; + else + cout << "32. root key of \"test4.rdb\" is opened\n"; + + if (reg_loadKey(hRootKey, OUString::createFromAscii("allFromTest2").pData, + OUString::createFromAscii("test5.rdb").pData)) + cout << "\n\t33. load all keys from \"test5.rdb\" under key \"allFromTest2\" failed\n"; + else + cout << "\n33. load all keys from test5.rdb under key \"allFromTest2\"\n"; + + if (reg_saveKey(hRootKey, OUString::createFromAscii("allFromTest2").pData, + OUString::createFromAscii("test6.rdb").pData)) + cout << "\n\t34. save all keys under \"allFromTest2\" in test6.rdb\n"; + else + cout << "\n34. save all keys under \"allFromTest2\" in test6.rdb\n"; + + + if (reg_createKey(hRootKey, OUString::createFromAscii("allFromTest3").pData, &hKey1)) + cout << "\t35. creating key \"allFromTest3\" failed\n"; + else + cout << "36. key \"allFromTest3\" is created\n"; + if (reg_createKey(hKey1, OUString::createFromAscii("myFirstKey2").pData, &hKey2)) + cout << "\t37. creating key \"myFirstKey2\" failed\n"; + else + cout << "37. key \"myFirstKey2\" is created\n"; + if (reg_createKey(hKey1, OUString::createFromAscii("mySecondKey2").pData, &hKey3)) + cout << "\t38. creating key \"mySecondKey2\" failed\n"; + else + cout << "38. key \"mySecondKey2\" is created\n"; + + if (reg_mergeKey(hRootKey, OUString::createFromAscii("allFromTest3").pData, + OUString::createFromAscii("test6.rdb").pData, sal_False, sal_False)) + cout << "\n\t39. merge all keys under \"allFromTest2\" with all in test6.rdb\n"; + else + cout << "\n39. merge all keys under \"allFromTest2\" with all in test6.rdb\n"; + + if (reg_closeKey(hKey1)) + cout << "\n\t40. closing key \"allFromTest3\" of \"test5.rdb\" failed\n"; + else + cout << "\n40. closing key \"allFromTest3\" of \"test5.rdb\"\n"; + if (reg_closeKey(hKey2)) + cout << "\n\t41. closing key \"myFirstKey2\" of \"test5.rdb\" failed\n"; + else + cout << "\n41. closing key \"myFirstKey2\" of \"test5.rdb\"\n"; + if (reg_closeKey(hKey3)) + cout << "\n\t42. closing key \"mySecondKey2\" of \"test5.rdb\" failed\n"; + else + cout << "\n42. closing key \"mySecondKey2\" of \"test5.rdb\"\n"; + + + if (reg_deleteKey(hRootKey, OUString::createFromAscii("/allFromTest3/reg2FirstKey/reg2FirstSubKey").pData)) + cout << "\n\t43. delete key \"/allFromTest3/reg2FirstKey/reg2FirstSubKey\" failed\n"; + else + cout << "\n43. key \"/allFromTest3/reg2FirstKey/reg2FirstSubKey\" is deleted\n"; + + if (reg_openRegistry(OUString::createFromAscii("test4.rdb").pData, &hReg2, REG_READONLY)) + cout << "\n\t44. registry test4.rdb is opened for read only\n"; + else + cout << "\n44. registry test4.rdb is opened for read only\n"; + + RegHandle hReg3; + if (reg_openRegistry(OUString::createFromAscii("test4.rdb").pData, &hReg3, REG_READONLY)) + cout << "\n\t44.a). registry test4.rdb is opened for read only\n"; + else + cout << "\n44.a). registry test4.rdb is opened for read only\n"; + + if (reg_closeRegistry(hReg2)) + cout << "\t45. closing registry \"test4.rdb\" failed\n"; + else + cout << "45. registry \"test4.rdb\" is closed\n"; + + if (reg_closeKey(hRootKey)) + cout << "\n\t46. closing root key of \"test4.rdb\" failed\n"; + else + cout << "\n46. root key of \"test4.rdb\" is closed\n"; + + if (reg_closeRegistry(hReg)) + cout << "\t47. closing registry \"test4.rdb\" failed\n"; + else + cout << "47. registry \"test4.rdb\" is closed\n"; + + if (reg_closeRegistry(hReg3)) + cout << "\t47.a). closing registry \"test4.rdb\" failed\n"; + else + cout << "47.a). registry \"test4.rdb\" is closed\n"; + + return(0); +} + + diff --git a/registry/workben/test.cxx b/registry/workben/test.cxx new file mode 100644 index 000000000000..98b49618ea60 --- /dev/null +++ b/registry/workben/test.cxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * 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_registry.hxx" + +#include <stdio.h> + +#if (defined UNX) || (defined OS2) +int main() +#else +int _cdecl main() +#endif +{ + void test_coreReflection(); + void test_registry_CppApi(); + void test_generateMerge1(); + void test_generateMerge2(); + void test_merge(); + + test_coreReflection(); + test_registry_CppApi(); + test_generateMerge1(); + test_generateMerge2(); + test_merge(); + + return(0); +} + + |