istreamwrappertest.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Tencent is pleased to support the open source community by making RapidJSON available.
  2. //
  3. // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
  4. //
  5. // Licensed under the MIT License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://opensource.org/licenses/MIT
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include "unittest.h"
  15. #include "rapidjson/istreamwrapper.h"
  16. #include "rapidjson/encodedstream.h"
  17. #include "rapidjson/document.h"
  18. #include <sstream>
  19. #include <fstream>
  20. using namespace rapidjson;
  21. using namespace std;
  22. template <typename StringStreamType>
  23. static void TestStringStream() {
  24. typedef typename StringStreamType::char_type Ch;
  25. {
  26. StringStreamType iss;
  27. BasicIStreamWrapper<StringStreamType> is(iss);
  28. EXPECT_EQ(0, is.Tell());
  29. if (sizeof(Ch) == 1) {
  30. EXPECT_EQ(0, is.Peek4());
  31. EXPECT_EQ(0, is.Tell());
  32. }
  33. EXPECT_EQ(0, is.Peek());
  34. EXPECT_EQ(0, is.Take());
  35. EXPECT_EQ(0, is.Tell());
  36. }
  37. {
  38. Ch s[] = { 'A', 'B', 'C', '\0' };
  39. StringStreamType iss(s);
  40. BasicIStreamWrapper<StringStreamType> is(iss);
  41. EXPECT_EQ(0, is.Tell());
  42. if (sizeof(Ch) == 1)
  43. EXPECT_EQ(0, is.Peek4()); // less than 4 bytes
  44. for (int i = 0; i < 3; i++) {
  45. EXPECT_EQ(static_cast<size_t>(i), is.Tell());
  46. EXPECT_EQ('A' + i, is.Peek());
  47. EXPECT_EQ('A' + i, is.Peek());
  48. EXPECT_EQ('A' + i, is.Take());
  49. }
  50. EXPECT_EQ(3, is.Tell());
  51. EXPECT_EQ(0, is.Peek());
  52. EXPECT_EQ(0, is.Take());
  53. }
  54. {
  55. Ch s[] = { 'A', 'B', 'C', 'D', 'E', '\0' };
  56. StringStreamType iss(s);
  57. BasicIStreamWrapper<StringStreamType> is(iss);
  58. if (sizeof(Ch) == 1) {
  59. const Ch* c = is.Peek4();
  60. for (int i = 0; i < 4; i++)
  61. EXPECT_EQ('A' + i, c[i]);
  62. EXPECT_EQ(0, is.Tell());
  63. }
  64. for (int i = 0; i < 5; i++) {
  65. EXPECT_EQ(static_cast<size_t>(i), is.Tell());
  66. EXPECT_EQ('A' + i, is.Peek());
  67. EXPECT_EQ('A' + i, is.Peek());
  68. EXPECT_EQ('A' + i, is.Take());
  69. }
  70. EXPECT_EQ(5, is.Tell());
  71. EXPECT_EQ(0, is.Peek());
  72. EXPECT_EQ(0, is.Take());
  73. }
  74. }
  75. TEST(IStreamWrapper, istringstream) {
  76. TestStringStream<istringstream>();
  77. }
  78. TEST(IStreamWrapper, stringstream) {
  79. TestStringStream<stringstream>();
  80. }
  81. TEST(IStreamWrapper, wistringstream) {
  82. TestStringStream<wistringstream>();
  83. }
  84. TEST(IStreamWrapper, wstringstream) {
  85. TestStringStream<wstringstream>();
  86. }
  87. template <typename FileStreamType>
  88. static bool Open(FileStreamType& fs, const char* filename) {
  89. const char *paths[] = {
  90. "encodings",
  91. "bin/encodings",
  92. "../bin/encodings",
  93. "../../bin/encodings",
  94. "../../../bin/encodings"
  95. };
  96. char buffer[1024];
  97. for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
  98. sprintf(buffer, "%s/%s", paths[i], filename);
  99. fs.open(buffer, ios_base::in | ios_base::binary);
  100. if (fs.is_open())
  101. return true;
  102. }
  103. return false;
  104. }
  105. TEST(IStreamWrapper, ifstream) {
  106. ifstream ifs;
  107. ASSERT_TRUE(Open(ifs, "utf8bom.json"));
  108. IStreamWrapper isw(ifs);
  109. EncodedInputStream<UTF8<>, IStreamWrapper> eis(isw);
  110. Document d;
  111. EXPECT_TRUE(!d.ParseStream(eis).HasParseError());
  112. EXPECT_TRUE(d.IsObject());
  113. EXPECT_EQ(5, d.MemberCount());
  114. }
  115. TEST(IStreamWrapper, fstream) {
  116. fstream fs;
  117. ASSERT_TRUE(Open(fs, "utf8bom.json"));
  118. IStreamWrapper isw(fs);
  119. EncodedInputStream<UTF8<>, IStreamWrapper> eis(isw);
  120. Document d;
  121. EXPECT_TRUE(!d.ParseStream(eis).HasParseError());
  122. EXPECT_TRUE(d.IsObject());
  123. EXPECT_EQ(5, d.MemberCount());
  124. }
  125. // wifstream/wfstream only works on C++11 with codecvt_utf16
  126. // But many C++11 library still not have it.
  127. #if 0
  128. #include <codecvt>
  129. TEST(IStreamWrapper, wifstream) {
  130. wifstream ifs;
  131. ASSERT_TRUE(Open(ifs, "utf16bebom.json"));
  132. ifs.imbue(std::locale(ifs.getloc(),
  133. new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
  134. WIStreamWrapper isw(ifs);
  135. GenericDocument<UTF16<> > d;
  136. d.ParseStream<kParseDefaultFlags, UTF16<>, WIStreamWrapper>(isw);
  137. EXPECT_TRUE(!d.HasParseError());
  138. EXPECT_TRUE(d.IsObject());
  139. EXPECT_EQ(5, d.MemberCount());
  140. }
  141. TEST(IStreamWrapper, wfstream) {
  142. wfstream fs;
  143. ASSERT_TRUE(Open(fs, "utf16bebom.json"));
  144. fs.imbue(std::locale(fs.getloc(),
  145. new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
  146. WIStreamWrapper isw(fs);
  147. GenericDocument<UTF16<> > d;
  148. d.ParseStream<kParseDefaultFlags, UTF16<>, WIStreamWrapper>(isw);
  149. EXPECT_TRUE(!d.HasParseError());
  150. EXPECT_TRUE(d.IsObject());
  151. EXPECT_EQ(5, d.MemberCount());
  152. }
  153. #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS