only store the high surrogate, and use \0 to indicate its empty

This commit is contained in:
aG0aep6G 2018-04-23 23:04:46 +02:00
parent 2ab81bcbe7
commit bf1b4db8a3

View file

@ -2833,12 +2833,11 @@ is empty, throws an `Exception`. In case of an I/O error throws
int orientation_; int orientation_;
// A buffer for when we need to transcode. // A buffer for when we need to transcode.
wchar[2] rbuf16; wchar highSurrogate = '\0'; // '\0' indicates empty
size_t rbuf16Filled = 0; void highSurrogateShouldBeEmpty() @safe
void rbuf16ShouldBeEmpty() @safe
{ {
import std.utf : UTFException; import std.utf : UTFException;
if (rbuf16Filled > 0) if (highSurrogate != '\0')
throw new UTFException("unpaired surrogate UTF-16 value"); throw new UTFException("unpaired surrogate UTF-16 value");
} }
public: public:
@ -2864,7 +2863,7 @@ is empty, throws an `Exception`. In case of an I/O error throws
file_ = File.init; file_ = File.init;
/* Destroy file_ before possibly throwing. Else it wouldn't be /* Destroy file_ before possibly throwing. Else it wouldn't be
destroyed, and its reference count would be wrong. */ destroyed, and its reference count would be wrong. */
rbuf16ShouldBeEmpty(); highSurrogateShouldBeEmpty();
} }
this(this) @trusted this(this) @trusted
@ -2921,7 +2920,7 @@ is empty, throws an `Exception`. In case of an I/O error throws
static if (c.sizeof == 1) static if (c.sizeof == 1)
{ {
// simple char // simple char
rbuf16ShouldBeEmpty(); highSurrogateShouldBeEmpty();
if (orientation_ <= 0) trustedFPUTC(c, handle_); if (orientation_ <= 0) trustedFPUTC(c, handle_);
else trustedFPUTWC(c, handle_); else trustedFPUTWC(c, handle_);
} }
@ -2934,21 +2933,20 @@ is empty, throws an `Exception`. In case of an I/O error throws
{ {
if (c <= 0x7F) if (c <= 0x7F)
{ {
rbuf16ShouldBeEmpty(); highSurrogateShouldBeEmpty();
trustedFPUTC(c, handle_); trustedFPUTC(c, handle_);
} }
else if (0xD800 <= c && c <= 0xDBFF) // high surrogate else if (0xD800 <= c && c <= 0xDBFF) // high surrogate
{ {
rbuf16ShouldBeEmpty(); highSurrogateShouldBeEmpty();
rbuf16[0] = c; highSurrogate = c;
rbuf16Filled = 1;
} }
else // standalone or low surrogate else // standalone or low surrogate
{ {
rbuf16[rbuf16Filled] = c; immutable wchar[2] rbuf = [highSurrogate, c];
++rbuf16Filled; wstring str = rbuf[highSurrogate == '\0' ? 1 : 0 .. $];
wchar[] str = rbuf16[0 .. rbuf16Filled]; // Skipping the high surrogate when there's none.
rbuf16Filled = 0; highSurrogate = '\0';
immutable dchar d = decodeFront(str); immutable dchar d = decodeFront(str);
char[4] wbuf; char[4] wbuf;
immutable size = encode(wbuf, d); immutable size = encode(wbuf, d);
@ -2965,7 +2963,7 @@ is empty, throws an `Exception`. In case of an I/O error throws
{ {
import std.utf : encode; import std.utf : encode;
rbuf16ShouldBeEmpty(); highSurrogateShouldBeEmpty();
if (orientation_ <= 0) if (orientation_ <= 0)
{ {
if (c <= 0x7F) if (c <= 0x7F)