标签: streambuf

使用Boost Asio从串口读取

我想检查串口上的传入数据包,使用boost.asio.每个数据包将以一个字节长的标头开始,并指定已发送的消息类型.每种不同类型的消息都有自己的长度.我想写的函数应该不断地监听新的传入消息,当它找到它时应该读取它,并调用其他函数来解析它.我目前的代码如下:

void check_for_incoming_messages()
{
    boost::asio::streambuf response;
    boost::system::error_code error;
    std::string s1, s2;
    if (boost::asio::read(port, response, boost::asio::transfer_at_least(0), error)) {
        s1 = streambuf_to_string(response);
        int msg_code = s1[0];
        if (msg_code < 0 || msg_code >= NUM_MESSAGES) {
            // Handle error, invalid message header
        }
        if (boost::asio::read(port, response, boost::asio::transfer_at_least(message_lengths[msg_code]-s1.length()), error)) {
            s2 = streambuf_to_string(response);
            // Handle the content of s1 and s2
        }
        else if (error != boost::asio::error::eof) {
            throw boost::system::system_error(error);
        }
    }
    else if (error != boost::asio::error::eof) {
        throw boost::system::system_error(error);
    }
} …
Run Code Online (Sandbox Code Playgroud)

c++ serial-port streambuf boost-asio

6
推荐指数
1
解决办法
3万
查看次数

使用xsputn和overflow继承ostream和streambuf问题

我一直在研究创建我自己的ostream以及一个streambuf来处理我的ostream的缓冲区.我实际上大部分工作,我可以插入(<<)到我的流中,并获得字符串没有问题.我通过虚拟函数xsputn来实现这一点.但是,如果我输入(<<)一个浮点数或一个int到流而不是字符串xsputn永远不会被调用.

我已经遍历了代码,我看到流正在调用do_put,然后是f_put,它最终会尝试将float 1字符一次放入缓冲区.我可以让它调用我的虚函数溢出(int c)的实现,如果我让我的缓冲区没有空间,从而得到浮点数和int的数据.

现在问题就在这里,我需要知道何时将float放入缓冲区.换句话说,我需要知道这是什么时候最后一次溢出将被调用为特定值流入.xsputn对我有用的原因是因为我得到了整个值及其长度.所以我可以将它复制到缓冲区然后调用等待缓冲区已满的函数.

我无可否认地滥用了ostream设计,因为我需要缓存输出然后立即为每个输入值(<<)发送它.

无论如何要清楚我会以另一种方式重申我正在拍摄的内容.我很有可能以错误的方式解决这个问题.

我想使用一个继承的ostream和streambuf所以我可以输入值并允许它为我处理我的类型转换,然后我想将这些信息传递给另一个我将句柄传递给streambuf的对象(对于?).该对象有昂贵的i/o所以我不想一次发送数据1个字符.

如果不清楚,请提前抱歉.谢谢你的时间.

c++ iostream ostream streambuf

6
推荐指数
1
解决办法
3613
查看次数

是否可以更改ostringstream rdbuf?

我尝试以下代码:

ostringstream oss;

streambuf *psbuf, *backup;

backup = oss.rdbuf();     
psbuf = cout.rdbuf();        
oss.rdbuf(psbuf);        
oss << things << endl;
oss.rdbuf(backup);   
Run Code Online (Sandbox Code Playgroud)

但是不幸的是我得到了这个错误:

error: too many arguments to function call, expected 0, have 1
    oss.rdbuf(backup);   
Run Code Online (Sandbox Code Playgroud)

但是rdbuf有两个重载:

得到(1)basic_streambuf <char_type,traits_type> * rdbuf()const;

设置(2)basic_streambuf <char_type,traits_type> * rdbuf(basic_streambuf <char_type,traits_type> * sb);

是的,我知道它说,basic_streambuf但是它实际上只是一个typedef typedef basic_streambuf<char> streambuf;,因此它应该可以工作。为什么不起作用?

c++ ostringstream streambuf

6
推荐指数
1
解决办法
716
查看次数

提升streambuf消费和提交,它是什么

我似乎无法找到pas()和commit()实际意味着什么的好解释,实际上我根本不理解streambuf.

我的理解是,streambuf只是一个字符数组.但为什么在文档中,

basic_streambuf::data
Get a list of buffers that represents the input sequence.
Run Code Online (Sandbox Code Playgroud)

所以实际上有很多缓冲区?什么是'输入序列'和'输出序列'?这是另外两个缓冲区吗?

以下代码真正做了什么?

streambuf b;
size_t size;
size = read( socket, b.prepare( 1024 ) ); 
b.commit( size );
size = write( socket, b.data() );
b.consume( size );
Run Code Online (Sandbox Code Playgroud)

当我调用b.prepare()时,它是否为read()分配一个新的缓冲区来放置数据?那么数据何时从该缓冲区传输到底层的streambuf缓冲区?我以为是commit(),但是

basic_streambuf::commit
Move characters from the output sequence to the input sequence.
Run Code Online (Sandbox Code Playgroud)

因此似乎提交实际上将数据从"输出序列"移动到"输入序列",而没有提到用于存储数据的底层缓冲区!

streambuf

6
推荐指数
1
解决办法
2156
查看次数

当我的自定义streambuf类使用时,istream :: tellg()返回-1?

我正在尝试创建一个istream直接从原始内存缓冲区读取的内容.

