mirror of
https://github.com/oatpp/oatpp.git
synced 2025-04-18 19:00:23 +08:00
Merge branch 'v1.3.0' into connection_monitor
This commit is contained in:
commit
eb666070ab
@ -9,6 +9,9 @@ Contents:
|
||||
- [The New oatpp::String](#the-new-oatppstring)
|
||||
- [ConnectionPool::get() Timeout](#connectionpoolget-timeout)
|
||||
- [JSON Serializer Escape Flags](#json-serializer-escape-flags)
|
||||
- [Response::getBody()](#responsegetbody)
|
||||
- [data::stream::FIFOStream](#datastreamfifostream)
|
||||
- [data::stream::BufferedInputStream](#datastreambufferedinputstream)
|
||||
|
||||
|
||||
## The New oatpp::String
|
||||
@ -23,9 +26,15 @@ Now it's much easier to use `oatpp::String` since `oatpp::String` is now wrapper
|
||||
|
||||
{
|
||||
oatpp::String s1 = "Hello";
|
||||
std::string s2 = *s1;
|
||||
std::string s2 = *s1; // *s1 returns a refernce to the internal std::string object
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::String s1 = "Hello";
|
||||
std::string s2 = s1; // s1 is used a l-value with a typecast operator
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
oatpp::String s1 = "Hello";
|
||||
bool b = s1 == "Hello"; // compare s1 with const char*
|
||||
@ -118,3 +127,29 @@ Output:
|
||||
res='"https://oatpp.io/"' # solidus isn't escaped
|
||||
```
|
||||
|
||||
## Response::getBody()
|
||||
|
||||
`oatpp::web::protocol::http::outgoing::Response` has a new method `getBody()` to retreive the body of the response. This is handy for response interceptors.
|
||||
|
||||
|
||||
## data::stream::FIFOStream
|
||||
|
||||
The new `FIFOStream` stream is a buffered
|
||||
[`InputStream`](https://oatpp.io/api/latest/oatpp/core/data/stream/Stream/#inputstream) with an
|
||||
[`WriteCallback`](https://oatpp.io/api/latest/oatpp/core/data/stream/Stream/#writecallback).
|
||||
Check the corresponding documentation on how to use these interfaces.
|
||||
|
||||
Instead of using a static buffer like `BufferInputStream` it is build upon `data::buffer::FIFOBuffer` and is able to
|
||||
dynamically grow when data is written to it that would surpass its capacity.
|
||||
It is especially useful if you need to buffer data from a stream upfront or have multiple data sources that should be
|
||||
buffered in a single stream.
|
||||
However, it is not synchronized, so be careful when using `FIFOStream` in a multithreaded manner.
|
||||
You need to implement your own locking.
|
||||
|
||||
|
||||
## data::stream::BufferedInputStream
|
||||
|
||||
`FIFOStream` also introduced a new interface
|
||||
[`BufferedInputStream`](https://oatpp.io/api/latest/oatpp/core/data/stream/Stream/#bufferedinputstream) which unifies
|
||||
the bufferd-stream-interface all existing buffered streams (`InputStreamBufferedProxy`, `BufferInputStream`,
|
||||
`FIFOStream`) to allow for generalisation.
|
||||
|
@ -107,6 +107,8 @@ add_library(oatpp
|
||||
oatpp/core/data/stream/BufferStream.hpp
|
||||
oatpp/core/data/stream/ChunkedBuffer.cpp
|
||||
oatpp/core/data/stream/ChunkedBuffer.hpp
|
||||
oatpp/core/data/stream/FIFOStream.cpp
|
||||
oatpp/core/data/stream/FIFOStream.hpp
|
||||
oatpp/core/data/stream/FileStream.cpp
|
||||
oatpp/core/data/stream/FileStream.hpp
|
||||
oatpp/core/data/stream/Stream.cpp
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
#define OATPP_VERSION "1.2.5"
|
||||
#define OATPP_VERSION "1.3.0"
|
||||
|
||||
typedef unsigned char v_char8;
|
||||
typedef v_char8 *p_char8;
|
||||
|
@ -246,7 +246,7 @@ v_io_size FIFOBuffer::write(const void *data, v_buff_size count) {
|
||||
|
||||
}
|
||||
|
||||
v_io_size FIFOBuffer::readAndWriteToStream(data::stream::OutputStream* stream, v_buff_size count, async::Action& action) {
|
||||
v_io_size FIFOBuffer::readAndWriteToStream(data::stream::WriteCallback* stream, v_buff_size count, async::Action& action) {
|
||||
|
||||
if(!m_canRead) {
|
||||
return IOError::RETRY_READ;
|
||||
@ -299,7 +299,7 @@ v_io_size FIFOBuffer::readAndWriteToStream(data::stream::OutputStream* stream, v
|
||||
|
||||
}
|
||||
|
||||
v_io_size FIFOBuffer::readFromStreamAndWrite(data::stream::InputStream* stream, v_buff_size count, async::Action& action) {
|
||||
v_io_size FIFOBuffer::readFromStreamAndWrite(data::stream::ReadCallback* stream, v_buff_size count, async::Action& action) {
|
||||
|
||||
if(m_canRead && m_writePosition == m_readPosition) {
|
||||
return IOError::RETRY_WRITE;
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
* @param action
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
v_io_size readAndWriteToStream(data::stream::OutputStream* stream, v_buff_size count, async::Action& action);
|
||||
v_io_size readAndWriteToStream(data::stream::WriteCallback* stream, v_buff_size count, async::Action& action);
|
||||
|
||||
/**
|
||||
* call stream.read() and then write bytes read to buffer
|
||||
@ -132,7 +132,7 @@ public:
|
||||
* @param action
|
||||
* @return
|
||||
*/
|
||||
v_io_size readFromStreamAndWrite(data::stream::InputStream* stream, v_buff_size count, async::Action& action);
|
||||
v_io_size readFromStreamAndWrite(data::stream::ReadCallback* stream, v_buff_size count, async::Action& action);
|
||||
|
||||
/**
|
||||
* flush all availableToRead bytes to stream
|
||||
|
@ -26,6 +26,9 @@
|
||||
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
#include "oatpp/core/data/share/MemoryLabel.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
@ -36,7 +39,46 @@ String::String(const std::shared_ptr<std::string>& ptr, const type::Type* const
|
||||
throw std::runtime_error("Value type does not match");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String String::loadFromFile(const char* filename) {
|
||||
std::ifstream file (filename, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
if (file.is_open()) {
|
||||
auto result = data::mapping::type::String(file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read((char*) result->data(), result->size());
|
||||
file.close();
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void String::saveToFile(const char* filename) const {
|
||||
std::ofstream fs(filename, std::ios::out | std::ios::binary);
|
||||
if(m_ptr != nullptr) {
|
||||
fs.write(m_ptr->data(), m_ptr->size());
|
||||
}
|
||||
fs.close();
|
||||
}
|
||||
|
||||
const std::string& String::operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
bool String::equalsCI_ASCII(const std::string& other) {
|
||||
auto ciLabel = share::StringKeyLabelCI(m_ptr);
|
||||
return ciLabel == other;
|
||||
}
|
||||
|
||||
bool String::equalsCI_ASCII(const String& other) {
|
||||
auto ciLabel = share::StringKeyLabelCI(m_ptr);
|
||||
return ciLabel == other;
|
||||
}
|
||||
|
||||
bool String::equalsCI_ASCII(const char* other) {
|
||||
auto ciLabel = share::StringKeyLabelCI(m_ptr);
|
||||
return ciLabel == other;
|
||||
}
|
||||
|
||||
String operator + (const char* a, const String& b) {
|
||||
data::stream::BufferOutputStream stream;
|
||||
stream << a << b;
|
||||
|
@ -30,10 +30,14 @@
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <iterator>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
|
||||
namespace __class {
|
||||
|
||||
|
||||
class String; // FWD
|
||||
|
||||
class Int8; // FWD
|
||||
@ -52,7 +56,7 @@ namespace __class {
|
||||
class Float64; // FWD
|
||||
|
||||
class Boolean; // FWD
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,13 +66,13 @@ class String : public type::ObjectWrapper<std::string, __class::String> {
|
||||
public:
|
||||
String(const std::shared_ptr<std::string>& ptr, const type::Type* const valueType);
|
||||
public:
|
||||
|
||||
|
||||
String() {}
|
||||
|
||||
explicit String(v_buff_size size)
|
||||
: type::ObjectWrapper<std::string, __class::String>(std::make_shared<std::string>(size, 0))
|
||||
{}
|
||||
|
||||
|
||||
String(const char* data, v_buff_size size)
|
||||
: type::ObjectWrapper<std::string, __class::String>(std::make_shared<std::string>(data, size))
|
||||
{}
|
||||
@ -102,24 +106,43 @@ public:
|
||||
std::make_shared<std::string>(std::forward<std::string>(str))
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
String(const std::shared_ptr<std::string>& ptr)
|
||||
: type::ObjectWrapper<std::string, __class::String>(ptr)
|
||||
{}
|
||||
|
||||
|
||||
String(std::shared_ptr<std::string>&& ptr)
|
||||
: type::ObjectWrapper<std::string, __class::String>(std::forward<std::shared_ptr<std::string>>(ptr))
|
||||
{}
|
||||
|
||||
|
||||
String(const String& other)
|
||||
: type::ObjectWrapper<std::string, __class::String>(other)
|
||||
{}
|
||||
|
||||
|
||||
String(String&& other)
|
||||
: type::ObjectWrapper<std::string, __class::String>(std::forward<String>(other))
|
||||
{}
|
||||
|
||||
const std::string& operator*() const {
|
||||
/**
|
||||
* Load data from file and store in &id:oatpp::String;.
|
||||
* @param filename - name of the file.
|
||||
* @return - &id:oatpp::String;.
|
||||
*/
|
||||
static String loadFromFile(const char* filename);
|
||||
|
||||
/**
|
||||
* Save content of the buffer to file.
|
||||
* @param filename - name of the file.
|
||||
*/
|
||||
void saveToFile(const char* filename) const;
|
||||
|
||||
const std::string& operator*() const;
|
||||
|
||||
operator std::string() const {
|
||||
if (this->m_ptr == nullptr) {
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::String::operator std::string() const]: "
|
||||
"Error. Null pointer.");
|
||||
}
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
@ -165,6 +188,27 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive compare (ASCII only).
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
bool equalsCI_ASCII(const std::string& other);
|
||||
|
||||
/**
|
||||
* Case insensitive compare (ASCII only).
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
bool equalsCI_ASCII(const String& other);
|
||||
|
||||
/**
|
||||
* Case insensitive compare (ASCII only).
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
bool equalsCI_ASCII(const char* str);
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
@ -219,9 +263,9 @@ public:
|
||||
inline bool operator != (const String &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
String operator + (const char* a, const String& b);
|
||||
String operator + (const String& a, const char* b);
|
||||
String operator + (const String& a, const String& b);
|
||||
@ -301,7 +345,7 @@ public:
|
||||
inline operator TValueType() const {
|
||||
return *this->m_ptr;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -471,29 +515,29 @@ template<>
|
||||
struct ObjectWrapperByUnderlyingType <bool> {
|
||||
typedef Boolean ObjectWrapper;
|
||||
};
|
||||
|
||||
|
||||
namespace __class {
|
||||
|
||||
|
||||
class String {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Int8 {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class UInt8 {
|
||||
@ -510,12 +554,12 @@ namespace __class {
|
||||
class Int16 {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class UInt16 {
|
||||
@ -528,16 +572,16 @@ namespace __class {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Int32 {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class UInt32 {
|
||||
@ -550,16 +594,16 @@ namespace __class {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Int64 {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class UInt64 {
|
||||
@ -576,53 +620,53 @@ namespace __class {
|
||||
class Float32 {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Float64 {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Boolean {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}}}}
|
||||
|
||||
namespace std {
|
||||
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::String> {
|
||||
|
||||
|
||||
typedef oatpp::data::mapping::type::String argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
|
||||
result_type operator()(argument_type const& s) const noexcept {
|
||||
if(s.get() == nullptr) return 0;
|
||||
return hash<std::string> {} (*s);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -25,6 +25,8 @@
|
||||
#ifndef oatpp_data_share_MemoryLabel_hpp
|
||||
#define oatpp_data_share_MemoryLabel_hpp
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
#include "oatpp/core/utils/String.hpp"
|
||||
|
||||
@ -64,9 +66,15 @@ public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param str
|
||||
* @param ptr
|
||||
*/
|
||||
MemoryLabel(const std::shared_ptr<std::string>& str) : MemoryLabel(str, str->data(), (v_buff_size) str->size()) {}
|
||||
MemoryLabel(const std::shared_ptr<std::string>& ptr) :
|
||||
MemoryLabel(
|
||||
ptr,
|
||||
ptr ? ptr->data() : nullptr,
|
||||
ptr ? (v_buff_size) ptr->size() : 0
|
||||
)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -105,7 +113,7 @@ public:
|
||||
*/
|
||||
void captureToOwnMemory() const {
|
||||
if(!m_memoryHandle || m_memoryHandle->data() != (const char*)m_data || m_memoryHandle->size() != m_size) {
|
||||
m_memoryHandle.reset(new std::string((const char*) m_data, m_size));
|
||||
m_memoryHandle = std::make_shared<std::string>((const char*) m_data, m_size);
|
||||
m_data = (p_char8) m_memoryHandle->data();
|
||||
}
|
||||
}
|
||||
@ -117,7 +125,8 @@ public:
|
||||
* @return - `true` if equals.
|
||||
*/
|
||||
bool equals(const char* data) const {
|
||||
return utils::String::compare(m_data, m_size, data, std::strlen(data)) == 0;
|
||||
auto len = data != nullptr ? std::strlen(data) : 0;
|
||||
return utils::String::compare(m_data, m_size, data, len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,7 +179,13 @@ public:
|
||||
StringKeyLabel() : MemoryLabel() {};
|
||||
|
||||
StringKeyLabel(std::nullptr_t) : MemoryLabel() {}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param ptr
|
||||
*/
|
||||
StringKeyLabel(const std::shared_ptr<std::string>& ptr) : MemoryLabel(ptr) {}
|
||||
|
||||
StringKeyLabel(const std::shared_ptr<std::string>& memoryHandle, const char* data, v_buff_size size);
|
||||
StringKeyLabel(const char* constText);
|
||||
StringKeyLabel(const String& str);
|
||||
@ -229,6 +244,8 @@ public:
|
||||
|
||||
StringKeyLabelCI(std::nullptr_t) : MemoryLabel() {}
|
||||
|
||||
StringKeyLabelCI(const std::shared_ptr<std::string>& ptr) : MemoryLabel(ptr) {}
|
||||
|
||||
StringKeyLabelCI(const std::shared_ptr<std::string>& memoryHandle, const char* data, v_buff_size size);
|
||||
StringKeyLabelCI(const char* constText);
|
||||
StringKeyLabelCI(const String& str);
|
||||
@ -242,7 +259,8 @@ public:
|
||||
}
|
||||
|
||||
inline bool operator==(const char* str) const {
|
||||
return utils::String::compareCI(m_data, m_size, str, std::strlen(str)) == 0;
|
||||
auto len = str != nullptr ? std::strlen(str) : 0;
|
||||
return utils::String::compareCI_ASCII(m_data, m_size, str, len) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const char* str) const {
|
||||
@ -252,7 +270,7 @@ public:
|
||||
inline bool operator==(const String& str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
return utils::String::compareCI(m_data, m_size, str->data(), str->size()) == 0;
|
||||
return utils::String::compareCI_ASCII(m_data, m_size, str->data(), str->size()) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const String& str) const {
|
||||
@ -260,7 +278,7 @@ public:
|
||||
}
|
||||
|
||||
inline bool operator==(const StringKeyLabelCI &other) const {
|
||||
return utils::String::compareCI(m_data, m_size, other.m_data, other.m_size) == 0;
|
||||
return utils::String::compareCI_ASCII(m_data, m_size, other.m_data, other.m_size) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const StringKeyLabelCI &other) const {
|
||||
@ -268,11 +286,11 @@ public:
|
||||
}
|
||||
|
||||
inline bool operator < (const StringKeyLabelCI &other) const {
|
||||
return utils::String::compareCI(m_data, m_size, other.m_data, other.m_size) < 0;
|
||||
return utils::String::compareCI_ASCII(m_data, m_size, other.m_data, other.m_size) < 0;
|
||||
}
|
||||
|
||||
inline bool operator > (const StringKeyLabelCI &other) const {
|
||||
return utils::String::compareCI(m_data, m_size, other.m_data, other.m_size) > 0;
|
||||
return utils::String::compareCI_ASCII(m_data, m_size, other.m_data, other.m_size) > 0;
|
||||
}
|
||||
|
||||
};
|
||||
@ -289,7 +307,7 @@ namespace std {
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabel const& s) const noexcept {
|
||||
|
||||
p_char8 data = (p_char8) s.getData();
|
||||
auto data = (p_char8) s.getData();
|
||||
result_type result = 0;
|
||||
for(v_buff_size i = 0; i < s.getSize(); i++) {
|
||||
v_char8 c = data[i];
|
||||
@ -309,7 +327,7 @@ namespace std {
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabelCI const& s) const noexcept {
|
||||
|
||||
p_char8 data = (p_char8) s.getData();
|
||||
auto data = (p_char8) s.getData();
|
||||
result_type result = 0;
|
||||
for(v_buff_size i = 0; i < s.getSize(); i++) {
|
||||
v_char8 c = data[i] | 32;
|
||||
|
@ -238,4 +238,27 @@ void BufferInputStream::setCurrentPosition(v_buff_size position) {
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
v_io_size BufferInputStream::peek(void *data, v_buff_size count, async::Action &action) {
|
||||
(void) action;
|
||||
|
||||
v_buff_size desiredAmount = count;
|
||||
if(desiredAmount > m_size - m_position) {
|
||||
desiredAmount = m_size - m_position;
|
||||
}
|
||||
std::memcpy(data, &m_data[m_position], desiredAmount);
|
||||
return desiredAmount;
|
||||
}
|
||||
|
||||
v_io_size BufferInputStream::availableToRead() const {
|
||||
return m_size - m_position;
|
||||
}
|
||||
|
||||
v_io_size BufferInputStream::commitReadOffset(v_buff_size count) {
|
||||
if(count > m_size - m_position) {
|
||||
count = m_size - m_position;
|
||||
}
|
||||
m_position += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
/**
|
||||
* BufferInputStream
|
||||
*/
|
||||
class BufferInputStream : public InputStream {
|
||||
class BufferInputStream : public BufferedInputStream {
|
||||
public:
|
||||
static data::stream::DefaultInitializedContext DEFAULT_CONTEXT;
|
||||
private:
|
||||
@ -245,6 +245,26 @@ public:
|
||||
*/
|
||||
void setCurrentPosition(v_buff_size position);
|
||||
|
||||
/**
|
||||
* Peek up to count of bytes int he buffer
|
||||
* @param data
|
||||
* @param count
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
v_io_size peek(void *data, v_buff_size count, async::Action& action) override;
|
||||
|
||||
/**
|
||||
* Amount of bytes currently available to read from buffer.
|
||||
* @return &id:oatpp::v_io_size;.
|
||||
*/
|
||||
v_io_size availableToRead() const override;
|
||||
|
||||
/**
|
||||
* Commit read offset
|
||||
* @param count
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
v_io_size commitReadOffset(v_buff_size count) override;
|
||||
|
||||
};
|
||||
|
||||
|
136
src/oatpp/core/data/stream/FIFOStream.cpp
Normal file
136
src/oatpp/core/data/stream/FIFOStream.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Benedikt-Alexander Mokroß <github@bamkrs.de>
|
||||
*
|
||||
* 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 "FIFOStream.hpp"
|
||||
#include "oatpp/core/utils/Binary.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace stream {
|
||||
|
||||
data::stream::DefaultInitializedContext FIFOInputStream::DEFAULT_CONTEXT(data::stream::StreamType::STREAM_FINITE);
|
||||
|
||||
FIFOInputStream::FIFOInputStream(v_buff_size initialSize)
|
||||
: m_memoryHandle(std::make_shared<std::string>(initialSize, (char)0))
|
||||
, m_fifo(std::make_shared<data::buffer::FIFOBuffer>((void*)m_memoryHandle->data(), m_memoryHandle->size(), 0, 0, false))
|
||||
, m_maxCapacity(-1) {
|
||||
|
||||
}
|
||||
|
||||
void FIFOInputStream::reset() {
|
||||
m_fifo->setBufferPosition(0, 0, false);
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::read(void *data, v_buff_size count, async::Action& action) {
|
||||
(void) action;
|
||||
return m_fifo->read(data, count);
|
||||
}
|
||||
|
||||
void FIFOInputStream::setInputStreamIOMode(IOMode ioMode) {
|
||||
m_ioMode = ioMode;
|
||||
}
|
||||
|
||||
IOMode FIFOInputStream::getInputStreamIOMode() {
|
||||
return m_ioMode;
|
||||
}
|
||||
|
||||
Context& FIFOInputStream::getInputStreamContext() {
|
||||
return DEFAULT_CONTEXT;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::string> FIFOInputStream::getDataMemoryHandle() {
|
||||
return m_memoryHandle;
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::write(const void *data, v_buff_size count, async::Action &action) {
|
||||
(void) action;
|
||||
reserveBytesUpfront(count);
|
||||
return m_fifo->write(data, count);
|
||||
}
|
||||
|
||||
void FIFOInputStream::reserveBytesUpfront(v_buff_size count) {
|
||||
|
||||
v_buff_size capacityNeeded = availableToRead() + count;
|
||||
|
||||
if(capacityNeeded > m_fifo->getBufferSize()) {
|
||||
|
||||
v_buff_size newCapacity = utils::Binary::nextP2(capacityNeeded);
|
||||
|
||||
if(newCapacity < 0 || (m_maxCapacity > 0 && newCapacity > m_maxCapacity)) {
|
||||
newCapacity = m_maxCapacity;
|
||||
}
|
||||
|
||||
if(newCapacity < capacityNeeded) {
|
||||
throw std::runtime_error("[oatpp::data::stream::BufferOutputStream::reserveBytesUpfront()]: Error. Unable to allocate requested memory.");
|
||||
}
|
||||
|
||||
// ToDo: In-Memory-Resize
|
||||
auto newHandle = std::make_shared<std::string>(newCapacity, (char)0);
|
||||
v_io_size oldSize = m_fifo->availableToRead();
|
||||
m_fifo->read((void*)newHandle->data(), oldSize);
|
||||
auto newFifo = std::make_shared<data::buffer::FIFOBuffer>((void*)newHandle->data(), newHandle->size(), 0, oldSize, oldSize > 0);
|
||||
m_memoryHandle = newHandle;
|
||||
m_fifo = newFifo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::readAndWriteToStream(data::stream::OutputStream *stream,
|
||||
v_buff_size count,
|
||||
async::Action &action) {
|
||||
return m_fifo->readAndWriteToStream(stream, count, action);
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::readFromStreamAndWrite(data::stream::InputStream *stream,
|
||||
v_buff_size count,
|
||||
async::Action &action) {
|
||||
reserveBytesUpfront(count);
|
||||
return m_fifo->readFromStreamAndWrite(stream, count, action);
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::flushToStream(data::stream::OutputStream *stream) {
|
||||
return m_fifo->flushToStream(stream);
|
||||
}
|
||||
|
||||
async::CoroutineStarter FIFOInputStream::flushToStreamAsync(const std::shared_ptr<data::stream::OutputStream> &stream) {
|
||||
return m_fifo->flushToStreamAsync(stream);
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::availableToWrite() {
|
||||
return m_fifo->availableToWrite();
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::peek(void *data, v_buff_size count, async::Action &action) {
|
||||
(void) action;
|
||||
return m_fifo->peek(data, count);
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::availableToRead() const {
|
||||
return m_fifo->availableToRead();
|
||||
}
|
||||
|
||||
v_io_size FIFOInputStream::commitReadOffset(v_buff_size count) {
|
||||
return m_fifo->commitReadOffset(count);
|
||||
}
|
||||
|
||||
}}}
|
175
src/oatpp/core/data/stream/FIFOStream.hpp
Normal file
175
src/oatpp/core/data/stream/FIFOStream.hpp
Normal file
@ -0,0 +1,175 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Benedikt-Alexander Mokroß <github@bamkrs.de>
|
||||
*
|
||||
* 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_FIFOStream_hpp
|
||||
#define oatpp_data_stream_FIFOStream_hpp
|
||||
|
||||
#include "Stream.hpp"
|
||||
#include "oatpp/core/data/buffer/FIFOBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace stream {
|
||||
|
||||
|
||||
/**
|
||||
* FIFOInputStream
|
||||
*/
|
||||
class FIFOInputStream : public BufferedInputStream, public WriteCallback {
|
||||
public:
|
||||
static data::stream::DefaultInitializedContext DEFAULT_CONTEXT;
|
||||
private:
|
||||
std::shared_ptr<std::string> m_memoryHandle;
|
||||
std::shared_ptr<data::buffer::FIFOBuffer> m_fifo;
|
||||
v_buff_size m_maxCapacity;
|
||||
IOMode m_ioMode;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param data - buffer.
|
||||
*/
|
||||
FIFOInputStream(v_buff_size initialSize = 4096);
|
||||
|
||||
static std::shared_ptr<FIFOInputStream> createShared(v_buff_size initialSize = 4096) {
|
||||
return std::make_shared<FIFOInputStream>(initialSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards all data in the buffer and resets it to an empty state
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Read data from stream. <br>
|
||||
* It is a legal case if return result < count. Caller should handle this!
|
||||
* *Calls to this method are always NON-BLOCKING*
|
||||
* @param data - buffer to read data to.
|
||||
* @param count - size of the buffer.
|
||||
* @param action - async specific action. If action is NOT &id:oatpp::async::Action::TYPE_NONE;, then
|
||||
* caller MUST return this action on coroutine iteration.
|
||||
* @return - actual number of bytes read. 0 - designates end of the buffer.
|
||||
*/
|
||||
v_io_size read(void *data, v_buff_size count, async::Action& action) override;
|
||||
|
||||
/**
|
||||
* Set stream I/O mode.
|
||||
* @throws
|
||||
*/
|
||||
void setInputStreamIOMode(IOMode ioMode) override;
|
||||
|
||||
/**
|
||||
* Get stream I/O mode.
|
||||
* @return
|
||||
*/
|
||||
IOMode getInputStreamIOMode() override;
|
||||
|
||||
/**
|
||||
* Get stream context.
|
||||
* @return
|
||||
*/
|
||||
Context& getInputStreamContext() override;
|
||||
|
||||
/**
|
||||
* Get data memory handle.
|
||||
* @return - data memory handle.
|
||||
*/
|
||||
std::shared_ptr<std::string> getDataMemoryHandle();
|
||||
|
||||
/**
|
||||
* Write operation callback.
|
||||
* @param data - pointer to data.
|
||||
* @param count - size of the data in bytes.
|
||||
* @param action - async specific action. If action is NOT &id:oatpp::async::Action::TYPE_NONE;, then
|
||||
* caller MUST return this action on coroutine iteration.
|
||||
* @return - actual number of bytes written. 0 - to indicate end-of-file.
|
||||
*/
|
||||
v_io_size write(const void *data, v_buff_size count, async::Action &action) override;
|
||||
|
||||
/**
|
||||
* Peek up to count of bytes int he buffer
|
||||
* @param data
|
||||
* @param count
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
v_io_size peek(void *data, v_buff_size count, async::Action& action) override;
|
||||
|
||||
/**
|
||||
* Amount of bytes currently available to read from buffer.
|
||||
* @return &id:oatpp::v_io_size;.
|
||||
*/
|
||||
v_io_size availableToRead() const override;
|
||||
|
||||
/**
|
||||
* Commit read offset
|
||||
* @param count
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
v_io_size commitReadOffset(v_buff_size count) override;
|
||||
|
||||
/**
|
||||
* Reserve bytes for future writes. Check &id:oatpp::data::stream::FIFOStream::availableToWrite for the capacity.
|
||||
*/
|
||||
void reserveBytesUpfront(v_buff_size count);
|
||||
|
||||
/**
|
||||
* call read and then write bytes read to output stream
|
||||
* @param stream
|
||||
* @param count
|
||||
* @param action
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
v_io_size readAndWriteToStream(data::stream::OutputStream* stream, v_buff_size count, async::Action& action);
|
||||
|
||||
/**
|
||||
* call stream.read() and then write bytes read to buffer
|
||||
* @param stream
|
||||
* @param count
|
||||
* @param action
|
||||
* @return
|
||||
*/
|
||||
v_io_size readFromStreamAndWrite(data::stream::InputStream* stream, v_buff_size count, async::Action& action);
|
||||
|
||||
/**
|
||||
* flush all availableToRead bytes to stream
|
||||
* @param stream
|
||||
* @return
|
||||
*/
|
||||
v_io_size flushToStream(data::stream::OutputStream* stream);
|
||||
|
||||
/**
|
||||
* flush all availableToRead bytes to stream in asynchronous manner
|
||||
* @param stream - &id:data::stream::OutputStream;.
|
||||
* @return - &id:async::CoroutineStarter;.
|
||||
*/
|
||||
async::CoroutineStarter flushToStreamAsync(const std::shared_ptr<data::stream::OutputStream>& stream);
|
||||
|
||||
/**
|
||||
* Amount of buffer space currently available for data writes.
|
||||
* @return &id:oatpp::v_io_size;.
|
||||
*/
|
||||
v_io_size availableToWrite();
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // oatpp_data_stream_FIFOStream_hpp
|
@ -350,6 +350,38 @@ public:
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Buffered Input Stream
|
||||
*/
|
||||
class BufferedInputStream : public InputStream {
|
||||
public:
|
||||
/**
|
||||
* Default virtual destructor.
|
||||
*/
|
||||
virtual ~BufferedInputStream() = default;
|
||||
|
||||
/**
|
||||
* Peek up to count of bytes int he buffer
|
||||
* @param data
|
||||
* @param count
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
virtual v_io_size peek(void *data, v_buff_size count, async::Action& action) = 0;
|
||||
|
||||
/**
|
||||
* Amount of bytes currently available to read from buffer.
|
||||
* @return &id:oatpp::v_io_size;.
|
||||
*/
|
||||
virtual v_io_size availableToRead() const = 0;
|
||||
|
||||
/**
|
||||
* Commit read offset
|
||||
* @param count
|
||||
* @return [1..count], IOErrors.
|
||||
*/
|
||||
virtual v_io_size commitReadOffset(v_buff_size count) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* I/O Stream.
|
||||
*/
|
||||
|
@ -101,5 +101,9 @@ oatpp::data::stream::IOMode InputStreamBufferedProxy::getInputStreamIOMode() {
|
||||
Context& InputStreamBufferedProxy::getInputStreamContext() {
|
||||
return m_inputStream->getInputStreamContext();
|
||||
}
|
||||
|
||||
|
||||
v_io_size InputStreamBufferedProxy::availableToRead() const {
|
||||
return m_buffer.availableToRead();
|
||||
}
|
||||
|
||||
}}}
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class InputStreamBufferedProxy : public oatpp::base::Countable, public InputStream {
|
||||
class InputStreamBufferedProxy : public oatpp::base::Countable, public BufferedInputStream {
|
||||
public:
|
||||
OBJECT_POOL(InputStreamBufferedProxy_Pool, InputStreamBufferedProxy, 32)
|
||||
SHARED_OBJECT_POOL(Shared_InputStreamBufferedProxy_Pool, InputStreamBufferedProxy, 32)
|
||||
@ -119,9 +119,11 @@ public:
|
||||
|
||||
v_io_size read(void *data, v_buff_size count, async::Action& action) override;
|
||||
|
||||
v_io_size peek(void *data, v_buff_size count, async::Action& action);
|
||||
v_io_size peek(void *data, v_buff_size count, async::Action& action) override;
|
||||
|
||||
v_io_size commitReadOffset(v_buff_size count);
|
||||
v_io_size commitReadOffset(v_buff_size count) override;
|
||||
|
||||
v_io_size availableToRead() const override;
|
||||
|
||||
/**
|
||||
* Set InputStream I/O mode.
|
||||
|
@ -23,29 +23,10 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "String.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
|
||||
namespace oatpp { namespace utils {
|
||||
|
||||
data::mapping::type::String String::loadFromFile(const char* filename) {
|
||||
std::ifstream file (filename, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
if (file.is_open()) {
|
||||
auto result = data::mapping::type::String(file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read((char*) result->data(), result->size());
|
||||
file.close();
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void String::saveToFile(const data::mapping::type::String& data, const char* filename) {
|
||||
std::ofstream fs(filename, std::ios::out | std::ios::binary);
|
||||
fs.write(data->data(), data->size());
|
||||
fs.close();
|
||||
}
|
||||
|
||||
v_buff_size String::compare(const void* data1, v_buff_size size1, const void* data2, v_buff_size size2) {
|
||||
|
||||
if(data1 == data2) return 0;
|
||||
@ -68,7 +49,7 @@ v_buff_size String::compare(const void* data1, v_buff_size size1, const void* da
|
||||
|
||||
}
|
||||
|
||||
v_buff_size String::compareCI(const void* data1, v_buff_size size1, const void* data2, v_buff_size size2) {
|
||||
v_buff_size String::compareCI_ASCII(const void* data1, v_buff_size size1, const void* data2, v_buff_size size2) {
|
||||
|
||||
if(data1 == data2) return 0;
|
||||
if(data1 == nullptr) return -1;
|
||||
@ -101,14 +82,14 @@ v_buff_size String::compareCI(const void* data1, v_buff_size size1, const void*
|
||||
|
||||
}
|
||||
|
||||
void String::lowerCaseASCII(void* data, v_buff_size size) {
|
||||
void String::lowerCase_ASCII(void* data, v_buff_size size) {
|
||||
for(v_buff_size i = 0; i < size; i++) {
|
||||
v_char8 a = ((p_char8) data)[i];
|
||||
if(a >= 'A' && a <= 'Z') ((p_char8) data)[i] = a | 32;
|
||||
}
|
||||
}
|
||||
|
||||
void String::upperCaseASCII(void* data, v_buff_size size) {
|
||||
void String::upperCase_ASCII(void* data, v_buff_size size) {
|
||||
for(v_buff_size i = 0; i < size; i++) {
|
||||
v_char8 a = ((p_char8) data)[i];
|
||||
if(a >= 'a' && a <= 'z') ((p_char8) data)[i] = a & 223;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef oatpp_utils_String_hpp
|
||||
#define oatpp_utils_String_hpp
|
||||
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
#include "oatpp/core/base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace utils {
|
||||
@ -36,19 +35,6 @@ namespace oatpp { namespace utils {
|
||||
class String {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Load data from file and store in &id:oatpp::String;.
|
||||
* @param filename - name of the file.
|
||||
* @return - &id:oatpp::String;.
|
||||
*/
|
||||
static data::mapping::type::String loadFromFile(const char* filename);
|
||||
|
||||
/**
|
||||
* Save content of the buffer to file.
|
||||
* @param filename - name of the file.
|
||||
*/
|
||||
static void saveToFile(const data::mapping::type::String& data, const char* filename);
|
||||
|
||||
/**
|
||||
* Compare data1, data2 using `std::memcmp`.
|
||||
* *It's safe to pass nullptr for data1/data2*
|
||||
@ -63,7 +49,7 @@ public:
|
||||
static v_buff_size compare(const void* data1, v_buff_size size1, const void* data2, v_buff_size size2);
|
||||
|
||||
/**
|
||||
* Compare data1, data2 - case insensitive.
|
||||
* Compare data1, data2 - case insensitive (ASCII only).
|
||||
* *It's safe to pass nullptr for data1/data2*
|
||||
* @param data1 - pointer to data1.
|
||||
* @param size1 - size of data1.
|
||||
@ -73,21 +59,21 @@ public:
|
||||
* 0 if all count bytes of data1 and data2 are equal.<br>
|
||||
* Positive value if the first differing byte in data1 is greater than the corresponding byte in data2.
|
||||
*/
|
||||
static v_buff_size compareCI(const void* data1, v_buff_size size1, const void* data2, v_buff_size size2);
|
||||
static v_buff_size compareCI_ASCII(const void* data1, v_buff_size size1, const void* data2, v_buff_size size2);
|
||||
|
||||
/**
|
||||
* Change characters in data to lowercase (ASCII only).
|
||||
* @param data - pointer to data.
|
||||
* @param size - size of the data.
|
||||
*/
|
||||
static void lowerCaseASCII(void* data, v_buff_size size);
|
||||
static void lowerCase_ASCII(void* data, v_buff_size size);
|
||||
|
||||
/**
|
||||
* Change characters in data to uppercase (ASCII only).
|
||||
* @param data - pointer to data.
|
||||
* @param size - size of the data.
|
||||
*/
|
||||
static void upperCaseASCII(void* data, v_buff_size size);
|
||||
static void upperCase_ASCII(void* data, v_buff_size size);
|
||||
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ oatpp::String Url::Parser::parseScheme(oatpp::parser::Caret& caret) {
|
||||
if(size > 0) {
|
||||
std::unique_ptr<v_char8[]> buff(new v_char8[size]);
|
||||
std::memcpy(buff.get(), &caret.getData()[pos0], size);
|
||||
utils::String::lowerCaseASCII(buff.get(), size);
|
||||
utils::String::lowerCase_ASCII(buff.get(), size);
|
||||
return oatpp::String((const char*)buff.get(), size);
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -72,7 +72,7 @@ void SchemaMigration::migrate() {
|
||||
break;
|
||||
|
||||
case SOURCE_FILE:
|
||||
script = utils::String::loadFromFile(source.param->c_str());
|
||||
script = oatpp::String::loadFromFile(source.param->c_str());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -48,6 +48,10 @@ protocol::http::Headers& Response::getHeaders() {
|
||||
return m_headers;
|
||||
}
|
||||
|
||||
std::shared_ptr<Body> Response::getBody() const {
|
||||
return m_body;
|
||||
}
|
||||
|
||||
void Response::putHeader(const oatpp::String& key, const oatpp::String& value) {
|
||||
m_headers.put(key, value);
|
||||
}
|
||||
|
@ -89,6 +89,12 @@ public:
|
||||
*/
|
||||
Headers& getHeaders();
|
||||
|
||||
/**
|
||||
* Get body
|
||||
* @return - &id:oatpp::web::protocol::http::outgoing::Body;
|
||||
*/
|
||||
std::shared_ptr<Body> getBody() const;
|
||||
|
||||
/**
|
||||
* Add http header.
|
||||
* @param key - &id:oatpp::String;.
|
||||
|
@ -55,7 +55,7 @@ void CommunicationUtils::considerConnectionState(const std::shared_ptr<protocol:
|
||||
/* Set HTTP/1.1 default Connection header value (Keep-Alive), if no Connection header present in response. */
|
||||
/* Set keep-alive to value specified in response otherwise */
|
||||
auto& protocol = request->getStartingLine().protocol;
|
||||
if(protocol && oatpp::utils::String::compareCI(protocol.getData(), protocol.getSize(), "HTTP/1.1", 8) == 0) {
|
||||
if(protocol && oatpp::utils::String::compareCI_ASCII(protocol.getData(), protocol.getSize(), "HTTP/1.1", 8) == 0) {
|
||||
if(outState && outState != Header::Value::CONNECTION_KEEP_ALIVE) {
|
||||
connectionState = ConnectionState::CLOSING;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
ProcessorToUpper(v_int32 bufferSize) : BaseProcessor(bufferSize) {}
|
||||
|
||||
void process(p_char8 data, v_buff_size size) override {
|
||||
utils::String::upperCaseASCII(data, size);
|
||||
utils::String::upperCase_ASCII(data, size);
|
||||
}
|
||||
|
||||
};
|
||||
@ -104,7 +104,7 @@ public:
|
||||
ProcessorToLower(v_int32 bufferSize) : BaseProcessor(bufferSize) {}
|
||||
|
||||
void process(p_char8 data, v_buff_size size) override {
|
||||
utils::String::lowerCaseASCII(data, size);
|
||||
utils::String::lowerCase_ASCII(data, size);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -221,6 +221,99 @@ void StringTest::onRun() {
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test compareCI_ASCII methods 1");
|
||||
|
||||
oatpp::String s1 = "hello";
|
||||
|
||||
{
|
||||
oatpp::String s2;
|
||||
OATPP_ASSERT(!s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
const char* s2 = nullptr;
|
||||
OATPP_ASSERT(!s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test compareCI_ASCII methods 2");
|
||||
|
||||
oatpp::String s1;
|
||||
|
||||
{
|
||||
oatpp::String s2 = "hello";
|
||||
OATPP_ASSERT(!s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
std::string s2 = "hello";
|
||||
OATPP_ASSERT(!s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
const char* s2 = "hello";
|
||||
OATPP_ASSERT(!s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::String s2;
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
const char* s2 = nullptr;
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII(nullptr));
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
bool exceptionThrown = false;
|
||||
|
||||
try {
|
||||
std::string s2 = s1;
|
||||
} catch (const std::runtime_error& e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
|
||||
OATPP_ASSERT(exceptionThrown);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test compareCI_ASCII methods 3");
|
||||
|
||||
oatpp::String s1 = "hello";
|
||||
|
||||
{
|
||||
oatpp::String s2 = "HELLO";
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
std::string s2 = "HELLO";
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
const char* s2 = "HELLO";
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII(s2));
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_ASSERT(s1.equalsCI_ASCII("HELLO"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user