summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--stream.c8
-rw-r--r--tests/010/strstream.expected1
-rw-r--r--tests/010/strstream.txr11
4 files changed, 39 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 17929da5..8298ec3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/stream.c b/stream.c
index 233ee3d4..e4e75982 100644
--- a/stream.c
+++ b/stream.c
@@ -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")))