revise ODBC Unicode string functions

http://support.microsoft.com/kb/294169
added Buffer::size/capacityBytes returning length of buffer in bytes
only windows Unicode ODBC tested
reverting the SF #506 fix (non-conforming driver, causes problems with
other ODBC drivers)
This commit is contained in:
Aleksandar Fabijanic 2012-12-15 13:47:22 -06:00
parent e4db0abc68
commit 031302469f
7 changed files with 67 additions and 61 deletions

View File

@ -56,7 +56,7 @@ inline void makeUTF16(SQLCHAR* pSQLChar, SQLSMALLINT length, std::string& target
}
inline void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, int length, SQLPOINTER pTarget, SQLINTEGER targetLength);
void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength);
/// Utility function for conversion from UTF-16 to UTF-8.

View File

@ -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<wchar_t>& 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<wchar_t>& 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<wchar_t>& buffer, int length, SQLPOINTER pTarg
}
inline void makeUTF8(Poco::Buffer<wchar_t>& 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

View File

@ -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) ?

View File

@ -72,14 +72,14 @@ void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::string& target)
}
void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, int length, SQLPOINTER pTarget, SQLINTEGER targetLength)
void makeUTF8(Poco::Buffer<SQLWCHAR>& 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;
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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<int> b(s);
assert (b.size() == s);
assert (b.sizeBytes() == s * sizeof(int));
assert (b.capacity() == s);
assert (b.capacityBytes() == s * sizeof(int));
std::vector<int> v;
for (int i = 0; i < s; ++i)
v.push_back(i);