summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/cc50_solaris_intel
diff options
context:
space:
mode:
authorPhilipp Lohmann <pl@openoffice.org>2001-06-21 09:11:26 +0000
committerPhilipp Lohmann <pl@openoffice.org>2001-06-21 09:11:26 +0000
commitc52e1826080e695b67ea8dda7975c75221c9984b (patch)
tree21943ea3e729055093c52a599b3bf8f82f69502c /bridges/source/cpp_uno/cc50_solaris_intel
parentdb52bcfcbc0e11e64587aa6c05373034c861dbf4 (diff)
#88580# updated binding according to local RTTI
Diffstat (limited to 'bridges/source/cpp_uno/cc50_solaris_intel')
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/except.cxx365
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx294
2 files changed, 446 insertions, 213 deletions
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
index f6336af23458..d5efb45583da 100644
--- a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: except.cxx,v $
*
- * $Revision: 1.6 $
+ * $Revision: 1.7 $
*
- * last change: $Author: dbo $ $Date: 2001-05-15 11:16:21 $
+ * last change: $Author: pl $ $Date: 2001-06-21 10:11:26 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -85,6 +85,8 @@
#include "cc50_solaris_intel.hxx"
+#include <hash.cxx>
+
// need a += operator for OString and sal_Char
namespace rtl
{
@@ -105,7 +107,6 @@ using namespace com::sun::star::uno;
namespace CPPU_CURRENT_NAMESPACE
{
-//==================================================================================================
static OString toUNOname( const OString & rRTTIname )
{
OString aRet;
@@ -116,7 +117,7 @@ static OString toUNOname( const OString & rRTTIname )
while( 1 )
{
- if( *pRTTI == ':' || *pRTTI == 0 )
+ if( *pRTTI == ':' || ! *pRTTI )
{
if( aRet.getLength() )
aRet += ".";
@@ -136,133 +137,49 @@ static OString toUNOname( const OString & rRTTIname )
//==================================================================================================
static OString toRTTIname( const OString & rUNOname )
{
- OStringBuffer ret( 64 );
+ OStringBuffer aRet( rUNOname.getLength()*2 );
sal_Int32 nIndex = 0;
do
{
- if (nIndex > 0)
- {
- ret.append( RTL_CONSTASCII_STRINGPARAM("::") );
- }
- ret.append( rUNOname.getToken( 0, '.', nIndex ) );
- }
- while (nIndex >= 0);
+ if( nIndex > 0 )
+ aRet.append( "::" );
+ aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
+ } while( nIndex != -1 );
- return ret.makeStringAndClear();
+ return aRet.makeStringAndClear();
}
//==================================================================================================
-static int replaceQdDdD( const OString& rIn, OString& rOutdD, OString& rOutdDdD )
-{
- int nRet = 0;
- int nLen = rIn.getLength(), i, n;
- rOutdD = OString();
- rOutdDdD = OString();
- for( i = 0, n = 0; ( i = rIn.indexOf( 'Q', i ) ) != -1 && i < nLen; i++ )
- {
- rOutdD += rIn.copy( n, i-n+1 );
- rOutdDdD += rIn.copy( n, i-n+1 );
- n = i+1;
- rOutdD += "dD";
- rOutdDdD += "dDdD";
- nRet++;
- }
- rOutdD += rIn.copy( n );
- rOutdDdD += rIn.copy( n );
- return nRet;
-}
-
-static OString toRTTIsymbolname( const OString & rRTTIname )
+static OString toRTTImangledname( const OString & rRTTIname )
{
if( ! rRTTIname.getLength() )
return OString();
- OString aRet;
- OString aPrefix;
+ OStringBuffer aRet( rRTTIname.getLength()*2 );
- int nUnoTokens = 1;
+ aRet.append( "__1n" );
sal_Int32 nIndex = 0;
- for ( ; nIndex < rRTTIname.getLength(); ++nIndex )
- {
- if (rRTTIname[ nIndex ] == ':')
- {
- ++nUnoTokens;
- }
- }
-
- int nAdjust = 0;
- int i = 0;
- nIndex = 0;
do
{
OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
int nBytes = aToken.getLength();
if( nBytes )
{
- OString aAdd;
- if( nBytes > 25 )
- {
- aAdd += (sal_Char)( nBytes/26 + 'a' );
- aAdd += (sal_Char)( nBytes % 26 + 'A' );
- }
- else
- aAdd += (sal_Char)( nBytes + 'A' );
- aRet += aAdd;
- // special case "Q"
- if( ( ( nBytes % 26 ) +'A' ) == 'Q' )
- {
- aRet += "dD";
- nAdjust += 2;
- }
-
- OString adD, adDdD;
- int nRepl = replaceQdDdD( aToken, adD, adDdD );
- if( nUnoTokens == 1 )
+ if( nBytes > 25 )
{
- // must replace "Q" by "QdD"
- aRet += adD;
- nAdjust += 2* nRepl;
+ aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
+ aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
}
else
- {
- // must replace "Q" by "QdDdD"
- aRet += adDdD;
- nAdjust += 4* nRepl;
- }
-
- if( i < nUnoTokens - 1 )
- {
- aPrefix += aAdd;
- // must replace "Q" by "QdD"
- aPrefix += adD;
- }
- }
-
- ++i; // token count
- }
- while (nIndex >= 0);
-
- aRet += '_';
-
- if( aPrefix.getLength() )
- {
- int nBytes = aRet.getLength() - nAdjust + 10;
- if( nBytes > 25 )
- {
- aPrefix += (sal_Char)( nBytes/26 + 'a' );
- aPrefix += (sal_Char)( nBytes % 26 + 'A' );
+ aRet.append( (sal_Char)( nBytes + 'A' ) );
+ aRet.append( aToken );
}
- else
- aPrefix += (sal_Char)( nBytes + 'A' );
+ } while( nIndex != -1 );
+ aRet.append( '_' );
- aRet = "__1c" + aPrefix + "__RTTI__1n" + aRet + "_";
- }
- else
- aRet = "__RTTI__1n"+aRet;
-
- return aRet;
+ return aRet.makeStringAndClear();
}
//##################################################################################################
@@ -271,24 +188,34 @@ static OString toRTTIsymbolname( const OString & rRTTIname )
class RTTIHolder
{
- static std::map< OString, void* > aAllRTTI;
+ std::map< OString, void* > aAllRTTI;
public:
- static void* getRTTI( const OString& rTypename );
- static void* getRTTI_UnoName( const OString& rUnoTypename )
+ ~RTTIHolder();
+
+ void* getRTTI( const OString& rTypename );
+ void* getRTTI_UnoName( const OString& rUnoTypename )
{ return getRTTI( toRTTIname( rUnoTypename ) ); }
- static void* insertRTTI( const OString& rTypename );
- static void* insertRTTI_UnoName( const OString& rTypename )
+ void* insertRTTI( const OString& rTypename );
+ void* insertRTTI_UnoName( const OString& rTypename )
{ return insertRTTI( toRTTIname( rTypename ) ); }
-
- // rSuperTypename MUST exist !!!
- static void* insertRTTI( const OString& rTypename, const OString& rSuperTypename );
- static void* insertRTTI_UnoNames( const OString& rTypename, const OString& rSuperTypename )
- { return insertRTTI( toRTTIname( rTypename ), toRTTIname( rSuperTypename ) ); }
-
+ void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
};
-std::map< OString, void* > RTTIHolder::aAllRTTI;
+RTTIHolder::~RTTIHolder()
+{
+ for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
+ iPos != aAllRTTI.end(); ++iPos )
+ {
+ void ** pRTTI = (void **)iPos->second;
+ ::free( pRTTI[ 0 ] );
+ delete (void *)pRTTI;
+ }
+}
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
void* RTTIHolder::getRTTI( const OString& rTypename )
{
@@ -297,19 +224,12 @@ void* RTTIHolder::getRTTI( const OString& rTypename )
element = aAllRTTI.find( rTypename );
if( element != aAllRTTI.end() )
return (*element).second;
- // create new rtti
- // first look for existing type info function
- static void* pMain = dlopen( NULL, RTLD_NOW );
- void* pSymbol = dlsym( pMain, toRTTIsymbolname( rTypename ).getStr() );
- if( pSymbol )
- {
- // there exists type info, use it (otherwise it will not be equal
- // since addresses - not contents - are matched in RTTI compare)
- aAllRTTI[ rTypename ] = pSymbol;
- return pSymbol;
- }
- // no type found
+ // create rtti structure
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
return NULL;
}
@@ -317,14 +237,21 @@ static long nMagicId = 1;
void* RTTIHolder::insertRTTI( const OString& rTypename )
{
+ OString aMangledName( toRTTImangledname( rTypename ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+
+ // rSuperTypename MUST exist !!!
void** pRTTI = new void*[ 19 ];
- memset( pRTTI, 0, 19*sizeof( void* ) );
pRTTI[ 0 ] = (void*)strdup( rTypename.getStr() );
+ pRTTI[ 1 ] = NULL;
pRTTI[ 2 ] = (void*)(7*sizeof(void*));
- pRTTI[ 3 ] = (void*)nMagicId++;
- pRTTI[ 4 ] = (void*)nMagicId++;
- pRTTI[ 5 ] = (void*)nMagicId++;
- pRTTI[ 6 ] = (void*)nMagicId++;
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
pRTTI[ 9 ] = pRTTI[ 3 ];
pRTTI[ 10 ] = pRTTI[ 4 ];
@@ -333,89 +260,87 @@ void* RTTIHolder::insertRTTI( const OString& rTypename )
pRTTI[ 13 ] = (void*)0x80000000;
aAllRTTI[ rTypename ] = (void*)pRTTI;
+#ifdef DEBUG
+ fprintf( stderr,
+ "generating base RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8x %.8x\n",
+ rTypename.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
return pRTTI;
}
-void* RTTIHolder::insertRTTI( const OString& rTypename, const OString& rSuperTypename )
+void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
{
- OSL_ENSURE( ! getRTTI( rTypename ), "insert RTTI called on already existing type" );
-
- void** pBaseRTTI = (void**)getRTTI( rSuperTypename );
- OSL_ENSURE( pBaseRTTI, "insert RTTI called with nonexisting supertype" );
+ OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
- std::list< void* > aSuperTypes;
+ void* pHaveRTTI = getRTTI( aRTTICompTypeName );
+ if( pHaveRTTI )
+ return pHaveRTTI;
- void** pTypeList = pBaseRTTI + 2 + ((int)pBaseRTTI[2] / sizeof(void*));
- while( *pTypeList != (void*)0x80000000 )
- aSuperTypes.push_back( *pTypeList++ );
-
- void** pRTTI = new void*[ 8 + aSuperTypes.size()+1 ];
- memset( pRTTI, 0, (8 + aSuperTypes.size()+1 + 5)*sizeof(void*));
- pRTTI[ 0 ] = (void*)strdup( rTypename.getStr() );
- pRTTI[ 2 ] = (void*)(7*sizeof(void*));
- pRTTI[ 3 ] = (void*)nMagicId++;
- pRTTI[ 4 ] = (void*)nMagicId++;
- pRTTI[ 5 ] = (void*)nMagicId++;
- pRTTI[ 6 ] = (void*)nMagicId++;
-
- int nPos = 9;
- while( aSuperTypes.size() )
- {
- pRTTI[ nPos++ ] = aSuperTypes.front();
- aSuperTypes.pop_front();
- }
- pRTTI[ nPos++ ] = 0;
- pRTTI[ nPos++ ] = pRTTI[ 3 ];
- pRTTI[ nPos++ ] = pRTTI[ 4 ];
- pRTTI[ nPos++ ] = pRTTI[ 5 ];
- pRTTI[ nPos++ ] = pRTTI[ 6 ];
- pRTTI[ nPos ] = (void*)0x80000000;
-
- aAllRTTI[ rTypename ] = pRTTI;
- return pRTTI;
-}
+ if( ! pCompTypeDescr->pBaseTypeDescription )
+ // this is a base type
+ return insertRTTI( aRTTICompTypeName );
-//--------------------------------------------------------------------------------------------------
+ // get base class RTTI
+ void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
+ OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
-static void* generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
-{
- OString aCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ // find out the size to allocate for RTTI
+ void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
+ int nInherit;
+ for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
+ ;
- void* pRTTI = RTTIHolder::getRTTI_UnoName( aCompTypeName );
- if( pRTTI )
- return pRTTI;
+ OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
- if( ! pCompTypeDescr->pBaseTypeDescription )
- // this is a base type
- return RTTIHolder::insertRTTI_UnoName( aCompTypeName );
- // generate super rtti if necessary
- void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
- OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype!" );
+ void** pRTTI = new void*[ 14 + nInherit * 5 ];
+ pRTTI[ 0 ] = (void*)strdup( aRTTICompTypeName.getStr() );
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
+ pRTTI[ 8 +nInherit*5 ] = NULL;
+ pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
+ pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
+ pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
+ pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
+ pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
+
+ aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
+
+#ifdef DEBUG
+ fprintf( stderr,
+ "generating struct RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8X %.8x\n",
+ aRTTICompTypeName.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
- return RTTIHolder::insertRTTI_UnoNames(
- aCompTypeName,
- OUStringToOString( pCompTypeDescr->pBaseTypeDescription->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US )
- );
+ return pRTTI;
}
-//--------------------------------------------------------------------------------------------------
-
-static Mutex s_aMutex;
-static std::map< void*, typelib_TypeDescription* > aExceptionMap;
+//__________________________________________________________________________________________________
static void deleteException( void* pExc )
{
- MutexGuard aGuard( s_aMutex );
- std::map< void*, typelib_TypeDescription* >::iterator element =
- aExceptionMap.find( pExc );
- OSL_ASSERT( element != aExceptionMap.end() );
- if( element != aExceptionMap.end() )
- {
- typelib_TypeDescription* pType = (*element).second;
- aExceptionMap.erase( pExc );
- uno_destructData( pExc, pType, cpp_release );
- typelib_typedescription_release( pType );
- }
+ typelib_TypeDescription* pType = (typelib_TypeDescription*)((void**)pExc)[-2];
+ uno_destructData( pExc, pType, cpp_release );
+ typelib_typedescription_release( pType );
}
//__________________________________________________________________________________________________
@@ -424,29 +349,43 @@ static void deleteException( void* pExc )
//#### exported ####################################################################################
//##################################################################################################
-
void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
{
- // construct cpp exception object
typelib_TypeDescription * pTypeDescr = 0;
+ // will be released by deleteException
typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
- void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize ); // will be released in generated dtor
- uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+ void* pRTTI;
+ {
+ static ::osl::Mutex aMutex;
+ ::osl::Guard< ::osl::Mutex > guard( aMutex );
- // destruct uno exception
- uno_any_destruct( pUnoExc, 0 );
+ static RTTIHolder * s_pRTTI = 0;
+ if (! s_pRTTI)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTI = new RTTIHolder();
+#else
+ static RTTIHolder s_aRTTI;
+ s_pRTTI = &s_aRTTI;
+#endif
+ }
+
+ pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
// a must be
OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
- typelib_CompoundTypeDescription * pCompTypeDescr = (typelib_CompoundTypeDescription *)pTypeDescr;
- void* pRTTI = generateRTTI( pCompTypeDescr );
+ void** pExcSpace = (void**)__Crun::ex_alloc( pTypeDescr->nSize + 8 );
+ void * pCppExc = (void*)(((char*)pExcSpace)+8);
+ // will be released in generated dtor
+ // alignment to 8
+ pExcSpace[0] = pTypeDescr;
+ uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
- {
- MutexGuard aGuard( s_aMutex );
- aExceptionMap[ pCppExc ] = pTypeDescr;
- }
+ // destruct uno exception
+ uno_any_destruct( pUnoExc, 0 );
__Crun::ex_throw( pCppExc, (const __Crun::static_type_info*)pRTTI, deleteException );
}
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx
new file mode 100644
index 000000000000..82c2c5502659
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx
@@ -0,0 +1,294 @@
+/*************************************************************************
+ *
+ * $RCSfile: hash.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: pl $ $Date: 2001-06-21 10:11:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#ifndef TEST
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+#else
+typedef unsigned int sal_uInt32;
+#endif
+
+#include <string.h>
+
+/*
+ * build a hash for a character buffer using the NIST algorithm
+ */
+
+class NIST_Hash
+{
+
+ // helper functions
+ sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return z ^ ( x & ( y ^ z ) );
+ }
+
+ sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return x ^ y ^ z;
+ }
+
+ sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return ( x & y ) + ( z & ( x ^ y ) );
+ }
+
+ sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
+ {
+ return ( nValue << nBits ) | ( nValue >> (32-nBits) );
+ }
+
+ sal_uInt32 expand_nostore( sal_uInt32 index )
+ {
+ return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ sal_uInt32 expand_store( sal_uInt32 index )
+ {
+ return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction )
+ {
+ e += rotl(a,5);
+ switch( nFunction )
+ {
+ case 1: e += f1( b, c, d );break;
+ case 2:
+ case 4: e += f2( b, c, d );break;
+ case 3: e += f3( b, c, d );break;
+ }
+ e += constant + datum;
+ b = rotl( b, 30 );
+ }
+
+ void transform();
+ void final();
+
+ // data members
+ sal_uInt32 data[16];
+ sal_uInt32 hashdata[5];
+public:
+ NIST_Hash( const char* pString, sal_uInt32 nLen );
+
+ sal_uInt32 *getHash() { return hashdata; }
+};
+
+void NIST_Hash::transform()
+{
+ // constants
+ const sal_uInt32 K2 = 0x5A827999;
+ const sal_uInt32 K3 = 0x6ED9EBA1;
+ const sal_uInt32 K5 = 0x8F1BBCDC;
+ const sal_uInt32 K10 = 0xCA62C1D6;
+
+ sal_uInt32 a, b, c, d, e;
+ a = hashdata[0];
+ b = hashdata[1];
+ c = hashdata[2];
+ d = hashdata[3];
+ e = hashdata[4];
+
+ subRound( a, b, c, d, e, K2, data[ 0], 1 );
+ subRound( e, a, b, c, d, K2, data[ 1], 1 );
+ subRound( d, e, a, b, c, K2, data[ 2], 1 );
+ subRound( c, d, e, a, b, K2, data[ 3], 1 );
+ subRound( b, c, d, e, a, K2, data[ 4], 1 );
+ subRound( a, b, c, d, e, K2, data[ 5], 1 );
+ subRound( e, a, b, c, d, K2, data[ 6], 1 );
+ subRound( d, e, a, b, c, K2, data[ 7], 1 );
+ subRound( c, d, e, a, b, K2, data[ 8], 1 );
+ subRound( b, c, d, e, a, K2, data[ 9], 1 );
+ subRound( a, b, c, d, e, K2, data[10], 1 );
+ subRound( e, a, b, c, d, K2, data[11], 1 );
+ subRound( d, e, a, b, c, K2, data[12], 1 );
+ subRound( c, d, e, a, b, K2, data[13], 1 );
+ subRound( b, c, d, e, a, K2, data[14], 1 );
+ subRound( a, b, c, d, e, K2, data[15], 1 );
+ subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
+ subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
+ subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
+ subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
+
+ subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
+
+ subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
+
+ subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
+
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+#define BLOCKSIZE sizeof( data )
+
+NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
+{
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+
+ sal_uInt32 nBytes = nLen;
+
+ while( nLen >= sizeof( data ) )
+ {
+ memcpy( data, pString, sizeof( data ) );
+ pString += sizeof( data );
+ nLen -= sizeof( data );
+ transform();
+ }
+ memcpy( data, pString, nLen );
+ ((char*)data)[nLen++] = 0x80;
+ if( nLen > sizeof( data ) - 8 )
+ {
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
+ transform();
+ memset( data, 0, sizeof( data ) - 8 );
+ }
+ else
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
+ data[14] = 0;
+ data[15] = nBytes << 3;
+ transform();
+}
+
+#ifdef TEST
+#include <stdio.h>
+int main( int argc, const char** argv )
+{
+ const char* pHash = argc < 2 ? argv[0] : argv[1];
+
+ NIST_Hash aHash( pHash, strlen( pHash ) );
+ sal_uInt32* pBits = aHash.getHash();
+
+ printf( "text : %s\n"
+ "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
+ pHash,
+ pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
+ );
+ return 0;
+}
+
+#endif