[IOStreams] Is such a behaviour considered as bug
Hello *, I really enjoyed working with Iostreams, while testing some of my components. Using IOStreams with array_device seemed to be a very powerfull approach to test some of my stream based algorithms. But currently I face some issues which seem to be really weired to me. I produced some code snippet to better explain it. I used Boost.Test library to verify my assumptions. using namespace boost; namespace io=boost::iostreams; typedef unsinged char byte; typedef array<byte, 2> arr_buffer; //boost::array typedef io::basic_array<byte> arr_dev; arr_buffer buffer_ = {{}}; arr_dev dev_(buffer_.begin(), buffer_.end()); io::stream<arr_dev> ios_(dev_); arr_dev::pair_type range = dev_.input_sequence(); BOOST_MESSAGE("size: " << distance(range.first, range.second)); // output: size is 2 BOOST_CHECK_EQUAL(0u, ios_.tellg()); //stream is at position 0 as expected ios_.seekg(1); BOOST_CHECK_EQUAL(1u, ios_.tellg()); // stream is at position 1 as expected ios_.seekg(2); BOOST_MESSAGE("current pos: " << ios_.tellg()); // !!! stream is at position 2 ios_.seekg(3); BOOST_MESSAGE("current pos: " << ios_.tellg()); // stream is at position -1 BOOST_MESSAGE("eof: " << ios_.eof()); // !!! but eof is false If the defined stream is only 2 bytes long why is 2 a valid stream position? Why is eof always false? Do you think this behavior is buggy? I changed the same behavior to read bytes from stream and created an array of length 3, but passed the range of 2 bytes to the device ctor. This works as expected: arr_buffer buffer_ = {{'a', 'b', 'c'}}; arr_dev dev_(buffer_.begin(), buffer_.begin()+2); //range of 2 bytes is passed io::stream<arr_dev> ios_(dev_); arr_dev::pair_type range = dev_.input_sequence(); BOOST_MESSAGE("size: " << distance(range.first, range.second)); byte bt; BOOST_MESSAGE("current pos: " << ios_.tellg()); // prints 0 BOOST_CHECK_EQUAL(0u, ios_.tellg()); ios_.read(&bt, 1); BOOST_MESSAGE("retrieved: " << bt); // prints 'a' BOOST_MESSAGE("current pos: " << ios_.tellg()); //prints 1 BOOST_CHECK_EQUAL(1u, ios_.tellg()); ios_.read(&bt, 1); BOOST_MESSAGE("retrieved: " << bt); // prints 'b' BOOST_MESSAGE("current pos: " << ios_.tellg()); // !!! prints 2, why not -1??? ios_.read(&bt, 1); BOOST_MESSAGE("retrieved: " << bt); // still prints 'b' => nothing retrieved BOOST_MESSAGE("current pos: " << ios_.tellg()); // !!! now it prints -1 BOOST_MESSAGE("eof: " << ios_.eof()); // !!! now eof is true Any ideas why it behaves as described? With Kind Regards, Ovanes
On 11 August 2011 14:22, Ovanes Markarian <om_boost@keywallet.com> wrote:
If the defined stream is only 2 bytes long why is 2 a valid stream position?
There needs to be an offset for the end of the stream. I'm actually not sure if it should be -1 for larger values though.
Why is eof always false? Do you think this behavior is buggy?
IIRC in streams eof is only set when you try to read past the end of the file.
Hello Daniel, thanks for your answers. Please see my answers below. On Fri, Aug 12, 2011 at 11:37 PM, Daniel James <dnljms@gmail.com> wrote:
On 11 August 2011 14:22, Ovanes Markarian <om_boost@keywallet.com> wrote:
If the defined stream is only 2 bytes long why is 2 a valid stream
position?
There needs to be an offset for the end of the stream. I'm actually not sure if it should be -1 for larger values though.
To be honest, I do not understand what offset do you mean here. Why does array_device needs an offset for the end of stream and stringstream does not? I looked up the behavior in the standard (for stringstream, since I assume array_device should behave similar in regards of positioning and memory related nature of stringstream) and there is clearly written that seeking to an invalid pos will cause tellg to return -1. I would propose to change the array_device to be more consistent with stringstream in these regards. In Standard C++ IOStreams and Locales by A. Langer & K. Kreft is also stated for basic_istream<char_type, traits_type>& seekg(...) on p.489: "Repositions this to the location designated by pos, by calling this->rdbuf()->pubseekpos(off) [or] (off,dir). !!! Failures are indicated by the state of *this.!!! [...]" And now the tellg counterpart: "If this->fail()==true, returns pos_type(-1), othewise [...]" In case of stringstream seekg immediately fails if seeking the stream to an invalid pos, without any offsets. I find the behavior of array_device somehow unnatural, especially for the case where I would like to mimic other std streams for easier testing.
Why is eof always false? Do you think this behavior is buggy?
IIRC in streams eof is only set when you try to read past the end of the file.
Yes, you are right. I double checked this in the Standard. As the my upper answer points out, the stream should be in the failed state. Many thanks for your time, Ovanes
participants (2)
-
Daniel James
-
Ovanes Markarian