/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */
/* camel-stream.c : abstract class for a stream
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
* This library is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*
* Authors: Michael Zucchi
*/
#include "evolution-data-server-config.h"
#include
#include "camel-stream-null.h"
struct _CamelStreamNullPrivate {
gsize written;
gboolean ends_with_crlf;
gboolean ends_with_cr; /* Just for cases when the CRLF is split into two writes, CR and LF */
};
static void camel_stream_null_seekable_init (GSeekableIface *iface);
G_DEFINE_TYPE_WITH_CODE (CamelStreamNull, camel_stream_null, CAMEL_TYPE_STREAM,
G_ADD_PRIVATE (CamelStreamNull)
G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, camel_stream_null_seekable_init))
static gssize
stream_null_write (CamelStream *stream,
const gchar *buffer,
gsize n,
GCancellable *cancellable,
GError **error)
{
CamelStreamNull *stream_null = CAMEL_STREAM_NULL (stream);
stream_null->priv->written += n;
if (n >= 2) {
stream_null->priv->ends_with_crlf = buffer[n - 2] == '\r' && buffer[n - 1] == '\n';
stream_null->priv->ends_with_cr = buffer[n - 1] == '\r';
} else if (n == 1) {
stream_null->priv->ends_with_crlf = stream_null->priv->ends_with_cr && buffer[n - 1] == '\n';
stream_null->priv->ends_with_cr = buffer[n - 1] == '\r';
}
return n;
}
static gboolean
stream_null_eos (CamelStream *stream)
{
return TRUE;
}
static goffset
stream_null_tell (GSeekable *seekable)
{
return 0;
}
static gboolean
stream_null_can_seek (GSeekable *seekable)
{
return TRUE;
}
static gboolean
stream_null_seek (GSeekable *seekable,
goffset offset,
GSeekType type,
GCancellable *cancellable,
GError **error)
{
if (type != G_SEEK_SET || offset != 0) {
g_set_error_literal (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Only reset to beginning is supported with CamelHttpStream"));
return FALSE;
}
CAMEL_STREAM_NULL (seekable)->priv->written = 0;
return TRUE;
}
static gboolean
stream_null_can_truncate (GSeekable *seekable)
{
return FALSE;
}
static gboolean
stream_null_truncate_fn (GSeekable *seekable,
goffset offset,
GCancellable *cancellable,
GError **error)
{
/* XXX Don't bother translating this. Camel never calls it. */
g_set_error_literal (
error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Truncation is not supported");
return FALSE;
}
static void
camel_stream_null_class_init (CamelStreamNullClass *class)
{
CamelStreamClass *stream_class;
stream_class = CAMEL_STREAM_CLASS (class);
stream_class->write = stream_null_write;
stream_class->eos = stream_null_eos;
}
static void
camel_stream_null_seekable_init (GSeekableIface *iface)
{
iface->tell = stream_null_tell;
iface->can_seek = stream_null_can_seek;
iface->seek = stream_null_seek;
iface->can_truncate = stream_null_can_truncate;
iface->truncate_fn = stream_null_truncate_fn;
}
static void
camel_stream_null_init (CamelStreamNull *stream_null)
{
stream_null->priv = camel_stream_null_get_instance_private (stream_null);
stream_null->priv->ends_with_crlf = FALSE;
stream_null->priv->ends_with_cr = FALSE;
}
/**
* camel_stream_null_new:
*
* Returns a null stream. A null stream is always at eof, and
* always returns success for all reads and writes.
*
* Returns: (transfer full): a new #CamelStreamNull
**/
CamelStream *
camel_stream_null_new (void)
{
return g_object_new (CAMEL_TYPE_STREAM_NULL, NULL);
}
/**
* camel_stream_null_get_bytes_written:
* @stream_null: a #CamelStreamNull
*
* Returns: how many bytes had been written to the @stream_null since
* it was created or rewind to the beginning.
*
* Since: 3.24
**/
gsize
camel_stream_null_get_bytes_written (CamelStreamNull *stream_null)
{
g_return_val_if_fail (CAMEL_IS_STREAM_NULL (stream_null), -1);
return stream_null->priv->written;
}
/**
* camel_stream_null_get_ends_with_crlf:
* @stream_null: a #CamelStreamNull
*
* Returns: Whether the data being written to @stream_null ended with CRLF.
*
* Since: 3.30
**/
gboolean
camel_stream_null_get_ends_with_crlf (CamelStreamNull *stream_null)
{
g_return_val_if_fail (CAMEL_IS_STREAM_NULL (stream_null), FALSE);
return stream_null->priv->ends_with_crlf;
}