diff --git a/Data/ODBC/include/Poco/Data/ODBC/Unicode_UNIXODBC.h b/Data/ODBC/include/Poco/Data/ODBC/Unicode_UNIXODBC.h index f45f3a3f0..5e0746e96 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Unicode_UNIXODBC.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Unicode_UNIXODBC.h @@ -56,7 +56,7 @@ inline void makeUTF16(SQLCHAR* pSQLChar, SQLSMALLINT length, std::string& target } -inline void makeUTF8(Poco::Buffer& buffer, int length, SQLPOINTER pTarget, SQLINTEGER targetLength); +void makeUTF8(Poco::Buffer& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength); /// Utility function for conversion from UTF-16 to UTF-8. diff --git a/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h b/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h index 33d451a8f..78846ed32 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h @@ -42,7 +42,7 @@ namespace Poco { namespace Data { -namespace ODBC { +namespace ODBC { inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target) @@ -56,16 +56,15 @@ inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target } -inline void makeUTF16(SQLCHAR* pSQLChar, SQLSMALLINT length, std::wstring& target) - /// Utility function for conversion from UTF-8 to UTF-16. +inline void makeUTF8(Poco::Buffer& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength) + /// Utility function for conversion from UTF-16 to UTF-8. Length is in bytes. { - makeUTF16(pSQLChar, (SQLINTEGER) length, target); -} + if (buffer.sizeBytes() < length) + throw InvalidArgumentException("Specified length exceeds available length."); + else if ((length % 2) != 0) + throw InvalidArgumentException("Length must be an even number."); - -inline void makeUTF8(Poco::Buffer& buffer, int length, SQLPOINTER pTarget, SQLINTEGER targetLength) - /// Utility function for conversion from UTF-16 to UTF-8. -{ + length /= sizeof(wchar_t); std::string result; UnicodeConverter::toUTF8(buffer.begin(), length, result); @@ -74,13 +73,6 @@ inline void makeUTF8(Poco::Buffer& buffer, int length, SQLPOINTER pTarg } -inline void makeUTF8(Poco::Buffer& buffer, int length, SQLPOINTER pTarget, SQLSMALLINT targetLength) - /// Utility function for conversion from UTF-16 to UTF-8. -{ - makeUTF8(buffer, length, pTarget, (SQLINTEGER) targetLength); -} - - } } } // namespace Poco::Data::ODBC diff --git a/Data/ODBC/src/SessionImpl.cpp b/Data/ODBC/src/SessionImpl.cpp index 91b704b58..a7b743d2d 100644 --- a/Data/ODBC/src/SessionImpl.cpp +++ b/Data/ODBC/src/SessionImpl.cpp @@ -218,7 +218,7 @@ bool SessionImpl::canTransact() if (ODBC_TXN_CAPABILITY_UNKNOWN == _canTransact) { SQLUSMALLINT ret; - checkError(Poco::Data::ODBC::SQLGetInfo(_db, SQL_TXN_CAPABLE, &ret, sizeof(ret), 0), + checkError(Poco::Data::ODBC::SQLGetInfo(_db, SQL_TXN_CAPABLE, &ret, 0, 0), "Failed to obtain transaction capability info."); _canTransact = (SQL_TC_NONE != ret) ? diff --git a/Data/ODBC/src/Unicode_UNIXODBC.cpp b/Data/ODBC/src/Unicode_UNIXODBC.cpp index c82762860..5e453a529 100644 --- a/Data/ODBC/src/Unicode_UNIXODBC.cpp +++ b/Data/ODBC/src/Unicode_UNIXODBC.cpp @@ -72,14 +72,14 @@ void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::string& target) } -void makeUTF8(Poco::Buffer& buffer, int length, SQLPOINTER pTarget, SQLINTEGER targetLength) +void makeUTF8(Poco::Buffer& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength) { UTF8Encoding utf8Encoding; UTF16Encoding utf16Encoding; TextConverter converter(utf16Encoding, utf8Encoding); std::string result; - if (0 != converter.convert(buffer.begin(), length * sizeof(SQLWCHAR), result)) + if (0 != converter.convert(buffer.begin(), length, result)) throw DataFormatException("Error converting UTF-16 to UTF-8"); std::memset(pTarget, 0, targetLength); @@ -103,7 +103,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt, iCol, iField, buffer.begin(), - (SQLSMALLINT) buffer.size() * sizeof(SQLWCHAR), + (SQLSMALLINT) buffer.sizeBytes(), pcbCharAttr, pNumAttr); @@ -157,8 +157,8 @@ SQLRETURN SQLConnect(SQLHDBC hdbc, makeUTF16(szAuthStr, cbAuthStr, sqlPWD); return SQLConnectW(hdbc, - (SQLWCHAR*) sqlDSN.c_str(), cbDSN, - (SQLWCHAR*) sqlUID.c_str(), cbUID, + (SQLWCHAR*) sqlDSN.c_str(), cbDSN, + (SQLWCHAR*) sqlUID.c_str(), cbUID, (SQLWCHAR*) sqlPWD.c_str(), cbAuthStr); } @@ -184,7 +184,7 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt, pibScale, pfNullable); - makeUTF8(buffer, *pcbColName, szColName, cbColNameMax); + makeUTF8(buffer, *pcbColName * sizeof(SQLWCHAR), szColName, cbColNameMax); return rc; } @@ -227,7 +227,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc, SQLRETURN rc = SQLGetConnectAttrW(hdbc, fAttribute, buffer.begin(), - (SQLINTEGER) buffer.size() * sizeof(SQLWCHAR), + (SQLINTEGER) buffer.sizeBytes(), pcbValue); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); @@ -293,7 +293,7 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc, iRecord, iField, buffer.begin(), - (SQLINTEGER) buffer.size() * sizeof(SQLWCHAR), + (SQLINTEGER) buffer.sizeBytes(), pcbValue); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); @@ -343,7 +343,7 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType, iRecord, fDiagField, buffer.begin(), - (SQLSMALLINT) buffer.size() * sizeof(SQLWCHAR), + (SQLSMALLINT) buffer.sizeBytes(), pcbDiagInfo); makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax); @@ -383,8 +383,8 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType, (SQLSMALLINT) bufErr.size(), pcbErrorMsg); - makeUTF8(bufState, stateLen, szSqlState, stateLen); - makeUTF8(bufErr, *pcbErrorMsg, szErrorMsg, cbErrorMsgMax); + makeUTF8(bufState, stateLen * sizeof(SQLWCHAR), szSqlState, stateLen); + makeUTF8(bufErr, *pcbErrorMsg * sizeof(SQLWCHAR), szErrorMsg, cbErrorMsgMax); return rc; } @@ -462,11 +462,11 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt, return SQLGetStmtAttrW(hstmt, fAttribute, (SQLPOINTER) buffer.begin(), - (SQLINTEGER) buffer.size() * sizeof(SQLWCHAR), + (SQLINTEGER) buffer.sizeBytes(), pcbValue); } - return SQLGetStmtAttrW(hstmt, fAttribute, rgbValue, cbValueMax, pcbValue); + return SQLGetStmtAttrW(hstmt, fAttribute, rgbValue, cbValueMax, pcbValue); } @@ -505,7 +505,7 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc, SQLRETURN rc = SQLGetInfoW(hdbc, fInfoType, (SQLPOINTER) buffer.begin(), - (SQLSMALLINT) buffer.size() * sizeof(SQLWCHAR), + (SQLSMALLINT) buffer.sizeBytes(), pcbInfoValue); makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax); @@ -595,8 +595,8 @@ SQLRETURN SQLDataSources(SQLHENV henv, (SQLSMALLINT) bufDesc.size(), pcbDesc); - makeUTF8(bufDSN, *pcbDSN, szDSN, cbDSNMax); - makeUTF8(bufDesc, *pcbDesc, szDesc, cbDescMax); + makeUTF8(bufDSN, *pcbDSN * sizeof(SQLWCHAR), szDSN, cbDSNMax); + makeUTF8(bufDesc, *pcbDesc * sizeof(SQLWCHAR), szDesc, cbDescMax); return rc; } @@ -628,7 +628,7 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc, pcbConnStrOut, fDriverCompletion); - makeUTF8(out, *pcbConnStrOut, pcbConnStrOut, cbConnStrOutMax); + makeUTF8(out, *pcbConnStrOut * sizeof(SQLWCHAR), pcbConnStrOut, cbConnStrOutMax); return rc; } @@ -653,7 +653,7 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc, (SQLSMALLINT) bufConnStrOut.size(), pcbConnStrOut); - makeUTF8(bufConnStrOut, *pcbConnStrOut, szConnStrOut, cbConnStrOutMax); + makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(SQLWCHAR), szConnStrOut, cbConnStrOutMax); return rc; } @@ -710,7 +710,7 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc, (SQLINTEGER) bufSQLOut.size(), pcbSqlStr); - makeUTF8(bufSQLOut, *pcbSqlStr, szSqlStr, cbSqlStrMax); + makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(SQLWCHAR), szSqlStr, cbSqlStrMax); return rc; } @@ -787,8 +787,8 @@ SQLRETURN SQLDrivers(SQLHENV henv, (SQLSMALLINT) bufDriverAttr.size(), pcbDrvrAttr); - makeUTF8(bufDriverDesc, *pcbDriverDesc, szDriverDesc, cbDriverDescMax); - makeUTF8(bufDriverAttr, *pcbDrvrAttr, szDriverAttributes, cbDrvrAttrMax); + makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(SQLWCHAR), szDriverDesc, cbDriverDescMax); + makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(SQLWCHAR), szDriverAttributes, cbDrvrAttrMax); return rc; } diff --git a/Data/ODBC/src/Unicode_WIN32.cpp b/Data/ODBC/src/Unicode_WIN32.cpp index e11de14cf..2513e7e16 100644 --- a/Data/ODBC/src/Unicode_WIN32.cpp +++ b/Data/ODBC/src/Unicode_WIN32.cpp @@ -54,7 +54,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT iCol, SQLUSMALLINT iField, SQLPOINTER pCharAttr, - SQLSMALLINT cbCharAttrMax, + SQLSMALLINT cbCharAttrMax, SQLSMALLINT* pcbCharAttr, NumAttrPtrType pNumAttr) { @@ -66,7 +66,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt, iCol, iField, buffer.begin(), - (SQLSMALLINT) buffer.size() * sizeof(wchar_t), + (SQLSMALLINT) buffer.sizeBytes(), pcbCharAttr, pNumAttr); @@ -78,7 +78,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt, iCol, iField, pCharAttr, - cbCharAttrMax, + cbCharAttrMax, pcbCharAttr, pNumAttr); } @@ -150,7 +150,7 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt, pibScale, pfNullable); - makeUTF8(buffer, *pcbColName, szColName, cbColNameMax); + makeUTF8(buffer, *pcbColName * sizeof(wchar_t), szColName, cbColNameMax); return rc; } @@ -195,7 +195,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc, SQLRETURN rc = SQLGetConnectAttrW(hdbc, fAttribute, buffer.begin(), - (SQLINTEGER) buffer.size() * sizeof(wchar_t), + (SQLINTEGER) buffer.sizeBytes(), pcbValue); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); @@ -263,7 +263,7 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc, iRecord, iField, buffer.begin(), - (SQLINTEGER) buffer.size() * sizeof(wchar_t), + (SQLINTEGER) buffer.sizeBytes(), pcbValue); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); @@ -312,7 +312,7 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType, iRecord, fDiagField, buffer.begin(), - (SQLSMALLINT) buffer.size() * sizeof(wchar_t), + (SQLSMALLINT) buffer.sizeBytes(), pcbDiagInfo); makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax); @@ -351,8 +351,8 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType, (SQLSMALLINT) bufErr.size(), pcbErrorMsg); - makeUTF8(bufState, stateLen, szSqlState, stateLen); - makeUTF8(bufErr, *pcbErrorMsg, szErrorMsg, cbErrorMsgMax); + makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen); + makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax); return rc; } @@ -438,7 +438,7 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt, return SQLGetStmtAttrW(hstmt, fAttribute, (SQLPOINTER) buffer.begin(), - (SQLINTEGER) buffer.size() * sizeof(wchar_t), + (SQLINTEGER) buffer.sizeBytes(), pcbValue); } @@ -485,7 +485,7 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc, SQLRETURN rc = SQLGetInfoW(hdbc, fInfoType, (SQLPOINTER) buffer.begin(), - (SQLSMALLINT) buffer.size() * sizeof(wchar_t), + (SQLSMALLINT) buffer.sizeBytes(), pcbInfoValue); makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax); @@ -579,8 +579,8 @@ SQLRETURN SQLDataSources(SQLHENV henv, (SQLSMALLINT) bufDesc.size(), pcbDesc); - makeUTF8(bufDSN, *pcbDSN, szDSN, cbDSNMax); - makeUTF8(bufDesc, *pcbDesc, szDesc, cbDescMax); + makeUTF8(bufDSN, *pcbDSN * sizeof(wchar_t), szDSN, cbDSNMax); + makeUTF8(bufDesc, *pcbDesc * sizeof(wchar_t), szDesc, cbDescMax); return rc; } @@ -612,7 +612,7 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc, pcbConnStrOut, fDriverCompletion); - makeUTF8(bufOut, *pcbConnStrOut, szConnStrOut, cbConnStrOutMax); + makeUTF8(bufOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax); return rc; } @@ -637,7 +637,7 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc, (SQLSMALLINT) bufConnStrOut.size(), pcbConnStrOut); - makeUTF8(bufConnStrOut, *pcbConnStrOut, szConnStrOut, cbConnStrOutMax); + makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax); return rc; } @@ -694,7 +694,7 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc, (SQLINTEGER) bufSQLOut.size(), pcbSqlStr); - makeUTF8(bufSQLOut, *pcbSqlStr, szSqlStr, cbSqlStrMax); + makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(wchar_t), szSqlStr, cbSqlStrMax); return rc; } @@ -771,8 +771,8 @@ SQLRETURN SQLDrivers(SQLHENV henv, (SQLSMALLINT) bufDriverAttr.size(), pcbDrvrAttr); - makeUTF8(bufDriverDesc, *pcbDriverDesc, szDriverDesc, cbDriverDescMax); - makeUTF8(bufDriverAttr, *pcbDrvrAttr, szDriverAttributes, cbDrvrAttrMax); + makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(wchar_t), szDriverDesc, cbDriverDescMax); + makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(wchar_t), szDriverAttributes, cbDrvrAttrMax); return rc; } diff --git a/Foundation/include/Poco/Buffer.h b/Foundation/include/Poco/Buffer.h index 3f72c87e1..cefdc9267 100644 --- a/Foundation/include/Poco/Buffer.h +++ b/Foundation/include/Poco/Buffer.h @@ -178,11 +178,17 @@ public: } std::size_t capacity() const - /// Returns the allocated memory size. + /// Returns the allocated memory size in elements. { return _capacity; } + std::size_t capacityBytes() const + /// Returns the allocated memory size in bytes. + { + return _capacity * sizeof(T); + } + void swap(Buffer& other) /// Swaps the buffer with another one. { @@ -224,10 +230,16 @@ public: } std::size_t size() const - /// Returns the used size of the buffer. + /// Returns the used size of the buffer in elements. { return _used; } + + std::size_t sizeBytes() const + /// Returns the used size of the buffer in bytes. + { + return _used * sizeof(T); + } T* begin() /// Returns a pointer to the beginning of the buffer. diff --git a/Foundation/testsuite/src/CoreTest.cpp b/Foundation/testsuite/src/CoreTest.cpp index 5e4fe4d06..f96f676eb 100644 --- a/Foundation/testsuite/src/CoreTest.cpp +++ b/Foundation/testsuite/src/CoreTest.cpp @@ -128,10 +128,10 @@ void CoreTest::testFixedLength() assert (sizeof(Poco::UInt16) == 2); assert (sizeof(Poco::Int32) == 4); assert (sizeof(Poco::UInt32) == 4); - #if defined(POCO_HAVE_INT64) +#if defined(POCO_HAVE_INT64) assert (sizeof(Poco::Int64) == 8); assert (sizeof(Poco::UInt64) == 8); - #endif +#endif assert (sizeof(Poco::IntPtr) == sizeof(void*)); assert (sizeof(Poco::UIntPtr) == sizeof(void*)); } @@ -201,7 +201,9 @@ void CoreTest::testBuffer() std::size_t s = 10; Buffer b(s); assert (b.size() == s); + assert (b.sizeBytes() == s * sizeof(int)); assert (b.capacity() == s); + assert (b.capacityBytes() == s * sizeof(int)); std::vector v; for (int i = 0; i < s; ++i) v.push_back(i);