Skip to content

Commit

Permalink
revise ODBC Unicode string functions
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
aleks-f committed Dec 15, 2012
1 parent e4db0ab commit 0313024
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Data/ODBC/include/Poco/Data/ODBC/Unicode_UNIXODBC.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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. /// Utility function for conversion from UTF-16 to UTF-8.




Expand Down
24 changes: 8 additions & 16 deletions Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@


namespace Poco { namespace Poco {
namespace Data { namespace Data {
namespace ODBC { namespace ODBC {




inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target) inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target)
Expand All @@ -56,16 +56,15 @@ inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target
} }




inline void makeUTF16(SQLCHAR* pSQLChar, SQLSMALLINT length, std::wstring& target) inline void makeUTF8(Poco::Buffer<wchar_t>& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength)
/// Utility function for conversion from UTF-8 to UTF-16. /// 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) length /= sizeof(wchar_t);
/// Utility function for conversion from UTF-16 to UTF-8.
{
std::string result; std::string result;
UnicodeConverter::toUTF8(buffer.begin(), length, result); UnicodeConverter::toUTF8(buffer.begin(), length, result);


Expand All @@ -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 } } } // namespace Poco::Data::ODBC




Expand Down
2 changes: 1 addition & 1 deletion Data/ODBC/src/SessionImpl.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ bool SessionImpl::canTransact()
if (ODBC_TXN_CAPABILITY_UNKNOWN == _canTransact) if (ODBC_TXN_CAPABILITY_UNKNOWN == _canTransact)
{ {
SQLUSMALLINT ret; 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."); "Failed to obtain transaction capability info.");


_canTransact = (SQL_TC_NONE != ret) ? _canTransact = (SQL_TC_NONE != ret) ?
Expand Down
42 changes: 21 additions & 21 deletions Data/ODBC/src/Unicode_UNIXODBC.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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; UTF8Encoding utf8Encoding;
UTF16Encoding utf16Encoding; UTF16Encoding utf16Encoding;
TextConverter converter(utf16Encoding, utf8Encoding); TextConverter converter(utf16Encoding, utf8Encoding);


std::string result; 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"); throw DataFormatException("Error converting UTF-16 to UTF-8");


std::memset(pTarget, 0, targetLength); std::memset(pTarget, 0, targetLength);
Expand All @@ -103,7 +103,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
iCol, iCol,
iField, iField,
buffer.begin(), buffer.begin(),
(SQLSMALLINT) buffer.size() * sizeof(SQLWCHAR), (SQLSMALLINT) buffer.sizeBytes(),
pcbCharAttr, pcbCharAttr,
pNumAttr); pNumAttr);


Expand Down Expand Up @@ -157,8 +157,8 @@ SQLRETURN SQLConnect(SQLHDBC hdbc,
makeUTF16(szAuthStr, cbAuthStr, sqlPWD); makeUTF16(szAuthStr, cbAuthStr, sqlPWD);


return SQLConnectW(hdbc, return SQLConnectW(hdbc,
(SQLWCHAR*) sqlDSN.c_str(), cbDSN, (SQLWCHAR*) sqlDSN.c_str(), cbDSN,
(SQLWCHAR*) sqlUID.c_str(), cbUID, (SQLWCHAR*) sqlUID.c_str(), cbUID,
(SQLWCHAR*) sqlPWD.c_str(), cbAuthStr); (SQLWCHAR*) sqlPWD.c_str(), cbAuthStr);
} }


Expand All @@ -184,7 +184,7 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
pibScale, pibScale,
pfNullable); pfNullable);


makeUTF8(buffer, *pcbColName, szColName, cbColNameMax); makeUTF8(buffer, *pcbColName * sizeof(SQLWCHAR), szColName, cbColNameMax);
return rc; return rc;
} }


Expand Down Expand Up @@ -227,7 +227,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
SQLRETURN rc = SQLGetConnectAttrW(hdbc, SQLRETURN rc = SQLGetConnectAttrW(hdbc,
fAttribute, fAttribute,
buffer.begin(), buffer.begin(),
(SQLINTEGER) buffer.size() * sizeof(SQLWCHAR), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);


makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
Expand Down Expand Up @@ -293,7 +293,7 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
iRecord, iRecord,
iField, iField,
buffer.begin(), buffer.begin(),
(SQLINTEGER) buffer.size() * sizeof(SQLWCHAR), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);


makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
Expand Down Expand Up @@ -343,7 +343,7 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
iRecord, iRecord,
fDiagField, fDiagField,
buffer.begin(), buffer.begin(),
(SQLSMALLINT) buffer.size() * sizeof(SQLWCHAR), (SQLSMALLINT) buffer.sizeBytes(),
pcbDiagInfo); pcbDiagInfo);


makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax); makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
Expand Down Expand Up @@ -383,8 +383,8 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
(SQLSMALLINT) bufErr.size(), (SQLSMALLINT) bufErr.size(),
pcbErrorMsg); pcbErrorMsg);


makeUTF8(bufState, stateLen, szSqlState, stateLen); makeUTF8(bufState, stateLen * sizeof(SQLWCHAR), szSqlState, stateLen);
makeUTF8(bufErr, *pcbErrorMsg, szErrorMsg, cbErrorMsgMax); makeUTF8(bufErr, *pcbErrorMsg * sizeof(SQLWCHAR), szErrorMsg, cbErrorMsgMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -462,11 +462,11 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
return SQLGetStmtAttrW(hstmt, return SQLGetStmtAttrW(hstmt,
fAttribute, fAttribute,
(SQLPOINTER) buffer.begin(), (SQLPOINTER) buffer.begin(),
(SQLINTEGER) buffer.size() * sizeof(SQLWCHAR), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);
} }


return SQLGetStmtAttrW(hstmt, fAttribute, rgbValue, cbValueMax, pcbValue); return SQLGetStmtAttrW(hstmt, fAttribute, rgbValue, cbValueMax, pcbValue);
} }




Expand Down Expand Up @@ -505,7 +505,7 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
SQLRETURN rc = SQLGetInfoW(hdbc, SQLRETURN rc = SQLGetInfoW(hdbc,
fInfoType, fInfoType,
(SQLPOINTER) buffer.begin(), (SQLPOINTER) buffer.begin(),
(SQLSMALLINT) buffer.size() * sizeof(SQLWCHAR), (SQLSMALLINT) buffer.sizeBytes(),
pcbInfoValue); pcbInfoValue);


makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax); makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
Expand Down Expand Up @@ -595,8 +595,8 @@ SQLRETURN SQLDataSources(SQLHENV henv,
(SQLSMALLINT) bufDesc.size(), (SQLSMALLINT) bufDesc.size(),
pcbDesc); pcbDesc);


makeUTF8(bufDSN, *pcbDSN, szDSN, cbDSNMax); makeUTF8(bufDSN, *pcbDSN * sizeof(SQLWCHAR), szDSN, cbDSNMax);
makeUTF8(bufDesc, *pcbDesc, szDesc, cbDescMax); makeUTF8(bufDesc, *pcbDesc * sizeof(SQLWCHAR), szDesc, cbDescMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -628,7 +628,7 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
pcbConnStrOut, pcbConnStrOut,
fDriverCompletion); fDriverCompletion);


makeUTF8(out, *pcbConnStrOut, pcbConnStrOut, cbConnStrOutMax); makeUTF8(out, *pcbConnStrOut * sizeof(SQLWCHAR), pcbConnStrOut, cbConnStrOutMax);


return rc; return rc;
} }
Expand All @@ -653,7 +653,7 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
(SQLSMALLINT) bufConnStrOut.size(), (SQLSMALLINT) bufConnStrOut.size(),
pcbConnStrOut); pcbConnStrOut);


makeUTF8(bufConnStrOut, *pcbConnStrOut, szConnStrOut, cbConnStrOutMax); makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(SQLWCHAR), szConnStrOut, cbConnStrOutMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -710,7 +710,7 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
(SQLINTEGER) bufSQLOut.size(), (SQLINTEGER) bufSQLOut.size(),
pcbSqlStr); pcbSqlStr);


makeUTF8(bufSQLOut, *pcbSqlStr, szSqlStr, cbSqlStrMax); makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(SQLWCHAR), szSqlStr, cbSqlStrMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -787,8 +787,8 @@ SQLRETURN SQLDrivers(SQLHENV henv,
(SQLSMALLINT) bufDriverAttr.size(), (SQLSMALLINT) bufDriverAttr.size(),
pcbDrvrAttr); pcbDrvrAttr);


