Introduce convenience wrappers FileInputStream/FileOutputStream

This commit is contained in:
lganzzzo 2019-07-28 22:09:16 +04:00
parent 98c33d3b92
commit 61dbc98ceb
3 changed files with 313 additions and 0 deletions

View File

@ -82,6 +82,8 @@ add_library(oatpp
oatpp/core/data/stream/BufferInputStream.hpp
oatpp/core/data/stream/ChunkedBuffer.cpp
oatpp/core/data/stream/ChunkedBuffer.hpp
oatpp/core/data/stream/FileStream.cpp
oatpp/core/data/stream/FileStream.hpp
oatpp/core/data/stream/Stream.cpp
oatpp/core/data/stream/Stream.hpp
oatpp/core/data/stream/StreamBufferedProxy.cpp

View File

@ -0,0 +1,142 @@
/***************************************************************************
*
* 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 "FileStream.hpp"
namespace oatpp { namespace data{ namespace stream {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FileInputStream
FileInputStream::FileInputStream(std::FILE* file, bool ownsFile)
: m_file(file)
, m_ownsFile(ownsFile)
, m_ioMode(IOMode::NON_BLOCKING)
{}
FileInputStream::FileInputStream(const char* filename)
: FileInputStream(std::fopen(filename, "rb"), true)
{
if(!m_file) {
OATPP_LOGE("[oatpp::data::stream::FileInputStream::FileInputStream(filename)]", "Error. Can't open file '%s'.", filename);
throw std::runtime_error("[oatpp::data::stream::FileInputStream::FileInputStream(filename)]: Error. Can't open file.");
}
}
FileInputStream::~FileInputStream() {
if(m_ownsFile) {
std::fclose(m_file);
}
}
std::FILE* FileInputStream::getFile() {
return m_file;
}
data::v_io_size FileInputStream::read(void *data, data::v_io_size count) {
return std::fread(data, 1, count, m_file);
}
oatpp::async::Action FileInputStream::suggestInputStreamAction(data::v_io_size ioResult) {
if(ioResult > 0) {
return oatpp::async::Action::createActionByType(oatpp::async::Action::TYPE_REPEAT);
}
OATPP_LOGE("[oatpp::data::stream::FileInputStream::suggestInputStreamAction()]", "Error. ioResult=%d", ioResult);
const char* message =
"Error. FileInputStream::suggestOutputStreamAction() method is called with (ioResult <= 0).\n"
"Conceptual error.";
throw std::runtime_error(message);
}
void FileInputStream::setInputStreamIOMode(IOMode ioMode) {
m_ioMode = ioMode;
}
IOMode FileInputStream::getInputStreamIOMode() {
return m_ioMode;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FileOutputStream
FileOutputStream::FileOutputStream(std::FILE* file, bool ownsFile)
: m_file(file)
, m_ownsFile(ownsFile)
, m_ioMode(IOMode::NON_BLOCKING)
{}
FileOutputStream::FileOutputStream(const char* filename, const char* mode)
: FileOutputStream(std::fopen(filename, mode), true)
{
if(!m_file) {
OATPP_LOGE("[oatpp::data::stream::FileOutputStream::FileOutputStream(filename, mode)]", "Error. Can't open file '%s'.", filename);
throw std::runtime_error("[oatpp::data::stream::FileOutputStream::FileOutputStream(filename, mode)]: Error. Can't open file.");
}
}
FileOutputStream::~FileOutputStream() {
if(m_ownsFile) {
std::fclose(m_file);
}
}
std::FILE* FileOutputStream::getFile() {
return m_file;
}
data::v_io_size FileOutputStream::write(const void *data, data::v_io_size count) {
return std::fwrite(data, 1, count, m_file);
}
oatpp::async::Action FileOutputStream::suggestOutputStreamAction(data::v_io_size ioResult) {
if(ioResult > 0) {
return oatpp::async::Action::createActionByType(oatpp::async::Action::TYPE_REPEAT);
}
OATPP_LOGE("[oatpp::data::stream::FileOutputStream::suggestInputStreamAction()]", "Error. ioResult=%d", ioResult);
const char* message =
"Error. FileOutputStream::suggestOutputStreamAction() method is called with (ioResult <= 0).\n"
"Conceptual error.";
throw std::runtime_error(message);
}
void FileOutputStream::setOutputStreamIOMode(IOMode ioMode) {
m_ioMode = ioMode;
}
IOMode FileOutputStream::getOutputStreamIOMode() {
return m_ioMode;
}
}}}

View File

@ -0,0 +1,169 @@
/***************************************************************************
*
* 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.
*
***************************************************************************/
#ifndef oatpp_data_stream_FileStream_hpp
#define oatpp_data_stream_FileStream_hpp
#include "Stream.hpp"
#include <cstdio>
namespace oatpp { namespace data{ namespace stream {
/**
* Wrapper over `std::FILE`.
*/
class FileInputStream : public InputStream {
private:
std::FILE* m_file;
bool m_ownsFile;
IOMode m_ioMode;
public:
/**
* Constructor.
* @param file - file.
* @param ownsFile - if `true` then call close on `FileInputStream` destruction.
*/
FileInputStream(std::FILE* file, bool ownsFile);
/**
* Constructor.
* @param filename - name of the file.
*/
FileInputStream(const char* filename);
/**
* Virtual destructor.
*/
~FileInputStream();
/**
* Get file.
* @return
*/
std::FILE* getFile();
/**
* Read data from stream up to count bytes, and return number of bytes actually read. <br>
* It is a legal case if return result < count. Caller should handle this!
* @param data - buffer to read data to.
* @param count - size of the buffer.
* @return - actual number of bytes read.
*/
data::v_io_size read(void *data, data::v_io_size count) override;
/**
* Implementation of InputStream must suggest async actions for I/O results. <br>
* Suggested Action is used for scheduling coroutines in async::Executor. <br>
* **Stream MUST always give the same file-handle if applicable**
* @param ioResult - result of the call to &l:InputStream::read ();.
* @return - &id:oatpp::async::Action;.
*/
oatpp::async::Action suggestInputStreamAction(data::v_io_size ioResult) override;
/**
* Set stream I/O mode.
* @throws
*/
void setInputStreamIOMode(IOMode ioMode) override;
/**
* Get stream I/O mode.
* @return
*/
IOMode getInputStreamIOMode() override;
};
/**
* Wrapper over `std::FILE`.
*/
class FileOutputStream : public OutputStream {
private:
std::FILE* m_file;
bool m_ownsFile;
IOMode m_ioMode;
public:
/**
* Constructor.
* @param file - file.
* @param ownsFile - if `true` then call close on `FileInputStream` destruction.
*/
FileOutputStream(std::FILE* file, bool ownsFile);
/**
* Constructor.
* @param filename - name of the file.
* @param mode - ("wb" - create new/override, "ab" - create new/append).
*/
FileOutputStream(const char* filename, const char* mode = "wb");
/**
* Virtual destructor.
*/
~FileOutputStream();
/**
* Get file.
* @return
*/
std::FILE* getFile();
/**
* Write data to stream up to count bytes, and return number of bytes actually written. <br>
* It is a legal case if return result < count. Caller should handle this!
* @param data - data to write.
* @param count - number of bytes to write.
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;.
*/
data::v_io_size write(const void *data, data::v_io_size count) override;
/**
* Implementation of OutputStream must suggest async actions for I/O results. <br>
* Suggested Action is used for scheduling coroutines in async::Executor. <br>
* **Stream MUST always give the same file-handle if applicable**
* @param ioResult - result of the call to &l:OutputStream::write ();.
* @return - &id:oatpp::async::Action;.
*/
oatpp::async::Action suggestOutputStreamAction(data::v_io_size ioResult) override;
/**
* Set stream I/O mode.
* @throws
*/
void setOutputStreamIOMode(IOMode ioMode) override;
/**
* Get stream I/O mode.
* @return
*/
IOMode getOutputStreamIOMode() override;
};
}}}
#endif // oatpp_data_stream_FileStream_hpp