Browse files

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)
  • Loading branch information...
1 parent e4db0ab commit 031302469fb7e3e1c6219f08f188bc42eb66fc08 @aleks-f aleks-f committed Dec 15, 2012
View
2 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<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
24 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<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
2 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) ?
View
42 Data/ODBC/src/Unicode_UNIXODBC.cpp
@@ -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
36 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;
}
View
16 Foundation/include/Poco/Buffer.h
@@ -178,11 +178,17 @@ class Buffer
}
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 @@ class Buffer
}
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
6 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<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);

0 comments on commit 0313024

Please sign in to comment.