diff --git a/include/rapidjson/ostreamwrapper.h b/include/rapidjson/ostreamwrapper.h new file mode 100644 index 0000000..4cf407e --- /dev/null +++ b/include/rapidjson/ostreamwrapper.h @@ -0,0 +1,69 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// 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 "stream.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::ostringstream + - \c std::stringstream + - \c std::wpstringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wofstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_ostream. +*/ + +template +class OStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + OStreamWrapper(StreamType& stream) : stream_(stream) {} + + void Put(Ch c) { + stream_.put(c); + } + + void Flush() { + stream_.flush(); + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + StreamType& stream_; +}; + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END diff --git a/test/unittest/CMakeLists.txt b/test/unittest/CMakeLists.txt index 728ccf1..9c13816 100644 --- a/test/unittest/CMakeLists.txt +++ b/test/unittest/CMakeLists.txt @@ -12,6 +12,7 @@ set(UNITTEST_SOURCES namespacetest.cpp pointertest.cpp prettywritertest.cpp + ostreamwrappertest.cpp readertest.cpp regextest.cpp schematest.cpp diff --git a/test/unittest/ostreamwrappertest.cpp b/test/unittest/ostreamwrappertest.cpp new file mode 100644 index 0000000..ba231bd --- /dev/null +++ b/test/unittest/ostreamwrappertest.cpp @@ -0,0 +1,91 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// 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 "unittest.h" + +#include "rapidjson/ostreamwrapper.h" +#include "rapidjson/encodedstream.h" +#include "rapidjson/document.h" +#include +#include + +using namespace rapidjson; +using namespace std; + +template +static void TestStringStream() { + typedef typename StringStreamType::char_type Ch; + + Ch s[] = { 'A', 'B', 'C' }; + StringStreamType oss(s); + OStreamWrapper os(oss); + for (size_t i = 0; i < 3; i++) + os.Put(s[i]); + os.Flush(); + for (size_t i = 0; i < 3; i++) + EXPECT_EQ(s[i], oss.str()[i]); +} + +TEST(OStreamWrapper, ostringstream) { + TestStringStream(); +} + +TEST(OStreamWrapper, stringstream) { + TestStringStream(); +} + +TEST(OStreamWrapper, wostringstream) { + TestStringStream(); +} + +TEST(OStreamWrapper, wstringstream) { + TestStringStream(); +} + +TEST(OStreamWrapper, cout) { + OStreamWrapper os(cout); + const char* s = "Hello World!\n"; + while (*s) + os.Put(*s++); + os.Flush(); +} + +template +static void TestFileStream() { + char filename[L_tmpnam]; + FILE* fp = TempFile(filename); + fclose(fp); + + const char* s = "Hello World!\n"; + { + ofstream ofs(filename, ios::out | ios::binary); + OStreamWrapper osw(ofs); + for (const char* p = s; *p; p++) + osw.Put(*p); + osw.Flush(); + } + + fp = fopen(filename, "r"); + for (const char* p = s; *p; p++) + EXPECT_EQ(*p, static_cast(fgetc(fp))); + fclose(fp); +} + +TEST(OStreamWrapper, ofstream) { + TestFileStream(); +} + +TEST(OStreamWrapper, fstream) { + TestFileStream(); +}