diff options
author | Philipp Lohmann <pl@openoffice.org> | 2001-06-21 09:11:26 +0000 |
---|---|---|
committer | Philipp Lohmann <pl@openoffice.org> | 2001-06-21 09:11:26 +0000 |
commit | c52e1826080e695b67ea8dda7975c75221c9984b (patch) | |
tree | 21943ea3e729055093c52a599b3bf8f82f69502c /bridges/source/cpp_uno/cc50_solaris_intel | |
parent | db52bcfcbc0e11e64587aa6c05373034c861dbf4 (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.cxx | 365 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx | 294 |
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 |