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