Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15498124
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2009-06-09 12:54:07

浅析dbus_message_new_signal()函数内部具体实现

/** The object path used in local/in-process-generated messages. */
#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
/** This is a special interface whose methods can only be invoked
 * by the local implementation (messages from remote apps aren't
 * allowed to specify this interface).
 */

#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"

DBusMessage*
dbus_message_new_signal (const char *path,
                         const char *interface,
                         const char *name)
{
  DBusMessage *message;

  _dbus_return_val_if_fail (path != NULL, NULL);
  _dbus_return_val_if_fail (interface != NULL, NULL);
  _dbus_return_val_if_fail (name != NULL, NULL);
  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);

  message = dbus_message_new_empty_header (); // 如果message cache缓冲区有释放的message内存,返回

  // cache中的内存,否则调用message = dbus_new (DBusMessage, 1);申请一块内存,初始化完message内存之后

  // 进一步清空&message->header[luther.gliethttp]

  // 1.为&header->data申请32字节的数据存储保证空间.

  // 2.设置&header->data有效数据长度为0

  // 3.header->byte_order = byte_order; // 占用2字节空间以上数据对应的大小端模式

  // 4.header->padding = 0; // padding被强制初始化成0

  // 5.header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN; // 所有fileds域置无效值

  // 6.为&message->body申请32字节的数据存储保证空间.

  // 好了,一个全新的message空间申请完成了,同时message->header也完成了他应有的初始化工作.[lutehr.gliethttp]

  if (message == NULL)
    return NULL;

  if (!_dbus_header_create (&message->header, // 为空的message->header.data[]空间填入有效数据

                            DBUS_MESSAGE_TYPE_SIGNAL,
                            NULL, path, interface, name, NULL))
    {
      dbus_message_unref (message);
      return NULL;
    }

  dbus_message_set_no_reply (message, TRUE);

  return message;
}
==>_dbus_header_create
==>reserve_header_padding (header)
// 为header->data[]空间预留7字节padding,执行完reserve_header_padding(header)之后

// #define MAX_POSSIBLE_HEADER_PADDING 7

// header->data长度将等于MAX_POSSIBLE_HEADER_PADDING

// header->padding也将等于MAX_POSSIBLE_HEADER_PADDING

// #define HEADER_END_BEFORE_PADDING(header) \

  (_dbus_string_get_length (&(header)->data) - (header)->padding)
// header->data长度减去header->padding为header位于padding之前的结尾.

==>_dbus_type_writer_init_values_only (&writer, header->byte_order, // 初始化writer

                                      &_dbus_header_signature_str, 0,
                                      &header->data,
                                      HEADER_END_BEFORE_PADDING (header));
// _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);

 /** Header format is defined as a signature:
 * byte byte order
 * byte message type ID
 * byte flags
 * byte protocol version
 * uint32 body length
 * uint32 serial
 * array of struct (byte,variant) (field name, value)
 *
 * The length of the header can be computed as the
 * fixed size of the initial data, plus the length of
 * the array at the end, plus padding to an 8-boundary.
 */

#define DBUS_HEADER_SIGNATURE \
     DBUS_TYPE_BYTE_AS_STRING \
     DBUS_TYPE_BYTE_AS_STRING \
     DBUS_TYPE_BYTE_AS_STRING \
     DBUS_TYPE_BYTE_AS_STRING \
     DBUS_TYPE_UINT32_AS_STRING \
     DBUS_TYPE_UINT32_AS_STRING \
     DBUS_TYPE_ARRAY_AS_STRING \
     DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
     DBUS_TYPE_BYTE_AS_STRING \
     DBUS_TYPE_VARIANT_AS_STRING \
     DBUS_STRUCT_END_CHAR_AS_STRING

==>_dbus_type_writer_init_values_only (DBusTypeWriter *writer,
                                    int byte_order,
                                    const DBusString *type_str, // "yyyyuua(yv)"

                                    int type_pos, // 从0开始

                                    DBusString *value_str, // 数据字符串

                                    int value_pos) // 起始pos等于0

==*>writer->type_str = &_dbus_header_signature_str;// 所以writer->type_str指向同一个"yyyyuua(yv)"

   writer->type_pos = 0; // 从0开始

   writer->value_str = &header->data;
   writer->value_pos = 0; // 起始pos等于0

   writer->type_pos_is_expectation = TRUE; // type是自定义的,不需要追加

