2009-10-19 3 views
9

요청 방법이 std::streambuf* 인 네트워크 클라이언트가 있습니다. 이 메소드는 boost::iostreams::copy에 의해 구현되어 네트워크 API에 데이터를 쓰는 방법을 알고있는 사용자 정의 std::streambuf 파생 클래스로 작동합니다. 즉, 파일을 메모리로 모두 읽어 들일 필요없이 파일을 요청으로 스트리밍 할 수 있습니다.복사하지 않고 std :: string에서 스트리밍 하시겠습니까?

그러나 파일에없는 큰 데이터 블록을 보내야하는 경우가 있으므로 문자열을 사용하는 오버로드를 포함했습니다. 스트림에서 모든 네트워크 코드가 중복되지 않도록하려면 문자열을 나타내는 streambuf을 설정하고 다른 메서드를 호출해야한다는 것이 분명해 보였습니다.

std::istringstream ss(data); 
send(ss.rdbuf()); 

불행하게도, istringstream 어떤 경우에는 몇 메가 바이트의 데이터의 복사본을 만듭니다 : 나는이 일을 알아낼 수있는 유일한 방법은 같은 것이 있었다. 물론 일반적인 경우에 완벽하게 이해할 수 있습니다. 어떤 객체에 const 참조를 건네면 그 객체가 그 참조를 계속 사용할 수 있다고 가정하고 싶지는 않습니다.

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 * 인 이유는 무엇입니까? 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

4

이러한 문제가 발생하는 이유는 std :: string이 현재 수행중인 작업에 실제로 적합하지 않기 때문입니다. 더 나은 아이디어는 원시 데이터를 전달할 때 char of vector를 사용하는 것입니다. 가능한 경우, 나는 벡터를 사용하기 위해 모든 것을 바꿀 것입니다 : vector :: swap과 벡터에 대한 참조를 적절하게 복사하여 모든 복사를 제거하십시오. iostreams/streambuf API가 마음에 드시거나 streambuf가 필요한 항목을 처리해야하는 경우에는 자신과 같은 벡터를 사용하는 스트림buf를 만드는 것이 쉽습니다. 다른 답변에 나열된 것과 동일한 문제로 효과적으로 처리 할 수는 있지만 클래스 계약을 위반하지는 않습니다.

그렇지 않으면 내가 생각하기에는 어디서나 istringstream을지나 다니는 것이 가장 좋은 방법 일 것입니다.

+0

흥미로운 아이디어입니다. 기존 설정에 대해 좋아하는 것들 중 하나는'std :: stringbuf'에서 파생시켜 사용자 정의 입력 또는 출력 스트림을 설정할 수 있으며 하나 또는 두 개의 간단한 함수, 언더 플로우 또는'오버플로 '및' sync', 기본 클래스는 나를위한 모든 버퍼 관리를 처리합니다. 나는'std :: vector'를 기반으로하는 것들이 상당히 많은 코드를 필요로한다는 것을 의심합니다. 어쨌든 'swap'을 사용할 수는 있지만, 호출자가 상수 참조를 전달하는 대신 문자열을 포기하게해야합니다. –

2

imho, 가장 좋은 선택은 std :: strstream std :: strstream입니다.

+0

감사합니다. 나는 그것에 대해 몰랐습니다. 유일한 문제는'const char * '대신'char *'를 원하지만, 쉽게 해결할 수 있습니다. –

관련 문제