开发者

Transparently manipulating strings inserted into an ostream

开发者 https://www.devze.com 2023-01-19 15:17 出处:网络
I\'d like to provide an std::ostream that may or may not, from the user\'开发者_Python百科s point of view, encrypt its contents.

I'd like to provide an std::ostream that may or may not, from the user'开发者_Python百科s point of view, encrypt its contents.

Imagine some random function that uses an std::ostream&:

void write_stuff( std::ostream& stream ) {
    os << "stuff";
}

Whether stuff is output in cleartext or is encrypted is dependent on how the stream argument was initialized.

I'm thinking about inheriting from std::basic_streambuf, but I'm not sure it's the best way to go. I think the ideal scenario is some sort of filter object which is run before the contents are actually output. That way it'd be easy to chain operations, e.g. encrypting and then hex-encoding, which is a benefit that making my own basic_streambuf does not seem to give (not easily at least).

Any advices?

Thanks.

UPDATE: I followed the strategy laid out by the accepted answer. I found this article on writing a custom streambuf which performs XOR obfuscation to be extremely helpful as a starting point.


A streambuf can be implemented in terms of another arbitrary streambuf that's either passed in as an argument to the constructor or set with a special member function. And that allows you to stack streambuf implementations like you were thinking of.

You could even make a manipulator that uses the ostream's rdbuf function to get the current streambuf, call a function on your streambuf that sets the 'stacked' streambuf, and then calls rdbuf again to replace the ostream's streambuf with your own.

aes_ctr_streambuf encrypter(key);
zlib_streambuf compressor;
::std::cout << stack_streambuf(encrypter) << stack_streambuf(compressor);


It is hard to describe in short what you have to do in order to create an I/O stream for the new source or sink. Luckily, Jonathan Turkanis and CodeRage, LLC have created very nice building blocks with exceptional documentation that can help you save hundreds of hours of research and development of new streams. The library is called Boost.Iostreams.

The second example in documentation exactly shows how to solve your problem.

Also, note that they already have an output stream with zip compression. So maybe you don't even need to write a single line of code.

Good luck!


I'm not sure that what I'm about to suggest is exactly what you need (and its too complicated to be a comment), but have you ever heard of the stream manipulators ?

#include <iostream>
#include <iomanip>

int main(int, char**)
{
  int a = 10;
  std::cout << "a: " << a << std::endl; //outputs: "a: 10"
  std::cout << "a: " << std::hex << a << std::endl; //outputs: "a: a"
  std::cout << "a: " << std::dec << a << std::endl; //outputs: "a: 10"

  return EXIT_SUCCESS;
}

You may indeed use a similar pattern (this matches what you actually call a "filter" object) to somehow change the state of your custom stream object.

0

精彩评论

暂无评论...
验证码 换一张
取 消