bf3c1b18ade5a9275b3408875eb1ad6f3e0c5ce5
[platform/upstream/dbus.git] / dbus / dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-message.c  DBusMessage object
3  *
4  * Copyright (C) 2002, 2003  Red Hat Inc.
5  * Copyright (C) 2002, 2003  CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 1.2
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-internals.h"
26 #include "dbus-marshal.h"
27 #include "dbus-message.h"
28 #include "dbus-message-internal.h"
29 #include "dbus-memory.h"
30 #include "dbus-list.h"
31 #include <string.h>
32
33 /**
34  * @defgroup DBusMessageInternals DBusMessage implementation details
35  * @ingroup DBusInternals
36  * @brief DBusMessage private implementation details.
37  *
38  * The guts of DBusMessage and its methods.
39  *
40  * @{
41  */
42
43 enum
44 {
45   FIELD_HEADER_LENGTH,
46   FIELD_BODY_LENGTH,
47   FIELD_CLIENT_SERIAL,
48   FIELD_NAME,
49   FIELD_SERVICE,
50   FIELD_SENDER,
51   FIELD_REPLY_SERIAL,
52
53   FIELD_LAST
54 };
55
56 typedef struct
57 {
58   int offset; /**< Offset to start of field (location of name of field
59                * for named fields)
60                */
61 } HeaderField;
62
63 /**
64  * @brief Internals of DBusMessage
65  * 
66  * Object representing a message received from or to be sent to
67  * another application. This is an opaque object, all members
68  * are private.
69  */
70 struct DBusMessage
71 {
72   int refcount; /**< Reference count */
73
74   DBusString header; /**< Header network data, stored
75                       * separately from body so we can
76                       * independently realloc it.
77                       */
78
79   HeaderField header_fields[FIELD_LAST]; /**< Track the location
80                                            * of each field in "header"
81                                            */
82   
83   DBusString body;   /**< Body network data. */
84
85   char byte_order; /**< Message byte order. */
86
87   DBusCounter *size_counter; /**< Counter for the size of the message, or #NULL */
88   long size_counter_delta;   /**< Size we incremented the size counter by. */
89   
90   unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
91 };
92
93 /**
94  * @brief Internals of DBusMessageIter
95  * 
96  * Object representing a position in a message. All fields are internal.
97  */
98 struct DBusMessageIter
99 {
100   int refcount; /**< Reference count */
101
102   int pos; /**< Current position in the string */
103   
104   DBusMessage *message; /**< Message used */
105 };
106
107 /**
108  * Gets the data to be sent over the network for this message.
109  * The header and then the body should be written out.
110  * This function is guaranteed to always return the same
111  * data once a message is locked (with _dbus_message_lock()).
112  *
113  * @param message the message.
114  * @param header return location for message header data.
115  * @param body return location for message body data.
116  */
117 void
118 _dbus_message_get_network_data (DBusMessage          *message,
119                                 const DBusString    **header,
120                                 const DBusString    **body)
121 {
122   _dbus_assert (message->locked);
123   
124   *header = &message->header;
125   *body = &message->body;
126 }
127
128 static void
129 adjust_field_offsets (DBusMessage *message,
130                       int          offsets_after,
131                       int          delta)
132 {
133   int i;
134
135   if (delta == 0)
136     return;
137   
138   i = 0;
139   while (i < FIELD_LAST)
140     {
141       if (message->header_fields[i].offset > offsets_after)
142         message->header_fields[i].offset += delta;
143
144       ++i;
145     }
146 }
147
148 static const char*
149 get_string_field (DBusMessage *message,
150                   int          field,
151                   int         *len)
152 {
153   int offset = message->header_fields[field].offset;
154   const char *data;
155   
156   if (offset < 0)
157     return NULL;
158
159   /* offset points to string length, string data follows it */
160   /* FIXME _dbus_demarshal_const_string() that returned
161    * a reference to the string plus its len might be nice.
162    */
163   
164   if (len)
165     *len = _dbus_demarshal_int32 (&message->header,
166                                   message->byte_order,
167                                   offset,
168                                   NULL);
169
170   _dbus_string_get_const_data (&message->header,
171                                &data);
172   
173   return data + (offset + 4); 
174 }
175
176 static dbus_int32_t
177 get_int_field (DBusMessage *message,
178                      int          field)
179 {
180   int offset = message->header_fields[field].offset;
181   
182   if (offset < 0)
183     return -1; /* useless if -1 is a valid value of course */
184
185   return _dbus_demarshal_int32 (&message->header,
186                                 message->byte_order,
187                                 offset,
188                                 NULL);
189 }
190
191 static dbus_bool_t
192 append_int_field (DBusMessage *message,
193                   int          field,
194                   const char  *name,
195                   int          value)
196 {
197   int orig_len;
198
199   _dbus_assert (!message->locked);
200   
201   orig_len = _dbus_string_get_length (&message->header);
202   
203   if (!_dbus_string_align_length (&message->header, 4))
204     goto failed;  
205   
206   if (!_dbus_string_append_len (&message->header, name, 4))
207     goto failed;
208
209   if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
210     goto failed;
211
212   if (!_dbus_string_align_length (&message->header, 4))
213     goto failed;
214   
215   message->header_fields[FIELD_REPLY_SERIAL].offset =
216     _dbus_string_get_length (&message->header);
217   
218   if (!_dbus_marshal_int32 (&message->header, DBUS_COMPILER_BYTE_ORDER,
219                             value))
220     goto failed;
221
222   return TRUE;
223   
224  failed:
225   message->header_fields[field].offset = -1;
226   _dbus_string_set_length (&message->header, orig_len);
227   return FALSE;
228 }
229
230 static dbus_bool_t
231 append_string_field (DBusMessage *message,
232                      int          field,
233                      const char  *name,
234                      const char  *value)
235 {
236   int orig_len;
237
238   _dbus_assert (!message->locked);
239   
240   orig_len = _dbus_string_get_length (&message->header);
241
242   if (!_dbus_string_align_length (&message->header, 4))
243     goto failed;
244   
245   if (!_dbus_string_append_len (&message->header, name, 4))
246     goto failed;
247   
248   if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING))
249     goto failed;
250
251   if (!_dbus_string_align_length (&message->header, 4))
252     goto failed;
253   
254   message->header_fields[field].offset =
255     _dbus_string_get_length (&message->header);
256   
257   if (!_dbus_marshal_string (&message->header, DBUS_COMPILER_BYTE_ORDER,
258                              value))
259     goto failed;
260
261   return TRUE;
262   
263  failed:
264   message->header_fields[field].offset = -1;
265   _dbus_string_set_length (&message->header, orig_len);
266   return FALSE;
267 }
268
269 static dbus_bool_t
270 set_int_field (DBusMessage *message,
271                int          field,
272                int          value)
273 {
274   int offset = message->header_fields[field].offset;
275
276   _dbus_assert (!message->locked);
277   
278   if (offset < 0)
279     {
280       /* need to append the field */
281
282       switch (field)
283         {
284         case FIELD_REPLY_SERIAL:
285           return append_int_field (message, field,
286                                    DBUS_HEADER_FIELD_REPLY,
287                                    value);
288         default:
289           _dbus_assert_not_reached ("appending an int field we don't support appending");
290           return FALSE;
291         }
292     }
293   else
294     {
295       _dbus_marshal_set_int32 (&message->header,
296                                message->byte_order,
297                                offset, value);
298
299       return TRUE;
300     }
301 }
302
303 static dbus_bool_t
304 set_string_field (DBusMessage *message,
305                   int          field,
306                   const char  *value)
307 {
308   int offset = message->header_fields[field].offset;
309
310   _dbus_assert (!message->locked);
311   _dbus_assert (value != NULL);
312   
313   if (offset < 0)
314     {      
315       /* need to append the field */
316
317       switch (field)
318         {
319         case FIELD_SENDER:
320           return append_string_field (message, field,
321                                       DBUS_HEADER_FIELD_SENDER,
322                                       value);
323         default:
324           _dbus_assert_not_reached ("appending a string field we don't support appending");
325           return FALSE;
326         }
327     }
328   else
329     {
330       DBusString v;
331       int old_len;
332       int new_len;
333       
334       old_len = _dbus_string_get_length (&message->header);
335
336       _dbus_string_init_const_len (&v, value,
337                                    strlen (value) + 1); /* include nul */
338       if (!_dbus_marshal_set_string (&message->header,
339                                      message->byte_order,
340                                      offset, &v))
341         return FALSE;
342       
343       new_len = _dbus_string_get_length (&message->header);
344
345       adjust_field_offsets (message,
346                             offset,
347                             new_len - old_len);
348
349       return TRUE;
350     }
351 }
352
353 /**
354  * Sets the client serial of a message. 
355  * This can only be done once on a message.
356  *
357  * @param message the message
358  * @param client_serial the client serial
359  */
360 void
361 _dbus_message_set_client_serial (DBusMessage  *message,
362                                  dbus_int32_t  client_serial)
363 {
364   _dbus_assert (!message->locked);
365   _dbus_assert (_dbus_message_get_client_serial (message) < 0);
366
367   set_int_field (message, FIELD_CLIENT_SERIAL,
368                  client_serial);
369 }
370
371 /**
372  * Sets the reply serial of a message (the client serial
373  * of the message this is a reply to).
374  *
375  * @param message the message
376  * @param reply_serial the client serial
377  * @returns #FALSE if not enough memory
378  */
379 dbus_bool_t
380 _dbus_message_set_reply_serial (DBusMessage  *message,
381                                 dbus_int32_t  reply_serial)
382 {
383   _dbus_assert (!message->locked);
384
385   return set_int_field (message, FIELD_REPLY_SERIAL,
386                         reply_serial);
387 }
388
389 /**
390  * Returns the client serial of a message or
391  * -1 if none has been specified.
392  *
393  * @param message the message
394  * @returns the client serial
395  */
396 dbus_int32_t
397 _dbus_message_get_client_serial (DBusMessage *message)
398 {
399   return get_int_field (message, FIELD_CLIENT_SERIAL);
400 }
401
402 /**
403  * Returns the serial that the message is
404  * a reply to or -1 if none.
405  *
406  * @param message the message
407  * @returns the reply serial
408  */
409 dbus_int32_t
410 _dbus_message_get_reply_serial  (DBusMessage *message)
411 {
412   return get_int_field (message, FIELD_REPLY_SERIAL);
413 }
414
415 /**
416  * Adds a counter to be incremented immediately with the
417  * size of this message, and decremented by the size
418  * of this message when this message if finalized.
419  *
420  * @param message the message
421  * @param counter the counter
422  */
423 void
424 _dbus_message_add_size_counter (DBusMessage *message,
425                                 DBusCounter *counter)
426 {
427   _dbus_assert (message->size_counter == NULL); /* If this fails we may need to keep a list of
428                                                  * counters instead of just one
429                                                  */
430
431   message->size_counter = counter;
432   _dbus_counter_ref (message->size_counter);
433
434   /* When we can change message size, we may want to
435    * update this each time we do so, or we may want to
436    * just KISS like this.
437    */
438   message->size_counter_delta =
439     _dbus_string_get_length (&message->header) +
440     _dbus_string_get_length (&message->body);
441
442   _dbus_verbose ("message has size %ld\n",
443                  message->size_counter_delta);
444   
445   _dbus_counter_adjust (message->size_counter, message->size_counter_delta);
446 }
447
448 static dbus_bool_t
449 dbus_message_create_header (DBusMessage *message,
450                             const char  *service,
451                             const char  *name)
452 {
453   if (!_dbus_string_append_byte (&message->header, DBUS_COMPILER_BYTE_ORDER))
454     return FALSE;
455   
456   if (!_dbus_string_append_len (&message->header, "\0\0\0", 3))
457     return FALSE;
458
459   message->header_fields[FIELD_HEADER_LENGTH].offset = 4;
460   if (!_dbus_marshal_int32 (&message->header, message->byte_order, 0))
461     return FALSE;
462
463   message->header_fields[FIELD_BODY_LENGTH].offset = 8;
464   if (!_dbus_marshal_int32 (&message->header, message->byte_order, 0))
465     return FALSE;
466
467   message->header_fields[FIELD_CLIENT_SERIAL].offset = 12;
468   if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
469     return FALSE;
470   
471   /* Marshal message service */
472   if (service != NULL)
473     {
474       if (!append_string_field (message,
475                                 FIELD_SERVICE,
476                                 DBUS_HEADER_FIELD_SERVICE,
477                                 service))
478         return FALSE;
479     }
480
481   _dbus_assert (name != NULL);
482   if (!append_string_field (message,
483                             FIELD_NAME,
484                             DBUS_HEADER_FIELD_NAME,
485                             name))
486     return FALSE;
487
488   return TRUE;
489 }
490
491 /**
492  * Locks a message. Allows checking that applications don't keep a
493  * reference to a message in the outgoing queue and change it
494  * underneath us. Messages are locked when they enter the outgoing
495  * queue (dbus_connection_send_message()), and the library complains
496  * if the message is modified while locked.
497  *
498  * @param message the message to lock.
499  */
500 void
501 _dbus_message_lock (DBusMessage  *message)
502 {
503   if (!message->locked)
504     {
505       /* Fill in our lengths */
506       set_int_field (message,
507                      FIELD_HEADER_LENGTH,
508                      _dbus_string_get_length (&message->header));
509
510       set_int_field (message,
511                      FIELD_BODY_LENGTH,
512                      _dbus_string_get_length (&message->body));
513
514       message->locked = TRUE;
515     }
516 }
517
518 /** @} */
519
520 /**
521  * @defgroup DBusMessage DBusMessage
522  * @ingroup  DBus
523  * @brief Message to be sent or received over a DBusConnection.
524  *
525  * A DBusMessage is the most basic unit of communication over a
526  * DBusConnection. A DBusConnection represents a stream of messages
527  * received from a remote application, and a stream of messages
528  * sent to a remote application.
529  *
530  * @{
531  */
532
533 /**
534  * @typedef DBusMessage
535  *
536  * Opaque data type representing a message received from or to be
537  * sent to another application.
538  */
539
540 static DBusMessage*
541 dbus_message_new_empty_header (void)
542 {
543   DBusMessage *message;
544   int i;
545   
546   message = dbus_new0 (DBusMessage, 1);
547   if (message == NULL)
548     return NULL;
549   
550   message->refcount = 1;
551   message->byte_order = DBUS_COMPILER_BYTE_ORDER;
552   
553   i = 0;
554   while (i < FIELD_LAST)
555     {
556       message->header_fields[i].offset = -1;
557       ++i;
558     }
559   
560   if (!_dbus_string_init (&message->header, _DBUS_INT_MAX))
561     {
562       dbus_free (message);
563       return NULL;
564     }
565   
566   if (!_dbus_string_init (&message->body, _DBUS_INT_MAX))
567     {
568       _dbus_string_free (&message->header);
569       dbus_free (message);
570       return NULL;
571     }
572   
573   return message;
574 }
575
576
577 /**
578  * Constructs a new message. Returns #NULL if memory
579  * can't be allocated for the message.
580  *
581  * @todo use DBusString internally to store service and name.
582  *
583  * @param service service that the message should be sent to
584  * @param name name of the message
585  * @returns a new DBusMessage, free with dbus_message_unref()
586  * @see dbus_message_unref()
587  */
588 DBusMessage*
589 dbus_message_new (const char *service,
590                   const char *name)
591 {
592   DBusMessage *message;
593
594   message = dbus_message_new_empty_header ();
595   if (message == NULL)
596     return NULL;
597   
598   if (!dbus_message_create_header (message, service, name))
599     {
600       dbus_message_unref (message);
601       return NULL;
602     }
603   
604   return message;
605 }
606
607 /**
608  * Constructs a message that is a reply to some other
609  * message. Returns #NULL if memory can't be allocated
610  * for the message.
611  *
612  * @param name the name of the message
613  * @param original_message the message which the created
614  * message is a reply to.
615  * @returns a new DBusMessage, free with dbus_message_unref()
616  * @see dbus_message_new(), dbus_message_unref()
617  */ 
618 DBusMessage*
619 dbus_message_new_reply (const char  *name,
620                         DBusMessage *original_message)
621 {
622   DBusMessage *message;
623   const char *sender;
624
625   sender = get_string_field (original_message,
626                              FIELD_SENDER, NULL);
627
628   _dbus_assert (sender != NULL);
629   
630   message = dbus_message_new (sender, name);
631   
632   if (message == NULL)
633     return NULL;
634
635   if (!_dbus_message_set_reply_serial (message,
636                                        _dbus_message_get_client_serial (original_message)))
637     {
638       dbus_message_unref (message);
639       return NULL;
640     }
641
642   return message;
643 }
644
645
646 /**
647  * Increments the reference count of a DBusMessage.
648  *
649  * @param message The message
650  * @see dbus_message_unref
651  */
652 void
653 dbus_message_ref (DBusMessage *message)
654 {
655   _dbus_assert (message->refcount > 0);
656   
657   message->refcount += 1;
658 }
659
660 /**
661  * Decrements the reference count of a DBusMessage.
662  *
663  * @param message The message
664  * @see dbus_message_ref
665  */
666 void
667 dbus_message_unref (DBusMessage *message)
668 {
669   _dbus_assert (message->refcount > 0);
670
671   message->refcount -= 1;
672   if (message->refcount == 0)
673     {
674       if (message->size_counter != NULL)
675         {
676           _dbus_counter_adjust (message->size_counter,
677                                 - message->size_counter_delta);
678           _dbus_counter_unref (message->size_counter);
679         }
680       
681       _dbus_string_free (&message->header);
682       _dbus_string_free (&message->body);
683       
684       dbus_free (message);
685     }
686 }
687
688 /**
689  * Gets the name of a message.
690  *
691  * @param message the message
692  * @returns the message name (should not be freed)
693  */
694 const char*
695 dbus_message_get_name (DBusMessage *message)
696 {
697   return get_string_field (message, FIELD_NAME, NULL);
698 }
699
700 /**
701  * Gets the destination service of a message.
702  *
703  * @param message the message
704  * @returns the message destination service (should not be freed)
705  */
706 const char*
707 dbus_message_get_service (DBusMessage *message)
708 {
709   return get_string_field (message, FIELD_SERVICE, NULL);
710 }
711
712 /**
713  * Appends fields to a message given a variable argument
714  * list. The variable argument list should contain the type
715  * of the field followed by the value to add.
716  * The list is terminated with 0.
717  *
718  * @param message the message
719  * @param first_field_type type of the first field
720  * @param ... value of first field, list of additional type-value pairs
721  * @returns #TRUE on success
722  */
723 dbus_bool_t
724 dbus_message_append_fields (DBusMessage *message,
725                             int first_field_type,
726                             ...)
727 {
728   dbus_bool_t retval;
729   va_list var_args;
730
731   va_start (var_args, first_field_type);
732   retval = dbus_message_append_fields_valist (message,
733                                               first_field_type,
734                                               var_args);
735   va_end (var_args);
736
737   return retval;
738 }
739
740 /**
741  * This function takes a va_list for use by language bindings
742  *
743  * @see dbus_message_append_fields.  
744  * @param message the message
745  * @param first_field_type type of first field
746  * @param var_args value of first field, then list of type/value pairs
747  * @returns #TRUE on success
748  */
749 dbus_bool_t
750 dbus_message_append_fields_valist (DBusMessage *message,
751                                    int          first_field_type,
752                                    va_list      var_args)
753 {
754   int type, old_len;
755
756   old_len = _dbus_string_get_length (&message->body);
757   
758   type = first_field_type;
759
760   while (type != 0)
761     {
762       switch (type)
763         {
764         case DBUS_TYPE_INT32:
765           if (!dbus_message_append_int32 (message, va_arg (var_args, dbus_int32_t)))
766             goto enomem;
767           break;
768         case DBUS_TYPE_UINT32:
769           if (!dbus_message_append_uint32 (message, va_arg (var_args, dbus_uint32_t)))
770             goto enomem;            
771           break;
772         case DBUS_TYPE_DOUBLE:
773           if (!dbus_message_append_double (message, va_arg (var_args, double)))
774             goto enomem;
775           break;
776         case DBUS_TYPE_STRING:
777           if (!dbus_message_append_string (message, va_arg (var_args, const char *)))
778             goto enomem;
779           break;
780         case DBUS_TYPE_BYTE_ARRAY:
781           {
782             int len;
783             unsigned char *data;
784
785             data = va_arg (var_args, unsigned char *);
786             len = va_arg (var_args, int);
787
788             if (!dbus_message_append_byte_array (message, data, len))
789               goto enomem;
790           }
791           break;
792         case DBUS_TYPE_STRING_ARRAY:
793           {
794             int len;
795             const char **data;
796             
797             data = va_arg (var_args, const char **);
798             len = va_arg (var_args, int);
799
800             if (!dbus_message_append_string_array (message, data, len))
801               goto enomem;
802           }
803           break;
804           
805         default:
806           _dbus_warn ("Unknown field type %d\n", type);
807         }
808
809       type = va_arg (var_args, int);
810     }
811
812   return TRUE;
813
814  enomem:
815   _dbus_string_set_length (&message->body, old_len);
816   return FALSE;
817 }
818
819 /**
820  * Appends a 32 bit signed integer to the message.
821  *
822  * @param message the message
823  * @param value the integer value
824  * @returns #TRUE on success
825  */
826 dbus_bool_t
827 dbus_message_append_int32 (DBusMessage  *message,
828                            dbus_int32_t  value)
829 {
830   _dbus_assert (!message->locked);
831
832   if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_INT32))
833     {
834       _dbus_string_shorten (&message->body, 1);
835       return FALSE;
836     }
837   
838   return _dbus_marshal_int32 (&message->body,
839                               DBUS_COMPILER_BYTE_ORDER, value);
840 }
841
842 /**
843  * Appends a 32 bit unsigned integer to the message.
844  *
845  * @param message the message
846  * @param value the integer value
847  * @returns #TRUE on success
848  */
849 dbus_bool_t
850 dbus_message_append_uint32 (DBusMessage   *message,
851                             dbus_uint32_t  value)
852 {
853   _dbus_assert (!message->locked);
854
855   if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_UINT32))
856     {
857       _dbus_string_shorten (&message->body, 1);
858       return FALSE;
859     }
860   
861   return _dbus_marshal_uint32 (&message->body,
862                                DBUS_COMPILER_BYTE_ORDER, value);
863 }
864
865 /**
866  * Appends a double value to the message.
867  *
868  * @param message the message
869  * @param value the double value
870  * @returns #TRUE on success
871  */
872 dbus_bool_t
873 dbus_message_append_double (DBusMessage *message,
874                             double       value)
875 {
876   _dbus_assert (!message->locked);
877
878   if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DOUBLE))
879     {
880       _dbus_string_shorten (&message->body, 1);
881       return FALSE;
882     }
883   
884   return _dbus_marshal_double (&message->body,
885                                DBUS_COMPILER_BYTE_ORDER, value);
886 }
887
888 /**
889  * Appends a UTF-8 string to the message.
890  *
891  * @param message the message
892  * @param value the string
893  * @returns #TRUE on success
894  */
895 dbus_bool_t
896 dbus_message_append_string (DBusMessage *message,
897                             const char  *value)
898 {
899   _dbus_assert (!message->locked);
900
901   if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING))
902     {
903       _dbus_string_shorten (&message->body, 1);
904       return FALSE;
905     }
906   
907   return _dbus_marshal_string (&message->body,
908                                DBUS_COMPILER_BYTE_ORDER, value);
909 }
910
911 /**
912  * Appends a byte array to the message.
913  *
914  * @param message the message
915  * @param value the array
916  * @param len the length of the array
917  * @returns #TRUE on success
918  */
919 dbus_bool_t
920 dbus_message_append_byte_array (DBusMessage         *message,
921                                 unsigned const char *value,
922                                 int                 len)
923 {
924   _dbus_assert (!message->locked);
925
926   if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_BYTE_ARRAY))
927     {
928       _dbus_string_shorten (&message->body, 1);
929       return FALSE;
930     }
931   
932   return _dbus_marshal_byte_array (&message->body,
933                                    DBUS_COMPILER_BYTE_ORDER, value, len);
934 }
935
936 /**
937  * Appends a string array to the message.
938  *
939  * @param message the message
940  * @param value the array
941  * @param len the length of the array
942  * @returns #TRUE on success
943  */
944 dbus_bool_t
945 dbus_message_append_string_array (DBusMessage *message,
946                                   const char **value,
947                                   int          len)
948 {
949   _dbus_assert (!message->locked);
950
951   if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_STRING_ARRAY))
952     {
953       _dbus_string_shorten (&message->body, 1);
954       return FALSE;
955     }
956   
957   return _dbus_marshal_string_array (&message->body,
958                                      DBUS_COMPILER_BYTE_ORDER, value, len);
959 }
960
961 /**
962  * Gets fields from a message given a variable argument list.
963  * The variable argument list should contain the type of the
964  * field followed by a pointer to where the value should be
965  * stored. The list is terminated with 0.
966  *
967  *  @todo rename get_args to avoid confusion with header fields
968  * 
969  * @param message the message
970  * @param first_field_type the first field type
971  * @param ... location for first field value, then list of type-location pairs
972  * @returns result code
973  */
974 DBusResultCode
975 dbus_message_get_fields (DBusMessage *message,
976                          int          first_field_type,
977                          ...)
978 {
979   DBusResultCode retval;
980   va_list var_args;
981
982   va_start (var_args, first_field_type);
983   retval = dbus_message_get_fields_valist (message, first_field_type, var_args);
984   va_end (var_args);
985
986   return retval;
987 }
988
989 /**
990  * This function takes a va_list for use by language bindings
991  *
992  * @todo this function (or some lower-level non-convenience function)
993  * needs better error handling; should allow the application to
994  * distinguish between out of memory, and bad data from the remote
995  * app. It also needs to not leak a bunch of args when it gets
996  * to the arg that's bad, as that would be a security hole
997  * (allow one app to force another to leak memory)
998  *
999  * @todo We need to free the field data when an error occurs.
1000  *
1001  * @todo rename get_args_valist to avoid confusion with header fields
1002  *
1003  * @see dbus_message_get_fields
1004  * @param message the message
1005  * @param first_field_type type of the first field
1006  * @param var_args return location for first field, followed by list of type/location pairs
1007  * @returns result code
1008  */
1009 DBusResultCode
1010 dbus_message_get_fields_valist (DBusMessage *message,
1011                                 int          first_field_type,
1012                                 va_list      var_args)
1013 {
1014   int spec_type, msg_type, i;
1015   DBusMessageIter *iter;
1016
1017   iter = dbus_message_get_fields_iter (message);
1018
1019   if (iter == NULL)
1020     return DBUS_RESULT_NO_MEMORY;
1021   
1022   spec_type = first_field_type;
1023   i = 0;
1024   
1025   while (spec_type != 0)
1026     {
1027       msg_type = dbus_message_iter_get_field_type (iter);      
1028       
1029       if (msg_type != spec_type)
1030         {
1031           _dbus_verbose ("Field %d is specified to be of type \"%s\", but "
1032                          "is actually of type \"%s\"\n", i,
1033                          _dbus_type_to_string (spec_type),
1034                          _dbus_type_to_string (msg_type));
1035           dbus_message_iter_unref (iter);
1036
1037           return DBUS_RESULT_INVALID_FIELDS;
1038         }
1039
1040       switch (spec_type)
1041         {
1042         case DBUS_TYPE_INT32:
1043           {
1044             dbus_int32_t *ptr;
1045
1046             ptr = va_arg (var_args, dbus_int32_t *);
1047
1048             *ptr = dbus_message_iter_get_int32 (iter);
1049             break;
1050           }
1051         case DBUS_TYPE_UINT32:
1052           {
1053             dbus_uint32_t *ptr;
1054
1055             ptr = va_arg (var_args, dbus_uint32_t *);
1056
1057             *ptr = dbus_message_iter_get_uint32 (iter);
1058             break;
1059           }
1060
1061         case DBUS_TYPE_DOUBLE:
1062           {
1063             double *ptr;
1064
1065             ptr = va_arg (var_args, double *);
1066
1067             *ptr = dbus_message_iter_get_double (iter);
1068             break;
1069           }
1070
1071         case DBUS_TYPE_STRING:
1072           {
1073             char **ptr;
1074
1075             ptr = va_arg (var_args, char **);
1076
1077             *ptr = dbus_message_iter_get_string (iter);
1078
1079             if (!*ptr)
1080               return DBUS_RESULT_NO_MEMORY;
1081             
1082             break;
1083           }
1084
1085         case DBUS_TYPE_BYTE_ARRAY:
1086           {
1087             unsigned char **ptr;
1088             int *len;
1089
1090             ptr = va_arg (var_args, unsigned char **);
1091             len = va_arg (var_args, int *);
1092
1093             *ptr = dbus_message_iter_get_byte_array (iter, len);
1094
1095             if (!*ptr)
1096               return DBUS_RESULT_NO_MEMORY;
1097             
1098             break;
1099           }
1100         case DBUS_TYPE_STRING_ARRAY:
1101           {
1102             char ***ptr;
1103             int *len;
1104
1105             ptr = va_arg (var_args, char ***);
1106             len = va_arg (var_args, int *);
1107
1108             *ptr = dbus_message_iter_get_string_array (iter, len);
1109             
1110             if (!*ptr)
1111               return DBUS_RESULT_NO_MEMORY;
1112             
1113             break;
1114           }
1115         default:          
1116           _dbus_warn ("Unknown field type %d\n", spec_type);
1117         }
1118       
1119       spec_type = va_arg (var_args, int);
1120       if (spec_type != 0 && !dbus_message_iter_next (iter))
1121         {
1122           _dbus_verbose ("More fields than exist in the message were specified or field is corrupt\n");
1123
1124           dbus_message_iter_unref (iter);  
1125           return DBUS_RESULT_INVALID_FIELDS;
1126         }
1127       i++;
1128     }
1129
1130   dbus_message_iter_unref (iter);
1131   return DBUS_RESULT_SUCCESS;
1132 }
1133
1134 /**
1135  * Returns a DBusMessageIter representing the fields of the
1136  * message passed in.
1137  *
1138  * @todo IMO the message iter should follow the GtkTextIter pattern,
1139  * a static object with a "stamp" value used to detect invalid
1140  * iter uses (uninitialized or after changing the message).
1141  * ref/unref is kind of annoying to deal with, and slower too.
1142  * This implies not ref'ing the message from the iter.
1143  *
1144  * @todo rename get_args_iter to avoid confusion with header fields
1145  * 
1146  * @param message the message
1147  * @returns a new iter.
1148  */
1149 DBusMessageIter *
1150 dbus_message_get_fields_iter (DBusMessage *message)
1151 {
1152   DBusMessageIter *iter;
1153   
1154   iter = dbus_new (DBusMessageIter, 1);
1155
1156   dbus_message_ref (message);
1157   
1158   iter->refcount = 1;
1159   iter->message = message;
1160   iter->pos = 0;
1161
1162   return iter;
1163 }
1164
1165 /**
1166  * Increments the reference count of a DBusMessageIter.
1167  *
1168  * @param iter the message iter
1169  * @see dbus_message_iter_unref
1170  */
1171 void
1172 dbus_message_iter_ref (DBusMessageIter *iter)
1173 {
1174   _dbus_assert (iter->refcount > 0);
1175   
1176   iter->refcount += 1;
1177 }
1178
1179 /**
1180  * Decrements the reference count of a DBusMessageIter.
1181  *
1182  * @param iter The message iter
1183  * @see dbus_message_iter_ref
1184  */
1185 void
1186 dbus_message_iter_unref (DBusMessageIter *iter)
1187 {
1188   _dbus_assert (iter->refcount > 0);
1189
1190   iter->refcount -= 1;
1191
1192   if (iter->refcount == 0)
1193     {
1194       dbus_message_unref (iter->message);
1195
1196       dbus_free (iter);
1197     }
1198 }
1199
1200 /**
1201  * Checks if an iterator has any more fields.
1202  *
1203  * @param iter the message iter
1204  * @returns #TRUE if there are more fields
1205  * following
1206  */
1207 dbus_bool_t
1208 dbus_message_iter_has_next (DBusMessageIter *iter)
1209 {
1210   int end_pos;
1211   
1212   if (!_dbus_marshal_get_field_end_pos (&iter->message->body, iter->message->byte_order,
1213                                         iter->pos, &end_pos))
1214     return FALSE;
1215   
1216   if (end_pos >= _dbus_string_get_length (&iter->message->body))
1217     return FALSE;
1218   
1219   return TRUE;  
1220 }
1221
1222 /**
1223  * Moves the iterator to the next field.
1224  *
1225  * @param iter The message iter
1226  * @returns #TRUE if the iterator was moved to the next field
1227  */
1228 dbus_bool_t
1229 dbus_message_iter_next (DBusMessageIter *iter)
1230 {
1231   int end_pos;
1232   
1233   if (!_dbus_marshal_get_field_end_pos (&iter->message->body, iter->message->byte_order,
1234                                         iter->pos, &end_pos))
1235     return FALSE;
1236
1237   if (end_pos >= _dbus_string_get_length (&iter->message->body))
1238     return FALSE;
1239
1240   iter->pos = end_pos;
1241
1242   return TRUE;
1243 }
1244
1245 /**
1246  * Returns the field type of the field that the
1247  * message iterator points at.
1248  *
1249  * @param iter the message iter
1250  * @returns the field type
1251  */
1252 int
1253 dbus_message_iter_get_field_type (DBusMessageIter *iter)
1254 {
1255   const char *data;
1256
1257   if (iter->pos >= _dbus_string_get_length (&iter->message->body))
1258     return DBUS_TYPE_INVALID;
1259
1260   _dbus_string_get_const_data_len (&iter->message->body, &data, iter->pos, 1);
1261
1262   if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_STRING_ARRAY)
1263     return *data;
1264
1265   return DBUS_TYPE_INVALID;
1266 }
1267
1268 /**
1269  * Returns the string value that an iterator may point to.
1270  * Note that you need to check that the iterator points to
1271  * a string value before using this function.
1272  *
1273  * @see dbus_message_iter_get_field_type
1274  * @param iter the message iter
1275  * @returns the string
1276  */
1277 char *
1278 dbus_message_iter_get_string (DBusMessageIter *iter)
1279 {
1280   _dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_STRING);
1281
1282   return _dbus_demarshal_string (&iter->message->body, iter->message->byte_order,
1283                                  iter->pos + 1, NULL);
1284 }
1285
1286 /**
1287  * Returns the 32 bit signed integer value that an iterator may point to.
1288  * Note that you need to check that the iterator points to
1289  * a string value before using this function.
1290  *
1291  * @see dbus_message_iter_get_field_type
1292  * @param iter the message iter
1293  * @returns the integer
1294  */
1295 int
1296 dbus_message_iter_get_int32 (DBusMessageIter *iter)
1297 {
1298   return _dbus_demarshal_int32 (&iter->message->body, iter->message->byte_order,
1299                                 iter->pos + 1, NULL);
1300 }
1301
1302 /**
1303  * Returns the 32 bit unsigned integer value that an iterator may point to.
1304  * Note that you need to check that the iterator points to
1305  * a string value before using this function.
1306  *
1307  * @see dbus_message_iter_get_field_type
1308  * @param iter the message iter
1309  * @returns the integer
1310  */
1311 int
1312 dbus_message_iter_get_uint32 (DBusMessageIter *iter)
1313 {
1314   return _dbus_demarshal_uint32 (&iter->message->body, iter->message->byte_order,
1315                                  iter->pos + 1, NULL);
1316 }
1317
1318 /**
1319  * Returns the double value that an iterator may point to.
1320  * Note that you need to check that the iterator points to
1321  * a string value before using this function.
1322  *
1323  * @see dbus_message_iter_get_field_type
1324  * @param iter the message iter
1325  * @returns the double
1326  */
1327 double
1328 dbus_message_iter_get_double (DBusMessageIter *iter)
1329 {
1330   return _dbus_demarshal_double (&iter->message->body, iter->message->byte_order,
1331                                  iter->pos + 1, NULL);
1332 }
1333
1334 /**
1335  * Returns the byte array that the iterator may point to.
1336  * Note that you need to check that the iterator points
1337  * to a byte array prior to using this function.
1338  *
1339  * @todo this function should probably take "unsigned char **" as
1340  * an out param argument, and return boolean or result code.
1341  *
1342  * @param iter the iterator
1343  * @param len return location for length of byte array
1344  * @returns the byte array
1345  */
1346 unsigned char *
1347 dbus_message_iter_get_byte_array (DBusMessageIter *iter,
1348                                   int             *len)
1349 {
1350   _dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_BYTE_ARRAY);
1351
1352   return _dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
1353                                      iter->pos + 1, NULL, len);
1354 }
1355
1356 /**
1357  * Returns the string array that the iterator may point to.
1358  * Note that you need to check that the iterator points
1359  * to a byte array prior to using this function.
1360  *
1361  * @todo this function should probably take "char **" as
1362  * an out param argument, and return boolean or result code.
1363  *
1364  * @param iter the iterator
1365  * @param len return location for length of byte array
1366  * @returns the byte array
1367  */
1368 char **
1369 dbus_message_iter_get_string_array (DBusMessageIter *iter,
1370                                     int             *len)
1371 {
1372   _dbus_assert (dbus_message_iter_get_field_type (iter) == DBUS_TYPE_STRING_ARRAY);
1373
1374   return _dbus_demarshal_string_array (&iter->message->body, iter->message->byte_order,
1375                                        iter->pos + 1, NULL, len);
1376 }
1377
1378 /**
1379  * Sets the message sender.
1380  *
1381  * @todo implement #NULL sender to unset
1382  *
1383  * @param message the message
1384  * @param sender the sender
1385  * @returns #FALSE if not enough memory
1386  */
1387 dbus_bool_t
1388 dbus_message_set_sender (DBusMessage  *message,
1389                          const char   *sender)
1390 {
1391   _dbus_assert (!message->locked);
1392
1393   if (sender == NULL)
1394     {
1395       _dbus_warn ("need to implement unsetting sender field\n");
1396       return TRUE;
1397     }
1398   else
1399     {
1400       return set_string_field (message,
1401                                FIELD_SENDER,
1402                                sender);
1403     }
1404 }
1405
1406 const char*
1407 dbus_message_get_sender (DBusMessage *message)
1408 {
1409   return get_string_field (message, FIELD_SENDER, NULL);
1410 }
1411
1412 /** @} */
1413
1414 /**
1415  * @addtogroup DBusMessageInternals
1416  *
1417  * @{
1418  */
1419 /**
1420  * @typedef DBusMessageLoader
1421  *
1422  * The DBusMessageLoader object encapsulates the process of converting
1423  * a byte stream into a series of DBusMessage. It buffers the incoming
1424  * bytes as efficiently as possible, and generates a queue of
1425  * messages. DBusMessageLoader is typically used as part of a
1426  * DBusTransport implementation. The DBusTransport then hands off
1427  * the loaded messages to a DBusConnection, making the messages
1428  * visible to the application.
1429  * 
1430  */
1431
1432 /**
1433  * Implementation details of DBusMessageLoader.
1434  * All members are private.
1435  */
1436 struct DBusMessageLoader
1437 {
1438   int refcount;        /**< Reference count. */
1439
1440   DBusString data;     /**< Buffered data */
1441   
1442   DBusList *messages;  /**< Complete messages. */
1443
1444   long max_message_size; /**< Maximum size of a message */
1445   
1446   unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
1447
1448   unsigned int corrupted : 1; /**< We got broken data, and are no longer working */
1449 };
1450
1451 /**
1452  * The initial buffer size of the message loader.
1453  * 
1454  * @todo this should be based on min header size plus some average
1455  * body size, or something. Or rather, the min header size only, if we
1456  * want to try to read only the header, store that in a DBusMessage,
1457  * then read only the body and store that, etc., depends on
1458  * how we optimize _dbus_message_loader_get_buffer() and what
1459  * the exact message format is.
1460  */
1461 #define INITIAL_LOADER_DATA_LEN 32
1462
1463 /**
1464  * Creates a new message loader. Returns #NULL if memory can't
1465  * be allocated.
1466  *
1467  * @returns new loader, or #NULL.
1468  */
1469 DBusMessageLoader*
1470 _dbus_message_loader_new (void)
1471 {
1472   DBusMessageLoader *loader;
1473
1474   loader = dbus_new0 (DBusMessageLoader, 1);
1475   if (loader == NULL)
1476     return NULL;
1477   
1478   loader->refcount = 1;
1479
1480   /* Try to cap message size at something that won't *totally* hose
1481    * the system if we have a couple of them.
1482    */
1483   loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
1484   
1485   if (!_dbus_string_init (&loader->data, _DBUS_INT_MAX))
1486     {
1487       dbus_free (loader);
1488       return NULL;
1489     }
1490
1491   /* preallocate the buffer for speed, ignore failure */
1492   _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);
1493   _dbus_string_set_length (&loader->data, 0);
1494   
1495   return loader;
1496 }
1497
1498 /**
1499  * Increments the reference count of the loader.
1500  *
1501  * @param loader the loader.
1502  */
1503 void
1504 _dbus_message_loader_ref (DBusMessageLoader *loader)
1505 {
1506   loader->refcount += 1;
1507 }
1508
1509 /**
1510  * Decrements the reference count of the loader and finalizes the
1511  * loader when the count reaches zero.
1512  *
1513  * @param loader the loader.
1514  */
1515 void
1516 _dbus_message_loader_unref (DBusMessageLoader *loader)
1517 {
1518   loader->refcount -= 1;
1519   if (loader->refcount == 0)
1520     {
1521       _dbus_list_foreach (&loader->messages,
1522                           (DBusForeachFunction) dbus_message_unref,
1523                           NULL);
1524       _dbus_list_clear (&loader->messages);
1525       _dbus_string_free (&loader->data);
1526       dbus_free (loader);
1527     }
1528 }
1529
1530 /**
1531  * Gets the buffer to use for reading data from the network.  Network
1532  * data is read directly into an allocated buffer, which is then used
1533  * in the DBusMessage, to avoid as many extra memcpy's as possible.
1534  * The buffer must always be returned immediately using
1535  * _dbus_message_loader_return_buffer(), even if no bytes are
1536  * successfully read.
1537  *
1538  * @todo this function can be a lot more clever. For example
1539  * it can probably always return a buffer size to read exactly
1540  * the body of the next message, thus avoiding any memory wastage
1541  * or reallocs.
1542  * 
1543  * @param loader the message loader.
1544  * @param buffer the buffer
1545  */
1546 void
1547 _dbus_message_loader_get_buffer (DBusMessageLoader  *loader,
1548                                  DBusString        **buffer)
1549 {
1550   _dbus_assert (!loader->buffer_outstanding);
1551
1552   *buffer = &loader->data;
1553   
1554   loader->buffer_outstanding = TRUE;
1555 }
1556
1557 /**
1558  * The smallest header size that can occur. 
1559  * (It won't be valid)
1560  */
1561 #define DBUS_MINIMUM_HEADER_SIZE 16
1562
1563 /** Pack four characters as in "abcd" into a uint32 */
1564 #define FOUR_CHARS_TO_UINT32(a, b, c, d)                \
1565                       ((((dbus_uint32_t)a) << 24) |     \
1566                        (((dbus_uint32_t)b) << 16) |     \
1567                        (((dbus_uint32_t)c) << 8)  |     \
1568                        ((dbus_uint32_t)d))
1569
1570 /** DBUS_HEADER_FIELD_NAME packed into a dbus_uint32_t */
1571 #define DBUS_HEADER_FIELD_NAME_AS_UINT32    \
1572   FOUR_CHARS_TO_UINT32 ('n', 'a', 'm', 'e')
1573
1574 /** DBUS_HEADER_FIELD_SERVICE packed into a dbus_uint32_t */
1575 #define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
1576   FOUR_CHARS_TO_UINT32 ('s', 'r', 'v', 'c')
1577
1578 /** DBUS_HEADER_FIELD_REPLY packed into a dbus_uint32_t */
1579 #define DBUS_HEADER_FIELD_REPLY_AS_UINT32   \
1580   FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
1581
1582 /** DBUS_HEADER_FIELD_SENDER Packed into a dbus_uint32_t */
1583 #define DBUS_HEADER_FIELD_SENDER_AS_UINT32  \
1584   FOUR_CHARS_TO_UINT32 ('s', 'n', 'd', 'r')
1585
1586
1587 /* FIXME should be using DBusString for the stuff we demarshal.  char*
1588  * evil. Also, out of memory handling here seems suboptimal.
1589  * Should probably report it as a distinct error from "corrupt message,"
1590  * so we can postpone parsing this message. Also, we aren't
1591  * checking for demarshal failure everywhere.
1592  */
1593 static dbus_bool_t
1594 decode_header_data (DBusString   *data,
1595                     int           header_len,
1596                     int           byte_order,
1597                     HeaderField   fields[FIELD_LAST])
1598 {
1599   const char *field;
1600   int pos, new_pos;
1601   int i;
1602   
1603   if (header_len < 16)
1604     return FALSE;
1605
1606   i = 0;
1607   while (i < FIELD_LAST)
1608     {
1609       fields[i].offset = -1;
1610       ++i;
1611     }
1612   
1613   fields[FIELD_HEADER_LENGTH].offset = 4;
1614   fields[FIELD_BODY_LENGTH].offset = 8;   
1615   fields[FIELD_CLIENT_SERIAL].offset = 12;
1616   
1617   /* Now handle the fields */
1618   pos = 16;
1619   while (pos < header_len)
1620     {
1621       pos = _DBUS_ALIGN_VALUE (pos, 4);
1622       
1623       if ((pos + 4) > header_len)
1624         return FALSE;      
1625       
1626       _dbus_string_get_const_data_len (data, &field, pos, 4);
1627       pos += 4;
1628
1629       _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
1630
1631       /* I believe FROM_BE is right, but if not we'll find out
1632        * I guess. ;-)
1633        */
1634       switch (DBUS_UINT32_FROM_BE (*(int*)field))
1635         {
1636         case DBUS_HEADER_FIELD_SERVICE_AS_UINT32:
1637           if (fields[FIELD_SERVICE].offset >= 0)
1638             {
1639               _dbus_verbose ("%s field provided twice\n",
1640                              DBUS_HEADER_FIELD_SERVICE);
1641               return FALSE;
1642             }
1643           
1644           fields[FIELD_SERVICE].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
1645           _dbus_verbose ("Found service name at offset %d\n",
1646                          fields[FIELD_SERVICE].offset);
1647           break;
1648
1649         case DBUS_HEADER_FIELD_NAME_AS_UINT32:
1650           if (fields[FIELD_NAME].offset >= 0)
1651             {
1652               _dbus_verbose ("%s field provided twice\n",
1653                              DBUS_HEADER_FIELD_NAME);
1654               return FALSE;
1655             }
1656           
1657           fields[FIELD_NAME].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
1658
1659           _dbus_verbose ("Found message name at offset %d\n",
1660                          fields[FIELD_NAME].offset);
1661           break;
1662         case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
1663           if (fields[FIELD_SENDER].offset >= 0)
1664             {
1665               _dbus_verbose ("%s field provided twice\n",
1666                              DBUS_HEADER_FIELD_SENDER);
1667               return FALSE;
1668             }
1669           
1670           fields[FIELD_SENDER].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
1671
1672           _dbus_verbose ("Found sender name at offset %d\n",
1673                          fields[FIELD_NAME].offset);
1674           break;
1675           
1676         case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
1677           if (fields[FIELD_REPLY_SERIAL].offset >= 0)
1678             {
1679               _dbus_verbose ("%s field provided twice\n",
1680                              DBUS_HEADER_FIELD_REPLY);
1681               return FALSE;
1682             }
1683           
1684           fields[FIELD_REPLY_SERIAL].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
1685
1686           _dbus_verbose ("Found reply serial at offset %d\n",
1687                          fields[FIELD_REPLY_SERIAL].offset);
1688           break;
1689
1690         default:
1691           _dbus_verbose ("Ignoring an unknown header field: %c%c%c%c\n",
1692                          field[0], field[1], field[2], field[3]);
1693         }
1694
1695       /* This function has to validate the fields */
1696       if (!_dbus_marshal_get_field_end_pos (data, byte_order, pos, &new_pos))
1697         return FALSE;
1698
1699       if (new_pos > header_len)
1700         return FALSE;
1701       
1702       pos = new_pos;
1703     }
1704   
1705   return TRUE;
1706 }
1707
1708 /**
1709  * Returns a buffer obtained from _dbus_message_loader_get_buffer(),
1710  * indicating to the loader how many bytes of the buffer were filled
1711  * in. This function must always be called, even if no bytes were
1712  * successfully read.
1713  *
1714  * @param loader the loader.
1715  * @param buffer the buffer.
1716  * @param bytes_read number of bytes that were read into the buffer.
1717  */
1718 void
1719 _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
1720                                     DBusString         *buffer,
1721                                     int                 bytes_read)
1722 {
1723   _dbus_assert (loader->buffer_outstanding);
1724   _dbus_assert (buffer == &loader->data);
1725
1726   loader->buffer_outstanding = FALSE;
1727
1728   if (loader->corrupted)
1729     return;
1730
1731   while (_dbus_string_get_length (&loader->data) >= 16)
1732     {
1733       DBusMessage *message;      
1734       const char *header_data;
1735       int byte_order, header_len, body_len;
1736       
1737       _dbus_string_get_const_data_len (&loader->data, &header_data, 0, 16);
1738
1739       _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
1740       
1741       byte_order = header_data[0];
1742
1743       if (byte_order != DBUS_LITTLE_ENDIAN &&
1744           byte_order != DBUS_BIG_ENDIAN)
1745         {
1746           _dbus_verbose ("Message with bad byte order '%c' received\n",
1747                          byte_order);
1748           loader->corrupted = TRUE;
1749           return;
1750         }
1751
1752       header_len = _dbus_unpack_int32 (byte_order, header_data + 4);
1753       body_len = _dbus_unpack_int32 (byte_order, header_data + 8);
1754
1755       if (header_len + body_len > loader->max_message_size)
1756         {
1757           _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %d\n",
1758                          header_len, body_len, loader->max_message_size);
1759           loader->corrupted = TRUE;
1760           return;
1761         }
1762
1763       if (_dbus_string_get_length (&loader->data) >= header_len + body_len)
1764         {
1765           HeaderField fields[FIELD_LAST];
1766           int i;
1767           
1768           /* FIXME right now if this doesn't have enough memory, the
1769            * loader becomes corrupted. Instead we should just not
1770            * parse this message for now.
1771            */
1772           if (!decode_header_data (&loader->data, header_len, byte_order,
1773                                    fields))
1774             {
1775               loader->corrupted = TRUE;
1776               return;
1777             }
1778
1779           message = dbus_message_new_empty_header ();
1780           if (message == NULL)
1781             break; /* ugh, postpone this I guess. */
1782
1783           /* Copy in the offsets we found */
1784           i = 0;
1785           while (i < FIELD_LAST)
1786             {
1787               message->header_fields[i] = fields[i];
1788               ++i;
1789             }
1790           
1791           if (!_dbus_list_append (&loader->messages, message))
1792             {
1793               dbus_message_unref (message);
1794               break;
1795             }
1796
1797           _dbus_assert (_dbus_string_get_length (&message->header) == 0);
1798           _dbus_assert (_dbus_string_get_length (&message->body) == 0);
1799
1800           _dbus_assert (_dbus_string_get_length (&loader->data) >=
1801                         (header_len + body_len));
1802           
1803           if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
1804             {
1805               _dbus_list_remove_last (&loader->messages, message);
1806               dbus_message_unref (message);
1807               break;
1808             }
1809           
1810           if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
1811             {
1812               dbus_bool_t result;
1813
1814               /* put the header back, we'll try again later */
1815               result = _dbus_string_copy_len (&message->header, 0, header_len,
1816                                               &loader->data, 0);
1817               _dbus_assert (result); /* because DBusString never reallocs smaller */
1818
1819               _dbus_list_remove_last (&loader->messages, message);
1820               dbus_message_unref (message);
1821               break;
1822             }
1823
1824           _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
1825           _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
1826
1827           _dbus_verbose ("Loaded message %p\n", message);
1828         }
1829       else
1830         break;
1831     }
1832 }
1833
1834 /**
1835  * Pops a loaded message (passing ownership of the message
1836  * to the caller). Returns #NULL if no messages have been
1837  * loaded.
1838  *
1839  * @param loader the loader.
1840  * @returns the next message, or #NULL if none.
1841  */
1842 DBusMessage*
1843 _dbus_message_loader_pop_message (DBusMessageLoader *loader)
1844 {
1845   return _dbus_list_pop_first (&loader->messages);
1846 }
1847
1848
1849 /**
1850  * Checks whether the loader is confused due to bad data.
1851  * If messages are received that are invalid, the
1852  * loader gets confused and gives up permanently.
1853  * This state is called "corrupted."
1854  *
1855  * @param loader the loader
1856  * @returns #TRUE if the loader is hosed.
1857  */
1858 dbus_bool_t
1859 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
1860 {
1861   return loader->corrupted;
1862 }
1863
1864 /**
1865  * Sets the maximum size message we allow.
1866  *
1867  * @param loader the loader
1868  * @param size the max message size in bytes
1869  */
1870 void
1871 _dbus_message_loader_set_max_message_size (DBusMessageLoader  *loader,
1872                                            long                size)
1873 {
1874   loader->max_message_size = size;
1875 }
1876
1877 /**
1878  * Gets the maximum allowed message size in bytes.
1879  *
1880  * @param loader the loader
1881  * @returns max size in bytes
1882  */
1883 long
1884 _dbus_message_loader_get_max_message_size (DBusMessageLoader  *loader)
1885 {
1886   return loader->max_message_size;
1887 }
1888
1889 /** @} */
1890 #ifdef DBUS_BUILD_TESTS
1891 #include "dbus-test.h"
1892 #include <stdio.h>
1893
1894 static void
1895 message_iter_test (DBusMessage *message)
1896 {
1897   DBusMessageIter *iter;
1898   char *str;
1899   
1900   iter = dbus_message_get_fields_iter (message);
1901
1902   /* String tests */
1903   if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_STRING)
1904     _dbus_assert_not_reached ("Field type isn't string");
1905
1906   str = dbus_message_iter_get_string (iter);
1907   if (strcmp (str, "Test string") != 0)
1908     _dbus_assert_not_reached ("Strings differ");
1909   dbus_free (str);
1910
1911   if (!dbus_message_iter_next (iter))
1912     _dbus_assert_not_reached ("Reached end of fields");
1913
1914   /* Signed integer tests */
1915   if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_INT32)
1916     _dbus_assert_not_reached ("Field type isn't int32");
1917
1918   if (dbus_message_iter_get_int32 (iter) != -0x12345678)
1919     _dbus_assert_not_reached ("Signed integers differ");
1920
1921   if (!dbus_message_iter_next (iter))
1922     _dbus_assert_not_reached ("Reached end of fields");
1923   
1924   /* Unsigned integer tests */
1925   if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_UINT32)
1926     _dbus_assert_not_reached ("Field type isn't int32");
1927
1928   if (dbus_message_iter_get_int32 (iter) != 0xedd1e)
1929     _dbus_assert_not_reached ("Unsigned integers differ");
1930
1931   if (!dbus_message_iter_next (iter))
1932     _dbus_assert_not_reached ("Reached end of fields");
1933
1934   /* Double tests */
1935   if (dbus_message_iter_get_field_type (iter) != DBUS_TYPE_DOUBLE)
1936     _dbus_assert_not_reached ("Field type isn't double");
1937
1938   if (dbus_message_iter_get_double (iter) != 3.14159)
1939     _dbus_assert_not_reached ("Doubles differ");
1940
1941   if (dbus_message_iter_next (iter))
1942     _dbus_assert_not_reached ("Didn't reach end of fields");
1943   
1944   dbus_message_iter_unref (iter);
1945 }
1946
1947 /**
1948  * @ingroup DBusMessageInternals
1949  * Unit test for DBusMessage.
1950  *
1951  * @returns #TRUE on success.
1952  */
1953 dbus_bool_t
1954 _dbus_message_test (void)
1955 {
1956   DBusMessage *message;
1957   DBusMessageLoader *loader;
1958   int i;
1959   const char *data;
1960   dbus_int32_t our_int;
1961   char *our_str;
1962   double our_double;
1963   
1964   /* Test the vararg functions */
1965   message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
1966   _dbus_message_set_client_serial (message, 1);
1967   dbus_message_append_fields (message,
1968                               DBUS_TYPE_INT32, -0x12345678,
1969                               DBUS_TYPE_STRING, "Test string",
1970                               DBUS_TYPE_DOUBLE, 3.14159,
1971                               0);
1972   _dbus_verbose_bytes_of_string (&message->header, 0,
1973                                  _dbus_string_get_length (&message->header));
1974   _dbus_verbose_bytes_of_string (&message->body, 0,
1975                                  _dbus_string_get_length (&message->body));
1976   
1977   if (dbus_message_get_fields (message,
1978                                DBUS_TYPE_INT32, &our_int,
1979                                DBUS_TYPE_STRING, &our_str,
1980                                DBUS_TYPE_DOUBLE, &our_double,
1981                                0) != DBUS_RESULT_SUCCESS)
1982     _dbus_assert_not_reached ("Could not get fields");
1983
1984   if (our_int != -0x12345678)
1985     _dbus_assert_not_reached ("integers differ!");
1986
1987   if (our_double != 3.14159)
1988     _dbus_assert_not_reached ("doubles differ!");
1989
1990   if (strcmp (our_str, "Test string") != 0)
1991     _dbus_assert_not_reached ("strings differ!");
1992
1993   dbus_free (our_str);
1994   dbus_message_unref (message);
1995   
1996   message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
1997   _dbus_message_set_client_serial (message, 1);
1998   _dbus_message_set_reply_serial (message, 0x12345678);
1999
2000   dbus_message_append_string (message, "Test string");
2001   dbus_message_append_int32 (message, -0x12345678);
2002   dbus_message_append_uint32 (message, 0xedd1e);
2003   dbus_message_append_double (message, 3.14159);
2004
2005   message_iter_test (message);
2006
2007   /* Message loader test */
2008   _dbus_message_lock (message);
2009   loader = _dbus_message_loader_new ();
2010
2011   /* Write the header data one byte at a time */
2012   _dbus_string_get_const_data (&message->header, &data);
2013   for (i = 0; i < _dbus_string_get_length (&message->header); i++)
2014     {
2015       DBusString *buffer;
2016
2017       _dbus_message_loader_get_buffer (loader, &buffer);
2018       _dbus_string_append_byte (buffer, data[i]);
2019       _dbus_message_loader_return_buffer (loader, buffer, 1);
2020     }
2021
2022   /* Write the body data one byte at a time */
2023   _dbus_string_get_const_data (&message->body, &data);
2024   for (i = 0; i < _dbus_string_get_length (&message->body); i++)
2025     {
2026       DBusString *buffer;
2027
2028       _dbus_message_loader_get_buffer (loader, &buffer);
2029       _dbus_string_append_byte (buffer, data[i]);
2030       _dbus_message_loader_return_buffer (loader, buffer, 1);
2031     }
2032
2033   dbus_message_unref (message);
2034
2035   /* Now pop back the message */
2036   if (_dbus_message_loader_get_is_corrupted (loader))
2037     _dbus_assert_not_reached ("message loader corrupted");
2038   
2039   message = _dbus_message_loader_pop_message (loader);
2040   if (!message)
2041     _dbus_assert_not_reached ("received a NULL message");
2042
2043   if (_dbus_message_get_reply_serial (message) != 0x12345678)
2044     _dbus_assert_not_reached ("reply serial fields differ");
2045   
2046   message_iter_test (message);
2047   
2048   dbus_message_unref (message);
2049   _dbus_message_loader_unref (loader);
2050
2051   return TRUE;
2052 }
2053
2054 #endif /* DBUS_BUILD_TESTS */