下面的例子展示了向ACE_Message_Block写入多个字符串并一次性输出
#include "ace/Message_Block.h"
#include "ace/OS.h"
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char * argv[])
{
//if the BUFFERSIZE is too small to save
//data,it will cause run time error!
const int BUFFERSIZE = 1024;
ACE_Message_Block* mblk = new ACE_Message_Block(BUFFERSIZE);
string str("Hello ACE_Message_Block");
ACE_OS::sprintf(mblk->wr_ptr(),"%s",str.c_str());
//if you do it like below,
//mblk->wr_ptr(sizeof("Hello ACE_Message_Block"));
//then the ‘\0‘ will be written in message block
//you may do it like this
mblk->wr_ptr(str.size());
//you must use wr_ptr(n) to go ahead,because
//it will not go ahead by itself
ACE_OS::sprintf(mblk->wr_ptr(),"%s",str.c_str());
mblk->wr_ptr(str.size());
ACE_OS::printf("message :%s",mblk->rd_ptr());
//use delete to release the memory
mblk->release();
return 0;
};输出:
message :Hello ACE_Message_BlockHello ACE_Message_Block请按任意键继续. . .
ACE_Message_Block中有多个获取大小或者长度的函数,容易混淆.
下图是根据ACE_Message_Block(实际是ACE_Data_Block)空间的处理状况所绘,能比较清晰的反应出它们的异同.
需要注意,为了表现出多样性,下图是wr_ptr(),rd_ptr(),size()都调用过之后的情景.

红色表示是ACE_Message_Block独有的函数, 其余则ACE_Message_Block和ACE_Data_Block均有.
矩形纸上函数的返回值均为指针类型,之下的返回值均为size_t类型.
|
函数 |
说明 |
|
length() |
有效数据的长度 == wr_ptr() – rd_ptr() |
|
size() |
全部可用空间的长度,如果没有size()而变小,则等同capacity() == mark() – base() |
|
space() |
剩余可用空间的长度 <= size() - length(),因为不含rd_ptr()移动过的空间 == mark() – wr_ptr() |
|
capacity() |
最大空间的长度(ACE_Message_Block构造或初始化时所用参数值) == end() – base() |
|
total_length() |
复合消息(ACE_Message_Block内单向链 cont())的总长度 |
|
total_size() |
复合消息(ACE_Message_Block内单向链 cont())的总大小 |
|
total_capacity() |
复合消息(ACE_Message_Block内单向链 cont())的总空间大小 |
duplicate()浅拷贝函数,公用一个内部的ACE_Data_Block
ACE_Message_Block::duplicate() 与 ACE_Data_Block.duplicate()的实现是不同的.
ACE_Data_Block::duplicate()简单的只是将自身的reference加+1, 然后返回自身(this)
ACE_Message_Block:duplicate()则将自身copy了一份, 然后将自身的状态值赋给拷贝,注意它们公用同一个data_block.而且ACE_Message_Block::duplicate()支持复合消息,它会检查内部单向链,来依次调用其duplicate().
这里ACE_Data_Block::duplicate()的函数行为很怪异,以后就能看出它怪异行为的影响.说实话,这个地方如此设计我很不理解,因为ACE_Data_Block本身其实已经有reference了.
ACE_Message_Block::clone()深拷贝, 不但拷贝自身,内部的ACE_Data_Block也一并拷贝了,并且支持复合消息.
ACE_Data_Block.size(size_t len)函数, 动态的变化ACE_Data_Block持有的空间.
ACE_Message_Block.size(size_t len)函数是ACE_Data_Block.size(size_t len)的简单包裹.
如果len比现有的尺寸小, 简单的cur_size_ = length;
如果len比现有的尺寸大, 会申请新的空间并拷贝原所有数据.
注意! 这里可能会发生空间控制权的转换! 即标志位DONT_DELETE的变化.若原ACE_Data_Block使用托管空间,则此时会更替为自己申请的空间,从而拥有了控制权, 所以此时要注意原有空间的管理.
对ACE_Message_Block和ACE_Data_Block, 除非主动调用size(), 否则它们不会自动申请和扩大空间.
下面的例子展示了如何通过size函数动态申请空间以适应新的需要
#include "ace/Message_Block.h"
#include "ace/OS.h"
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char * argv[])
{
const int BUFFERSIZE = 10;
ACE_Message_Block* mblk = new ACE_Message_Block(BUFFERSIZE);
cout<<"mblk size "<<mblk->size()<<endl;
string str("Hello ACE_Message_Block");
//check the space wheather enough befor write to mblk
if (mblk->space()<str.size())
{
mblk->size(mblk->size()+str.size());
}
cout<<"mblk size "<<mblk->size()<<endl;
ACE_OS::sprintf(mblk->wr_ptr(),"%s",str.c_str());
mblk->wr_ptr(str.size());
//check the space wheather enough befor write to mblk
if (mblk->space()<str.size())
{
mblk->size(mblk->size()+str.size());
}
cout<<"mblk size "<<mblk->size()<<endl;
ACE_OS::sprintf(mblk->wr_ptr(),"%s",str.c_str());
mblk->wr_ptr(str.size());
ACE_OS::printf("message :%s",mblk->rd_ptr());
mblk->release();
return 0;
};
ACE_Message_Block::crunch() 将现有数据移动到现有的缓冲的开始.
ACE_Message_Block::reset()将现有读写指针赋为初始值(ACE_Data_Block.base())
ACE_Message_Block::base()是对ACE_Data_Block.base()的简单包裹
ACE_Message_Block,布布扣,bubuko.com
原文:http://blog.csdn.net/calmreason/article/details/21165441