summaryrefslogtreecommitdiff
path: root/src/unistring.h
diff options
context:
space:
mode:
authorKuang-che Wu <kcwu@google.com>2020-06-06 12:43:46 +0800
committerMartin Michlmayr <tbm@cyrius.com>2021-01-17 10:31:00 +0800
commit2dae3bbedcdf55983d23fc90bb36111c7eb68fc7 (patch)
tree446f93d9c625f40828188f37b970e5f01fc2d368 /src/unistring.h
parent0e19e3fe51c2c056a91af48e4733aa13a840fdaa (diff)
downloadfork-ledger-2dae3bbedcdf55983d23fc90bb36111c7eb68fc7.tar.gz
fork-ledger-2dae3bbedcdf55983d23fc90bb36111c7eb68fc7.tar.bz2
fork-ledger-2dae3bbedcdf55983d23fc90bb36111c7eb68fc7.zip
format_t::truncate support wide characters
also add unit tests
Diffstat (limited to 'src/unistring.h')
-rw-r--r--src/unistring.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/unistring.h b/src/unistring.h
index 8cc4a9cd..87b2f904 100644
--- a/src/unistring.h
+++ b/src/unistring.h
@@ -111,6 +111,54 @@ public:
return utf8result;
}
+ std::string extract_by_width(std::string::size_type begin,
+ std::size_t len) const
+ {
+ std::string utf8result;
+ std::size_t this_width = width();
+ std::string::size_type this_len = length();
+
+ assert(begin <= this_width);
+ if (begin + len > this_width)
+ len = this_width - begin;
+
+ std::size_t pos = 0;
+ std::size_t begin_idx = 0, end_idx = 0;
+ std::size_t head = 0, tail = 0;
+ for (std::size_t idx = 0; idx < this_len; ++idx) {
+ std::size_t w = mk_wcwidth(utf32chars[idx]);
+
+ if (pos < begin) {
+ if (pos + w >= begin) {
+ head = std::min(pos + w, begin + len) - begin;
+ begin_idx = idx + 1;
+ }
+ } else if (pos < begin + len) {
+ if (pos + w > begin + len) {
+ tail = begin + len - pos;
+ end_idx = idx;
+ }
+ if (pos + w == begin + len) {
+ tail = 0;
+ end_idx = idx + 1;
+ }
+ }
+ pos += w;
+ }
+
+ utf8result += std::string(head, '.');
+
+ if (begin_idx < end_idx)
+ utf8::unchecked::utf32to8
+ (utf32chars.begin() + static_cast<std::string::difference_type>(begin_idx),
+ utf32chars.begin() + static_cast<std::string::difference_type>(end_idx),
+ std::back_inserter(utf8result));
+
+ utf8result += std::string(tail, '.');
+
+ return utf8result;
+ }
+
std::size_t find(const boost::uint32_t __s, std::size_t __pos = 0) const {
std::size_t idx = 0;
foreach (const boost::uint32_t& ch, utf32chars) {