Поток из std :: string без копирования?
У меня есть сетевой клиент с методом запроса, который принимаетstd::streambuf*
, Этот метод реализуетсяboost::iostreams::copy
по обычаюstd::streambuf
класс, который знает, как записать данные в сетевой API, который прекрасно работает. Это означает, что я могу направить файл в запрос без необходимости считывать все это в память.
Однако в некоторых случаях необходимо отправлять большие блоки данных, которых нет в файле, поэтому я включил перегрузку, которая принимает строку. Чтобы избежать дублирования всего сетевого кода в потоке, казалось очевидным, что я должен установитьstreambuf
представляя строку и вызвать другой метод. Единственный способ сделать эту работу - это что-то вроде:
std::istringstream ss(data);
send(ss.rdbuf());
К несчастью,istringstream
делает копию данных, которая в некоторых случаях составляет несколько мегабайт. Конечно, в общем случае это имеет смысл, если вы передаете константную ссылку на какой-то объект, который вам не нужен, при условии, что он может продолжать использовать эту ссылку.
Я работал над этим со следующим:
struct zerocopy_istringbuf
: public std::stringbuf
{
zerocopy_istringbuf(std::string const* s)
: std::stringbuf(std::ios::in)
{
char* p = const_cast<char*>(s->c_str());
setg(p, p, p + s->length());
}
};
...
send(&zerocopy_istringbuf(data));
Кажется, это работает просто отлично, но мне интересно, действительно ли это необходимо. Почему неstd::istringstream
иметь перегрузку, принимаяstd::string const *
? Есть лучший способ сделать это?