diff options
author | Roger Leigh <rleigh@debian.org> | 2006-06-24 18:23:24 +0000 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2006-06-24 18:23:24 +0000 |
commit | e62d95e0dc28f5218f1993096091af367a6bdab8 (patch) | |
tree | dc8d70fe948386ab67f078a57ec7b594dd4eab13 /sbuild/sbuild-util.cc | |
parent | 89bae29a6d45262a08f4e6cf5e97c040aba18297 (diff) | |
download | schroot-e62d95e0dc28f5218f1993096091af367a6bdab8.tar.gz |
* sbuild/sbuild-format-detail.h: Use a wide string to get
consistent alignment when using a UTF-8 locale.
* sbuild/sbuild-util.cc
(widen_string): New function. Convert a narrow string to a wide
string.
(narrow_string): New function. Convert a wide string to a narrow
string.
Diffstat (limited to 'sbuild/sbuild-util.cc')
-rw-r--r-- | sbuild/sbuild-util.cc | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/sbuild/sbuild-util.cc b/sbuild/sbuild-util.cc index 58aeff51..3a4200b8 100644 --- a/sbuild/sbuild-util.cc +++ b/sbuild/sbuild-util.cc @@ -163,6 +163,96 @@ sbuild::split_string (std::string const& value, return ret; } +std::wstring +sbuild::widen_string (std::string const& str, + std::locale locale) +{ + typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_type; + codecvt_type const& cvt = std::use_facet<codecvt_type>(locale); + mbstate_t state; + const char *cbegin = str.data(), *cend = str.data() + str.size(), *cnext; + wchar_t *wcnext; + wchar_t wcbuf[80]; + std::wstring ret; + + std::memset(&state, 0, sizeof(mbstate_t)); + + while (1) + { + std::codecvt_base::result res = + cvt.in(state, + cbegin, cend, cnext, + wcbuf, wcbuf + (sizeof(wcbuf) / sizeof(wcbuf[0])), wcnext); + + if (res == std::codecvt_base::ok || std::codecvt_base::partial) + { + ret += std::wstring(wcbuf, wcnext); + if (cend == cnext) + break; + } + else if (res == std::codecvt_base::noconv) + { + ret += std::wstring(cbegin, cend); + break; + } + else if (res == std::codecvt_base::error) + { + break; + } + else + break; + + cbegin = cnext; + } + + return ret; +} + +std::string +sbuild::narrow_string (std::wstring const& str, + std::locale locale) +{ + typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_type; + codecvt_type const& cvt = std::use_facet<codecvt_type>(locale); + mbstate_t state; + const wchar_t *wcbegin = str.data(), *wcend = str.data() + str.size(), *wcnext; + char *cnext; + char cbuf[80]; + std::string ret; + + std::memset(&state, 0, sizeof(mbstate_t)); + + while (1) + { + std::codecvt_base::result res = + cvt.out(state, + wcbegin, wcend, wcnext, + cbuf, cbuf + (sizeof(cbuf) / sizeof(cbuf[0])), cnext); + + if (res == std::codecvt_base::ok || std::codecvt_base::partial) + { + ret += std::string(cbuf, cnext); + if (wcend == wcnext) + break; + } + else if (res == std::codecvt_base::noconv) + { + ret += std::string(wcbegin, wcend); + break; + } + else if (res == std::codecvt_base::error) + { + break; + } + else + break; + + wcbegin = wcnext; + } + + return ret; +} + std::string sbuild::find_program_in_path (std::string const& program, std::string const& path, |