取得streambuf/stringbuf数据的所有权 [英] Taking ownership of streambuf/stringbuf data

查看:76
本文介绍了取得streambuf/stringbuf数据的所有权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个用于写入自动调整大小数组的接口.一种方法是使用通用std::ostream *.

然后考虑ostringstream是否是目标:

void WritePNG(ostream *out, const uint8_t *pixels);

void *WritePNGToMemory(uint8_t *pixels)
{
  ostringstream out;
  WritePng(&out, pixels);

  uint8_t *copy = new uint8_t[out.tellp()];
  memcpy(copy, out.str().c_str(), out.tellp()];
  return copy;
}

但是我想避免使用memcpy().有没有办法在底层的stringbuf类中获取数组的所有权并将其返回?

我感到无法使用标准库完成此操作,因为流缓冲区甚至可能不是连续数组.

解决方案

IIRC字符串流存在的原因(与strstream相比)是为了解决内存所有权的模糊问题,这些问题将通过直接缓冲区访问而出现.例如我认为更改是为了明确阻止您要执行的操作.

我认为您必须自己通过覆盖流缓冲区来做到这一点.为了回答类似的问题,我为输入流提出了一些建议,这些建议最终获得了很多好评.但说实话,我当时当时还不知道我在说什么,

通过此网络链接进行高位流缓冲区",只是回显并为您提供对其缓冲区的引用可能会给出:

#include <iostream>
#include <streambuf>

class outbuf : public std::streambuf {
    std::string data;

protected:
    virtual int_type overflow (int_type c) {
        if (c != EOF)
            data.push_back(c);
        return c;
    }

public:
    std::string& get_contents() { return data; }
};

int main() {
    outbuf ob;
    std::ostream out(&ob);
    out << "some stuff";
    std::string& data = ob.get_contents();
    std::cout << data;
    return 0;
}

我确信它以各种方式被破坏了.但是大写缓冲区的作者似乎认为,单独重写overflow()方法会让他们将所有输出大写为流,因此我猜可能会争辩说,如果写一个自己的缓冲区就足以看到所有输出. >

但是,即使这样,一次执行一个字符似乎不是最佳选择……而且谁知道从一开始就从streambuf继承会带来什么样的开销. 请咨询您最近的C ++ iostream专家,以了解正确的正确方法.但希望它证明了某种可能性.

I'd like an interface for writing to an automatically resizing array. One way to do this is with a generic std::ostream *.

Then consider if ostringstream is the target:

void WritePNG(ostream *out, const uint8_t *pixels);

void *WritePNGToMemory(uint8_t *pixels)
{
  ostringstream out;
  WritePng(&out, pixels);

  uint8_t *copy = new uint8_t[out.tellp()];
  memcpy(copy, out.str().c_str(), out.tellp()];
  return copy;
}

But I want to avoid the memcpy(). Is there a way to take ownership of the array in the underlying stringbuf class and return that?

I get the feeling this can't be done using standard library, since the stream buffer might not even be a contiguous array.

解决方案

IIRC the whole reason stringstream exists (vs strstream) was to sort out the fuzzy questions of memory ownership that would come up by giving direct buffer access. e.g. I think that change was to specifically prevent what you are asking to do.

One way or another I think you'd have to do it yourself, by overriding the stream buffer. To answer a similar question I suggested something for input streams that wound up getting quite a few upvotes. But honestly I didn't know what I was talking about then, nor now when I suggest the following:

Hacking up this link from the web for doing an "uppercasing stream buffer" to one that just echoes and gives you a reference to its buffer might give:

#include <iostream>
#include <streambuf>

class outbuf : public std::streambuf {
    std::string data;

protected:
    virtual int_type overflow (int_type c) {
        if (c != EOF)
            data.push_back(c);
        return c;
    }

public:
    std::string& get_contents() { return data; }
};

int main() {
    outbuf ob;
    std::ostream out(&ob);
    out << "some stuff";
    std::string& data = ob.get_contents();
    std::cout << data;
    return 0;
}

I'm sure it's broken in all kinds of ways. But the uppercase-buffer-authors seemed to think that overriding the overflow() method alone would let them uppercase all output to the stream, so I guess one could argue that it's enough to see all output if writing to one's own buffer.

But even so, going one character at a time seems suboptimal...and who knows what overhead you get from inheriting from streambuf in the first place. Consult your nearest C++ iostream expert for what the actual right way is. But hopefully it's proof that something of the sort is possible.

这篇关于取得streambuf/stringbuf数据的所有权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