diff options
author | Lionel Elie Mamane <lionel@mamane.lu> | 2012-01-24 22:20:31 +0100 |
---|---|---|
committer | Lionel Elie Mamane <lionel@mamane.lu> | 2012-01-29 19:00:38 +0100 |
commit | 63b6b1d6120d82c4baf5cb679d75dcc5427dbbc3 (patch) | |
tree | bd2f0165d5d6ace3616d244c9d8b0afeef75fd18 /connectivity/source | |
parent | bec18a80f59085c034e5adb1bb61d8365c1406c3 (diff) |
make OTools::getValue insanely safe, factorise get{Int,Long,Byte,...}
Diffstat (limited to 'connectivity/source')
3 files changed, 124 insertions, 56 deletions
diff --git a/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx b/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx index 59876bb4c2de..6dd78812d28d 100644 --- a/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx +++ b/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx @@ -170,6 +170,30 @@ sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::findColumn( const ::rtl::OUString break; return i; } + +template < typename T, SQLSMALLINT sqlTypeId > T ODatabaseMetaDataResultSet::getInteger ( sal_Int32 columnIndex ) +{ + checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); + ::osl::MutexGuard aGuard( m_aMutex ); + + columnIndex = mapColumn(columnIndex); + T nVal = 0; + if(columnIndex <= m_nDriverColumnCount) + { + getValue<T>(m_pConnection, m_aStatementHandle, columnIndex, sqlTypeId, m_bWasNull, **this, nVal); + + if ( !m_aValueRange.empty() ) + { + ::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter (m_aValueRange.find(columnIndex)); + if ( aValueRangeIter != m_aValueRange.end() ) + return static_cast<T>(aValueRangeIter->second[nVal]); + } + } + else + m_bWasNull = sal_True; + return nVal; +} + // ------------------------------------------------------------------------- Reference< ::com::sun::star::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) { @@ -215,24 +239,7 @@ sal_Bool SAL_CALL ODatabaseMetaDataResultSet::getBoolean( sal_Int32 columnIndex sal_Int8 SAL_CALL ODatabaseMetaDataResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) { - - checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( m_aMutex ); - - - columnIndex = mapColumn(columnIndex); - sal_Int8 nVal = 0; - if(columnIndex <= m_nDriverColumnCount) - { - OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_TINYINT,m_bWasNull,**this,&nVal,sizeof nVal); - - ::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter; - if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end()) - return sal_Int8((*aValueRangeIter).second[(sal_Int32)nVal]); - } - else - m_bWasNull = sal_True; - return nVal; + return getInteger<sal_Int8, SQL_C_STINYINT>( columnIndex ); } // ------------------------------------------------------------------------- @@ -322,24 +329,7 @@ float SAL_CALL ODatabaseMetaDataResultSet::getFloat( sal_Int32 columnIndex ) thr sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) { - - checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( m_aMutex ); - - - columnIndex = mapColumn(columnIndex); - sal_Int32 nVal = 0; - if(columnIndex <= m_nDriverColumnCount) - { - OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_LONG,m_bWasNull,**this,&nVal,sizeof nVal); - - ::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter; - if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end()) - return (*aValueRangeIter).second[(sal_Int32)nVal]; - } - else - m_bWasNull = sal_True; - return nVal; + return getInteger<sal_Int32, SQL_C_SLONG>( columnIndex ); } // ------------------------------------------------------------------------- @@ -349,10 +339,9 @@ sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getRow( ) throw(SQLException, Ru } // ------------------------------------------------------------------------- -sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) +sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) { - ::dbtools::throwFunctionNotSupportedException( "XRow::getLong", *this ); - return 0; + return getInteger<sal_Int64, SQL_C_SBIGINT>( columnIndex ); } // ------------------------------------------------------------------------- @@ -398,23 +387,7 @@ Any SAL_CALL ODatabaseMetaDataResultSet::getObject( sal_Int32 /*columnIndex*/, c sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) { - - checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( m_aMutex ); - - columnIndex = mapColumn(columnIndex); - sal_Int16 nVal = 0; - if(columnIndex <= m_nDriverColumnCount) - { - OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_SHORT,m_bWasNull,**this,&nVal,sizeof nVal); - - ::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter; - if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end()) - return sal_Int16((*aValueRangeIter).second[(sal_Int32)nVal]); - } - else - m_bWasNull = sal_True; - return nVal; + return getInteger<sal_Int16, SQL_C_SSHORT>( columnIndex ); } // ------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/odbcbase/OTools.cxx b/connectivity/source/drivers/odbcbase/OTools.cxx index 4da70ef9f812..9e8714cb0ca8 100644 --- a/connectivity/source/drivers/odbcbase/OTools.cxx +++ b/connectivity/source/drivers/odbcbase/OTools.cxx @@ -45,6 +45,82 @@ using namespace com::sun::star::uno; using namespace com::sun::star::sdbc; using namespace com::sun::star::util; +namespace { +size_t sqlTypeLen ( SQLSMALLINT _nType ) +{ + switch (_nType) + { + case SQL_C_CHAR: + return sizeof(SQLCHAR *); + case SQL_C_WCHAR: + return sizeof(SQLWCHAR *); + case SQL_C_SSHORT: + case SQL_C_SHORT: + return sizeof(SQLSMALLINT); + case SQL_C_USHORT: + return sizeof(SQLUSMALLINT); + case SQL_C_SLONG: + case SQL_C_LONG: + return sizeof(SQLINTEGER); + case SQL_C_ULONG: + return sizeof(SQLUINTEGER); + case SQL_C_FLOAT: + return sizeof(SQLREAL); + case SQL_C_DOUBLE: + OSL_ENSURE(sizeof(SQLDOUBLE) == sizeof(SQLFLOAT), "SQLDOUBLE/SQLFLOAT confusion"); + return sizeof(SQLDOUBLE); + case SQL_C_BIT: + return sizeof(SQLCHAR); + case SQL_C_STINYINT: + case SQL_C_TINYINT: + return sizeof(SQLSCHAR); + case SQL_C_UTINYINT: + return sizeof(SQLCHAR); + case SQL_C_SBIGINT: + return sizeof(SQLBIGINT); + case SQL_C_UBIGINT: + return sizeof(SQLUBIGINT); + /* UnixODBC gives this the same value as SQL_C_UBIGINT + case SQL_C_BOOKMARK: + return sizeof(BOOKMARK); */ + case SQL_C_BINARY: + // UnixODBC gives these the same value + //case SQL_C_VARBOOKMARK: + return sizeof(SQLCHAR*); + case SQL_C_TYPE_DATE: + case SQL_C_DATE: + return sizeof(SQL_DATE_STRUCT); + case SQL_C_TYPE_TIME: + case SQL_C_TIME: + return sizeof(SQL_TIME_STRUCT); + case SQL_C_TYPE_TIMESTAMP: + case SQL_C_TIMESTAMP: + return sizeof(SQL_TIMESTAMP_STRUCT); + case SQL_C_NUMERIC: + return sizeof(SQL_NUMERIC_STRUCT); + case SQL_C_GUID: + return sizeof(SQLGUID); + case SQL_C_INTERVAL_YEAR: + case SQL_C_INTERVAL_MONTH: + case SQL_C_INTERVAL_DAY: + case SQL_C_INTERVAL_HOUR: + case SQL_C_INTERVAL_MINUTE: + case SQL_C_INTERVAL_SECOND: + case SQL_C_INTERVAL_YEAR_TO_MONTH: + case SQL_C_INTERVAL_DAY_TO_HOUR: + case SQL_C_INTERVAL_DAY_TO_MINUTE: + case SQL_C_INTERVAL_DAY_TO_SECOND: + case SQL_C_INTERVAL_HOUR_TO_MINUTE: + case SQL_C_INTERVAL_HOUR_TO_SECOND: + case SQL_C_INTERVAL_MINUTE_TO_SECOND: + return sizeof(SQL_INTERVAL_STRUCT); + default: + return static_cast<size_t>(-1); + } +} +} + + void OTools::getValue( OConnection* _pConnection, SQLHANDLE _aStatementHandle, sal_Int32 columnIndex, @@ -55,6 +131,23 @@ void OTools::getValue( OConnection* _pConnection, SQLLEN _nSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getValue" ); + const size_t properSize = sqlTypeLen(_nType); + if ( properSize == static_cast<size_t>(-1) ) + OSL_FAIL("connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size"); + else + { + OSL_ENSURE(static_cast<size_t>(_nSize) == properSize, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to"); + if ( static_cast<size_t>(_nSize) > properSize ) + { + OSL_FAIL("memory region is too big - trying to fudge it"); + memset(_pValue, 0, _nSize); +#ifdef OSL_BIGENDIAN + // This is skewed in favour of integer types + _pValue += _nSize - properSize; +#endif + } + } + OSL_ENSURE(static_cast<size_t>(_nSize) >= properSize, "memory region is too small"); SQLLEN pcbValue = SQL_NULL_DATA; OTools::ThrowException(_pConnection, (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, diff --git a/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx b/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx index 1ae6042ca04f..7a17249ec8e3 100644 --- a/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx +++ b/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx @@ -125,6 +125,8 @@ namespace connectivity sal_Int32 nHandle ) const; ~ODatabaseMetaDataResultSet(); + template < typename T, SQLSMALLINT sqlTypeId > T getInteger ( sal_Int32 columnIndex ); + public: // ein Konstruktor, der fuer das Returnen des Objektes benoetigt wird: ODatabaseMetaDataResultSet(OConnection* _pConnection); |