Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed|libcore|String: Reverse-iterating a multibyte string
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent 2df3250 commit 0ed1262
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
12 changes: 6 additions & 6 deletions doomsday/libs/core/include/de/data/string.h
Expand Up @@ -58,21 +58,21 @@ struct DE_PUBLIC Sensitivity
};

enum PositionType { ByteOffset, CharacterOffset };

template <PositionType PosType>
struct StronglyTypedPosition
{
dsize index;

using Pos = StronglyTypedPosition<PosType>;

static constexpr PositionType type = PosType;
static constexpr dsize npos = std::numeric_limits<dsize>::max();

explicit constexpr StronglyTypedPosition(dsize i = npos)
: index(i)
{}

explicit operator bool() const { return index != npos; }

inline bool operator==(dsize i) const { return index == i; }
Expand Down Expand Up @@ -101,14 +101,14 @@ struct StronglyTypedPosition
Pos &operator++() { if (index != npos) index++; return *this; }
Pos &operator--() { if (index != npos) index--; return *this; }
};

using BytePos = StronglyTypedPosition<ByteOffset>;

/**
* Character index. A single character may be composed of multiple bytes.
*/
using CharPos = StronglyTypedPosition<CharacterOffset>;

/**
* Multibyte character iterator.
*/
Expand Down Expand Up @@ -144,7 +144,7 @@ struct DE_PUBLIC mb_iterator
BytePos pos(const char *reference) const { return BytePos(i - reference); }
BytePos pos(const String &reference) const;

Char decode() const;
Char decode(bool *ok = nullptr) const;
};

/**
Expand Down
13 changes: 10 additions & 3 deletions doomsday/libs/core/src/data/string.cpp
Expand Up @@ -1102,7 +1102,7 @@ String String::fromPercentEncoding(const Block &percentEncoded) // static
}

//------------------------------------------------------------------------------------------------

String::const_reverse_iterator::const_reverse_iterator(const Range<const char *> &range)
: iter(range.end, range.start)
{
Expand Down Expand Up @@ -1133,7 +1133,7 @@ Char mb_iterator::operator*() const
return decode();
}

Char mb_iterator::decode() const
Char mb_iterator::decode(bool *ok) const
{
wchar_t ch = 0;
curCharLen = std::mbrtowc(&ch, i, MB_CUR_MAX, &mb);
Expand All @@ -1143,6 +1143,11 @@ Char mb_iterator::decode() const
// doesn't hang due to never reaching the end of the string.
ch = '?';
curCharLen = 1;
if (ok) *ok = false;
}
else
{
if (ok) *ok = true;
}
return ch;
}
Expand Down Expand Up @@ -1173,7 +1178,9 @@ mb_iterator &mb_iterator::operator--()
for (int j = 1; j < MB_CUR_MAX; ++j)
{
mb_iterator prec = i - j;
if (prec.decode() != 0 && prec.curCharLen == j)
bool ok;
prec.decode(&ok);
if (ok) // && prec.curCharLen == j)
{
prec.start = start;
*this = prec;
Expand Down

0 comments on commit 0ed1262

Please sign in to comment.