==>v_BYTE = header->byte_order;
   _dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, &v_BYTE)
==*>_dbus_type_writer_write_basic_no_typecode (writer, type, value)
==**>_dbus_marshal_write_basic (writer->value_str, // &header->data

                                writer->value_pos, // 0

                                type,
                                value,
                                writer->byte_order,
                                &writer->value_pos);
==**>_dbus_marshal_write_basic (DBusString *str,// &header->data

                           int insert_at,
                           int type,
                           const void *value,
                           int byte_order,
                           int *pos_after);
这样header->data[0] = v_BYTE;
    writer->value_pos = writer->value_pos + 1;
所以writer->value_pos = 1;
==*>write_or_verify_typecode (writer, type)
==**>if (writer->container_type != DBUS_TYPE_ARRAY)
        writer->type_pos += 1; // 这时writer->type_pos等于1

此时header->data[0]等于header->byte_order
writer->value_pos等于1
writer->type_pos等于1

writer->type_str指向"yyyyuua(yv)"

==>v_BYTE = message_type;
   _dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, &v_BYTE)
此时header->data[1]等于message_type
writer->value_pos等于2
writer->type_pos等于2

==>v_BYTE = 0;
   _dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, &v_BYTE)
此时header->data[2]等于0
writer->value_pos等于3
writer->type_pos等于3

==>v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
   _dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, &v_BYTE)
此时header->data[3]等于DBUS_MAJOR_PROTOCOL_VERSION
writer->value_pos等于4
writer->type_pos等于4

==>v_UINT32 = 0; /* body length */
   _dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, &v_UINT32)
此时header->data[4字节对齐调整后位置]等于0
writer->value_pos等于4字节对齐调整后位置+4后的数值
writer->type_pos等于5

==>v_UINT32 = 0; /* serial */
   _dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, &v_UINT32)
此时header->data[4字节对齐调整后位置]等于0
writer->value_pos等于4字节对齐调整后位置+4后的数值
writer->type_pos等于6

/** Offset from start of _dbus_header_signature_str to the signature of the fields array */
#define FIELDS_ARRAY_SIGNATURE_OFFSET 6
下面创建展开一个新的container,该container的array->value_pos等于writer的value_pos,这样
array这个container将继续向writer->value_str数据区,即header->data内存区,存放这个新的
container对应的数据们,其实这个展开了的新的container,就是将一个独立的具有自身运算规则
的实体,将这个实体从writer->type_pos中抠出来独立进行数据填充运算,运算得到的数据最终还是
存放到header->data数据区中,这是一个很高明的做法[luther.gliethttp]
==>_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
                              &_dbus_header_signature_str, // 其值为"yyyyuua(yv)"

                              FIELDS_ARRAY_SIGNATURE_OFFSET, // 'a'位于第6个偏移

                              &array) // 将"a(yv)"作为一个独立的container展开,然后按格式继续存放数据

dbus_bool_t
_dbus_type_writer_recurse (DBusTypeWriter *writer,
                           int container_type,
                           const DBusString *contained_type,
                           int contained_type_start,
                           DBusTypeWriter *sub)
{
  int contained_type_len;

  if (contained_type)
    contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
// contained_type其值为"yyyyuua(yv)"

// contained_type_start为6

// find_len_of_complete_type就是计算a(yv)这个数组小括号部分包含字节数(包括小括号)

// 即计算"(yv)"字符串长度,很明显为4

// 所以contained_type_len等于4

  else
    contained_type_len = 0;
// 展开"a(yv)"成立一个新的container,作为后续数据处理的基writer.[luther.gliethttp]

  return _dbus_type_writer_recurse_contained_len (writer, container_type,
                                                  contained_type,
                                                  contained_type_start,
                                                  contained_type_len,
                                                  sub,
                                                  FALSE);
}
==*>_dbus_type_writer_recurse_contained_len
==**>writer_recurse_init_and_check (writer, container_type, sub);
==***>_dbus_type_writer_init (sub,
                          writer->byte_order,
                          writer->type_str,
// 上面已经分析了writer->type_str = &_dbus_header_signature_str;

// 他们的对应的字符串为"yyyyuua(yv)"

                          writer->type_pos, // 现在writer->type_pos等于6

                          writer->value_str,// writer->value_str仍然等于&header->data;

                          writer->value_pos)// writer->value_pos等于上面存入writer->type_str

