istreamwrappertest.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. #ifdef _MSC_VER
  21. RAPIDJSON_DIAG_PUSH
  22. RAPIDJSON_DIAG_OFF(4702) // unreachable code
  23. #endif
  24. using namespace rapidjson;
  25. using namespace std;
  26. template <typename StringStreamType>
  27. static void TestStringStream() {
  28. typedef typename StringStreamType::char_type Ch;
  29. {
  30. StringStreamType iss;
  31. BasicIStreamWrapper<StringStreamType> is(iss);
  32. EXPECT_EQ(0, is.Tell());
  33. if (sizeof(Ch) == 1) {
  34. EXPECT_EQ(0, is.Peek4());
  35. EXPECT_EQ(0, is.Tell());
  36. }
  37. EXPECT_EQ(0, is.Peek());
  38. EXPECT_EQ(0, is.Take());
  39. EXPECT_EQ(0, is.Tell());
  40. }
  41. {
  42. Ch s[] = { 'A', 'B', 'C', '\0' };
  43. StringStreamType iss(s);
  44. BasicIStreamWrapper<StringStreamType> is(iss);
  45. EXPECT_EQ(0, is.Tell());
  46. if (sizeof(Ch) == 1) {
  47. EXPECT_EQ(0, is.Peek4()); // less than 4 bytes
  48. }
  49. for (int i = 0; i < 3; i++) {
  50. EXPECT_EQ(static_cast<size_t>(i), is.Tell());
  51. EXPECT_EQ('A' + i, is.Peek());
  52. EXPECT_EQ('A' + i, is.Peek());
  53. EXPECT_EQ('A' + i, is.Take());
  54. }
  55. EXPECT_EQ(3, is.Tell());
  56. EXPECT_EQ(0, is.Peek());
  57. EXPECT_EQ(0, is.Take());
  58. }
  59. {
  60. Ch s[] = { 'A', 'B', 'C', 'D', 'E', '\0' };
  61. StringStreamType iss(s);
  62. BasicIStreamWrapper<StringStreamType> is(iss);
  63. if (sizeof(Ch) == 1) {
  64. const Ch* c = is.Peek4();
  65. for (int i = 0; i < 4; i++)
  66. EXPECT_EQ('A' + i, c[i]);
  67. EXPECT_EQ(0, is.Tell());
  68. }
  69. for (int i = 0; i < 5; i++) {
  70. EXPECT_EQ(static_cast<size_t>(i), is.Tell());
  71. EXPECT_EQ('A' + i, is.Peek());
  72. EXPECT_EQ('A' + i, is.Peek());
  73. EXPECT_EQ('A' + i, is.Take());
  74. }
  75. EXPECT_EQ(5, is.Tell());
  76. EXPECT_EQ(0, is.Peek());
  77. EXPECT_EQ(0, is.Take());
  78. }
  79. }
  80. TEST(IStreamWrapper, istringstream) {
  81. TestStringStream<istringstream>();
  82. }
  83. TEST(IStreamWrapper, stringstream) {
  84. TestStringStream<stringstream>();
  85. }
  86. TEST(IStreamWrapper, wistringstream) {
  87. TestStringStream<wistringstream>();
  88. }
  89. TEST(IStreamWrapper, wstringstream) {
  90. TestStringStream<wstringstream>();
  91. }
  92. template <typename FileStreamType>
  93. static bool Open(FileStreamType& fs, const char* filename) {
  94. const char *paths[] = {
  95. "encodings",
  96. "bin/encodings",
  97. "../bin/encodings",
  98. "../../bin/encodings",
  99. "../../../bin/encodings"
  100. };
  101. char buffer[1024];
  102. for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
  103. sprintf(buffer, "%s/%s", paths[i], filename);
  104. fs.open(buffer, ios_base::in | ios_base::binary);
  105. if (fs.is_open())
  106. return true;
  107. }
  108. return false;
  109. }
  110. TEST(IStreamWrapper, ifstream) {
  111. ifstream ifs;
  112. ASSERT_TRUE(Open(ifs, "utf8bom.json"));
  113. IStreamWrapper isw(ifs);
  114. EncodedInputStream<UTF8<>, IStreamWrapper> eis(isw);
  115. Document d;
  116. EXPECT_TRUE(!d.ParseStream(eis).HasParseError());
  117. EXPECT_TRUE(d.IsObject());
  118. EXPECT_EQ(5, d.MemberCount());
  119. }
  120. TEST(IStreamWrapper, fstream) {
  121. fstream fs;
  122. ASSERT_TRUE(Open(fs, "utf8bom.json"));
  123. IStreamWrapper isw(fs);
  124. EncodedInputStream<UTF8<>, IStreamWrapper> eis(isw);
  125. Document d;
  126. EXPECT_TRUE(!d.ParseStream(eis).HasParseError());
  127. EXPECT_TRUE(d.IsObject());
  128. EXPECT_EQ(5, d.MemberCount());
  129. }
  130. // wifstream/wfstream only works on C++11 with codecvt_utf16
  131. // But many C++11 library still not have it.
  132. #if 0
  133. #include <codecvt>
  134. TEST(IStreamWrapper, wifstream) {
  135. wifstream ifs;
  136. ASSERT_TRUE(Open(ifs, "utf16bebom.json"));
  137. ifs.imbue(std::locale(ifs.getloc(),
  138. new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
  139. WIStreamWrapper isw(ifs);
  140. GenericDocument<UTF16<> > d;
  141. d.ParseStream<kParseDefaultFlags, UTF16<>, WIStreamWrapper>(isw);
  142. EXPECT_TRUE(!d.HasParseError());
  143. EXPECT_TRUE(d.IsObject());
  144. EXPECT_EQ(5, d.MemberCount());
  145. }
  146. TEST(IStreamWrapper, wfstream) {
  147. wfstream fs;
  148. ASSERT_TRUE(Open(fs, "utf16bebom.json"));
  149. fs.imbue(std::locale(fs.getloc(),
  150. new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
  151. WIStreamWrapper isw(fs);
  152. GenericDocument<UTF16<> > d;
  153. d.ParseStream<kParseDefaultFlags, UTF16<>, WIStreamWrapper>(isw);
  154. EXPECT_TRUE(!d.HasParseError());
  155. EXPECT_TRUE(d.IsObject());
  156. EXPECT_EQ(5, d.MemberCount());
  157. }
  158. #endif
  159. #ifdef _MSC_VER
  160. RAPIDJSON_DIAG_POP
  161. #endif