What is the standard output buffer called? - c++

When I write a filebuf, everything is ok.
I'd like to know what is called a buffer for standard output.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
filebuf m;
m.open("/home/patryk/untitled6/text.txt", ios::out);
ostream out(&m);
out<<"to ja";
}
I don't want use e.g cout.rdbuf.
Only as above
The name of the output stream
#include <iostream>
using namespace std;
int main()
{
ostream out(cout.rdbuf());
out<<"to ja";
}

It is an implementation defined type derived from std::streambuf Here is what a popular C++ reference says:
The global objects std::cout and std::wcout control output to a stream buffer of implementation-defined type (derived from std::streambuf), associated with the standard C output stream stdout.
This means you can only realistically access the instance currently inside std::coutusing std::cout.rdbuf() - unless your compiler vendor provides non-standard access to its relevant internals.
For example, GCC provides stdio_filebuf, an instance of which could be "wrapped around" the standard output file descriptor.

In both examples, there is no need to use std::ostream the way you are.
In the first example, use std::ofstream instead of std::filebuf:
ofstream out("/home/patryk/untitled6/text.txt");
out << "to ja";
In the second example, std::cout is already a std::ostream so just write to it directly:
cout << "to ja";
In both cases, this abstracts away how the actual buffers are implemented. Just focus on the higher level stream interface by itself. The buffers used are just implementation details.

Related

Transform a buffer into an istream to work in existing programs

I am trying to create a native nodejs module, using NAN and c ++, I want to transform an existing program that uses std::ifstream stream (filename, std :: ifstream :: in | std :: ifstream :: binary); to load a file into a javascript module that can load a buffer and send it to c ++
The original c ++ code was made to work via command line, I don't want to have to write a file to disk, I would like to send this file using a nodejs buffer.
index.js
const fs = require('fs')
const addon = require('./build/Release/image_edit');
fs.readFile('image.png', function read(err, buffer) {
if (err) {
throw err;
}
var result = addon.edit(buffer, buffer.length);
//console.log(result)
});
main.cpp
#include <node.h>
#include <node_buffer.h>
#include <iostream>
#include <nan.h>
#include <sstream>
#include <string>
#include <fstream>
#include <streambuf>
#include <istream>
using namespace Nan;
using namespace v8;
uint32_t read(std::istream& in)
{
uint32_t v;
in.read(reinterpret_cast<char*>(&v), sizeof(v));
return v;
}
NAN_METHOD(edit) {
unsigned char*buffer = (unsigned char*) node::Buffer::Data(info[0]->ToObject());
unsigned int size = info[1]->Uint32Value();
//the closest I could to manipulating the data was using a vector
std::vector<uint32_t> png_data(buffer, buffer + size);
//The main core of the program uses the in.read function to parse the file, tb uses in.clear () and in.seekg ();
//here an example of how this is done
uint32_t count = readU32(stream);
}
NAN_MODULE_INIT(Init) {
Nan::Set(target, New<String>("edit").ToLocalChecked(),
GetFunction(New<FunctionTemplate>(edit)).ToLocalChecked());
}
NODE_MODULE(image_edit, Init)
I tried using the following code to verify that the data received is valid and if the recorded file is the same as the original, everything looks fine.
std::ofstream FILE("test.png", std::ios::out | std::ofstream::binary);
std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<char>(FILE));
The question is, how do I make this buffer received from nodejs into something read the same way an ifstream does, without having to drastically change the c ++ program?
The main methods called by the program in c ++ are: .seekg (), .push_back, .clear (),
This kind of thing is usually done by implementing a custom subclass of std::streambuf, and then using it to construct a std::istream.
std::istream has a constructor that takes a pointer to a std::streambuf as a parameter, so the basic outline is something like this
class my_streambuf : public std::streambuf {
// ... Your implementation of your subclass
};
my_streambuf msb{ /* Parameters to your class's constructor */ }
std::istream i{&msb};
At this point, i is an ordinary input stream and does everything that any other input stream does. You can seek it. You can read from it.
Of course, the hard part is implementing your custom subclass of std::streambuf. This is not something that can be fully described in one or two paragraphs on stackoverflow.com. You should read std::streambuf's documentation, specifically the descriptions of its virtual methods. Your custom subclass will need to reimplement std::streambuf's virtual methods and make them work with your buffer. It's likely you will not need to reimplement all the virtual methods. For some of them their default implementation will be sufficient. Some of them won't be needed, for what you end up doing with std::istream.
You will have to determine, based on you specific needs to what extent you need to reimplement which std::streambuf's virtual methods, and how.
Of course, another, easy alternative is to use your buffer to construct a std::string, and then using it to construct a std::istringstream, and call it a day. Of course, that'll be somewhat wasteful and require effectively doubling the memory used for the data, with a second copy that's owned by a throw-away std::string, and copying it. If this is a small amount of data that's probably fine, but if your buffer is very big that may not be practical, and a custom std::streambuf subclass that uses the buffer directly is your only option.
Like the other answer mentioned, you can use an std::stringstream if you don't want to go the std::streambuf route:
std::stringstream ss;
std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<uint32_t>(ss));
Then you just use it like an input stream.

