diff options
Diffstat (limited to 'dbus/dbus-message-builder.c')
| -rw-r--r-- | dbus/dbus-message-builder.c | 193 | 
1 files changed, 177 insertions, 16 deletions
| diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c index 390dda75..c9dc8ca5 100644 --- a/dbus/dbus-message-builder.c +++ b/dbus/dbus-message-builder.c @@ -40,9 +40,12 @@   * @{   */ +/** + * Saved length + */  typedef struct  { -  DBusString name; +  DBusString name; /**< Name of the length */    int start;  /**< Calculate length since here */    int length; /**< length to write */    int offset; /**< where to write it into the data */ @@ -265,6 +268,73 @@ append_saved_length (DBusString       *dest,    return TRUE;  } +static int +message_type_from_string (const DBusString *str, +                          int               start) +{ +  const char *s; + +  s = _dbus_string_get_const_data_len (str, start, +                                       _dbus_string_get_length (str) - start); + +  if (strncmp (s, "method_call", strlen ("method_call")) == 0) +    return DBUS_MESSAGE_TYPE_METHOD_CALL; +  else if (strncmp (s, "method_return", strlen ("method_return")) == 0) +    return DBUS_MESSAGE_TYPE_METHOD_RETURN; +  else if (strncmp (s, "signal", strlen ("signal")) == 0) +    return DBUS_MESSAGE_TYPE_SIGNAL; +  else if (strncmp (s, "error", strlen ("error")) == 0) +    return DBUS_MESSAGE_TYPE_ERROR; +  else if (strncmp (s, "invalid", strlen ("invalid")) == 0) +    return DBUS_MESSAGE_TYPE_INVALID; +  else +    return -1; +} + +static dbus_bool_t +append_string_field (DBusString *dest, +                     int         endian, +                     int         field, +                     int         type, +                     const char *value) +{ +  int len; +   +  if (!_dbus_string_append_byte (dest, field)) +    { +      _dbus_warn ("couldn't append field name byte\n"); +      return FALSE; +    } +   +  if (!_dbus_string_append_byte (dest, type)) +    { +      _dbus_warn ("could not append typecode byte\n"); +      return FALSE; +    } + +  len = strlen (value); + +  if (!_dbus_marshal_uint32 (dest, endian, len)) +    { +      _dbus_warn ("couldn't append string length\n"); +      return FALSE; +    } +   +  if (!_dbus_string_append (dest, value)) +    { +      _dbus_warn ("couldn't append field value\n"); +      return FALSE; +    } + +  if (!_dbus_string_append_byte (dest, 0)) +    { +      _dbus_warn ("couldn't append string nul term\n"); +      return FALSE; +    } + +  return TRUE; +} +  /**   * Reads the given filename, which should be in "message description   * language" (look at some examples), and builds up the message data @@ -274,7 +344,8 @@ append_saved_length (DBusString       *dest,   *    * The file format is:   * @code - *   VALID_HEADER normal header; byte order, padding, header len, body len, serial + *   VALID_HEADER <type> normal header; byte order, type, padding, header len, body len, serial + *   REQUIRED_FIELDS add required fields with placeholder values   *   BIG_ENDIAN switch to big endian   *   LITTLE_ENDIAN switch to little endian   *   OPPOSITE_ENDIAN switch to opposite endian @@ -286,7 +357,7 @@ append_saved_length (DBusString       *dest,   *                     (or if no START_LENGTH, absolute length)   *   LENGTH <name> inserts the saved length of the same name   *   CHOP <N> chops last N bytes off the data - *   FIELD_NAME <abcd> inserts 4-byte field name + *   HEADER_FIELD <fieldname> inserts a header field name byte   *   TYPE <typename> inserts a typecode byte    * @endcode   *  @@ -299,6 +370,7 @@ append_saved_length (DBusString       *dest,   *   UINT64 <N> marshals a UINT64   *   DOUBLE <N> marshals a double   *   STRING 'Foo' marshals a string + *   OBJECT_PATH '/foo/bar' marshals an object path   *   BYTE_ARRAY { 'a', 3, 4, 5, 6} marshals a BYTE array   *   BOOLEAN_ARRAY { false, true, false} marshals a BOOLEAN array   *   INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array @@ -386,6 +458,13 @@ _dbus_message_data_load (DBusString       *dest,          {            int i;            DBusString name; +          int message_type; + +          if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER ")) +            { +              _dbus_warn ("no args to VALID_HEADER\n"); +              goto parse_failed; +            }            if (!_dbus_string_append_byte (dest, endian))              { @@ -393,8 +472,22 @@ _dbus_message_data_load (DBusString       *dest,                goto parse_failed;              } +          message_type = message_type_from_string (&line, +                                                   strlen ("VALID_HEADER ")); +          if (message_type < 0) +            { +              _dbus_warn ("VALID_HEADER not followed by space then known message type\n"); +              goto parse_failed; +            } +           +          if (!_dbus_string_append_byte (dest, message_type)) +            { +              _dbus_warn ("could not append message type\n"); +              goto parse_failed; +            } +                      i = 0; -          while (i < 3) +          while (i < 2)              {                if (!_dbus_string_append_byte (dest, '\0'))                  { @@ -424,6 +517,25 @@ _dbus_message_data_load (DBusString       *dest,              }          }        else if (_dbus_string_starts_with_c_str (&line, +                                               "REQUIRED_FIELDS")) +        { +          if (!append_string_field (dest, endian, +                                    DBUS_HEADER_FIELD_INTERFACE, +                                    DBUS_TYPE_STRING, +                                    "org.freedesktop.BlahBlahInterface")) +            goto parse_failed; +          if (!append_string_field (dest, endian, +                                    DBUS_HEADER_FIELD_MEMBER, +                                    DBUS_TYPE_STRING, +                                    "BlahBlahMethod")) +            goto parse_failed; +          if (!append_string_field (dest, endian, +                                    DBUS_HEADER_FIELD_PATH, +                                    DBUS_TYPE_OBJECT_PATH, +                                    "/blah/blah/path")) +            goto parse_failed; +        } +      else if (_dbus_string_starts_with_c_str (&line,                                                 "BIG_ENDIAN"))          {            endian = DBUS_BIG_ENDIAN; @@ -561,25 +673,42 @@ _dbus_message_data_load (DBusString       *dest,            PERFORM_UNALIGN (dest);          }        else if (_dbus_string_starts_with_c_str (&line, -                                               "FIELD_NAME")) +                                               "HEADER_FIELD"))          { +	  int field; +            _dbus_string_delete_first_word (&line); -          if (_dbus_string_get_length (&line) != 4) +          if (_dbus_string_starts_with_c_str (&line, "INVALID")) +            field = DBUS_HEADER_FIELD_INVALID; +          else if (_dbus_string_starts_with_c_str (&line, "PATH")) +	    field = DBUS_HEADER_FIELD_PATH; +          else if (_dbus_string_starts_with_c_str (&line, "INTERFACE")) +	    field = DBUS_HEADER_FIELD_INTERFACE; +          else if (_dbus_string_starts_with_c_str (&line, "MEMBER")) +	    field = DBUS_HEADER_FIELD_MEMBER; +          else if (_dbus_string_starts_with_c_str (&line, "ERROR_NAME")) +	    field = DBUS_HEADER_FIELD_ERROR_NAME; +          else if (_dbus_string_starts_with_c_str (&line, "REPLY_SERIAL")) +	    field = DBUS_HEADER_FIELD_REPLY_SERIAL; +          else if (_dbus_string_starts_with_c_str (&line, "SERVICE")) +	    field = DBUS_HEADER_FIELD_SERVICE; +          else if (_dbus_string_starts_with_c_str (&line, "SENDER_SERVICE")) +	    field = DBUS_HEADER_FIELD_SENDER_SERVICE; +	  else if (_dbus_string_starts_with_c_str (&line, "UNKNOWN")) +	    field = 22; /* random unknown header field */ +          else              { -              _dbus_warn ("Field name must be four characters not \"%s\"\n", -                          _dbus_string_get_const_data (&line)); +              _dbus_warn ("%s is not a valid header field name\n", +			  _dbus_string_get_const_data (&line));                goto parse_failed;              } -          if (unalign) -            unalign = FALSE; -          else -            _dbus_string_align_length (dest, 4); -           -          if (!_dbus_string_copy (&line, 0, dest, -                                  _dbus_string_get_length (dest))) -            goto parse_failed; +          if (!_dbus_string_append_byte (dest, field)) +	    { +              _dbus_warn ("could not append header field name byte\n"); +	      goto parse_failed; +	    }          }        else if (_dbus_string_starts_with_c_str (&line,                                                 "TYPE")) @@ -604,6 +733,8 @@ _dbus_message_data_load (DBusString       *dest,              code = DBUS_TYPE_DOUBLE;            else if (_dbus_string_starts_with_c_str (&line, "STRING"))              code = DBUS_TYPE_STRING; +          else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH")) +            code = DBUS_TYPE_OBJECT_PATH;            else if (_dbus_string_starts_with_c_str (&line, "NAMED"))              code = DBUS_TYPE_NAMED;            else if (_dbus_string_starts_with_c_str (&line, "ARRAY")) @@ -1226,6 +1357,36 @@ _dbus_message_data_load (DBusString       *dest,            PERFORM_UNALIGN (dest);          } +      else if (_dbus_string_starts_with_c_str (&line, +                                               "OBJECT_PATH")) +        { +          SAVE_FOR_UNALIGN (dest, 4); +          int size_offset; +          int old_len; +           +          _dbus_string_delete_first_word (&line); +           +          size_offset = _dbus_string_get_length (dest); +          size_offset = _DBUS_ALIGN_VALUE (size_offset, 4); +          if (!_dbus_marshal_uint32 (dest, endian, 0)) +            { +              _dbus_warn ("Failed to append string size\n"); +              goto parse_failed; +            } + +          old_len = _dbus_string_get_length (dest); +          if (!append_quoted_string (dest, &line, 0, NULL)) +            { +              _dbus_warn ("Failed to append quoted string\n"); +              goto parse_failed; +            } + +          _dbus_marshal_set_uint32 (dest, endian, size_offset, +                                    /* subtract 1 for nul */ +                                    _dbus_string_get_length (dest) - old_len - 1); +           +          PERFORM_UNALIGN (dest); +        }              else          goto parse_failed; | 
