CRLF across 8k boundary inserts an empty line.

fixes issue#100

This introduces buffering of a trailing, non-leading CR for each buffer
passed to pluma_document_output_write(), for later possible recombination into
a CRLF.
Since this buffering has to be flushed at EOF, a flush method has been added to
the class. It is implicitly called at document close time.
This commit is contained in:
Patrick Monnerat 2015-10-08 18:00:51 +02:00 committed by raveit65
parent 78101257f4
commit 43903ad12b
1 changed files with 35 additions and 7 deletions

View File

@ -66,6 +66,10 @@ static gssize pluma_document_output_stream_write (GOutputStream *stre
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
static gboolean pluma_document_output_stream_flush (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
static gboolean pluma_document_output_stream_close (GOutputStream *stream, static gboolean pluma_document_output_stream_close (GOutputStream *stream,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
@ -154,6 +158,7 @@ pluma_document_output_stream_class_init (PlumaDocumentOutputStreamClass *klass)
object_class->constructed = pluma_document_output_stream_constructed; object_class->constructed = pluma_document_output_stream_constructed;
stream_class->write_fn = pluma_document_output_stream_write; stream_class->write_fn = pluma_document_output_stream_write;
stream_class->flush = pluma_document_output_stream_flush;
stream_class->close_fn = pluma_document_output_stream_close; stream_class->close_fn = pluma_document_output_stream_close;
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
@ -290,7 +295,6 @@ pluma_document_output_stream_write (GOutputStream *stream,
gsize len; gsize len;
gboolean freetext = FALSE; gboolean freetext = FALSE;
const gchar *end; const gchar *end;
gsize nvalid;
gboolean valid; gboolean valid;
if (g_cancellable_set_error_if_cancelled (cancellable, error)) if (g_cancellable_set_error_if_cancelled (cancellable, error))
@ -328,16 +332,23 @@ pluma_document_output_stream_write (GOutputStream *stream,
/* validate */ /* validate */
valid = g_utf8_validate (text, len, &end); valid = g_utf8_validate (text, len, &end);
nvalid = end - text;
/* Avoid keeping a CRLF across two buffers. */
if (valid && len > 1 && end[-1] == '\r')
{
valid = FALSE;
end--;
}
if (!valid) if (!valid)
{ {
gsize remainder; gsize nvalid = end - text;
gsize remainder = len - nvalid;
remainder = len - nvalid; gunichar ch;
if ((remainder < MAX_UNICHAR_LEN) && if ((remainder < MAX_UNICHAR_LEN) &&
(g_utf8_get_char_validated (text + nvalid, remainder) == (gunichar)-2)) ((ch = g_utf8_get_char_validated (text + nvalid, remainder)) == (gunichar)-2 ||
ch == (gunichar)'\r'))
{ {
ostream->priv->buffer = g_strndup (end, remainder); ostream->priv->buffer = g_strndup (end, remainder);
ostream->priv->buflen = remainder; ostream->priv->buflen = remainder;
@ -345,7 +356,7 @@ pluma_document_output_stream_write (GOutputStream *stream,
} }
else else
{ {
/* TODO: we cuould escape invalid text and tag it in red /* TODO: we could escape invalid text and tag it in red
* and make the doc readonly. * and make the doc readonly.
*/ */
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
@ -367,6 +378,23 @@ pluma_document_output_stream_write (GOutputStream *stream,
return count; return count;
} }
static gboolean
pluma_document_output_stream_flush (GOutputStream *stream,
GCancellable *cancellable,
GError **error)
{
PlumaDocumentOutputStream *ostream = PLUMA_DOCUMENT_OUTPUT_STREAM (stream);
/* Flush deferred data if some. */
if (!ostream->priv->is_closed && ostream->priv->is_initialized &&
ostream->priv->buflen > 0 &&
pluma_document_output_stream_write (stream, "", 0, cancellable,
error) == -1)
return FALSE;
return TRUE;
}
static gboolean static gboolean
pluma_document_output_stream_close (GOutputStream *stream, pluma_document_output_stream_close (GOutputStream *stream,
GCancellable *cancellable, GCancellable *cancellable,