std::cout, ostream and other kinds of getting output stream

In my project (Unreal Engine 4) I don't have an output stream - instead of this I can communicate via UE_LOG function, which works pretty much similar to printf(). The problem is that I just made a .dll library (without Unreal includes) which I want to communicate through the iostream. My idea is - inside .dll library I use standard cout to write messages into ostream, I use all of it in Unreal Engine functions, where I grab ostream in form of string and output it into UE_LOG function.
Problem is I always treated std::cout as a part of magic, without thinking what is really inside (I am pretty sure most of us did). How I can handle this? Easy ways won't work (like grabbing stringstream and outputing it into UE_LOG).
My idea is - inside .dll library I use standard cout to write messages into ostream
You actually can replace the output buffer used with std::cout with your own implementation. Use the std::ostream::rdbuf() function to do so (example from the reference docs):
#include <iostream>
#include <sstream>
int main()
{
std::ostringstream local;
auto cout_buff = std::cout.rdbuf(); // save pointer to std::cout buffer
std::cout.rdbuf(local.rdbuf()); // substitute internal std::cout buffer with
// buffer of 'local' object
// now std::cout work with 'local' buffer
// you don't see this message
std::cout << "some message";
// go back to old buffer
std::cout.rdbuf(cout_buff);
// you will see this message
std::cout << "back to default buffer\n";
// print 'local' content
std::cout << "local content: " << local.str() << "\n";
}
(in case my edit won't be positively reviewed)
From OP: Thanks to your hints I finally found how to solve my problem. Suppose I want to get stream from cout and send it to printf (because I think stdio library is superior to iostream). Here how I can do this:
#include <iostream>
#include <sstream>
#include <cstdio>
using namespace std;
class ssbuf : public stringbuf{
protected:
int sync(){
printf("My buffer: %s",this->str().c_str());
str("");
return this->stringbuf::sync();
}
};
int main(){
ssbuf *buf = new ssbuf();
cout.rdbuf(buf);
cout<<"This is out stream "<<"and you cant do anything about it"<<endl;
cout<<"(don't) "<<"Vote Trump"<<endl;
}
Code is very raw, but it does it's job. I made child class of buffer which has method sync() downcasting original virtual method sync(). Except this it works like usual buffer, just grabs all console-out stream - exactly what we wanted. The str("") inside is to clean the buffer - probably not outputted stream doesn't clean itself.
Great thanks for help! Big GRIN for you! :D

How can I reverse the output stream in c++?

What I am trying to achieve is to use the standard std::cout and if you understand, reverse the output to an input so another part of my program can read it. No I cannot just call a function in the other part of my program because every function is and must stay private so this seems the only way to do it. I did a similar thing in java by redirecting the default output stream to my own custom one but I am somewhat new to c++. This is what I did in java:
System.setOut(customPrintStream);
Does anyone know of an alternative for c++ or a way to get whatever is printed to console?
The c++ standard library supports the concept of 'reverse iterators'.
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
int main()
{
auto s = std::string("Hello, World");
std::copy(std::rbegin(s), std::rend(s),
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
return 0;
}
expected output:
dlroW ,olleH
The streams in C++ read from and write to std::streambuf objects. You can replace the stream buffer of an std::ostream object using the rdbuf() function. For example, to capture all output written to std::cout in a std::string you could use something like this:
std::ostreamstream stream;
std::streambuf* sbuf = std::cout.rdbuf(stream.rdbuf());
// use code whose output is written to `std::cout`
std::cout.rdbuf(sbuf); // restore the original stream buffer
std::string output = stream.str();
In a real implementation you'd probably use an RAII approach to replace/restore the stream buffer. Also, you might want to use a custom stream buffer rather than a std::stringbuf but the basic remain as is.

Method parameter for both iostream and stringstream

I'd like to input a stream parameter to a method which can be either a <stringstream> or <iostream> as in:
void method(? out); // or
void method(? in);
If ? is <istream> or <ostream> it's straightforward. What I don't know is what to do if the parameter is either <istream> or <stringstream> or is either <ostream> or <stringstream>.
Can this be done?
The streams implementing both std::istream and std::ostream, e.g., std::stringstream and std::fstream derive from std::iostream (since they are all class templates, you'd look for basic_... in the standard). That is, if you really need a stream which is used for both input and output, you'd pass an std::iostream&.
The class std::iostream derives from both std::istream and std::ostream. The appropriate types are straight forward:
for reading only use std::istream&
for writing only use std::ostream&
for reading and writing use std::iostream& (I don't think I ever used this in production code)
Note that you need to seek when switching between reading and writing in case the stream may be a file stream: switching between reading and writing without intervening seek, even if the seek is to the current position, results in undefined behavior.
Both the string stream classes and file stream classes publically-derive from the general stream bases classes std::basic_istream<...> and std::basic_ostream<...>. This means that you can pass (for instance) std::ostringstream objects to functions that take std::ostream:
void test(std::ostream& os);
std::ostringstream buf;
test(buf); // Good!
Unless of course, you need additional functionality specific to the derived stream classes. For example, string streams provide an str() method and file streams provide open()/close() member functions. In the case where you need these, you can have test() take string streams or file streams as parameters.
void test(std::istringstream& iss)
{
std::cout << iss.str(); // Works because the type is a stringstream
}

Which locale will apply to cout after cout.rdbuf(fout.rdbuf())?

#include <locale>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ofstream fout("test.txt");
fout.imbue(locale("chs"));
cout.imbue(locale("C"));
cout.rdbuf(fout.rdbuf());
cout << "中文"; // Which locale will apply to here? "C" or "chs"?
}
The question is commented in the code.
From http://www.cplusplus.com/reference/ios/ios/imbue/
std::ios::imbue <ios>
locale imbue ( const locale& loc );
Imbue locale
Associates loc to both the stream and its associated stream buffer (if
any) as the new locale object to be used with locale-sensitive
operations.
All callback functions registered with register_callback with
imbue_event as its first parameter are called.
In fact, this member function calls its inherited homonym
ios_base::imbue(loc), and if the stream is associated with a stream
buffer, also calls rdbuf()->pubimbue(loc).
Also, see http://stdcxx.apache.org/doc/stdlibug/27-4.html
27.4.4 Collaboration of Locales and Iostreams
The base class ios_base contains a locale object. The formatting and
parsing functions defined by the derived stream classes use the
numeric facets of that locale.
The class template basic_ios holds a pointer to the stream buffer.
This stream buffer has a locale object, too, usually a copy of the
same locale object used by the functions of the stream classes. The
stream buffer's input and output functions use the code conversion
facet of the attached locale.
In your case, it would use the "C" numeric locale and the "chs" character locale.