2011-01-12 2 views
2

question about crypto++을 부탁 한 후 부스트 iostream을 사용하여 구현하려고했습니다.부스트 iostream 필터 사용 (닫기 및 복사 불가능)

#include <iostream> 
#include <cryptopp/sha.h> 
#include <algorithm> 
#include <boost/array.hpp> 
#include <boost/iostreams/concepts.hpp> 
#include <boost/iostreams/operations.hpp> 
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/device/file.hpp> 

template<typename hash> 
class sha_output_filter : public boost::iostreams::output_filter 
{ 
    hash _hash; 
    char _digest[hash::DIGESTSIZE]; 
public: 
    typedef char         char_type; 
    typedef boost::iostreams::output_filter_tag category; 

    sha_output_filter() {} 
    //sha_output_filter(const sha_output_filter &) = delete; 
    sha_output_filter &operator=(const sha_output_filter &) = delete; 

    template<typename Sink> 
    bool put (Sink &dest, int c) 
    { 
    std::cout << "put" << std::endl; 
    char _c = c; 
    _hash.Update ((const byte *)&_c, 1); 
    boost::iostreams::put (dest, c); 
    } 

    template<typename Source> 
    void close (Source &src) 
    { 
    std::cout << "close" << std::endl; 
    _hash.Final(_digest); 
    } 

    boost::array<char, hash::DIGESTSIZE> digest() { 
    boost::array<char, hash::DIGESTSIZE> tmp; 
    std::copy(_digest, _digest + hash::DIGESTSIZE, tmp.begin()); 
    return tmp; 
    } 
}; 

int main() 
{ 
    sha_output_filter<CryptoPP::SHA1> outf; 
    boost::iostreams::filtering_ostream out; 
    out.set_auto_close (true); 
    out.push(outf); 
    out.push(boost::iostreams::file_sink("my_file.txt")); 
    std::cout << "write" << std::endl; 
    out.write("123\n", 4); 
    out.pop(); 
    out.pop(); 
    boost::iostreams::file_sink hash_out("hash.txt"); 
    boost::array<char, CryptoPP::SHA1::DIGESTSIZE> digest = outf.digest(); 
    hash_out.write(digest.begin(), CryptoPP::SHA1::DIGESTSIZE); 
} 

문제 번호 : 나는 다음과 같은 코드를 생산했다. 1 : 내가 "if T is a standard stream or stream buffer type, by using the templated overload of push taking a non-const reference."을 알리는 문서에도 불구하고 비 복사 가능한 sha_output_filter 할 경우 작동하지 않지만, 내가 주석 라인의 경우 :

In file included from /usr/include/boost/iostreams/traits.hpp:31:0, 
       from /usr/include/boost/iostreams/detail/dispatch.hpp:17, 
       from /usr/include/boost/iostreams/flush.hpp:17, 
       from /usr/include/boost/iostreams/close.hpp:18, 
       from /usr/include/boost/iostreams/operations.hpp:16, 
       from test.cpp:6: 
