[kdbus] More detailed description for ENOBUFS errno
[platform/upstream/glib.git] / gio / gdataoutputstream.c
index 40f0e72..ea7deb1 100644 (file)
  * 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, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Larsson <alexl@redhat.com>
  */
 
-#include <config.h>
+#include "config.h"
 #include <string.h>
 #include "gdataoutputstream.h"
+#include "gseekable.h"
+#include "gioenumtypes.h"
+#include "gioerror.h"
 #include "glibintl.h"
 
+
 /**
  * SECTION:gdataoutputstream
- * @short_description: Data Output Stream.
- * @see_also: #GOutputStream.
+ * @short_description: Data Output Stream
+ * @include: gio/gio.h
+ * @see_also: #GOutputStream
  * 
  * Data output stream implements #GOutputStream and includes functions for 
  * writing data directly to an output stream.
@@ -42,7 +45,8 @@ struct _GDataOutputStreamPrivate {
 };
 
 enum {
-  PROP_0
+  PROP_0,
+  PROP_BYTE_ORDER
 };
 
 static void g_data_output_stream_set_property (GObject      *object,
@@ -54,9 +58,26 @@ static void g_data_output_stream_get_property (GObject      *object,
                                               GValue       *value,
                                               GParamSpec   *pspec);
 
-G_DEFINE_TYPE (GDataOutputStream,
-               g_data_output_stream,
-               G_TYPE_FILTER_OUTPUT_STREAM)
+static void     g_data_output_stream_seekable_iface_init (GSeekableIface  *iface);
+static goffset  g_data_output_stream_tell                (GSeekable       *seekable);
+static gboolean g_data_output_stream_can_seek            (GSeekable       *seekable);
+static gboolean g_data_output_stream_seek                (GSeekable       *seekable,
+                                                         goffset          offset,
+                                                         GSeekType        type,
+                                                         GCancellable    *cancellable,
+                                                         GError         **error);
+static gboolean g_data_output_stream_can_truncate        (GSeekable       *seekable);
+static gboolean g_data_output_stream_truncate            (GSeekable       *seekable,
+                                                         goffset          offset,
+                                                         GCancellable    *cancellable,
+                                                         GError         **error);
+
+G_DEFINE_TYPE_WITH_CODE (GDataOutputStream,
+                        g_data_output_stream,
+                        G_TYPE_FILTER_OUTPUT_STREAM,
+                         G_ADD_PRIVATE (GDataOutputStream)
+                        G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
+                                               g_data_output_stream_seekable_iface_init))
 
 
 static void
@@ -64,33 +85,47 @@ g_data_output_stream_class_init (GDataOutputStreamClass *klass)
 {
   GObjectClass *object_class;
 
-  g_type_class_add_private (klass, sizeof (GDataOutputStreamPrivate));
-
   object_class = G_OBJECT_CLASS (klass);
   object_class->get_property = g_data_output_stream_get_property;
   object_class->set_property = g_data_output_stream_set_property;
+
+  /**
+   * GDataOutputStream:byte-order:
+   *
+   * Determines the byte ordering that is used when writing 
+   * multi-byte entities (such as integers) to the stream.
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_BYTE_ORDER,
+                                   g_param_spec_enum ("byte-order",
+                                                      P_("Byte order"),
+                                                      P_("The byte order"),
+                                                      G_TYPE_DATA_STREAM_BYTE_ORDER,
+                                                      G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
+                                                      G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
+
 }
 
 static void
-g_data_output_stream_set_property (GObject         *object,
-                                 guint            prop_id,
-                                 const GValue    *value,
-                                 GParamSpec      *pspec)
+g_data_output_stream_set_property (GObject     *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
 {
-  GDataOutputStreamPrivate *priv;
-  GDataOutputStream        *dstream;
+  GDataOutputStream *dstream;
 
   dstream = G_DATA_OUTPUT_STREAM (object);
-  priv = dstream->priv;
 
   switch (prop_id) 
     {
+    case PROP_BYTE_ORDER:
+      g_data_output_stream_set_byte_order (dstream, g_value_get_enum (value));
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
-
 }
 
 static void
@@ -106,24 +141,34 @@ g_data_output_stream_get_property (GObject    *object,
   priv = dstream->priv;
 
   switch (prop_id)
-    { 
-  
+    {
+    case PROP_BYTE_ORDER:
+      g_value_set_enum (value, priv->byte_order);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
-
 }
+
 static void
 g_data_output_stream_init (GDataOutputStream *stream)
 {
-  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
-                                              G_TYPE_DATA_OUTPUT_STREAM,
-                                              GDataOutputStreamPrivate);
-
+  stream->priv = g_data_output_stream_get_instance_private (stream);
   stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
 }
 
+static void
+g_data_output_stream_seekable_iface_init (GSeekableIface *iface)
+{
+  iface->tell         = g_data_output_stream_tell;
+  iface->can_seek     = g_data_output_stream_can_seek;
+  iface->seek         = g_data_output_stream_seek;
+  iface->can_truncate = g_data_output_stream_can_truncate;
+  iface->truncate_fn  = g_data_output_stream_truncate;
+}
+
 /**
  * g_data_output_stream_new:
  * @base_stream: a #GOutputStream.
@@ -152,15 +197,19 @@ g_data_output_stream_new (GOutputStream *base_stream)
  * @order: a %GDataStreamByteOrder.
  * 
  * Sets the byte order of the data output stream to @order.
- * 
  **/
 void
