Why does the class std::stream_buf has an ugly function imbue() ?

X

xmllmx

Dear all,

It is not easy to state in simple words. So please allow me to
introduce my own thoughts about it.

To my understanding, at least there are three characteristics which
make a stream different from a buffer:

#1, a stream can only hold human-readable characters(ansi/unicode),
while a buffer can hold any bytes such as 0.

#2, a stream can automatically maintain a current position after read/
write, while a buffer can't.

#3, a stream can smartly convert any object to human-readable
characters or vice versa, while a buffer can't.

For convenience, I will use "stream" to indicate the class istream/
ostream hereunder.

According to Object-Oriented principles, one class should not care
things which are not related to its responsibilities.

The class stream is responsible for convert any object to human-
readable characters or vice versa, so it is natural that the class
stream should care the locale. So the class basic_ios has imbue(), it
is easy to understand.

The class stream_buf is just responsible for reading/writing
characters, which are unrelated to the locale. The stream_buf doesn't
care what the characters represent. So stream_buf should not has the
member functions imbue() and pubimbue(). However, in fact, the C++
standard requires stream_buf must provide the two functions. WHY?
 
X

xmllmx

Your thinking and thus most of your post is erroneous as C++ streams can
handle binary as well as text data.  std::istream::read can read binary
data and does not care about locale.

/Leigh- Hide quoted text -

- Show quoted text -

Thank you for quick response.

I know what you said. Though one can implement a binary stream, binary
stream does not conform with the C++ standard.

I wonder why the class stream_buf should care the locale.
 
J

James Kanze

[...]
The class stream_buf is just responsible for reading/writing
characters, which are unrelated to the locale.

The locale determines the character encoding, and how to
translate the external encoding into the internal one.
Typically, this is mainly an issue with wchar_t streams, which
The stream_buf doesn't care what the characters represent. So
stream_buf should not has the member functions imbue() and
pubimbue(). However, in fact, the C++ standard requires
stream_buf must provide the two functions. WHY?

So that the stream can propagate changes to its encoding down to
the streambuf, and that you can modify the encoding in the
streambuf without changing the locale in the stream.
 
J

James Kanze

On 04/11/2010 16:43, xmllmx wrote:

[...]
Interesting statement. I'm not really sure what is meant: I've
implemented an oxdrstream and an ixdrstream, and as far as I can
tell, they're 100% conform. There are no truely binary streams
in the standard, but with a bit of care, you can put the
standard streams into a mode which is binary.
That is just nonsense sorry. Of course it conforms with the C++
standard. Formatted input/output uses locales, Unformatted (binary)
input/output does not use locales.

If you're talking about the standard streams, that's false. All
streams use locale all the time. The binary/text flag is rather
a misnomer, as it simply serves to distinguish between two "file
types".

You can, in practice, use a stream to input or output raw binary
data, but you have to be very careful to imbue it with the "C"
locale (so that codecvt is the identity function), as well as
setting the binary flag when opening the file. (Formally, the
system may add additional 0's to the end when writing a binary
file, but I don't know of any modern systems that do.)
 
J

James Kanze

On 04/11/2010 18:15, James Kanze wrote:

[...]
Initially the global locale is the standard C locale so you
don't need to explicitly imbue it if the global locale has not
been changed.

If you can prove that it will never be changed, you mean. (In
practice, the global locale is almost always changed, since the
"C" locale isn't very useful for human interaction.)
What is the "additional 0's" nonsense?

The C++ standard refers to the C standard, and the C standard
explicitly says that an implementation can add 0's to the end of
a file opened in binary.
Please stop polluting discussions with irrelevent anecdotes of
old systems (unless really interesting/funny); such pollution
does not make understanding issues easier.

I put the information in parentheses, because I don't think it
that relevant today. But some people do like to know exactly
what the standard guarantees on such issues, even if you don't.
 
J

James Kanze

On 04/11/2010 18:15, James Kanze wrote:
[...]
You can, in practice, use a stream to input or output raw binary
data, but you have to be very careful to imbue it with the "C"
locale (so that codecvt is the identity function), as well as
setting the binary flag when opening the file. (Formally, the
system may add additional 0's to the end when writing a binary
file, but I don't know of any modern systems that do.)
Initially the global locale is the standard C locale so you
don't need to explicitly imbue it if the global locale has not
been changed.
If you can prove that it will never be changed, you mean. (In
practice, the global locale is almost always changed, since the
"C" locale isn't very useful for human interaction.)
Why state the obvious? Unless you are writing library code
you will already know if the global locale has been changed.

Are you kidding? How do you know what changes will occur in the
application in the future? In general, in all but the simplest
code, you have to assume that the global locale may have been
changed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top