const std::wstring s2ws(const std::string& src) { std::locale sys_locale(""); const char* data_from = src.c_str(); const char* data_from_end = src.c_str() + src.size(); const char* data_from_next = 0; wchar_t* data_to = new wchar_t[src.size() + 1]; wchar_t* data_to_end = data_to + src.size() + 1; wchar_t* data_to_next = 0; wmemset(data_to, 0, src.size() + 1); typedef std::codecvt<wchar_t, char, mbstate_t> convert_facet; mbstate_t in_state = 0; auto result = std::use_facet<convert_facet>(sys_locale).in( in_state, data_from, data_from_end, data_from_next, data_to, data_to_end, data_to_next); if (result == convert_facet::ok) { std::wstring dst = data_to; delete[] data_to; return dst; } else { printf("convert error!\n"); delete[] data_to; return std::wstring(L""); } }
bool WideStringToString(const std::wstring& src,std::string &str) { std::locale sys_locale(""); const wchar_t* data_from = src.c_str(); const wchar_t* data_from_end = src.c_str() + src.size(); const wchar_t* data_from_next = 0; int wchar_size = 4; char* data_to = new char[(src.size() + 1) * wchar_size]; char* data_to_end = data_to + (src.size() + 1) * wchar_size; char* data_to_next = 0; memset( data_to, 0, (src.size() + 1) * wchar_size ); typedef std::codecvt<wchar_t, char, mbstate_t> convert_facet; mbstate_t out_state = {0}; auto result = std::use_facet<convert_facet>(sys_locale).out( out_state, data_from, data_from_end, data_from_next, data_to, data_to_end, data_to_next ); if( result == convert_facet::ok) { str = data_to; delete[] data_to; return true; } delete[] data_to; return false; }
const std::string ws2s(const std::wstring& src) { std::locale sys_locale(""); const wchar_t* data_from = src.c_str(); const wchar_t* data_from_end = src.c_str() + src.size(); const wchar_t* data_from_next = 0; int wchar_size = 4; char* data_to = new char[(src.size() + 1) * wchar_size]; char* data_to_end = data_to + (src.size() + 1) * wchar_size; char* data_to_next = 0; memset(data_to, 0, (src.size() + 1) * wchar_size); typedef std::codecvt<wchar_t, char, mbstate_t> convert_facet; mbstate_t out_state = 0; auto result = std::use_facet<convert_facet>(sys_locale).out( out_state, data_from, data_from_end, data_from_next, data_to, data_to_end, data_to_next); if (result == convert_facet::ok) { std::string dst = data_to; delete[] data_to; return dst; } else { printf("convert error!\n"); delete[] data_to; return std::string(""); } }
bool StringToWideString( const std::string& src,std::wstring &wstr) { std::locale sys_locale(""); const char* data_from = src.c_str(); const char* data_from_end = src.c_str() + src.size(); const char* data_from_next = 0; wchar_t* data_to = new wchar_t[src.size() + 1]; wchar_t* data_to_end = data_to + src.size() + 1; wchar_t* data_to_next = 0; wmemset( data_to, 0, src.size() + 1 ); typedef std::codecvt<wchar_t, char, mbstate_t> convert_facet; mbstate_t in_state = {0}; auto result = std::use_facet<convert_facet>(sys_locale).in( in_state, data_from, data_from_end, data_from_next, data_to, data_to_end, data_to_next ); if( result == convert_facet::ok ) { wstr = data_to; delete[] data_to; return true; } delete[] data_to; return false; }
int main(int argc, char* argv[]) #endif { try { #if defined(WIN32) std::locale console_locale("Russian_Russia.866"); std::wcout.imbue(console_locale); std::wcerr.imbue(console_locale); std::locale sys_locale(""); #endif if (2 > argc || 4 < argc) { print_usage(); return EXIT_FAILURE; } std::size_t cpu_count = boost::thread::hardware_concurrency(); std::size_t concurrent_count = 2 > cpu_count ? 2 : cpu_count; std::size_t thread_count = 2; std::cout << "Number of found CPUs : " << cpu_count << std::endl << "Number of concurrent work threads: " << concurrent_count << std::endl << "Total number of work threads : " << thread_count << std::endl; #if defined(WIN32) std::wstring wide_device_name(argv[1]); const wcodecvt_type& wcodecvt(std::use_facet<wcodecvt_type>(sys_locale)); std::string device_name(ma::codecvt_cast::out(wide_device_name, wcodecvt)); #else std::string device_name(argv[1]); #endif std::size_t read_buffer_size = std::max<std::size_t>(1024, session::min_read_buffer_size); std::size_t message_queue_size = std::max<std::size_t>(64, session::min_message_queue_size); if (argc > 2) { try { read_buffer_size = boost::lexical_cast<std::size_t>(argv[2]); if (3 < argc) { message_queue_size = boost::lexical_cast<std::size_t>(argv[3]); } } catch (const boost::bad_lexical_cast& e) { std::cerr << L"Invalid parameter value/format: " << e.what() << std::endl; print_usage(); return EXIT_FAILURE; } catch (const std::exception& e) { std::cerr << "Unexpected error during parameters parsing: " << e.what() << std::endl; print_usage(); return EXIT_FAILURE; } } // if (argc > 2) #if defined(WIN32) std::wcout << L"NMEA 0183 device serial port: " << wide_device_name << std::endl << L"Read buffer size (bytes) : " << read_buffer_size << std::endl << L"Read buffer size (messages) : " << message_queue_size << std::endl; #else std::cout << "NMEA 0183 device serial port: " << device_name << std::endl << "Read buffer size (bytes) : " << read_buffer_size << std::endl << "Read buffer size (messages) : " << message_queue_size << std::endl; #endif // defined(WIN32) handler_allocator_type the_allocator; frame_buffer_ptr the_frame_buffer( boost::make_shared<frame_buffer_type>(message_queue_size)); // An io_service for the thread pool // (for the executors... Java Executors API? Apache MINA :) boost::asio::io_service session_io_service(concurrent_count); session_ptr the_session(session::create(session_io_service, read_buffer_size, message_queue_size, "$", "\x0a")); // Prepare the lower layer - open the serial port boost::system::error_code error; the_session->serial_port().open(device_name, error); if (error) { #if defined(WIN32) std::wstring error_message = ma::codecvt_cast::in(error.message(), wcodecvt); std::wcerr << L"Failed to open serial port: " << error_message << std::endl; #else std::cerr << "Failed to open serial port: " << error.message() << std::endl; #endif // defined(WIN32) return EXIT_FAILURE; } // Start session (not actually, because there are no work threads yet) the_session->async_start(ma::make_custom_alloc_handler(the_allocator, boost::bind(handle_start, the_session, boost::ref(the_allocator), the_frame_buffer, _1))); // Setup console controller ma::console_controller console_controller( boost::bind(handle_console_close, the_session)); std::cout << "Press Ctrl+C (Ctrl+Break) to exit...\n"; // Create work threads boost::thread_group work_threads; for (std::size_t i = 0; i != thread_count; ++i) { work_threads.create_thread( boost::bind(&boost::asio::io_service::run, &session_io_service)); } work_threads.join_all(); std::cout << "Work threads are stopped.\n"; return EXIT_SUCCESS; } catch (const std::exception& e) { std::cerr << "Unexpected error: " << e.what() << std::endl; } catch (...) { std::cerr << "Unknown exception" << std::endl; } return EXIT_FAILURE; }