Multipart. Basic file stream provider implementation.

This commit is contained in:
lganzzzo 2019-07-30 23:48:15 +04:00
parent 0d8e5a728e
commit 6033be1f25
6 changed files with 108 additions and 116 deletions

View File

@ -143,8 +143,8 @@ add_library(oatpp
oatpp/web/client/HttpRequestExecutor.hpp
oatpp/web/client/RequestExecutor.cpp
oatpp/web/client/RequestExecutor.hpp
oatpp/web/mime/multipart/FilePartReader.cpp
oatpp/web/mime/multipart/FilePartReader.hpp
oatpp/web/mime/multipart/FileStreamProvider.cpp
oatpp/web/mime/multipart/FileStreamProvider.hpp
oatpp/web/mime/multipart/InMemoryPartReader.cpp
oatpp/web/mime/multipart/InMemoryPartReader.hpp
oatpp/web/mime/multipart/Multipart.cpp

View File

@ -1,45 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "FilePartReader.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
void FilePartReader::onNewPart(const std::shared_ptr<Part>& part) {
}
void FilePartReader::onPartData(const std::shared_ptr<Part>& part, p_char8 data, oatpp::data::v_io_size size) {
}
async::CoroutineStarter AsyncFilePartReader::onNewPartAsync(const std::shared_ptr<Part>& part) {
return nullptr;
}
async::CoroutineStarter AsyncFilePartReader::onPartDataAsync(const std::shared_ptr<Part>& part, p_char8 data, oatpp::data::v_io_size size) {
return nullptr;
}
}}}}

View File

@ -0,0 +1,63 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "FileStreamProvider.hpp"
#include "oatpp/core/data/stream/FileStream.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
FileStreamProvider::FileStreamProvider(const oatpp::String& filename)
: m_filename(filename)
{}
std::shared_ptr<FileStreamProvider::OutputStream> FileStreamProvider::getOutputStream(const std::shared_ptr<Part>& part) {
return std::make_shared<data::stream::FileOutputStream>(m_filename->c_str());
}
std::shared_ptr<FileStreamProvider::InputStream> FileStreamProvider::getInputStream(const std::shared_ptr<Part>& part) {
return std::make_shared<data::stream::FileInputStream>(m_filename->c_str());
}
AsyncFileStreamProvider::AsyncFileStreamProvider(const oatpp::String& filename)
: m_filename(filename)
{}
async::CoroutineStarter AsyncFileStreamProvider::getOutputStreamAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::stream::OutputStream>& stream)
{
stream = std::make_shared<data::stream::FileOutputStream>(m_filename->c_str());
return nullptr;
}
async::CoroutineStarter AsyncFileStreamProvider::getInputStreamAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::stream::InputStream>& stream)
{
stream = std::make_shared<data::stream::FileInputStream>(m_filename->c_str());
return nullptr;
}
}}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_web_mime_multipart_FilePartReader_hpp
#define oatpp_web_mime_multipart_FilePartReader_hpp
#ifndef oatpp_web_mime_multipart_FileStreamProvider_hpp
#define oatpp_web_mime_multipart_FileStreamProvider_hpp
#include "StreamPartReader.hpp"
#include "Reader.hpp"
@ -44,8 +44,16 @@ public:
* Convenience typedef for &id:oatpp::data::stream::InputStream;.
*/
typedef oatpp::data::stream::InputStream InputStream;
private:
oatpp::String m_filename;
public:
/**
* Constructor.
* @param filename
*/
FileStreamProvider(const oatpp::String& filename);
/**
* Get stream to write (save) part data in.
* @param part
@ -79,73 +87,37 @@ public:
typedef oatpp::data::stream::InputStream InputStream;
public:
private:
oatpp::String m_filename;
public:
/**
* Get stream to write (save) part data in.
* Constructor.
* @param filename
*/
AsyncFileStreamProvider(const oatpp::String& filename);
/**
* Get stream to write (save) part data to.
* @param part
* @param stream - put here pointer to obtained stream.
* @return
*/
async::CoroutineStarterForResult<const std::shared_ptr<data::stream::OutputStream>&>
getOutputStreamAsync(const std::shared_ptr<Part>& part) override;
async::CoroutineStarter getOutputStreamAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::stream::OutputStream>& stream) override;
/**
* Get stream to read part data from. <br>
* This method is called after all data has been streamed to OutputStream.
* @param part
* @param stream - put here pointer to obtained stream.
* @return
*/
async::CoroutineStarterForResult<const std::shared_ptr<data::stream::InputStream>&>
getInputStreamAsync(const std::shared_ptr<Part>& part) override;
};
/**
* Part reader used in order to stream part to file.
*/
class FilePartReader : public PartReader {
public:
/**
* Called when new part headers are parsed and part object is created.
* @param part
*/
void onNewPart(const std::shared_ptr<Part>& part) override;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
*/
void onPartData(const std::shared_ptr<Part>& part, p_char8 data, oatpp::data::v_io_size size) override;
};
/**
* Async part reader used in order to stream part to file in Asynchronous manner.
*/
class AsyncFilePartReader : public AsyncPartReader {
public:
/**
* Called when new part headers are parsed and part object is created.
* @param part
* @return - &id:oatpp::async::CoroutineStarter;.
*/
async::CoroutineStarter onNewPartAsync(const std::shared_ptr<Part>& part) override;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
* @return - &id:oatpp::async::CoroutineStarter;.
*/
async::CoroutineStarter onPartDataAsync(const std::shared_ptr<Part>& part, p_char8 data, oatpp::data::v_io_size size) override;
async::CoroutineStarter getInputStreamAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::stream::InputStream>& stream) override;
};
}}}}
#endif // oatpp_web_mime_multipart_FilePartReader_hpp
#endif // oatpp_web_mime_multipart_FileStreamProvider_hpp