makeUTF8(bufDriverDesc, *pcbDriverDesc, szDriverDesc, cbDriverDescMax); makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(SQLWCHAR), szDriverDesc, cbDriverDescMax);
makeUTF8(bufDriverAttr, *pcbDrvrAttr, szDriverAttributes, cbDrvrAttrMax); makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(SQLWCHAR), szDriverAttributes, cbDrvrAttrMax);


return rc; return rc;
} }
Expand Down
36 changes: 18 additions & 18 deletions Data/ODBC/src/Unicode_WIN32.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
SQLUSMALLINT iCol, SQLUSMALLINT iCol,
SQLUSMALLINT iField, SQLUSMALLINT iField,
SQLPOINTER pCharAttr, SQLPOINTER pCharAttr,
SQLSMALLINT cbCharAttrMax, SQLSMALLINT cbCharAttrMax,
SQLSMALLINT* pcbCharAttr, SQLSMALLINT* pcbCharAttr,
NumAttrPtrType pNumAttr) NumAttrPtrType pNumAttr)
{ {
Expand All @@ -66,7 +66,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
iCol, iCol,
iField, iField,
buffer.begin(), buffer.begin(),
(SQLSMALLINT) buffer.size() * sizeof(wchar_t), (SQLSMALLINT) buffer.sizeBytes(),
pcbCharAttr, pcbCharAttr,
pNumAttr); pNumAttr);


Expand All @@ -78,7 +78,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
iCol, iCol,
iField, iField,
pCharAttr, pCharAttr,
cbCharAttrMax, cbCharAttrMax,
pcbCharAttr, pcbCharAttr,
pNumAttr); pNumAttr);
} }
Expand Down Expand Up @@ -150,7 +150,7 @@ SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
pibScale, pibScale,
pfNullable); pfNullable);


makeUTF8(buffer, *pcbColName, szColName, cbColNameMax); makeUTF8(buffer, *pcbColName * sizeof(wchar_t), szColName, cbColNameMax);
return rc; return rc;
} }


Expand Down Expand Up @@ -195,7 +195,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
SQLRETURN rc = SQLGetConnectAttrW(hdbc, SQLRETURN rc = SQLGetConnectAttrW(hdbc,
fAttribute, fAttribute,
buffer.begin(), buffer.begin(),
(SQLINTEGER) buffer.size() * sizeof(wchar_t), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);


makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
Expand Down Expand Up @@ -263,7 +263,7 @@ SQLRETURN SQLGetDescField(SQLHDESC hdesc,
iRecord, iRecord,
iField, iField,
buffer.begin(), buffer.begin(),
(SQLINTEGER) buffer.size() * sizeof(wchar_t), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);


makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax); makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
Expand Down Expand Up @@ -312,7 +312,7 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
iRecord, iRecord,
fDiagField, fDiagField,
buffer.begin(), buffer.begin(),
(SQLSMALLINT) buffer.size() * sizeof(wchar_t), (SQLSMALLINT) buffer.sizeBytes(),
pcbDiagInfo); pcbDiagInfo);


makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax); makeUTF8(buffer, *pcbDiagInfo, rgbDiagInfo, cbDiagInfoMax);
Expand Down Expand Up @@ -351,8 +351,8 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
(SQLSMALLINT) bufErr.size(), (SQLSMALLINT) bufErr.size(),
pcbErrorMsg); pcbErrorMsg);


makeUTF8(bufState, stateLen, szSqlState, stateLen); makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen);
makeUTF8(bufErr, *pcbErrorMsg, szErrorMsg, cbErrorMsgMax); makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -438,7 +438,7 @@ SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
return SQLGetStmtAttrW(hstmt, return SQLGetStmtAttrW(hstmt,
fAttribute, fAttribute,
(SQLPOINTER) buffer.begin(), (SQLPOINTER) buffer.begin(),
(SQLINTEGER) buffer.size() * sizeof(wchar_t), (SQLINTEGER) buffer.sizeBytes(),
pcbValue); pcbValue);
} }


Expand Down Expand Up @@ -485,7 +485,7 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
SQLRETURN rc = SQLGetInfoW(hdbc, SQLRETURN rc = SQLGetInfoW(hdbc,
fInfoType, fInfoType,
(SQLPOINTER) buffer.begin(), (SQLPOINTER) buffer.begin(),
(SQLSMALLINT) buffer.size() * sizeof(wchar_t), (SQLSMALLINT) buffer.sizeBytes(),
pcbInfoValue); pcbInfoValue);


makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax); makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
Expand Down Expand Up @@ -579,8 +579,8 @@ SQLRETURN SQLDataSources(SQLHENV henv,
(SQLSMALLINT) bufDesc.size(), (SQLSMALLINT) bufDesc.size(),
pcbDesc); pcbDesc);


makeUTF8(bufDSN, *pcbDSN, szDSN, cbDSNMax); makeUTF8(bufDSN, *pcbDSN * sizeof(wchar_t), szDSN, cbDSNMax);
makeUTF8(bufDesc, *pcbDesc, szDesc, cbDescMax); makeUTF8(bufDesc, *pcbDesc * sizeof(wchar_t), szDesc, cbDescMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -612,7 +612,7 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
pcbConnStrOut, pcbConnStrOut,
fDriverCompletion); fDriverCompletion);


makeUTF8(bufOut, *pcbConnStrOut, szConnStrOut, cbConnStrOutMax); makeUTF8(bufOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax);


return rc; return rc;
} }
Expand All @@ -637,7 +637,7 @@ SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
(SQLSMALLINT) bufConnStrOut.size(), (SQLSMALLINT) bufConnStrOut.size(),
pcbConnStrOut); pcbConnStrOut);


makeUTF8(bufConnStrOut, *pcbConnStrOut, szConnStrOut, cbConnStrOutMax); makeUTF8(bufConnStrOut, *pcbConnStrOut * sizeof(wchar_t), szConnStrOut, cbConnStrOutMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -694,7 +694,7 @@ SQLRETURN SQLNativeSql(SQLHDBC hdbc,
(SQLINTEGER) bufSQLOut.size(), (SQLINTEGER) bufSQLOut.size(),
pcbSqlStr); pcbSqlStr);


makeUTF8(bufSQLOut, *pcbSqlStr, szSqlStr, cbSqlStrMax); makeUTF8(bufSQLOut, *pcbSqlStr * sizeof(wchar_t), szSqlStr, cbSqlStrMax);


return rc; return rc;
} }
Expand Down Expand Up @@ -771,8 +771,8 @@ SQLRETURN SQLDrivers(SQLHENV henv,
(SQLSMALLINT) bufDriverAttr.size(), (SQLSMALLINT) bufDriverAttr.size(),
pcbDrvrAttr); pcbDrvrAttr);


makeUTF8(bufDriverDesc, *pcbDriverDesc, szDriverDesc, cbDriverDescMax); makeUTF8(bufDriverDesc, *pcbDriverDesc * sizeof(wchar_t), szDriverDesc, cbDriverDescMax);
makeUTF8(bufDriverAttr, *pcbDrvrAttr, szDriverAttributes, cbDrvrAttrMax); makeUTF8(bufDriverAttr, *pcbDrvrAttr * sizeof(wchar_t), szDriverAttributes, cbDrvrAttrMax);


return rc; return rc;
} }
Expand Down
16 changes: 14 additions & 2 deletions Foundation/include/Poco/Buffer.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -178,11 +178,17 @@ class Buffer
} }


std::size_t capacity() const std::size_t capacity() const
/// Returns the allocated memory size. /// Returns the allocated memory size in elements.
{ {
return _capacity; return _capacity;
} }


std::size_t capacityBytes() const
/// Returns the allocated memory size in bytes.
{
return _capacity * sizeof(T);
}

void swap(Buffer& other) void swap(Buffer& other)
/// Swaps the buffer with another one. /// Swaps the buffer with another one.
{ {
Expand Down Expand Up @@ -224,10 +230,16 @@ class Buffer
} }


std::size_t size() const std::size_t size() const
/// Returns the used size of the buffer. /// Returns the used size of the buffer in elements.
{ {
return _used; return _used;
} }

std::size_t sizeBytes() const
/// Returns the used size of the buffer in bytes.
{
return _used * sizeof(T);
}


T* begin() T* begin()
/// Returns a pointer to the beginning of the buffer. /// Returns a pointer to the beginning of the buffer.
Expand Down
Loading

0 comments on commit 0313024

Please sign in to comment.