-g_data_output_stream_set_byte_order (GDataOutputStream *stream,
-                                   GDataStreamByteOrder order)
+g_data_output_stream_set_byte_order (GDataOutputStream    *stream,
+                                     GDataStreamByteOrder  order)
 {
+  GDataOutputStreamPrivate *priv;
   g_return_if_fail (G_IS_DATA_OUTPUT_STREAM (stream));
-
-  stream->priv->byte_order = order;
+  priv = stream->priv;
+  if (priv->byte_order != order)
+    {
+      priv->byte_order = order;
+      g_object_notify (G_OBJECT (stream), "byte-order");
+    }
 }
 
 /**
@@ -181,9 +230,9 @@ g_data_output_stream_get_byte_order (GDataOutputStream *stream)
 
 /**
  * g_data_output_stream_put_byte:
- * @data_stream: a #GDataOutputStream.
+ * @stream: a #GDataOutputStream.
  * @data: a #guchar.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts a byte into the output stream.
@@ -191,16 +240,16 @@ g_data_output_stream_get_byte_order (GDataOutputStream *stream)
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_byte (GDataOutputStream     *data_stream,
-                              guchar                 data,
-                              GCancellable          *cancellable,
-                              GError               **error)
+g_data_output_stream_put_byte (GDataOutputStream  *stream,
+                              guchar              data,
+                              GCancellable       *cancellable,
+                              GError            **error)
 {
   gsize bytes_written;
   
-  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (data_stream), FALSE);
+  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 
-  return g_output_stream_write_all (G_OUTPUT_STREAM (data_stream),
+  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
                                    &data, 1,
                                    &bytes_written,
                                    cancellable, error);
@@ -210,7 +259,7 @@ g_data_output_stream_put_byte (GDataOutputStream     *data_stream,
  * g_data_output_stream_put_int16:
  * @stream: a #GDataOutputStream.
  * @data: a #gint16.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts a signed 16-bit integer into the output stream.
@@ -218,10 +267,10 @@ g_data_output_stream_put_byte (GDataOutputStream     *data_stream,
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_int16 (GDataOutputStream     *stream,
-                               gint16                 data,
-                               GCancellable          *cancellable,
-                               GError               **error)
+g_data_output_stream_put_int16 (GDataOutputStream  *stream,
+                               gint16              data,
+                               GCancellable       *cancellable,
+                               GError            **error)
 {
   gsize bytes_written;
   
@@ -250,7 +299,7 @@ g_data_output_stream_put_int16 (GDataOutputStream     *stream,
  * g_data_output_stream_put_uint16:
  * @stream: a #GDataOutputStream.
  * @data: a #guint16.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts an unsigned 16-bit integer into the output stream.
@@ -258,10 +307,10 @@ g_data_output_stream_put_int16 (GDataOutputStream     *stream,
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_uint16 (GDataOutputStream     *stream,
-                                guint16                data,
-                                GCancellable          *cancellable,
-                                GError               **error)
+g_data_output_stream_put_uint16 (GDataOutputStream  *stream,
+                                guint16             data,
+                                GCancellable       *cancellable,
+                                GError            **error)
 {
   gsize bytes_written;
   
@@ -290,7 +339,7 @@ g_data_output_stream_put_uint16 (GDataOutputStream     *stream,
  * g_data_output_stream_put_int32:
  * @stream: a #GDataOutputStream.
  * @data: a #gint32.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts a signed 32-bit integer into the output stream.
@@ -298,10 +347,10 @@ g_data_output_stream_put_uint16 (GDataOutputStream     *stream,
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_int32 (GDataOutputStream     *stream,
-                               gint32                 data,
-                               GCancellable          *cancellable,
-                               GError               **error)
+g_data_output_stream_put_int32 (GDataOutputStream  *stream,
+                               gint32              data,
+                               GCancellable       *cancellable,
+                               GError            **error)
 {
   gsize bytes_written;
   
@@ -330,7 +379,7 @@ g_data_output_stream_put_int32 (GDataOutputStream     *stream,
  * g_data_output_stream_put_uint32:
  * @stream: a #GDataOutputStream.
  * @data: a #guint32.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts an unsigned 32-bit integer into the stream.
@@ -338,10 +387,10 @@ g_data_output_stream_put_int32 (GDataOutputStream     *stream,
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_uint32 (GDataOutputStream     *stream,
-                                guint32                data,
-                                GCancellable          *cancellable,
-                                GError               **error)
+g_data_output_stream_put_uint32 (GDataOutputStream  *stream,
+                                guint32             data,
+                                GCancellable       *cancellable,
+                                GError            **error)
 {
   gsize bytes_written;
   
@@ -370,7 +419,7 @@ g_data_output_stream_put_uint32 (GDataOutputStream     *stream,
  * g_data_output_stream_put_int64:
  * @stream: a #GDataOutputStream.
  * @data: a #gint64.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts a signed 64-bit integer into the stream.
@@ -378,10 +427,10 @@ g_data_output_stream_put_uint32 (GDataOutputStream     *stream,
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_int64 (GDataOutputStream     *stream,
-                               gint64                 data,
-                               GCancellable          *cancellable,
-                               GError               **error)
+g_data_output_stream_put_int64 (GDataOutputStream  *stream,
+                               gint64              data,
+                               GCancellable       *cancellable,
+                               GError            **error)
 {
   gsize bytes_written;
   
@@ -410,7 +459,7 @@ g_data_output_stream_put_int64 (GDataOutputStream     *stream,
  * g_data_output_stream_put_uint64:
  * @stream: a #GDataOutputStream.
  * @data: a #guint64.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts an unsigned 64-bit integer into the stream.
@@ -418,10 +467,10 @@ g_data_output_stream_put_int64 (GDataOutputStream     *stream,
  * Returns: %TRUE if @data was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_uint64 (GDataOutputStream     *stream,
-                                guint64                data,
-                                GCancellable          *cancellable,
-                                GError               **error)
+g_data_output_stream_put_uint64 (GDataOutputStream  *stream,
+                                guint64             data,
+                                GCancellable       *cancellable,
+                                GError            **error)
 {
   gsize bytes_written;
   
@@ -450,7 +499,7 @@ g_data_output_stream_put_uint64 (GDataOutputStream     *stream,
  * g_data_output_stream_put_string:
  * @stream: a #GDataOutputStream.
  * @str: a string.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: a #GError, %NULL to ignore.
  * 
  * Puts a string into the output stream. 
@@ -458,10 +507,10 @@ g_data_output_stream_put_uint64 (GDataOutputStream     *stream,
  * Returns: %TRUE if @string was successfully added to the @stream.
  **/
 gboolean
