使用buffer_cast vs std :: string vs ostringstream将streambuf提升为const char *

时间:2014-07-09 07:53:06

标签: c++ xml boost tinyxml streambuf

我有一个使用boost :: read_until和boost :: streambuf的客户端/服务器应用程序。我正在从套接字读取XML消息,并希望用tinyXML2解析它,如下所示:

XMLDocument doc;
doc.parse(strPtr); // strPtr is const char* 

我需要以某种方式从streambuf中提取const char * strPtr。到目前为止,我在堆栈交换中找到了三种方法:

// method 1, string constructor
const char * streambufToPtr(boost::asio::streambuf &message) {
    boost::asio::streambuf::const_buffers_type bufs = message.data();
    std::string astr(boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + message.size());
    return astr.c_str();
}

// method 2, stringstream
const char * streambufToPtr(boost::asio::streambuf &message) {
    std::ostringstream ss;
    ss << &message;
    std::string astr = ss.str();
    return astr.c_str();
}

// method 3, buffer_cast
const char * streambufToPtr(boost::asio::streambuf &message) {
    const char* bufPtr=boost::asio::buffer_cast<const char*>(message.data());
    return bufPtr;
}

这三种方法都适用于我的代码(到目前为止)。方法1和2可能至少复制一次(或更多)数据,而方法3则执行其他操作。

每种方法都有什么变化? 他们相比有多快? 在缓冲区溢出,线程或其他陷阱方面,我可能会在以后使用网络客户端/服务器应用程序遇到这些问题吗?

1 个答案:

答案 0 :(得分:3)

  

每种方法的内容是什么?

第一种方法将字节复制到std::string并返回指向底层char数组的指针。这导致未定义的行为,因为函数返回时字符串被销毁,请不要使用它。

第二种方法首先将字节复制到ostringstream,然后复制到字符串(ss.str();),然后复制到另一个字符串(std::string astr =,尽管编译器可能会忽略最后一个副本)。它还返回一个指向函数返回时不再存在的东西的指针,不要使用它。

你的最后一个函数只是返回一个指向缓冲区底层字节的指针,并且是三个中具有明确定义行为的唯一一个(假设你的streambuf超过了char指针你传递给tinyXML2,并且在此期间不会被修改。

  

他们相比有多快?这些中的任何一个都是不可取的   缓冲区溢出,线程或其他陷阱我可能会在以后遇到   网络客户端/服务器应用程序?

这些都没有实际意义,因为其他两个功能都是无用的。