1 /* GIO - GLib Input, Output and Streaming Library 2 * 3 * Copyright (C) 2006-2007 Red Hat, Inc. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General 16 * Public License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 18 * Boston, MA 02111-1307, USA. 19 * 20 * Author: Alexander Larsson <alexl (at) redhat.com> 21 */ 22 23 #include "config.h" 24 #include <string.h> 25 #include "gdataoutputstream.h" 26 #include "gioenumtypes.h" 27 #include "glibintl.h" 28 29 #include "gioalias.h" 30 31 /** 32 * SECTION:gdataoutputstream 33 * @short_description: Data Output Stream 34 * @include: gio/gio.h 35 * @see_also: #GOutputStream 36 * 37 * Data output stream implements #GOutputStream and includes functions for 38 * writing data directly to an output stream. 39 * 40 **/ 41 42 43 44 struct _GDataOutputStreamPrivate { 45 GDataStreamByteOrder byte_order; 46 }; 47 48 enum { 49 PROP_0, 50 PROP_BYTE_ORDER 51 }; 52 53 static void g_data_output_stream_set_property (GObject *object, 54 guint prop_id, 55 const GValue *value, 56 GParamSpec *pspec); 57 static void g_data_output_stream_get_property (GObject *object, 58 guint prop_id, 59 GValue *value, 60 GParamSpec *pspec); 61 62 G_DEFINE_TYPE (GDataOutputStream, 63 g_data_output_stream, 64 G_TYPE_FILTER_OUTPUT_STREAM) 65 66 67 static void 68 g_data_output_stream_class_init (GDataOutputStreamClass *klass) 69 { 70 GObjectClass *object_class; 71 72 g_type_class_add_private (klass, sizeof (GDataOutputStreamPrivate)); 73 74 object_class = G_OBJECT_CLASS (klass); 75 object_class->get_property = g_data_output_stream_get_property; 76 object_class->set_property = g_data_output_stream_set_property; 77 78 /** 79 * GDataOutputStream:byte-order: 80 * 81 * Determines the byte ordering that is used when writing 82 * multi-byte entities (such as integers) to the stream. 83 */ 84 g_object_class_install_property (object_class, 85 PROP_BYTE_ORDER, 86 g_param_spec_enum ("byte-order", 87 P_("Byte order"), 88 P_("The byte order"), 89 G_TYPE_DATA_STREAM_BYTE_ORDER, 90 G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN, 91 G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB)); 92 93 } 94 95 static void 96 g_data_output_stream_set_property (GObject *object, 97 guint prop_id, 98 const GValue *value, 99 GParamSpec *pspec) 100 { 101 GDataOutputStream *dstream; 102 103 dstream = G_DATA_OUTPUT_STREAM (object); 104 105 switch (prop_id) 106 { 107 case PROP_BYTE_ORDER: 108 g_data_output_stream_set_byte_order (dstream, g_value_get_enum (value)); 109 break; 110 111 default: 112 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 113 break; 114 } 115 } 116 117 static void 118 g_data_output_stream_get_property (GObject *object, 119 guint prop_id, 120 GValue *value, 121 GParamSpec *pspec) 122 { 123 GDataOutputStreamPrivate *priv; 124 GDataOutputStream *dstream; 125 126 dstream = G_DATA_OUTPUT_STREAM (object); 127 priv = dstream->priv; 128 129 switch (prop_id) 130 { 131 case PROP_BYTE_ORDER: 132 g_value_set_enum (value, priv->byte_order); 133 break; 134 135 default: 136 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 137 break; 138 } 139 } 140 141 static void 142 g_data_output_stream_init (GDataOutputStream *stream) 143 { 144 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, 145 G_TYPE_DATA_OUTPUT_STREAM, 146 GDataOutputStreamPrivate); 147 148 stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; 149 } 150 151 /** 152 * g_data_output_stream_new: 153 * @base_stream: a #GOutputStream. 154 * 155 * Creates a new data output stream for @base_stream. 156 * 157 * Returns: #GDataOutputStream. 158 **/ 159 GDataOutputStream * 160 g_data_output_stream_new (GOutputStream *base_stream) 161 { 162 GDataOutputStream *stream; 163 164 g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL); 165 166 stream = g_object_new (G_TYPE_DATA_OUTPUT_STREAM, 167 "base-stream", base_stream, 168 NULL); 169 170 return stream; 171 } 172 173 /** 174 * g_data_output_stream_set_byte_order: 175 * @stream: a #GDataOutputStream. 176 * @order: a %GDataStreamByteOrder. 177 * 178 * Sets the byte order of the data output stream to @order. 179 **/ 180 void 181 g_data_output_stream_set_byte_order (GDataOutputStream *stream, 182 GDataStreamByteOrder order) 183 { 184 GDataOutputStreamPrivate *priv; 185 g_return_if_fail (G_IS_DATA_OUTPUT_STREAM (stream)); 186 priv = stream->priv; 187 if (priv->byte_order != order) 188 { 189 priv->byte_order = order; 190 g_object_notify (G_OBJECT (stream), "byte-order"); 191 } 192 } 193 194 /** 195 * g_data_output_stream_get_byte_order: 196 * @stream: a #GDataOutputStream. 197 * 198 * Gets the byte order for the stream. 199 * 200 * Returns: the #GDataStreamByteOrder for the @stream. 201 **/ 202 GDataStreamByteOrder 203 g_data_output_stream_get_byte_order (GDataOutputStream *stream) 204 { 205 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN); 206 207 return stream->priv->byte_order; 208 } 209 210 /** 211 * g_data_output_stream_put_byte: 212 * @stream: a #GDataOutputStream. 213 * @data: a #guchar. 214 * @cancellable: optional #GCancellable object, %NULL to ignore. 215 * @error: a #GError, %NULL to ignore. 216 * 217 * Puts a byte into the output stream. 218 * 219 * Returns: %TRUE if @data was successfully added to the @stream. 220 **/ 221 gboolean 222 g_data_output_stream_put_byte (GDataOutputStream *stream, 223 guchar data, 224 GCancellable *cancellable, 225 GError **error) 226 { 227 gsize bytes_written; 228 229 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 230 231 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 232 &data, 1, 233 &bytes_written, 234 cancellable, error); 235 } 236 237 /** 238 * g_data_output_stream_put_int16: 239 * @stream: a #GDataOutputStream. 240 * @data: a #gint16. 241 * @cancellable: optional #GCancellable object, %NULL to ignore. 242 * @error: a #GError, %NULL to ignore. 243 * 244 * Puts a signed 16-bit integer into the output stream. 245 * 246 * Returns: %TRUE if @data was successfully added to the @stream. 247 **/ 248 gboolean 249 g_data_output_stream_put_int16 (GDataOutputStream *stream, 250 gint16 data, 251 GCancellable *cancellable, 252 GError **error) 253 { 254 gsize bytes_written; 255 256 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 257 258 switch (stream->priv->byte_order) 259 { 260 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: 261 data = GINT16_TO_BE (data); 262 break; 263 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: 264 data = GINT16_TO_LE (data); 265 break; 266 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: 267 default: 268 break; 269 } 270 271 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 272 &data, 2, 273 &bytes_written, 274 cancellable, error); 275 } 276 277 /** 278 * g_data_output_stream_put_uint16: 279 * @stream: a #GDataOutputStream. 280 * @data: a #guint16. 281 * @cancellable: optional #GCancellable object, %NULL to ignore. 282 * @error: a #GError, %NULL to ignore. 283 * 284 * Puts an unsigned 16-bit integer into the output stream. 285 * 286 * Returns: %TRUE if @data was successfully added to the @stream. 287 **/ 288 gboolean 289 g_data_output_stream_put_uint16 (GDataOutputStream *stream, 290 guint16 data, 291 GCancellable *cancellable, 292 GError **error) 293 { 294 gsize bytes_written; 295 296 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 297 298 switch (stream->priv->byte_order) 299 { 300 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: 301 data = GUINT16_TO_BE (data); 302 break; 303 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: 304 data = GUINT16_TO_LE (data); 305 break; 306 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: 307 default: 308 break; 309 } 310 311 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 312 &data, 2, 313 &bytes_written, 314 cancellable, error); 315 } 316 317 /** 318 * g_data_output_stream_put_int32: 319 * @stream: a #GDataOutputStream. 320 * @data: a #gint32. 321 * @cancellable: optional #GCancellable object, %NULL to ignore. 322 * @error: a #GError, %NULL to ignore. 323 * 324 * Puts a signed 32-bit integer into the output stream. 325 * 326 * Returns: %TRUE if @data was successfully added to the @stream. 327 **/ 328 gboolean 329 g_data_output_stream_put_int32 (GDataOutputStream *stream, 330 gint32 data, 331 GCancellable *cancellable, 332 GError **error) 333 { 334 gsize bytes_written; 335 336 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 337 338 switch (stream->priv->byte_order) 339 { 340 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: 341 data = GINT32_TO_BE (data); 342 break; 343 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: 344 data = GINT32_TO_LE (data); 345 break; 346 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: 347 default: 348 break; 349 } 350 351 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 352 &data, 4, 353 &bytes_written, 354 cancellable, error); 355 } 356 357 /** 358 * g_data_output_stream_put_uint32: 359 * @stream: a #GDataOutputStream. 360 * @data: a #guint32. 361 * @cancellable: optional #GCancellable object, %NULL to ignore. 362 * @error: a #GError, %NULL to ignore. 363 * 364 * Puts an unsigned 32-bit integer into the stream. 365 * 366 * Returns: %TRUE if @data was successfully added to the @stream. 367 **/ 368 gboolean 369 g_data_output_stream_put_uint32 (GDataOutputStream *stream, 370 guint32 data, 371 GCancellable *cancellable, 372 GError **error) 373 { 374 gsize bytes_written; 375 376 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 377 378 switch (stream->priv->byte_order) 379 { 380 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: 381 data = GUINT32_TO_BE (data); 382 break; 383 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: 384 data = GUINT32_TO_LE (data); 385 break; 386 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: 387 default: 388 break; 389 } 390 391 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 392 &data, 4, 393 &bytes_written, 394 cancellable, error); 395 } 396 397 /** 398 * g_data_output_stream_put_int64: 399 * @stream: a #GDataOutputStream. 400 * @data: a #gint64. 401 * @cancellable: optional #GCancellable object, %NULL to ignore. 402 * @error: a #GError, %NULL to ignore. 403 * 404 * Puts a signed 64-bit integer into the stream. 405 * 406 * Returns: %TRUE if @data was successfully added to the @stream. 407 **/ 408 gboolean 409 g_data_output_stream_put_int64 (GDataOutputStream *stream, 410 gint64 data, 411 GCancellable *cancellable, 412 GError **error) 413 { 414 gsize bytes_written; 415 416 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 417 418 switch (stream->priv->byte_order) 419 { 420 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: 421 data = GINT64_TO_BE (data); 422 break; 423 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: 424 data = GINT64_TO_LE (data); 425 break; 426 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: 427 default: 428 break; 429 } 430 431 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 432 &data, 8, 433 &bytes_written, 434 cancellable, error); 435 } 436 437 /** 438 * g_data_output_stream_put_uint64: 439 * @stream: a #GDataOutputStream. 440 * @data: a #guint64. 441 * @cancellable: optional #GCancellable object, %NULL to ignore. 442 * @error: a #GError, %NULL to ignore. 443 * 444 * Puts an unsigned 64-bit integer into the stream. 445 * 446 * Returns: %TRUE if @data was successfully added to the @stream. 447 **/ 448 gboolean 449 g_data_output_stream_put_uint64 (GDataOutputStream *stream, 450 guint64 data, 451 GCancellable *cancellable, 452 GError **error) 453 { 454 gsize bytes_written; 455 456 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 457 458 switch (stream->priv->byte_order) 459 { 460 case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: 461 data = GUINT64_TO_BE (data); 462 break; 463 case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: 464 data = GUINT64_TO_LE (data); 465 break; 466 case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: 467 default: 468 break; 469 } 470 471 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 472 &data, 8, 473 &bytes_written, 474 cancellable, error); 475 } 476 477 /** 478 * g_data_output_stream_put_string: 479 * @stream: a #GDataOutputStream. 480 * @str: a string. 481 * @cancellable: optional #GCancellable object, %NULL to ignore. 482 * @error: a #GError, %NULL to ignore. 483 * 484 * Puts a string into the output stream. 485 * 486 * Returns: %TRUE if @string was successfully added to the @stream. 487 **/ 488 gboolean 489 g_data_output_stream_put_string (GDataOutputStream *stream, 490 const char *str, 491 GCancellable *cancellable, 492 GError **error) 493 { 494 gsize bytes_written; 495 496 g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); 497 g_return_val_if_fail (str != NULL, FALSE); 498 499 return g_output_stream_write_all (G_OUTPUT_STREAM (stream), 500 str, strlen (str), 501 &bytes_written, 502 cancellable, error); 503 } 504 505 #define __G_DATA_OUTPUT_STREAM_C__ 506 #include "gioaliasdef.c" 507