mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-20 22:31:23 +01:00
merged GH #2641: Implement DataURIStream for extracting data from data URIs
This commit is contained in:
parent
a052c627cc
commit
66d96744b1
@ -30,7 +30,7 @@ objects = ArchiveStrategy Ascii ASCIIEncoding AsyncChannel \
|
||||
FileStreamFactory URIStreamFactory URIStreamOpener UTF32Encoding UTF16Encoding UTF8Encoding UTF8String \
|
||||
Unicode UnicodeConverter Windows1250Encoding Windows1251Encoding Windows1252Encoding \
|
||||
UUID UUIDGenerator Void Var VarHolder VarIterator Format Pipe PipeImpl PipeStream SharedMemory \
|
||||
MemoryStream FileStream AtomicCounter
|
||||
MemoryStream FileStream AtomicCounter DataURIStream DataURIStreamFactory
|
||||
|
||||
zlib_objects = adler32 compress crc32 deflate \
|
||||
infback inffast inflate inftrees trees zutil
|
||||
|
78
Foundation/include/Poco/DataURIStream.h
Normal file
78
Foundation/include/Poco/DataURIStream.h
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// DataURIStream.h
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: DataURIStreamFactory
|
||||
//
|
||||
// Definition of the DataURIStream class.
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_DataURIStream_INCLUDED
|
||||
#define Foundation_DataURIStream_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class Base64Decoder;
|
||||
class MemoryInputStream;
|
||||
class URI;
|
||||
|
||||
|
||||
class Foundation_API DataURIStreamIOS: public virtual std::ios
|
||||
/// The base class for DataURIStream.
|
||||
///
|
||||
/// This class is needed to ensure the correct initialization
|
||||
/// order of the stream buffer and base classes.
|
||||
{
|
||||
public:
|
||||
DataURIStreamIOS(const URI& uri);
|
||||
~DataURIStreamIOS();
|
||||
std::streambuf* rdbuf();
|
||||
|
||||
protected:
|
||||
std::streambuf* _buf;
|
||||
|
||||
private:
|
||||
DataURIStreamIOS(const DataURIStreamIOS&);
|
||||
DataURIStreamIOS& operator = (const DataURIStreamIOS&);
|
||||
std::string _data;
|
||||
std::unique_ptr<MemoryInputStream> _memoryStream;
|
||||
std::unique_ptr<Base64Decoder> _base64Decoder;
|
||||
};
|
||||
|
||||
|
||||
class Foundation_API DataURIStream: public DataURIStreamIOS, public std::istream
|
||||
/// An input stream for reading data from a data URI.
|
||||
/// For example, when constructed from "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D" it reads "Hello, World!".
|
||||
{
|
||||
public:
|
||||
DataURIStream(const URI& uri);
|
||||
/// Creates a DataURIStream for the given data URI,
|
||||
/// ready for reading data.
|
||||
/// Throws a DataFormatException exception if the data is incorrect format.
|
||||
~DataURIStream();
|
||||
/// Destroys the DataURIStream.
|
||||
|
||||
private:
|
||||
DataURIStream(const DataURIStream&);
|
||||
DataURIStream& operator = (const DataURIStream&);
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_DataURIStream_INCLUDED
|
58
Foundation/include/Poco/DataURIStreamFactory.h
Normal file
58
Foundation/include/Poco/DataURIStreamFactory.h
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// DataURIStreamFactory.h
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: URI
|
||||
// Module: DataURIStreamFactory
|
||||
//
|
||||
// Definition of the DataURIStreamFactory class.
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_DataURIStreamFactory_INCLUDED
|
||||
#define Foundation_DataURIStreamFactory_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/URIStreamFactory.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class Foundation_API DataURIStreamFactory: public URIStreamFactory
|
||||
/// An implementation of the URIStreamFactory interface
|
||||
/// that read data from data URIs.
|
||||
/// For example, for URI "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D" it read "Hello, World!".
|
||||
{
|
||||
public:
|
||||
DataURIStreamFactory();
|
||||
/// Creates the DataURIStreamFactory.
|
||||
|
||||
~DataURIStreamFactory();
|
||||
/// Destroys the DataURIStreamFactory.
|
||||
|
||||
std::istream* open(const URI& uri);
|
||||
/// Creates an input stream returning decoded data from the given data URI.
|
||||
///
|
||||
/// Throws a DataFormatException exception if the data is incorrect format.
|
||||
|
||||
static void registerFactory();
|
||||
/// Registers the DataURIStreamFactory with the
|
||||
/// default URIStreamOpener instance.
|
||||
|
||||
static void unregisterFactory();
|
||||
/// Unregisters the DataURIStreamFactory with the
|
||||
/// default URIStreamOpener instance.
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_DataURIStreamFactory_INCLUDED
|
72
Foundation/src/DataURIStream.cpp
Normal file
72
Foundation/src/DataURIStream.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// DataURIStream.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Streams
|
||||
// Module: DataURIStreamFactory
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DataURIStream.h"
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/StreamUtil.h"
|
||||
#include "Poco/URI.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DataURIStreamIOS::DataURIStreamIOS(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "data");
|
||||
|
||||
const std::string& path = uri.getPath();
|
||||
size_t comma = path.find(',');
|
||||
if (comma == std::string::npos)
|
||||
throw DataFormatException();
|
||||
_data = path.substr(comma + 1);
|
||||
_memoryStream.reset(new MemoryInputStream(_data.data(), _data.length()));
|
||||
constexpr char base64[] = ";base64";
|
||||
const size_t base64Len = strlen(base64);
|
||||
if ((comma >= base64Len) && !path.compare(comma - base64Len, base64Len, base64, base64Len))
|
||||
{
|
||||
_base64Decoder.reset(new Base64Decoder(*_memoryStream, 0));
|
||||
_buf = _base64Decoder->rdbuf();
|
||||
}
|
||||
else
|
||||
_buf = _memoryStream->rdbuf();
|
||||
poco_ios_init(_buf);
|
||||
}
|
||||
|
||||
|
||||
DataURIStreamIOS::~DataURIStreamIOS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::streambuf* DataURIStreamIOS::rdbuf()
|
||||
{
|
||||
return _buf;
|
||||
}
|
||||
|
||||
|
||||
DataURIStream::DataURIStream(const URI& uri): DataURIStreamIOS(uri), std::istream(_buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataURIStream::~DataURIStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
54
Foundation/src/DataURIStreamFactory.cpp
Normal file
54
Foundation/src/DataURIStreamFactory.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// DataURIStreamFactory.cpp
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: URI
|
||||
// Module: DataURIStreamFactory
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DataURIStreamFactory.h"
|
||||
#include "Poco/DataURIStream.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/URIStreamOpener.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
DataURIStreamFactory::DataURIStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataURIStreamFactory::~DataURIStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* DataURIStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "data");
|
||||
|
||||
return new DataURIStream(uri);
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamFactory::registerFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().registerStreamFactory("data", new DataURIStreamFactory);
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamFactory::unregisterFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().unregisterStreamFactory("data");
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
@ -37,7 +37,8 @@ objects = ActiveMethodTest ActivityTest ActiveDispatcherTest \
|
||||
HashSetTest HashMapTest SharedMemoryTest OrderedContainersTest \
|
||||
UniqueExpireCacheTest UniqueExpireLRUCacheTest UnicodeConverterTest \
|
||||
TuplesTest NamedTuplesTest TypeListTest VarTest DynamicTestSuite FileStreamTest \
|
||||
MemoryStreamTest ObjectPoolTest DirectoryWatcherTest DirectoryIteratorsTest
|
||||
MemoryStreamTest ObjectPoolTest DirectoryWatcherTest DirectoryIteratorsTest \
|
||||
DataURIStreamTest
|
||||
|
||||
target = testrunner
|
||||
target_version = 1
|
||||
|
113
Foundation/testsuite/src/DataURIStreamTest.cpp
Normal file
113
Foundation/testsuite/src/DataURIStreamTest.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
//
|
||||
// DataURIStreamTest.cpp
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "DataURIStreamTest.h"
|
||||
#include "Poco/CppUnit/TestCaller.h"
|
||||
#include "Poco/CppUnit/TestSuite.h"
|
||||
#include "Poco/DataURIStream.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using Poco::DataFormatException;
|
||||
using Poco::DataURIStream;
|
||||
using Poco::StreamCopier;
|
||||
using Poco::URI;
|
||||
|
||||
|
||||
DataURIStreamTest::DataURIStreamTest(const std::string& name): CppUnit::TestCase(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DataURIStreamTest::~DataURIStreamTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamTest::testWithBase64()
|
||||
{
|
||||
{
|
||||
DataURIStream ds(URI("data:;base64,SGVsbG8sIFdvcmxkIQ%3D%3D"));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str() == "Hello, World!");
|
||||
}
|
||||
{
|
||||
DataURIStream ds(URI("data:text/vnd-example+xyz;foo=bar;base64,R0lGODdh"));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str() == "GIF87a");
|
||||
}
|
||||
{
|
||||
DataURIStream ds(URI("data:application/octet-stream;base64,A+b/7A=="));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str() == "\x03\xE6\xFF\xEC");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamTest::testWithoutBase64()
|
||||
{
|
||||
{
|
||||
DataURIStream ds(URI("data:,Hello%2C%20World!"));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str() == "Hello, World!");
|
||||
}
|
||||
{
|
||||
DataURIStream ds(URI("data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678"));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str() == "the data:1234,5678");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamTest::testZeroLengthData()
|
||||
{
|
||||
{
|
||||
DataURIStream ds(URI("data:text/plain;base64,"));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str().empty());
|
||||
}
|
||||
{
|
||||
DataURIStream ds(URI("data:,"));
|
||||
std::ostringstream ostr;
|
||||
StreamCopier::copyStream(ds, ostr);
|
||||
assertTrue (ostr.str().empty());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamTest::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DataURIStreamTest::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* DataURIStreamTest::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("DataURIStreamTest");
|
||||
|
||||
CppUnit_addTest(pSuite, DataURIStreamTest, testWithBase64);
|
||||
CppUnit_addTest(pSuite, DataURIStreamTest, testWithoutBase64);
|
||||
CppUnit_addTest(pSuite, DataURIStreamTest, testZeroLengthData);
|
||||
|
||||
return pSuite;
|
||||
}
|
37
Foundation/testsuite/src/DataURIStreamTest.h
Normal file
37
Foundation/testsuite/src/DataURIStreamTest.h
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// DataURIStreamTest.h
|
||||
//
|
||||
// Definition of the DataURItreamTest class.
|
||||
//
|
||||
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef DataURIStreamTest_INCLUDED
|
||||
#define DataURIStreamTest_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/CppUnit/TestCase.h"
|
||||
|
||||
|
||||
class DataURIStreamTest: public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
DataURIStreamTest(const std::string& name);
|
||||
~DataURIStreamTest();
|
||||
|
||||
void testWithBase64();
|
||||
void testWithoutBase64();
|
||||
void testZeroLengthData();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
};
|
||||
|
||||
|
||||
#endif // DataURIStreamTest_INCLUDED
|
@ -23,6 +23,7 @@
|
||||
#include "FileStreamTest.h"
|
||||
#include "MemoryStreamTest.h"
|
||||
#include "FIFOBufferStreamTest.h"
|
||||
#include "DataURIStreamTest.h"
|
||||
|
||||
|
||||
CppUnit::Test* StreamsTestSuite::suite()
|
||||
@ -43,6 +44,7 @@ CppUnit::Test* StreamsTestSuite::suite()
|
||||
pSuite->addTest(FileStreamTest::suite());
|
||||
pSuite->addTest(MemoryStreamTest::suite());
|
||||
pSuite->addTest(FIFOBufferStreamTest::suite());
|
||||
pSuite->addTest(DataURIStreamTest::suite());
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user