diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | stream.c | 8 | ||||
-rw-r--r-- | tests/010/strstream.expected | 1 | ||||
-rw-r--r-- | tests/010/strstream.txr | 11 |
4 files changed, 39 insertions, 4 deletions
@@ -1,3 +1,26 @@ +2012-03-13 Kaz Kylheku <kaz@kylheku.com> + + * stream.c (string_out_byte_flush): Bugfix. Do not loop inside this + function. This must not flush out more than one character out of this + small buffer, except when we are flushing out the last data. + The correct operation is predicated on the assumption that + a complete character can be pulled out. That's why we move the + buffer to the front after consuming it, and do not automatically + flush until there are four bytes. + (string_out_put_string): We loop the call to string_out_byte_flush + here because when a request comes in to write a Unicode character, + we flush all the bytes, even if the tail of those bytes forms + an incomplete sequence that turns into U+DCxx codes. + (get_string_from_stream): Use the same loop termination test + as in string_out_put_string, for consistency. In that function + it is needed to prevent infinite looping in the case when + the string_out_put_string is being called from string_out_byte_flush + and is thus re-entering it. + + * tests/010/strstream.expected: New file. + + * tests/010/strstream.txr: New file. + 2012-03-12 Kaz Kylheku <kaz@kylheku.com> Implementing put_byte for string output stream. @@ -468,7 +468,7 @@ static val string_out_byte_flush(struct string_output *so, val stream) { val result = nil; - while (so->tail < so->head) { + if (so->tail < so->head) { wint_t ch = utf8_decode(&so->ud, string_out_byte_callback, (mem_t *) so); int remaining = so->head - so->tail; if (remaining != 0) @@ -480,7 +480,7 @@ static val string_out_byte_flush(struct string_output *so, val stream) result = string_out_put_char(stream, chr(ch)); so->tail = 0; } - return nil; + return result; } static val string_out_put_string(val stream, val str) @@ -490,7 +490,7 @@ static val string_out_put_string(val stream, val str) if (so == 0) return nil; - if (so->head != 0) + while (so->head != so->tail) string_out_byte_flush(so, stream); { @@ -754,7 +754,7 @@ val get_string_from_stream(val stream) if (!so) return out; - if (so->head != 0) + while (so->head != so->tail) out = string_out_byte_flush(so, stream); stream->co.handle = 0; diff --git a/tests/010/strstream.expected b/tests/010/strstream.expected new file mode 100644 index 00000000..7e9cc628 --- /dev/null +++ b/tests/010/strstream.expected @@ -0,0 +1 @@ +"春が来た (Haru-ga Kita/Spring has Come)" diff --git a/tests/010/strstream.txr b/tests/010/strstream.txr new file mode 100644 index 00000000..5800172e --- /dev/null +++ b/tests/010/strstream.txr @@ -0,0 +1,11 @@ +@(do + (defun lazy-byte-stream (s) + (let (ch) (gen (set ch (get-byte s)) ch))) + + (let* ((data "春が来た (Haru-ga Kita/Spring has Come)") + (in-byte (make-string-byte-input-stream data)) + (out-byte (make-string-output-stream))) + (each ((b (lazy-byte-stream in-byte))) + (put-byte b out-byte)) + (print (get-string-from-stream out-byte)) + (pprint "\n"))) |