Mam klienta sieci z metodą żądania, która ma std::streambuf*
. Ta metoda jest implementowana przez boost::iostreams::copy
-przy użyciu niestandardowej klasy std::streambuf
, która wie, jak zapisać dane w sieciowym interfejsie API, który działa doskonale. Oznacza to, że mogę przesłać plik do żądania bez potrzeby wczytywania go do pamięci.Strumień ze std :: string bez tworzenia kopii?
Są jednak przypadki, w których należy wysłać duże bloki danych, których nie ma w pliku, dlatego uwzględniłem przeciążenie, które pobiera ciąg znaków. Aby uniknąć duplikowania całego kodu sieciowego w strumieniu, wydawało się oczywiste, że powinienem ustawić streambuf
reprezentujący ciąg i wywołać inną metodę. Jedynym sposobem mogę dowiedzieć się do tej pracy było coś takiego:
std::istringstream ss(data);
send(ss.rdbuf());
Niestety istringstream
tworzy kopię danych, które w niektórych przypadkach kilka megabajtów. Ma to sens w ogólnym przypadku, oczywiście, jeśli przekażesz odwołanie do jakiegoś obiektu, nie chcesz tego obiektu, zakładając, że może on nadal używać tego odniesienia.
Pracowałem wokół to z następujących powodów:
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));
To wydaje się działać dobrze, ale zastanawiam się, czy to naprawdę konieczne. Dlaczego std::istringstream
nie ma przeciążenia, biorąc std::string const *
? Czy jest lepszy sposób to zrobić?
Ciekawy pomysł. Jedną z rzeczy, które podoba mi się w istniejącej konfiguracji, jest to, że mogę skonfigurować niestandardowy strumień wejściowy lub wyjściowy, wywodząc się z 'std :: stringbuf' i mam tylko nadpisać jedną lub dwie proste funkcje, niedomiar lub' przepełnienie' i ' sync', klasa podstawowa obsługuje dla mnie całe zarządzanie buforami. Podejrzewam, że opieranie rzeczy 'std :: vector' oznaczałoby, że potrzebowałbym znacznie więcej kodu. Być może i tak będę mógł użyć 'swap', chociaż potrzebuję abonenta" zrezygnować "z ciągu, zamiast przekazywać stałe odniesienie. –