// 指定数据"yyyyuu"类型对应的数据之后最终align了的数值.

// 至少存放了1+1+1+1+4+4+align_bytes=12+align_bytes字节数据.


这样
sub->type_str = writer->type_str;对应的字符串为"yyyyuua(yv)"
sub->type_pos = writer->type_pos;等于6
sub->value_str= writer->value_str;等于&header->data
sub->value_pos= writer->value_pos;等于当前存入writer->value_str空间实际数据个数.
sub->container_type = DBUS_TYPE_ARRAY; // 数组

  ......
  if (writer->type_pos_is_expectation ||
      (sub->container_type == DBUS_TYPE_ARRAY || sub->container_type == DBUS_TYPE_VARIANT))
    sub->type_pos_is_expectation = TRUE; // 不需要将type数值存入writer->type_pos所在处

  else
    sub->type_pos_is_expectation = FALSE; // 需要将type数值存入writer->type_pos所在处

  ......
==***>_dbus_first_type_in_signature (writer->type_str, writer->type_pos);// 检查"yyyyuua(yv)"第6个偏移是否为数组关键字

==**>writer_recurse_array (writer, contained_type, contained_type_start, contained_type_len,
                          sub, is_array_append);
static dbus_bool_t
writer_recurse_array (DBusTypeWriter *writer,
                      const DBusString *contained_type,
                      int contained_type_start,
                      int contained_type_len,
                      DBusTypeWriter *sub,
                      dbus_bool_t is_array_append)
{
  dbus_uint32_t value = 0;
  int alignment;
  int aligned;

#ifndef DBUS_DISABLE_CHECKS
  if (writer->container_type == DBUS_TYPE_ARRAY &&
// 这时我们的writer->container_type等于DBUS_TYPE_INVALID;

      writer->type_str)
    {
      if (!_dbus_string_equal_substring (contained_type,
                                         contained_type_start,
                                         contained_type_len,
                                         writer->type_str,
                                         writer->u.array.element_type_pos + 1))
        {
          _dbus_warn_check_failed ("Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n",
                                   _dbus_string_get_const_data_len (contained_type,
                                                                    contained_type_start,
                                                                    contained_type_len));
          _dbus_assert_not_reached ("incompatible type for child array");
        }
    }
#endif /* DBUS_DISABLE_CHECKS */

  if (writer->enabled && !is_array_append)
    {
      /* 3 pad + 4 bytes for the array length, and 4 bytes possible padding
       * before array values
       */

      if (!_dbus_string_alloc_space (sub->value_str, 3 + 4 + 4)) // 提前申请4字节空间存放array长度,以保证空间足够

        return FALSE;
    }

  if (writer->type_str != NULL)
    {
      sub->type_pos += 1; /* move to point to the element type, since type_pos
                           * should be the expected type for further writes
                           */

      // 这时sub->type_pos指向"(yv)"字符串

      sub->u.array.element_type_pos = sub->type_pos; // 记录type_pos到array专用空间[luther.gliethttp]

    }

  if (!writer->type_pos_is_expectation)
    {
        // 如果type是不存在的,那么需要这里动态的将该type数值添加到writer->type_str[type_pos]处

      /* sub is a toplevel/outermost array so we need to write the type data */

      /* alloc space for array typecode, element signature */
      if (!_dbus_string_alloc_space (writer->type_str, 1 + contained_type_len))
        return FALSE;

      if (!_dbus_string_insert_byte (writer->type_str,
                                     writer->type_pos,
                                     DBUS_TYPE_ARRAY)) // 因为这是array,所以追加类型值

        _dbus_assert_not_reached ("failed to insert array typecode after prealloc");

      if (!_dbus_string_copy_len (contained_type,
        // 将contained_type[contained_type_start]开始contained_type_len个字节长度数据拷贝到

        // sub->type_str类型字符串sub->u.array.element_type_pos开始处.

                                  contained_type_start, contained_type_len,
                                  sub->type_str,
                                  sub->u.array.element_type_pos))
        _dbus_assert_not_reached ("should not have failed to insert array element typecodes");
    }

  if (writer->type_str != NULL)
    {
      /* If the parent is an array, we hold type_pos pointing at the array element type;
       * otherwise advance it to reflect the array value we just recursed into
       */

      if (writer->container_type != DBUS_TYPE_ARRAY) // 如果writer不是array,那么

// writer的type_pos需要跳过该结构体类型所占字节数,

// 这里writer->type_pos将指向"yyyyuua(yv)"该字符串的结尾'\0'数据.

        writer->type_pos += 1 + contained_type_len;
      else
        _dbus_assert (writer->type_pos_is_expectation); /* because it's an array */
    }

  if (writer->enabled)
    {
      /* Write (or jump over, if is_array_append) the length */
      // 将sub->value_pos对齐下一个4字节边界,以备后面存放array数据长度[luther.gliethttp]

      sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4);

      if (is_array_append)
        {
          sub->value_pos += 4;
        }
      else
        {
            // 向sub->u.array.len_pos偏移处存放array数据长度初始值0

            // 之后sub->value_pos将调整到4字节边界,之后再加4,指向

            // array数据长度存储空间的下一个有效数据存储空间[luther.gliethtp].

            // 这时的sub->value_pos一定在4字节边界.

          if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
                                                          &value))
            _dbus_assert_not_reached ("should not have failed to insert array len");
        }
        
      // 这时的sub->value_pos一定在4字节边界.

      _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4);

      /* Write alignment padding for array elements
       * Note that we write the padding *even for empty arrays*
       * to avoid wonky special cases
       */

      alignment = element_type_get_alignment (contained_type, contained_type_start);
      // array是4字节对齐的

      aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment);
      if (aligned != sub->value_pos)
        {
          if (!is_array_append)
            {
              if (!_dbus_string_insert_bytes (sub->value_str, // 将未4字节对齐的间隙填入'\0'数据

                                              sub->value_pos,
                                              aligned - sub->value_pos,
                                              '\0'))
                _dbus_assert_not_reached ("should not have failed to insert alignment padding");
            }

          sub->value_pos = aligned; // 新位置应该是对齐后的位置[luther.gliethtp]

        }

      sub->u.array.start_pos = sub->value_pos; // 这个已经位于4字节边界上的位置,就是

      // array做数据存放的起始位置 |array_len|sub->value_pos


      if (is_array_append)
        {
          dbus_uint32_t len;

          _dbus_assert (_DBUS_ALIGN_VALUE (sub->u.array.len_pos, 4) ==
                        (unsigned) sub->u.array.len_pos);
          // 需要将类型追加到

          len = _dbus_unpack_uint32 (sub->byte_order,
                                     _dbus_string_get_const_data_len (sub->value_str,
                                                                      sub->u.array.len_pos,
                                                                      4));

          sub->value_pos += len;
        }
    }
  else
    {
      /* not enabled, so we won't write the len_pos; set it to -1 to so indicate */
      sub->u.array.len_pos = -1; // 置成非法值,因为我们不能写

      sub->u.array.start_pos = sub->value_pos;
    }

  _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos);
  _dbus_assert (is_array_append || sub->u.array.start_pos == sub->value_pos);