View File

@ -103,6 +103,7 @@ async::CoroutineStarter AsyncStreamPartReader::onNewPartAsync(const std::shared_
private:
std::shared_ptr<Part> m_part;
std::shared_ptr<AsyncPartReaderStreamProvider> m_streamProvider;
std::shared_ptr<data::stream::OutputStream> m_obtainedStream;
public:
OnNewPartCoroutine(const std::shared_ptr<Part>& part,
@ -124,13 +125,13 @@ async::CoroutineStarter AsyncStreamPartReader::onNewPartAsync(const std::shared_
"Part tag object is not nullptr. Seems like this part is already being processed by another part reader.");
}
return m_streamProvider->getOutputStreamAsync(m_part).callbackTo(&OnNewPartCoroutine::onStreamObtained);
return m_streamProvider->getOutputStreamAsync(m_part, m_obtainedStream).next(yieldTo(&OnNewPartCoroutine::onStreamObtained));
}
Action onStreamObtained(const std::shared_ptr<data::stream::OutputStream>& stream) {
Action onStreamObtained() {
auto tagObject = std::make_shared<TagObject>();
tagObject->outputStream = stream;
tagObject->outputStream = m_obtainedStream;
m_part->setTag(TAG_NAME, tagObject);
return finish();
}
@ -176,6 +177,7 @@ async::CoroutineStarter AsyncStreamPartReader::onPartDone(const std::shared_ptr<
public:
std::shared_ptr<Part> m_part;
std::shared_ptr<AsyncPartReaderStreamProvider> m_streamProvider;
std::shared_ptr<data::stream::InputStream> m_obtainedStream;
public:
OnPartDoneCoroutine(const std::shared_ptr<Part>& part,
@ -185,11 +187,11 @@ async::CoroutineStarter AsyncStreamPartReader::onPartDone(const std::shared_ptr<
{}
Action act() override {
return m_streamProvider->getInputStreamAsync(m_part).callbackTo(&OnPartDoneCoroutine::onStreamObtained);
return m_streamProvider->getInputStreamAsync(m_part, m_obtainedStream).next(yieldTo(&OnPartDoneCoroutine::onStreamObtained));
}
Action onStreamObtained(const std::shared_ptr<data::stream::InputStream>& stream) {
m_part->setDataInfo(stream);
Action onStreamObtained() {
m_part->setDataInfo(m_obtainedStream);
m_part->clearTag();
return finish();
}

View File

@ -91,23 +91,23 @@ public:
virtual ~AsyncPartReaderStreamProvider() = default;
/**
* Get stream to write (save) part data in.
* Get stream to write (save) part data to.
* @param part
* @param stream - put here pointer to obtained stream.
* @return
*/
virtual
async::CoroutineStarterForResult<const std::shared_ptr<data::stream::OutputStream>&>
getOutputStreamAsync(const std::shared_ptr<Part>& part) = 0;
virtual async::CoroutineStarter getOutputStreamAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::stream::OutputStream>& stream) = 0;
/**
* Get stream to read part data from. <br>
* This method is called after all data has been streamed to OutputStream.
* @param part
* @param stream - put here pointer to obtained stream.
* @return
*/
virtual
async::CoroutineStarterForResult<const std::shared_ptr<data::stream::InputStream>&>
getInputStreamAsync(const std::shared_ptr<Part>& part) = 0;
virtual async::CoroutineStarter getInputStreamAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::stream::InputStream>& stream) = 0;
};