From 150219552fd106decc1e56c05c246c755293d15b Mon Sep 17 00:00:00 2001 From: lganzzzo Date: Mon, 25 Feb 2019 01:02:58 +0200 Subject: [PATCH] Better OutputStream, ChunkedBufferTest --- src/oatpp/core/data/stream/ChunkedBuffer.hpp | 7 +- src/oatpp/core/data/stream/Stream.cpp | 96 ++++++++++--- src/oatpp/core/data/stream/Stream.hpp | 27 ++-- src/oatpp/core/utils/ConversionUtils.cpp | 2 +- src/oatpp/web/server/api/Endpoint.cpp | 4 +- src/oatpp/web/server/handler/ErrorHandler.cpp | 10 +- test/CMakeLists.txt | 2 + test/oatpp/AllTestsMain.cpp | 14 +- .../core/data/stream/ChunkedBufferTest.cpp | 129 ++++++++++++++++++ .../core/data/stream/ChunkedBufferTest.hpp | 43 ++++++ 10 files changed, 289 insertions(+), 45 deletions(-) create mode 100644 test/oatpp/core/data/stream/ChunkedBufferTest.cpp create mode 100644 test/oatpp/core/data/stream/ChunkedBufferTest.hpp diff --git a/src/oatpp/core/data/stream/ChunkedBuffer.hpp b/src/oatpp/core/data/stream/ChunkedBuffer.hpp index 1f41f1ee..119c3866 100644 --- a/src/oatpp/core/data/stream/ChunkedBuffer.hpp +++ b/src/oatpp/core/data/stream/ChunkedBuffer.hpp @@ -125,7 +125,7 @@ private: data::v_io_size& outChunkPos); public: - + ChunkedBuffer() : m_size(0) , m_chunkPos(0) @@ -136,6 +136,11 @@ public: ~ChunkedBuffer() { clear(); } + +public: + + ChunkedBuffer(const ChunkedBuffer&) = delete; + ChunkedBuffer& operator=(const ChunkedBuffer&) = delete; public: diff --git a/src/oatpp/core/data/stream/Stream.cpp b/src/oatpp/core/data/stream/Stream.cpp index 478be45e..d7f3b0d2 100644 --- a/src/oatpp/core/data/stream/Stream.cpp +++ b/src/oatpp/core/data/stream/Stream.cpp @@ -77,43 +77,105 @@ data::v_io_size OutputStream::writeAsString(bool value) { // Functions -const std::shared_ptr& operator << -(const std::shared_ptr& s, const oatpp::String& str) { - s->write(str); +OutputStream& operator << (OutputStream& s, const oatpp::String& str) { + if(str) { + s.write(str); + } else { + s.write("[]"); + } return s; } -const std::shared_ptr& operator << -(const std::shared_ptr& s, const char* str) { - s->write(str); +OutputStream& operator << (OutputStream& s, const Int8& value) { + if(value.getPtr()) { + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const Int16& value) { + if(value.getPtr()) { + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const Int32& value) { + if(value.getPtr()) { + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const Int64& value) { + if(value.getPtr()) { + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const Float32& value) { + if(value.getPtr()) { + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const Float64& value) { + if(value.getPtr()) { + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const Boolean& value) { + if(value.getPtr()) { // use getPtr() here to avoid false to nullptr conversion + return operator << (s, value->getValue()); + } + s.write("[]"); + return s; +} + +OutputStream& operator << (OutputStream& s, const char* str) { + if(str != nullptr) { + s.write(str); + } else { + s.write("[]"); + } return s; } -const std::shared_ptr& operator << (const std::shared_ptr& s, v_int32 value) { - s->writeAsString(value); +OutputStream& operator << (OutputStream& s, v_int32 value) { + s.writeAsString(value); return s; } -const std::shared_ptr& operator << (const std::shared_ptr& s, v_int64 value) { - s->writeAsString(value); +OutputStream& operator << (OutputStream& s, v_int64 value) { + s.writeAsString(value); return s; } -const std::shared_ptr& operator << (const std::shared_ptr& s, v_float32 value) { - s->writeAsString(value); +OutputStream& operator << (OutputStream& s, v_float32 value) { + s.writeAsString(value); return s; } -const std::shared_ptr& operator << (const std::shared_ptr& s, v_float64 value) { - s->writeAsString(value); +OutputStream& operator << (OutputStream& s, v_float64 value) { + s.writeAsString(value); return s; } -const std::shared_ptr& operator << (const std::shared_ptr& s, bool value) { +OutputStream& operator << (OutputStream& s, bool value) { if(value) { - s->OutputStream::write("true"); + s.OutputStream::write("true"); } else { - s->OutputStream::write("false"); + s.OutputStream::write("false"); } return s; } diff --git a/src/oatpp/core/data/stream/Stream.hpp b/src/oatpp/core/data/stream/Stream.hpp index 6fe90710..30934e50 100644 --- a/src/oatpp/core/data/stream/Stream.hpp +++ b/src/oatpp/core/data/stream/Stream.hpp @@ -125,21 +125,22 @@ public: }; -const std::shared_ptr& operator << -(const std::shared_ptr& s, const oatpp::String& str); +OutputStream& operator << (OutputStream& s, const oatpp::String& str); +OutputStream& operator << (OutputStream& s, const Int8& value); +OutputStream& operator << (OutputStream& s, const Int16& value); +OutputStream& operator << (OutputStream& s, const Int32& value); +OutputStream& operator << (OutputStream& s, const Int64& value); +OutputStream& operator << (OutputStream& s, const Float32& value); +OutputStream& operator << (OutputStream& s, const Float64& value); +OutputStream& operator << (OutputStream& s, const Boolean& value); -const std::shared_ptr& operator << -(const std::shared_ptr& s, const char* str); - -const std::shared_ptr& operator << (const std::shared_ptr& s, v_int32 value); +OutputStream& operator << (OutputStream& s, const char* str); +OutputStream& operator << (OutputStream& s, v_int32 value); +OutputStream& operator << (OutputStream& s, v_int64 value); +OutputStream& operator << (OutputStream& s, v_float32 value); +OutputStream& operator << (OutputStream& s, v_float64 value); +OutputStream& operator << (OutputStream& s, bool value); -const std::shared_ptr& operator << (const std::shared_ptr& s, v_int64 value); - -const std::shared_ptr& operator << (const std::shared_ptr& s, v_float32 value); - -const std::shared_ptr& operator << (const std::shared_ptr& s, v_float64 value); - -const std::shared_ptr& operator << (const std::shared_ptr& s, bool value); /** * Read bytes from @fromStream" and write to @toStream" using @buffer of size @bufferSize diff --git a/src/oatpp/core/utils/ConversionUtils.cpp b/src/oatpp/core/utils/ConversionUtils.cpp index cde457d4..6622b46a 100644 --- a/src/oatpp/core/utils/ConversionUtils.cpp +++ b/src/oatpp/core/utils/ConversionUtils.cpp @@ -139,7 +139,7 @@ namespace oatpp { namespace utils { namespace conversion { oatpp::String float64ToStr(v_float64 value){ v_char8 buff [100]; - v_int32 size = float32ToCharSequence(value, &buff[0]); + v_int32 size = float64ToCharSequence(value, &buff[0]); if(size > 0){ return oatpp::String((const char*)&buff[0], size, true); } diff --git a/src/oatpp/web/server/api/Endpoint.cpp b/src/oatpp/web/server/api/Endpoint.cpp index 13106b51..75049eed 100644 --- a/src/oatpp/web/server/api/Endpoint.cpp +++ b/src/oatpp/web/server/api/Endpoint.cpp @@ -29,7 +29,7 @@ namespace oatpp { namespace web { namespace server { namespace api { oatpp::String Endpoint::Info::toString() { - auto stream = oatpp::data::stream::ChunkedBuffer::createShared(); + oatpp::data::stream::ChunkedBuffer stream; stream << "\nEndpoint\n"; @@ -61,7 +61,7 @@ oatpp::String Endpoint::Info::toString() { stream << "pathParam: '" << param.name << "', type: '" << param.type->name << "'\n"; } - return stream->toString(); + return stream.toString(); } }}}} diff --git a/src/oatpp/web/server/handler/ErrorHandler.cpp b/src/oatpp/web/server/handler/ErrorHandler.cpp index 12c10e84..3220f02f 100644 --- a/src/oatpp/web/server/handler/ErrorHandler.cpp +++ b/src/oatpp/web/server/handler/ErrorHandler.cpp @@ -33,12 +33,10 @@ std::shared_ptr DefaultErrorHandler::handleError(const protocol::http::Status& status, const oatpp::String& message) { auto stream = oatpp::data::stream::ChunkedBuffer::createShared(); - stream << "server=" << protocol::http::Header::Value::SERVER << "\n"; - stream << "code="; - stream->writeAsString(status.code); - stream << "\n"; - stream << "description=" << status.description << "\n"; - stream << "message=" << message << "\n"; + *stream << "server=" << protocol::http::Header::Value::SERVER << "\n"; + *stream << "code=" << status.code << "\n"; + *stream << "description=" << status.description << "\n"; + *stream << "message=" << message << "\n"; auto response = protocol::http::outgoing::Response::createShared (status, protocol::http::outgoing::ChunkedBufferBody::createShared(stream)); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8dd9219e..b55fdf73 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,6 +15,8 @@ add_executable(oatppAllTests oatpp/core/data/mapping/type/TypeTest.hpp oatpp/core/data/share/MemoryLabelTest.cpp oatpp/core/data/share/MemoryLabelTest.hpp + oatpp/core/data/stream/ChunkedBufferTest.cpp + oatpp/core/data/stream/ChunkedBufferTest.hpp oatpp/encoding/Base64Test.cpp oatpp/encoding/Base64Test.hpp oatpp/encoding/UnicodeTest.cpp diff --git a/test/oatpp/AllTestsMain.cpp b/test/oatpp/AllTestsMain.cpp index 646af071..ea2c1a05 100644 --- a/test/oatpp/AllTestsMain.cpp +++ b/test/oatpp/AllTestsMain.cpp @@ -6,6 +6,7 @@ #include "oatpp/network/virtual_/InterfaceTest.hpp" #include "oatpp/network/UrlTest.hpp" +#include "oatpp/core/data/stream/ChunkedBufferTest.hpp" #include "oatpp/core/data/share/MemoryLabelTest.hpp" #include "oatpp/parser/json/mapping/DeserializerTest.hpp" @@ -49,25 +50,28 @@ public: }; void runTests() { - - /* + OATPP_RUN_TEST(oatpp::test::base::RegRuleTest); OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest); + OATPP_RUN_TEST(oatpp::test::memory::MemoryPoolTest); OATPP_RUN_TEST(oatpp::test::memory::PerfTest); + OATPP_RUN_TEST(oatpp::test::collection::LinkedListTest); + + OATPP_RUN_TEST(oatpp::test::core::data::share::MemoryLabelTest); + OATPP_RUN_TEST(oatpp::test::core::data::stream::ChunkedBufferTest); OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::TypeTest); + OATPP_RUN_TEST(oatpp::test::parser::CaretTest); OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DeserializerTest); OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DTOMapperPerfTest); OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DTOMapperTest); + OATPP_RUN_TEST(oatpp::test::encoding::Base64Test); OATPP_RUN_TEST(oatpp::test::encoding::UnicodeTest); - OATPP_RUN_TEST(oatpp::test::core::data::share::MemoryLabelTest); -*/ OATPP_RUN_TEST(oatpp::test::network::UrlTest); - OATPP_RUN_TEST(oatpp::test::network::virtual_::PipeTest); OATPP_RUN_TEST(oatpp::test::network::virtual_::InterfaceTest); diff --git a/test/oatpp/core/data/stream/ChunkedBufferTest.cpp b/test/oatpp/core/data/stream/ChunkedBufferTest.cpp new file mode 100644 index 00000000..a039db46 --- /dev/null +++ b/test/oatpp/core/data/stream/ChunkedBufferTest.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * + * Project _____ __ ____ _ _ + * ( _ ) /__\ (_ _)_| |_ _| |_ + * )(_)( /(__)\ )( (_ _)(_ _) + * (_____)(__)(__)(__) |_| |_| + * + * + * Copyright 2018-present, Leonid Stryzhevskyi + * + * 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 "ChunkedBufferTest.hpp" + +#include "oatpp/core/data/stream/ChunkedBuffer.hpp" +#include "oatpp/core/utils/ConversionUtils.hpp" + +namespace oatpp { namespace test { namespace core { namespace data { namespace stream { + +void ChunkedBufferTest::onRun() { + + typedef oatpp::data::stream::ChunkedBuffer ChunkedBuffer; + + { + ChunkedBuffer stream; + + stream << "int=" << 1 << ", float=" << 1.1 << ", " + << "bool=" << true << " or " << false; + + OATPP_LOGD(TAG, "str='%s'", stream.toString()->c_str()); + + stream.clear(); + stream << 101; + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(101)); + + stream.clear(); + stream << (v_float32)101.1; + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float32ToStr(101.1)); + + stream.clear(); + stream << (v_float64)101.1; + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float64ToStr(101.1)); + + stream.clear(); + stream << true; + OATPP_ASSERT(stream.toString() == "true"); + + stream.clear(); + stream << false; + OATPP_ASSERT(stream.toString() == "false"); + + stream.clear(); + stream << oatpp::String("oat++"); + OATPP_ASSERT(stream.toString() == "oat++"); + + stream.clear(); + stream << oatpp::Int8(8); + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(8)); + + stream.clear(); + stream << oatpp::Int16(16); + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(16)); + + stream.clear(); + stream << oatpp::Int32(32); + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(32)); + + stream.clear(); + stream << oatpp::Int64(64); + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(64)); + + stream.clear(); + stream << oatpp::Float32(0.32); + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float32ToStr(0.32)); + + stream.clear(); + stream << oatpp::Float64(0.64); + OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float64ToStr(0.64)); + + stream.clear(); + stream << oatpp::Boolean(true); + OATPP_ASSERT(stream.toString() == "true"); + + stream.clear(); + stream << oatpp::Boolean(false); + OATPP_ASSERT(stream.toString() == "false"); + + } + + { + + ChunkedBuffer stream; + + for(v_int32 i = 0; i < ChunkedBuffer::CHUNK_ENTRY_SIZE * 10; i++) { + stream.write("0123456789", 10); + } + + auto wholeText = stream.toString(); + + OATPP_ASSERT(wholeText->getSize() == ChunkedBuffer::CHUNK_ENTRY_SIZE * 10 * 10); + + v_int32 substringSize = 10; + for(v_int32 i = 0; i < wholeText->getSize() - substringSize; i ++) { + OATPP_ASSERT(oatpp::String((const char*)&wholeText->getData()[i], substringSize, false) == stream.getSubstring(i, substringSize)); + } + + substringSize = ChunkedBuffer::CHUNK_ENTRY_SIZE * 2; + for(v_int32 i = 0; i < wholeText->getSize() - substringSize; i ++) { + OATPP_ASSERT(oatpp::String((const char*)&wholeText->getData()[i], substringSize, false) == stream.getSubstring(i, substringSize)); + } + + } + + +} + +}}}}} \ No newline at end of file diff --git a/test/oatpp/core/data/stream/ChunkedBufferTest.hpp b/test/oatpp/core/data/stream/ChunkedBufferTest.hpp new file mode 100644 index 00000000..efabbb70 --- /dev/null +++ b/test/oatpp/core/data/stream/ChunkedBufferTest.hpp @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Project _____ __ ____ _ _ + * ( _ ) /__\ (_ _)_| |_ _| |_ + * )(_)( /(__)\ )( (_ _)(_ _) + * (_____)(__)(__)(__) |_| |_| + * + * + * Copyright 2018-present, Leonid Stryzhevskyi + * + * 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_test_core_data_stream_ChunkedBufferTest_hpp +#define oatpp_test_core_data_stream_ChunkedBufferTest_hpp + +#include "oatpp-test/UnitTest.hpp" + +namespace oatpp { namespace test { namespace core { namespace data { namespace stream { + +class ChunkedBufferTest : public UnitTest{ +public: + + ChunkedBufferTest():UnitTest("TEST[core::data::stream::ChunkedBufferTest]"){} + void onRun() override; + +}; + +}}}}} + + +#endif //oatpp_test_core_data_stream_ChunkedBufferTest_hpp