#if RECURSIVE_MARSHAL_WRITE_TRACE
      _dbus_verbose (" type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d value_pos = %d\n", sub,
                     sub->type_str ?
                     _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0) :
                     "unknown",
                     sub->u.array.start_pos, sub->u.array.len_pos, sub->value_pos);
#endif

  return TRUE;
}
至此_dbus_type_writer_recurse()函数已经为我们创建展开了一个新的container,
该container的array->value_pos等于writer的value_pos,这样
array这个container将继续向writer->value_str数据区,即header->data内存区,存放这个新的
container对应的数据们,其实这个展开了的新的container,就是将一个独立的具有自身运算规则
的实体,将这个实体从writer->type_pos中抠出来独立进行数据填充运算,运算得到的数据最终还是
存放到header->data数据区中,这是一个很高明的做法[luther.gliethttp]
下面就是以array为基writer,根据array标识的type_pos和value_pos进行数据填充了.
==>write_basic_field (&array,
                      DBUS_HEADER_FIELD_PATH,
                      DBUS_TYPE_OBJECT_PATH,
                      &path);
static dbus_bool_t
write_basic_field (DBusTypeWriter *writer,
                   int field,
                   int type,
                   const void *value)
{
  DBusTypeWriter sub;
  DBusTypeWriter variant;
  int start;
  int padding;
  unsigned char field_byte;
  DBusString contained_type;
  char buf[2];

  start = writer->value_pos; // 就是array的value_pos,就是指向&header->data[value_pos]内存.

  padding = _dbus_string_get_length (writer->value_str) - start;
// 现在array的type_pos指向"(yv)"字符串,

// 所以继续抠出DBUS_TYPE_STRUCT即'('结构体.

// [注意这次执行_dbus_type_writer_recurse操作,writer就是array,

// 这里writer->container_type即array.container_type等于DBUS_TYPE_ARRAY]

// _dbus_type_writer_recurse==>writer_recurse_struct_or_dict_entry该函数完成之后

// sub->type_pos指向"yv)"字符串[luther.gliethttp].

  if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
                                  NULL, 0, &sub))
    goto append_failed;

  field_byte = field;
  // 写入"yv)"字符串的"y"数据

  if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
                                      &field_byte))
    goto append_failed;

  buf[0] = type;
  buf[1] = '\0';
  _dbus_string_init_const_len (&contained_type, buf, 1);