我在这里的另一篇文章中找到了一个很好的方法:

  class membuf : public basic_streambuf<char>
  {
  public:
      membuf(char* p, size_t n) {
          setg(p, p, p + n);
      }
  };
Run Code Online (Sandbox Code Playgroud)

然后我创建我istream使用这个membuf:

    membuf mb(dataPointer, dataLength);
    istream reader(&mb);
Run Code Online (Sandbox Code Playgroud)

然后我阅读使用getline()>>运算符,一切都很棒.但是,我似乎无法seekg()回退到缓冲区的开头,并且istream::tellg()总是返回-1.

我是否需要编写更多代码才能使这些代码发挥作用,或者这注定要失败?

c++ istream streambuf

5
推荐指数
1
解决办法
1256
查看次数

streams,stream_bufs,codecvt facets和\n到\ r \n的翻译

\r\r\n转换的C++ IO流的哪一部分?它stream_buf本身还是由codecvtfacet 进行内部到外部编码转换的一部分?

更新1

你们都说它是在streambuf/filebuf中完成的.好.但是这种安排如何处理,例如像UTF-16这样的外部编码?然后似乎必须打开文件ios::binary,禁用翻译.

c++ iostream streambuf codecvt

5
推荐指数
1
解决办法
528
查看次数

使用 buffer_cast 与 std::string 与 ostringstream 将 Streambuf 提升为 const char*

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

XMLDocument doc;
doc.parse(strPtr); // strPtr is const char* 
Run Code Online (Sandbox Code Playgroud)

我需要以某种方式从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 …
Run Code Online (Sandbox Code Playgroud)

c++ xml boost tinyxml streambuf

5
推荐指数
1
解决办法
4030
查看次数

如何实现自定义std :: streambuf的seekoff()?

我有以下基于此问题和答案的实现

struct membuf : std::streambuf
{
  membuf(char* begin, char* end)
  {
    this->setg(begin, begin, end);
  }

protected:
  virtual pos_type seekoff(off_type off,
                           std::ios_base::seekdir dir,
                           std::ios_base::openmode which = std::ios_base::in)
  {
    std::istream::pos_type ret;
    if(dir == std::ios_base::cur)
    {
      this->gbump(off);
    }
    // something is missing here...
  }
};
Run Code Online (Sandbox Code Playgroud)

我想通过以下方式在我的方法中使用它:

  char buffer[] = { 0x01, 0x0a };
  membuf sbuf(buffer, buffer + sizeof(buffer));
  std::istream in(&sbuf);
Run Code Online (Sandbox Code Playgroud)

然后调用,例如tellg()in并获得正确的结果。

到目前为止,它几乎是完美的-它不会在流的尽头停止。

我应该如何升级才能使其正常工作?

我的主要动机是模仿std::ifstream行为,但char[]在测试中将二进制文件输入到行为中(而不是依赖二进制文件)。

c++ istream seek streambuf

5
推荐指数
2
解决办法
1180
查看次数

rdbuf(...) 返回一个指针——谁拥有所指向的缓冲区?

有一个STL<ios>库函数

streambuf* std::basic_ios::rdbuf (streambuf* sb);

此函数可用于更改与流关联的流缓冲区。如果您使用它,它将返回一个指向先前使用的streambuf的指针。目前尚不清楚谁“拥有”该指针或它的生命周期是多少。标准(27.5.5.3/5)简单地说

返回: 的前一个值rdbuf()

这信息不是很丰富。是否可以保证该指针的有效期为多长时间?调用代码delete完成后是否应该使用指针?

c++ stl streambuf

5
推荐指数
1
解决办法
606
查看次数

在ostream上使用std :: endl使我的文件成为二进制文件

我正在开发一个使用libzip的项目.我在c ++ 14工作,我在libzip周围写了一个小包装,让我的生活更轻松.

我有一个std::ostream围绕自定义类继承的对象std::streambuf.此streambuf使用libzip函数写入存档中的文件.

一切都很好,直到我使用std::endl.当我这样做时,输出文件被我的所有文本阅读器读取为二进制文件(仅写入字符串).

我的文本阅读器检测到它的二进制文件,因为在我使用的地方std::endl有一个NUL字节,任何带有NUL字节的文件都被视为二进制文件.

所以我的问题是:这是正常的吗?我有办法使用std::endl吗?

我的代码(提取它可能不完全相同).

source.hpp

// my attributes
std::unique_ptr<zip_source_t, std::function<void(zip_source_t*)>> _source;
std::unique_ptr<std::ostream> _stream;
std::unique_ptr<_ZipBuffer> _buffer;

class _ZipBuffer : public std::streambuf {
    private:
        zip_source_t* _source;

        std::streamsize xsputn(char const* s, std::streamsize n) override;
        int overflow(int c) override;

    public:
        _ZipBuffer(zip_source_t* file);
};
Run Code Online (Sandbox Code Playgroud)

source.cpp

// create the streambuf and send it to the ostream
_buffer.reset(new _ZipBuffer(_source.get()));
_stream.reset(new std::ostream(_buffer.get()));

// the implementation of _ZipBuffer
Zip::Source::_ZipBuffer::_ZipBuffer(zip_source_t* source) {
    _source = source;
} …
Run Code Online (Sandbox Code Playgroud)

c++ ostream streambuf libzip c++14

5
推荐指数
1
解决办法
344
查看次数