Binary stream detection

A

Aaron Turner

Dear All,

I am working on some cross-platform code and using read() and
write() on binary streams. What I would like to do is to
determine whether a stream has been opened as binary to avoid
the problem where a file has been opened as text and then is
used on a Windows system as Windows 'helpfully' inserts extra
characters when it sees some control characters.

Whilst there is a mechanism to obtain format flags I have been
unable to find any flag or mechanism to determine the flags
used when opening the stream. Is there such a mechanism that
I am missing?

Many thanks

Aaron Turner
 
P

Pete Becker

Aaron said:
I am working on some cross-platform code and using read() and
write() on binary streams.

Binary streams are not portable. The only guarantee you have is that if
you write a file in binary mode you can read it with code compiled with
the same compiler (which implies the same compiler switches).
What I would like to do is to
determine whether a stream has been opened as binary to avoid
the problem where a file has been opened as text and then is
used on a Windows system as Windows 'helpfully' inserts extra
characters when it sees some control characters.

Different operating systems have different conventions for marking line
endings, and the C and C++ runtime systems convert '\n' characters into
the appropriate character sequence when you write a file in text mode.
When you read it in binary mode you get whatever bytes were written to
the file, which means you get different line ending sequences on Unix,
Windows, and Mac. If you're serious about writing cross-platform code,
lose the Unix jingoism.

To answer your question: no, you can't directly determine after the fact
whether a file was opened in the mode you wanted.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
C

Chris Theis

Aaron Turner said:
Dear All,

I am working on some cross-platform code and using read() and
write() on binary streams. What I would like to do is to
determine whether a stream has been opened as binary to avoid
the problem where a file has been opened as text and then is
used on a Windows system as Windows 'helpfully' inserts extra
characters when it sees some control characters.

Whilst there is a mechanism to obtain format flags I have been
unable to find any flag or mechanism to determine the flags
used when opening the stream. Is there such a mechanism that
I am missing?

There are the flags which are set in the ctor, but I'm not sure whether you
can access them directly. You might have a look in the implementation of
stream in the standard library. However, I'm a little puzzled by what you
want to achieve because shouldn't you, being the one who opens the stream,
know which mode was used or am I missing something?

Cheers
Chris
 
V

Victor Bazarov

Chris said:
There are the flags which are set in the ctor, but I'm not sure
whether you can access them directly. You might have a look in the
implementation of stream in the standard library. However, I'm a
little puzzled by what you want to achieve because shouldn't you,
being the one who opens the stream, know which mode was used or am I
missing something?

It's possible that the stream is given as an argument. Of course,
in such case there should be a convention in place what type of
stream it should be...

V
 
C

Chris Theis

Victor Bazarov said:
It's possible that the stream is given as an argument. Of course,
in such case there should be a convention in place what type of
stream it should be...

I totally agree on this point. IMHO either a convention or a wrapper that
should provide the required information should do the job.

Chris
 
A

Aaron Turner

Pete said:
Binary streams are not portable. The only guarantee you have is that if
you write a file in binary mode you can read it with code compiled with
the same compiler (which implies the same compiler switches).

The possibilities of different sizes of data types and endianess have
been dealt with in a series of 1 byte data blocks at the beginning which
allows the system to reconfigure for all the supported options that
the system will be compiled for. So it is portable in the sense that
it can adjust to those supported options.
To answer your question: no, you can't directly determine after the fact
whether a file was opened in the mode you wanted.

Thanks

Aaron Turner
 
A

Aaron Turner

Chris said:
There are the flags which are set in the ctor, but I'm not sure whether you
can access them directly. You might have a look in the implementation of
stream in the standard library. However, I'm a little puzzled by what you
want to achieve because shouldn't you, being the one who opens the stream,
know which mode was used or am I missing something?

The method that handles the stream and serialises information to/from it
is contained within a library. This takes into account differences of
datatype sizes, endianess, and so on. This has been tested on a wide
variety of Unix-like systems and 32 and 64 bit Windows of various
flavours. On Unix and Unix-like systems there isn't a problem within
the library code if the stream has been opened binary or text, but it
does present a problem on Windows system.

Whilst ideally users of the system should open the stream as binary I
can't necessarily enforce it, so detecting if it wasn't opened binary
and then throwing an error would be very useful.

Regards,

Aaron Turner
 
A

Aaron Turner

Chris said:
I totally agree on this point. IMHO either a convention or a wrapper that
should provide the required information should do the job.

Perhaps this might be the best idea. Whilst the old function in the
library will still need to remain for backwards compatibility adding
a wrapper class to enforce binary streams and adding some additional
wrappers within the library would provide a neat solution to this
issue.

Many thanks

Aaron Turner
 
A

Aaron Turner

Aaron said:
a wrapper class to enforce binary streams and adding some additional
wrappers within the library would provide a neat solution to this
issue.

Hmmm actually I spot a problem as the library code passes uses the
general istream and ostream, so a wrapper would have to allow
any classes derived from these as arguments too, which would
make a wrapper tricky.

Regards,

Aaron Turner
 

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
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top