// 在"v)"中抠出variant

  if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
                                  &contained_type, 0, &variant))
    goto append_failed;

  if (!_dbus_type_writer_write_basic (&variant, type, value))
    goto append_failed;

  if (!_dbus_type_writer_unrecurse (&sub, &variant))
    goto append_failed;

  if (!_dbus_type_writer_unrecurse (writer, &sub))
    goto append_failed;

  return TRUE;

 append_failed:
  _dbus_string_delete (writer->value_str,
                       start,
                       _dbus_string_get_length (writer->value_str) - start - padding);
  return FALSE;
}

_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
                           &contained_type, 0, &variant)
==>writer_recurse_variant
static dbus_bool_t
writer_recurse_variant (DBusTypeWriter *writer,
                        const DBusString *contained_type,
                        int contained_type_start,
                        int contained_type_len,
                        DBusTypeWriter *sub)
{
  int contained_alignment;
 
  if (writer->enabled)
    {
      /* Allocate space for the worst case, which is 1 byte sig
       * length, nul byte at end of sig, and 7 bytes padding to
       * 8-boundary.
       */

      // 用来存放sig的空间

      if (!_dbus_string_alloc_space (sub->value_str, contained_type_len + 9))
        return FALSE;
    }

  /* write VARIANT typecode to the parent's type string */
  // 这时type_pos指向"v)"字符串

  if (!write_or_verify_typecode (writer, DBUS_TYPE_VARIANT))
    return FALSE;

  /* If not enabled, mark that we have no type_str anymore ... */

  if (!writer->enabled)
    {
      sub->type_str = NULL;
      sub->type_pos = -1;

      return TRUE;
    }

  /* If we're enabled then continue ... */
  // 向&header->data[value_pos]插入type类型字符串长度,variant对应的长度为1

  if (!_dbus_string_insert_byte (sub->value_str,
                                 sub->value_pos,
                                 contained_type_len))
    _dbus_assert_not_reached ("should not have failed to insert variant type sig len");

  sub->value_pos += 1; // 数据偏移指针后移


  /* Here we switch over to the expected type sig we're about to write */
  sub->type_str = sub->value_str;
  sub->type_pos = sub->value_pos;
// ok,type类型长度填完之后,紧跟的内存空间就是存放contained_type_len长度的type类型控制数据

// 我们这里很简单就一个"o",即:DBUS_TYPE_OBJECT_PATH

  if (!_dbus_string_copy_len (contained_type, contained_type_start, contained_type_len,
                              sub->value_str, sub->value_pos))
// 将type类型数据拷贝到header->data[]空间

    _dbus_assert_not_reached ("should not have failed to insert variant type sig");

  sub->value_pos += contained_type_len; // header->data[]空间偏移指针调整


  if (!_dbus_string_insert_byte (sub->value_str,
// 追加DBUS_TYPE_INVALID数据,表示该variant类型控制结构结束[luther.gliethttp]

                                 sub->value_pos,
                                 DBUS_TYPE_INVALID))
    _dbus_assert_not_reached ("should not have failed to insert variant type nul termination");

  sub->value_pos += 1;

  contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (contained_type, contained_type_start)); // 调整value_pos到第1个type数据对齐边界上

 
  if (!_dbus_string_insert_bytes (sub->value_str, // 填充'\0'数据到调整发生的gaps间隙.

                                  sub->value_pos,
                                  _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment) - sub->value_pos,
                                  '\0'))
    _dbus_assert_not_reached ("should not have failed to insert alignment padding for variant body");
  sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, contained_alignment);

  return TRUE;
}