-g_data_output_stream_put_string (GDataOutputStream     *stream,
-                                const char            *str,
-                                GCancellable          *cancellable,
-                                GError               **error)
+g_data_output_stream_put_string (GDataOutputStream  *stream,
+                                const char         *str,
+                                GCancellable       *cancellable,
+                                GError            **error)
 {
   gsize bytes_written;
   
@@ -472,4 +521,78 @@ g_data_output_stream_put_string (GDataOutputStream     *stream,
                                    str, strlen (str),
                                    &bytes_written,
                                    cancellable, error);
-}  
+}
+
+static goffset
+g_data_output_stream_tell (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    return 0;
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  return g_seekable_tell (base_stream_seekable);
+}
+
+static gboolean
+g_data_output_stream_can_seek (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_data_output_stream_seek (GSeekable     *seekable,
+                          goffset        offset,
+                          GSeekType      type,
+                          GCancellable  *cancellable,
+                          GError       **error)
+{
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Seek not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  return g_seekable_seek (base_stream_seekable, offset, type, cancellable, error);
+}
+
+static gboolean
+g_data_output_stream_can_truncate (GSeekable *seekable)
+{
+  GOutputStream *base_stream;
+  
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  return G_IS_SEEKABLE (base_stream) && g_seekable_can_truncate (G_SEEKABLE (base_stream));
+}
+
+static gboolean
+g_data_output_stream_truncate (GSeekable     *seekable,
+                                  goffset        offset,
+                                  GCancellable  *cancellable,
+                                  GError       **error)
+{
+  GOutputStream *base_stream;
+  GSeekable *base_stream_seekable;
+
+  base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream;
+  if (!G_IS_SEEKABLE (base_stream))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Truncate not supported on base stream"));
+      return FALSE;
+    }
+
+  base_stream_seekable = G_SEEKABLE (base_stream);
+  return g_seekable_truncate (base_stream_seekable, offset, cancellable, error);
+}