Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1496521
  • 博文数量: 218
  • 博客积分: 6394
  • 博客等级: 准将
  • 技术积分: 2563
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-08 15:33
个人简介

持之以恒

文章分类

全部博文(218)

文章存档

2013年(8)

2012年(2)

2011年(21)

2010年(55)

2009年(116)

2008年(16)

分类: 网络与安全

2010-01-09 22:08:22

Winston原创,ACE开发者论坛版权所有。

ACE_Message_Block是ACE系统里面的“黏合剂”,所有的数据处理都涉及到ACE_Message_Block的使用。所以,有效的用好这个类很重要。
开发过程中,对这个类的使用,经常碰见的问题就是:居然有多个尺寸的表达方式,而且文档描述不清,比较容易造成混乱和误用。这里做一下解析,让大家明白用法上的差别。
1、length()和length(size_t len)

实现代码如下:
──────────────────────────────
ACE_INLINE size_t
ACE_Message_Block::length (void) const
{
  ACE_TRACE ("ACE_Message_Block::length");
  return this->wr_ptr_ - this->rd_ptr_;
}

// Sets the length of the "active" portion of the message.  This is defined as the offset from RD_PTR to WR_PTR.

ACE_INLINE void
ACE_Message_Block::length (size_t len)
{
  ACE_TRACE ("ACE_Message_Block::length");
  this->wr_ptr_ = this->rd_ptr_ + len;
}

可以清楚的看出,这个方法在取值的时候,是用“写指针” ─  “读指针”,而设置的时候,是把“写指针”置为“读指针”+ 长度。所以设置的时候请注意,不要产生越界行为。
──────────────────────────────

2、total_length()
──────────────────────────────
size_t
ACE_Message_Block::total_length (void) const
{
  ACE_TRACE ("ACE_Message_Block::total_length");

  size_t length = 0;
  for (const ACE_Message_Block *i = this;
       i != 0;
       i = i->cont ())
    length += i->length ();

  return length;
}

ACE_Message_Block有个重要的概念,是可以实现为内部单链表,外部双链表。
内部单链表可以用于支持复合消息,如消息头+消息尾,也可用于层次化协议栈。cont()方法就是用于此用途。
total_length()这个方法是返回每一个内部单链表中所有被链接的消息块长度之和。

3、size()和size(size_t length)
──────────────────────────────
// Return the length of the potential size of the message.

ACE_INLINE size_t
ACE_Message_Block::size (void) const
{
  ACE_TRACE ("ACE_Message_Block::size");
  return this->data_block ()->size ();
}
int
ACE_Message_Block::size (size_t length)
{
  ACE_TRACE ("ACE_Message_Block::size");

  // Resize the underlying .
  if (this->data_block ()->size (length) == -1)
    return -1;

  return 0;
}

这两个方法,操作的是ACE_Message_Block底层的ACE_Data_Block 对象的方法:
ACE_INLINE size_t
ACE_Data_Block::size (void) const
{
  ACE_TRACE ("ACE_Data_Block::size");
  return this->cur_size_;
}
int
ACE_Data_Block::size (size_t length)
{
  ACE_TRACE ("ACE_Data_Block::size");

  if (length <= this->max_size_)
    this->cur_size_ = length;
  else
    {
      // We need to resize!
      char *buf = 0;
      ACE_ALLOCATOR_RETURN (buf,
                            (char *) this->allocator_strategy_->malloc (length),
                            -1);

      ACE_OS::memcpy (buf,
                      this->base_,
                      this->cur_size_);
      if (ACE_BIT_DISABLED (this->flags_,
                            ACE_Message_Block::DONT_DELETE))
        this->allocator_strategy_->free ((void *) this->base_);
      else
        // We now assume ownership.
        ACE_CLR_BITS (this->flags_,
                      ACE_Message_Block::DONT_DELETE);
      this->max_size_ = length;
      this->cur_size_ = length;
      this->base_ = buf;
    }
  return 0;
}

从上面的代码可以看出,当是用size(size_t length)进行设置时,如果length大于当前已经拥有的尺寸,会导致内存重新分配,把已有数据重新复制到新内存地址。而是用size()返回时,是返回当前设置的数据区大小,与读写指针没有任何关系
阅读(1983) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~