test.cpp: In function ‘T boost::iostreams::detail::wrap(const T&, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’: 
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: instantiated from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:257:60: instantiated from ‘void boost::iostreams::detail::chain_base<Self, Ch, Tr, Alloc, Mode>::push_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Self = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, Ch = char, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:216:1: instantiated from ‘void boost::iostreams::detail::chain_base<Self, Ch, Tr, Alloc, Mode>::push(const T&, std::streamsize, std::streamsize, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, Self = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, Ch = char, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’ 
/usr/include/boost/iostreams/chain.hpp:496:7: instantiated from ‘void boost::iostreams::detail::chain_client<Chain>::push_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Chain = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:484:1: instantiated from ‘void boost::iostreams::detail::chain_client<Chain>::push(const T&, std::streamsize, std::streamsize, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, Chain = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, std::streamsize = long int, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’ 
test.cpp:51:16: instantiated from here 
test.cpp:20:3: error: deleted function ‘sha_output_filter<hash>::sha_output_filter(const sha_output_filter<hash>&) [with hash = CryptoPP::SHA1, sha_output_filter<hash> = sha_output_filter<CryptoPP::SHA1>]’ 
/usr/include/boost/iostreams/detail/wrap_unwrap.hpp:53:14: error: used here 
In file included from /usr/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp:23:0, 
       from /usr/include/boost/iostreams/stream_buffer.hpp:22, 
       from /usr/include/boost/iostreams/chain.hpp:35, 
       from /usr/include/boost/iostreams/filtering_streambuf.hpp:17, 
       from /usr/include/boost/iostreams/filtering_stream.hpp:22, 
       from test.cpp:7: 
test.cpp: In constructor ‘boost::iostreams::detail::concept_adapter<T>::concept_adapter(const T&) [with T = sha_output_filter<CryptoPP::SHA1>]’: 
/usr/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp:187:5: instantiated from ‘void boost::iostreams::detail::indirect_streambuf<T, Tr, Alloc, Mode>::open(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/stream_buffer.hpp:106:13: instantiated from ‘void boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::open_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: instantiated from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:257:60: instantiated from ‘void boost::iostreams::detail::chain_base<Self, Ch, Tr, Alloc, Mode>::push_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Self = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, Ch = char, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:216:1: instantiated from ‘void boost::iostreams::detail::chain_base<Self, Ch, Tr, Alloc, Mode>::push(const T&, std::streamsize, std::streamsize, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, Self = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, Ch = char, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’ 
/usr/include/boost/iostreams/chain.hpp:496:7: instantiated from ‘void boost::iostreams::detail::chain_client<Chain>::push_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Chain = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:484:1: instantiated from ‘void boost::iostreams::detail::chain_client<Chain>::push(const T&, std::streamsize, std::streamsize, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, Chain = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, std::streamsize = long int, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’ 
test.cpp:51:16: instantiated from here 
test.cpp:20:3: error: deleted function ‘sha_output_filter<hash>::sha_output_filter(const sha_output_filter<hash>&) [with hash = CryptoPP::SHA1, sha_output_filter<hash> = sha_output_filter<CryptoPP::SHA1>]’ 
/usr/include/boost/iostreams/detail/adapter/concept_adapter.hpp:67:48: error: used here 
test.cpp: In copy constructor ‘boost::iostreams::detail::concept_adapter<sha_output_filter<CryptoPP::SHA1> >::concept_adapter(const boost::iostreams::detail::concept_adapter<sha_output_filter<CryptoPP::SHA1> >&)’: 
/usr/include/boost/iostreams/detail/adapter/concept_adapter.hpp:38:23: instantiated from ‘void boost::iostreams::detail::optional<T>::reset(const T&) [with T = boost::iostreams::detail::concept_adapter<sha_output_filter<CryptoPP::SHA1> >]’ 
/usr/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp:187:5: instantiated from ‘void boost::iostreams::detail::indirect_streambuf<T, Tr, Alloc, Mode>::open(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/stream_buffer.hpp:106:13: instantiated from ‘void boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::open_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: instantiated from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:257:60: instantiated from ‘void boost::iostreams::detail::chain_base<Self, Ch, Tr, Alloc, Mode>::push_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Self = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, Ch = char, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:216:1: instantiated from ‘void boost::iostreams::detail::chain_base<Self, Ch, Tr, Alloc, Mode>::push(const T&, std::streamsize, std::streamsize, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, Self = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, Ch = char, Tr = std::char_traits<char>, Alloc = std::allocator<char>, Mode = boost::iostreams::output, std::streamsize = long int, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’ 
/usr/include/boost/iostreams/chain.hpp:496:7: instantiated from ‘void boost::iostreams::detail::chain_client<Chain>::push_impl(const T&, std::streamsize, std::streamsize) [with T = sha_output_filter<CryptoPP::SHA1>, Chain = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, std::streamsize = long int]’ 
/usr/include/boost/iostreams/chain.hpp:484:1: instantiated from ‘void boost::iostreams::detail::chain_client<Chain>::push(const T&, std::streamsize, std::streamsize, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type*) [with T = sha_output_filter<CryptoPP::SHA1>, Chain = boost::iostreams::chain<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char> >, std::streamsize = long int, typename boost::disable_if<boost::iostreams::is_std_io<T> >::type = void]’ 
test.cpp:51:16: instantiated from here 
test.cpp:20:3: error: deleted function ‘sha_output_filter<hash>::sha_output_filter(const sha_output_filter<hash>&) [with hash = CryptoPP::SHA1, sha_output_filter<hash> = sha_output_filter<CryptoPP::SHA1>]’ 
/usr/include/boost/iostreams/detail/adapter/concept_adapter.hpp:38:23: error: used here 
In file included from /usr/include/boost/iostreams/detail/streambuf/direct_streambuf.hpp:26:0, 
       from /usr/include/boost/iostreams/stream_buffer.hpp:21, 
       from /usr/include/boost/iostreams/chain.hpp:35, 
       from /usr/include/boost/iostreams/filtering_streambuf.hpp:17, 
       from /usr/include/boost/iostreams/filtering_stream.hpp:22, 
       from test.cpp:7: 
/usr/include/boost/iostreams/detail/optional.hpp: In member function ‘void boost::iostreams::detail::optional<T>::reset(const T&) [with T = boost::iostreams::detail::concept_adapter<sha_output_filter<CryptoPP::SHA1> >]’: 
/usr/include/boost/iostreams/detail/optional.hpp:100:9: note: synthesized method ‘boost::iostreams::detail::concept_adapter<sha_output_filter<CryptoPP::SHA1> >::concept_adapter(const boost::iostreams::detail::concept_adapter<sha_output_filter<CryptoPP::SHA1> >&)’ first required here 

그러나 boost::ref 작동합니다.


문제 번호. 2. 스트림을 닫는 방법?

write 
put 
put 
put 
put 

답변

5

첫 번째 문제는이 std::istream, std::ostream 또는 std::streambuf에서 파생되지 않기 때문에 당신의 sha_output_filterpush의 const가 아닌 오버로드를 사용하기위한 요구 사항을 충족하지 않는다는 것입니다, 그래서되지 않습니다 : 디버그 출력은 표준 스트림 또는 스트림 버퍼 유형으로 분류됩니다.
이 컴파일러

Test.cpp에에서 첫 번째 메시지 중 하나로부터 추론 할 수있다 : 기능에서 'T 부스트 :: IOSTREAMS :: 자세히 :: 랩 (const를 T &, 유형 이름 부스트 :: disable_if < 부스트 : IOSTREAMS :: is_std_io <T> > :: 종류 *) T = sha_output_filter < CryptoPP :: SHA1 >, 유형 이름 부스트 : disable_if < 부스트 : IOSTREAMS :: is_std_io <T> > :: TYPE = 보이드 ] ':

여기서는 boost::disable_if<...>::type을 성공적으로 확인할 수 있음을 나타내므로이 과부하를 비활성화하지 않습니다. 소스 코드를 살펴보면 non-const 과부하에 대해 enable_if 테스트를 찾을 수 있습니다. 두 번째 문제에 관해서는


, 필터는 폐쇄 것으로 표시되지 않으므로 부스트 라이브러리는 필터에 close를 호출 할 수 있습니다 알 수 없습니다.

struct category : boost::iostreams::output_filter_tag, boost::iostreams::closable_tag {}; 
category에 대한 형식 정의를 대체하여 해결할 수 있습니다