2011-01-12 4 views
2

question about crypto++私はブーストiostreamsを使用して実装しようとしました。ブーストiostreamsフィルタを使用する(closeとnon-copyable)

#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); 
} 

問題ありません:私は、次のコードを生成しました。しかし

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作品: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作る場合は動作しません。


問題はありません。 2.ストリームを閉じるには?デバッグ出力は次のようになります。

write 
put 
put 
put 
put 

答えて

5

最初の問題は、それがstd::istreamstd::ostreamまたはstd::streambufに由来するものではないので、それがないので、あなたのsha_output_filterは、pushの非constのオーバーロードを使用するための要件を満たしていないということです標準ストリームまたはストリームバッファタイプとして分類されます。
これはコンパイラ

TEST.CPPから最初のメッセージのいずれかから推定することができる :機能には「Tブースト::のiostream ::詳細::ラップ(constのT &、型名ブースト:: disable_if <後押し::のiostream :: is_std_io <T> > ::タイプ*)[T = sha_output_filter < CryptoPP :: SHA1 >、型名ブースト:: disable_if <ブースト::のiostream :: is_std_io <T> > ::タイプ=ボイド] ':

boost::disable_if<...>::typeを正常に解決できることを示すため、このオーバーロードを無効にしません。ソースコードを見ると、非const過負荷でenable_ifのテストが見つかるでしょう。


第二の問題に関しては、あなたのフィルタは閉鎖可能であるとしてマークされていないので、Boostライブラリは、それがフィルターにcloseを呼び出すことができます知っていません。

これは

struct category : boost::iostreams::output_filter_tag, boost::iostreams::closable_tag {}; 
categoryのためのtypedefを交換することによって解決することができます
関連する問題