_dbus_type_writer_write_basic (&variant, type, value) // 将数据写入到header->data[]内存空间.

即_dbus_type_writer_write_basic (&variant, DBUS_HEADER_FIELD_PATH,DBUS_TYPE_OBJECT_PATH)
_dbus_type_writer_write_basic
==*>_dbus_type_writer_write_basic_no_typecode
==**>_dbus_marshal_write_basic
==***>marshal_string (str, insert_at, vp->str, byte_order, pos_after);
==****>marshal_len_followed_by_bytes // 插入字符串

static dbus_bool_t
marshal_len_followed_by_bytes (int marshal_as,
                               DBusString *str,
                               int insert_at,
                               const unsigned char *value,
                               int data_len, /* doesn't include nul if any */
                               int byte_order,
                               int *pos_after)
{
  int pos;
  DBusString value_str;
  int value_len;

  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || byte_order == DBUS_BIG_ENDIAN);
  if (insert_at > _dbus_string_get_length (str))
    _dbus_warn ("insert_at = %d string len = %d data_len = %d\n",
                insert_at, _dbus_string_get_length (str), data_len);
 
  if (marshal_as == MARSHAL_AS_BYTE_ARRAY)
    value_len = data_len;
  else
    value_len = data_len + 1; /* value has a nul */ // 我们这里插入的就是字符串"org.freedesktop.DBus"


  _dbus_string_init_const_len (&value_str, value, value_len);

  pos = insert_at;

  if (marshal_as == MARSHAL_AS_SIGNATURE)
    {
      _dbus_assert (data_len <= DBUS_MAXIMUM_SIGNATURE_LENGTH);
      _dbus_assert (data_len <= 255); /* same as max sig len right now */
     
      if (!_dbus_string_insert_byte (str, pos, data_len))
        goto oom;

      pos += 1;
    }
  else
    {
      if (!marshal_4_octets (str, pos, data_len,
// 将字符串"org.freedesktop.DBus"长度写入header->data[]空间

                             byte_order, &pos))
        goto oom;
    }

  if (!_dbus_string_copy_len (&value_str, 0, value_len, // 拷贝数据

                              str, pos))
    goto oom;

#if 0
  /* too expensive */
  _dbus_assert (_dbus_string_equal_substring (&value_str, 0, value_len,
                                              str, pos));
  _dbus_verbose_bytes_of_string (str, pos, value_len);
#endif

  pos += value_len;

  if (pos_after)
    *pos_after = pos; // 最新空闲header->data[]空间偏移[luther.gliethttp]


  return TRUE;

 oom:
  /* Delete what we've inserted */
  _dbus_string_delete (str, insert_at, pos - insert_at);

  return FALSE;
}


type内容为"a(yv)",那么header->data[]中对应的区段数据为:
1. array_len |
2. field_byte[即DBUS_HEADER_FIELD_PATH] |
3. (variant)插入type类型字符串长度contained_type_len这里为1
[即只有'o'一个控制类型DBUS_TYPE_OBJECT_PATH]
4. (variant)插入type类型字符串'o'[即DBUS_TYPE_OBJECT_PATH]
5. 写入字符串"org.freedesktop.DBus"长度21(包含字符串结尾0数据)
6. 写入字符串"org.freedesktop.DBus"+'\0'

好了,"a(yv)"这个arry的arry[0]已经填充完毕了,之后重复上面的操作填充arry[1]...即可[luther.gliethttp]

阅读(6181) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~