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