• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //
2  //  Copyright (c) 2015 Artyom Beilis (Tonkikh)
3  //
4  //  Distributed under the Boost Software License, Version 1.0. (See
5  //  accompanying file LICENSE or copy at
6  //  http://www.boost.org/LICENSE_1_0.txt)
7  //
8  
9  #include <boost/nowide/iostream.hpp>
10  
11  #include <boost/nowide/utf/utf.hpp>
12  #include <limits>
13  #include <string>
14  
15  #include "test.hpp"
16  
isValidUTF8(const std::string & s)17  bool isValidUTF8(const std::string& s)
18  {
19      using namespace boost::nowide::utf;
20      for(std::string::const_iterator it = s.begin(); it != s.end();)
21      {
22          code_point c = utf_traits<char>::decode(it, s.end());
23          if(!is_valid_codepoint(c))
24              return false;
25      }
26      return true;
27  }
28  
test_main(int argc,char ** argv,char **)29  void test_main(int argc, char** argv, char**)
30  {
31      const char* example = "Basic letters: \xd7\xa9-\xd0\xbc-\xce\xbd\n"
32                            "East Asian Letters: \xe5\x92\x8c\xe5\xb9\xb3\n"
33                            "Non-BMP letters: \xf0\x9d\x84\x9e\n"
34                            "Invalid UTF-8: `\xFF' `\xd7\xFF' `\xe5\xFF\x8c' `\xf0\x9d\x84\xFF' \n"
35                            "\n";
36  
37      // If we are using the standard rdbuf we can only put back 1 char
38      if(boost::nowide::cin.rdbuf() == std::cin.rdbuf())
39      {
40          std::cout << "Using std::cin" << std::endl;
41          int maxval = 15000;
42          for(int i = 0; i < maxval; i++)
43          {
44              char c = i % 96 + ' ';
45              TEST(boost::nowide::cin.putback(c));
46              int ci = i % 96 + ' ';
47              TEST(boost::nowide::cin.get() == ci);
48          }
49      } else
50      {
51          int maxval = 15000;
52          for(int i = 0; i < maxval; i++)
53          {
54              char c = i % 96 + ' ';
55              TEST(boost::nowide::cin.putback(c));
56          }
57          for(int i = maxval - 1; i >= 0; i--)
58          {
59              int c = i % 96 + ' ';
60              TEST(boost::nowide::cin.get() == c);
61          }
62      }
63      boost::nowide::cout << "Normal I/O:" << std::endl;
64      boost::nowide::cout << example << std::endl;
65      boost::nowide::cerr << example << std::endl;
66  
67      boost::nowide::cout << "Flushing each character:" << std::endl;
68  
69      for(const char* s = example; *s; s++)
70      {
71          boost::nowide::cout << *s << std::flush;
72          TEST(boost::nowide::cout);
73      }
74  
75      TEST(boost::nowide::cout);
76      TEST(boost::nowide::cerr);
77      if(argc == 2 && argv[1] == std::string("-i"))
78      {
79          boost::nowide::cout << "Input 2 strings" << std::endl;
80          std::string v1, v2;
81          boost::nowide::cin >> v1 >> v2;
82          TEST(boost::nowide::cin);
83          TEST(isValidUTF8(v1));
84          TEST(isValidUTF8(v2));
85          boost::nowide::cout << "First:  " << v1 << std::endl;
86          boost::nowide::cout << "Second: " << v2 << std::endl;
87          TEST(boost::nowide::cout);
88  
89          // Check sync
90          boost::nowide::cout << "Input 2 strings\n";
91          boost::nowide::cout.flush();
92          TEST(boost::nowide::cin >> v1);
93          boost::nowide::cin.sync();
94          boost::nowide::cout << "First:  " << v1 << std::endl;
95          boost::nowide::cout << "2nd string should be ignored. Input 1 more + [ENTER]" << std::endl;
96          // And check getline not getting the CR
97          TEST(std::getline(boost::nowide::cin, v1));
98          TEST(!v1.empty() && v1[v1.size() - 1u] != '\r');
99          boost::nowide::cout << "Value:  " << v1 << std::endl;
100  
101          boost::nowide::cout << "Press ENTER to exit";
102          boost::nowide::cin.clear();
103          boost::nowide::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
104          boost::nowide::cin.get();
105      }
106  }
107