// 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/istreamwrapper.h" #include "rapidjson/encodedstream.h" #include "rapidjson/document.h" #include #include #if defined(_MSC_VER) && !defined(__clang__) RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_OFF(4702) // unreachable code #endif using namespace rapidjson; using namespace std; template static void TestStringStream() { typedef typename StringStreamType::char_type Ch; { StringStreamType iss; BasicIStreamWrapper is(iss); EXPECT_EQ(0u, is.Tell()); if (sizeof(Ch) == 1) { EXPECT_EQ(0, is.Peek4()); EXPECT_EQ(0u, is.Tell()); } EXPECT_EQ(0, is.Peek()); EXPECT_EQ(0, is.Take()); EXPECT_EQ(0u, is.Tell()); } { Ch s[] = { 'A', 'B', 'C', '\0' }; StringStreamType iss(s); BasicIStreamWrapper is(iss); EXPECT_EQ(0u, is.Tell()); if (sizeof(Ch) == 1) { EXPECT_EQ(0, is.Peek4()); // less than 4 bytes } for (int i = 0; i < 3; i++) { EXPECT_EQ(static_cast(i), is.Tell()); EXPECT_EQ('A' + i, is.Peek()); EXPECT_EQ('A' + i, is.Peek()); EXPECT_EQ('A' + i, is.Take()); } EXPECT_EQ(3u, is.Tell()); EXPECT_EQ(0, is.Peek()); EXPECT_EQ(0, is.Take()); } { Ch s[] = { 'A', 'B', 'C', 'D', 'E', '\0' }; StringStreamType iss(s); BasicIStreamWrapper is(iss); if (sizeof(Ch) == 1) { const Ch* c = is.Peek4(); for (int i = 0; i < 4; i++) EXPECT_EQ('A' + i, c[i]); EXPECT_EQ(0u, is.Tell()); } for (int i = 0; i < 5; i++) { EXPECT_EQ(static_cast(i), is.Tell()); EXPECT_EQ('A' + i, is.Peek()); EXPECT_EQ('A' + i, is.Peek()); EXPECT_EQ('A' + i, is.Take()); } EXPECT_EQ(5u, is.Tell()); EXPECT_EQ(0, is.Peek()); EXPECT_EQ(0, is.Take()); } } TEST(IStreamWrapper, istringstream) { TestStringStream(); } TEST(IStreamWrapper, stringstream) { TestStringStream(); } TEST(IStreamWrapper, wistringstream) { TestStringStream(); } TEST(IStreamWrapper, wstringstream) { TestStringStream(); } template static bool Open(FileStreamType& fs, const char* filename) { const char *paths[] = { "encodings", "bin/encodings", "../bin/encodings", "../../bin/encodings", "../../../bin/encodings" }; char buffer[1024]; for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { sprintf(buffer, "%s/%s", paths[i], filename); fs.open(buffer, ios_base::in | ios_base::binary); if (fs.is_open()) return true; } return false; } TEST(IStreamWrapper, ifstream) { ifstream ifs; ASSERT_TRUE(Open(ifs, "utf8bom.json")); IStreamWrapper isw(ifs); EncodedInputStream, IStreamWrapper> eis(isw); Document d; EXPECT_TRUE(!d.ParseStream(eis).HasParseError()); EXPECT_TRUE(d.IsObject()); EXPECT_EQ(5u, d.MemberCount()); } TEST(IStreamWrapper, fstream) { fstream fs; ASSERT_TRUE(Open(fs, "utf8bom.json")); IStreamWrapper isw(fs); EncodedInputStream, IStreamWrapper> eis(isw); Document d; EXPECT_TRUE(!d.ParseStream(eis).HasParseError()); EXPECT_TRUE(d.IsObject()); EXPECT_EQ(5u, d.MemberCount()); } // wifstream/wfstream only works on C++11 with codecvt_utf16 // But many C++11 library still not have it. #if 0 #include TEST(IStreamWrapper, wifstream) { wifstream ifs; ASSERT_TRUE(Open(ifs, "utf16bebom.json")); ifs.imbue(std::locale(ifs.getloc(), new std::codecvt_utf16)); WIStreamWrapper isw(ifs); GenericDocument > d; d.ParseStream, WIStreamWrapper>(isw); EXPECT_TRUE(!d.HasParseError()); EXPECT_TRUE(d.IsObject()); EXPECT_EQ(5, d.MemberCount()); } TEST(IStreamWrapper, wfstream) { wfstream fs; ASSERT_TRUE(Open(fs, "utf16bebom.json")); fs.imbue(std::locale(fs.getloc(), new std::codecvt_utf16)); WIStreamWrapper isw(fs); GenericDocument > d; d.ParseStream, WIStreamWrapper>(isw); EXPECT_TRUE(!d.HasParseError()); EXPECT_TRUE(d.IsObject()); EXPECT_EQ(5, d.MemberCount()); } #endif #if defined(_MSC_VER) && !defined(__clang__) RAPIDJSON_DIAG_POP #endif