mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 10:13:51 +01:00
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:
parent
e4db0abc68
commit
031302469f
@ -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.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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) ?
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user