mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-29 21:22:11 +01:00
fix(Extractor): move extraction decoding to AbstractExtractor #3396
This commit is contained in:
parent
7f26310ef2
commit
4dfbcd33db
@ -33,7 +33,6 @@
|
||||
#include "Poco/Nullable.h"
|
||||
#include "Poco/UTFString.h"
|
||||
#include "Poco/TextEncoding.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <map>
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
@ -592,11 +591,10 @@ private:
|
||||
val.clear();
|
||||
if (ret)
|
||||
{
|
||||
Poco::TextConverter conv(*_pDBEncoding, *_pToEncoding);
|
||||
val.resize(res.size());
|
||||
typename C::iterator vIt = val.begin();
|
||||
typename C::iterator it = res.begin();
|
||||
for (; it != res.end(); ++it, ++vIt) conv.convert(*it, *vIt);
|
||||
for (; it != res.end(); ++it, ++vIt) transcode(*it, *vIt);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -607,7 +605,7 @@ private:
|
||||
bool ret = false;
|
||||
if (Preparator::DE_BOUND == _dataExtraction)
|
||||
{
|
||||
if (!_transcode)
|
||||
if (!transcodeRequired())
|
||||
ret = extractBoundImplContainer(pos, val);
|
||||
else
|
||||
ret = stringContainerExtractConvert(pos, val);
|
||||
@ -628,9 +626,6 @@ private:
|
||||
PreparatorPtr _pPreparator;
|
||||
Preparator::DataExtraction _dataExtraction;
|
||||
std::vector<SQLLEN> _lengths;
|
||||
Poco::TextEncoding::Ptr _pDBEncoding;
|
||||
bool _transcode;
|
||||
Poco::TextEncoding::Ptr _pToEncoding;
|
||||
};
|
||||
|
||||
|
||||
|
@ -35,13 +35,10 @@ const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z by
|
||||
|
||||
Extractor::Extractor(const StatementHandle& rStmt,
|
||||
Preparator::Ptr pPreparator,
|
||||
TextEncoding::Ptr pDBEncoding):
|
||||
TextEncoding::Ptr pDBEncoding): AbstractExtractor(pDBEncoding),
|
||||
_rStmt(rStmt),
|
||||
_pPreparator(pPreparator),
|
||||
_dataExtraction(pPreparator->getDataExtraction()),
|
||||
_pDBEncoding(pDBEncoding),
|
||||
_transcode(_pDBEncoding && !_pDBEncoding->isA("UTF-8")),
|
||||
_pToEncoding(_transcode ? Poco::TextEncoding::find("UTF-8") : nullptr)
|
||||
_dataExtraction(pPreparator->getDataExtraction())
|
||||
{
|
||||
}
|
||||
|
||||
@ -707,7 +704,7 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (!_transcode)
|
||||
if (!transcodeRequired())
|
||||
{
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
ret = extractManualImpl(pos, val, SQL_C_CHAR);
|
||||
@ -721,8 +718,7 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
ret = extractManualImpl(pos, result, SQL_C_CHAR);
|
||||
else
|
||||
ret = extractBoundImpl(pos, result);
|
||||
Poco::TextConverter converter(*_pDBEncoding, *_pToEncoding);
|
||||
converter.convert(result, val);
|
||||
transcode(result, val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/UUID.h"
|
||||
#include "Poco/UTFString.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
#include "Poco/TextEncoding.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
@ -54,7 +57,8 @@ class Data_API AbstractExtractor
|
||||
public:
|
||||
using Ptr = SharedPtr<AbstractExtractor>;
|
||||
|
||||
AbstractExtractor();
|
||||
AbstractExtractor(Poco::TextEncoding::Ptr pDBEncoding = nullptr,
|
||||
Poco::TextEncoding::Ptr pToEncoding = nullptr);
|
||||
/// Creates the AbstractExtractor.
|
||||
|
||||
virtual ~AbstractExtractor();
|
||||
@ -346,6 +350,15 @@ public:
|
||||
|
||||
virtual void reset();
|
||||
/// Resets any information internally cached by the extractor.
|
||||
|
||||
protected:
|
||||
bool transcodeRequired() const;
|
||||
void transcode(const std::string& val1, std::string& val2);
|
||||
|
||||
private:
|
||||
Poco::TextEncoding::Ptr _pDBEncoding;
|
||||
Poco::TextEncoding::Ptr _pToEncoding;
|
||||
std::unique_ptr<Poco::TextConverter> _pConverter;
|
||||
};
|
||||
|
||||
|
||||
@ -358,6 +371,22 @@ inline void AbstractExtractor::reset()
|
||||
}
|
||||
|
||||
|
||||
inline bool AbstractExtractor::transcodeRequired() const
|
||||
{
|
||||
return _pConverter.operator bool();
|
||||
}
|
||||
|
||||
|
||||
inline void AbstractExtractor::transcode(const std::string& val1, std::string& val2)
|
||||
{
|
||||
if (_pConverter)
|
||||
{
|
||||
val2.clear();
|
||||
_pConverter->convert(val1, val2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@ -20,8 +20,18 @@ namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
AbstractExtractor::AbstractExtractor()
|
||||
AbstractExtractor::AbstractExtractor(Poco::TextEncoding::Ptr pDBEncoding,
|
||||
Poco::TextEncoding::Ptr pToEncoding):
|
||||
_pDBEncoding(pDBEncoding),
|
||||
_pToEncoding(pToEncoding ?
|
||||
pToEncoding : _pDBEncoding ?
|
||||
Poco::TextEncoding::find("UTF-8") : nullptr),
|
||||
_pConverter(_pDBEncoding ?
|
||||
new Poco::TextConverter(*pDBEncoding, *_pToEncoding) :
|
||||
nullptr)
|
||||
{
|
||||
poco_assert_dbg((!_pDBEncoding && !_pToEncoding) ||
|
||||
(_pDBEncoding && _pToEncoding));
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
#include "DataTest.h"
|
||||
#include "Extractor.h"
|
||||
#include "CppUnit/TestCaller.h"
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Data/DynamicLOB.h"
|
||||
#include "Poco/Data/DynamicDateTime.h"
|
||||
#include "Poco/Latin1Encoding.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
@ -45,6 +47,7 @@ using Poco::UInt32;
|
||||
using Poco::Int64;
|
||||
using Poco::UInt64;
|
||||
using Poco::DateTime;
|
||||
using Poco::Latin1Encoding;
|
||||
using Poco::Dynamic::Var;
|
||||
using Poco::InvalidAccessException;
|
||||
using Poco::IllegalStateException;
|
||||
@ -65,6 +68,7 @@ using Poco::Data::Row;
|
||||
using Poco::Data::SimpleRowFormatter;
|
||||
using Poco::Data::Date;
|
||||
using Poco::Data::Time;
|
||||
using Poco::Data::AbstractExtractor;
|
||||
using Poco::Data::AbstractExtraction;
|
||||
using Poco::Data::AbstractExtractionVec;
|
||||
using Poco::Data::AbstractExtractionVecVec;
|
||||
@ -1358,6 +1362,29 @@ void DataTest::testExternalBindingAndExtraction()
|
||||
}
|
||||
|
||||
|
||||
void DataTest::testTranscode()
|
||||
{
|
||||
Latin1Encoding::Ptr pL2E = new Latin1Encoding();
|
||||
|
||||
const unsigned char latin1Chars[] = { 'g', 252, 'n', 't', 'e', 'r', 0 };
|
||||
const unsigned char utf8Chars[] = { 'g', 195, 188, 'n', 't', 'e', 'r', 0 };
|
||||
std::string latin1Text((const char*)latin1Chars);
|
||||
std::string utf8Text((const char*)utf8Chars);
|
||||
|
||||
Poco::Data::Test::Extractor ext;
|
||||
ext.setString(latin1Text);
|
||||
std::string utf8Out;
|
||||
assertTrue (ext.extract(0, utf8Out));
|
||||
assertTrue(utf8Out == latin1Text);
|
||||
|
||||
Poco::Data::Test::Extractor ext2(new Latin1Encoding());
|
||||
ext2.setString(latin1Text);
|
||||
utf8Out.clear();
|
||||
assertTrue(ext2.extract(0, utf8Out));
|
||||
assertTrue(utf8Out == utf8Text);
|
||||
}
|
||||
|
||||
|
||||
void DataTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -1388,6 +1415,7 @@ CppUnit::Test* DataTest::suite()
|
||||
CppUnit_addTest(pSuite, DataTest, testRowFormat);
|
||||
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
|
||||
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
||||
CppUnit_addTest(pSuite, DataTest, testTranscode);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
void testRowFormat();
|
||||
void testDateAndTime();
|
||||
void testExternalBindingAndExtraction();
|
||||
void testTranscode();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -18,7 +18,8 @@ namespace Data {
|
||||
namespace Test {
|
||||
|
||||
|
||||
Extractor::Extractor()
|
||||
Extractor::Extractor(Poco::TextEncoding::Ptr pDBEncoding):
|
||||
AbstractExtractor(pDBEncoding)
|
||||
{
|
||||
}
|
||||
|
||||
@ -130,7 +131,10 @@ bool Extractor::extract(std::size_t pos, char& val)
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
{
|
||||
val = "";
|
||||
if (!transcodeRequired())
|
||||
val = _stringValue;
|
||||
else
|
||||
transcode(_stringValue, val);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ class Extractor: public Poco::Data::AbstractExtractor
|
||||
/// A no-op implementation of AbstractExtractor for testing.
|
||||
{
|
||||
public:
|
||||
Extractor();
|
||||
Extractor(Poco::TextEncoding::Ptr pDBEncoding = nullptr);
|
||||
/// Creates the Extractor.
|
||||
|
||||
~Extractor();
|
||||
@ -110,6 +110,14 @@ public:
|
||||
/// Returns true if the current row value at pos column is null.
|
||||
|
||||
void reset();
|
||||
|
||||
void setString(const std::string& str)
|
||||
{
|
||||
_stringValue = str;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _stringValue;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user