Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Initial Developer of the Original Code is
16 : * Caolán McNamara <caolanm@redhat.com> (Red Hat, Inc.)
17 : * Portions created by the Initial Developer are Copyright (C) 2011 the
18 : * Initial Developer. All Rights Reserved.
19 : *
20 : * Contributor(s): Caolán McNamara <caolanm@redhat.com>
21 : *
22 : * Alternatively, the contents of this file may be used under the terms of
23 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : * instead of those above.
27 : */
28 :
29 : #include <sal/types.h>
30 : #include "cppunit/TestAssert.h"
31 : #include "cppunit/TestFixture.h"
32 : #include "cppunit/extensions/HelperMacros.h"
33 : #include "cppunit/plugin/TestPlugIn.h"
34 : #include <tools/stream.hxx>
35 : #include <sstream>
36 :
37 : //Tests for eofbit/badbit/goodbit/failbit
38 :
39 : namespace
40 : {
41 :
42 30 : class Test: public CppUnit::TestFixture
43 : {
44 : public:
45 : void test_stdstream();
46 : void test_fastostring();
47 : void test_read_cstring();
48 : void test_read_pstring();
49 : void test_readline();
50 :
51 4 : CPPUNIT_TEST_SUITE(Test);
52 2 : CPPUNIT_TEST(test_stdstream);
53 2 : CPPUNIT_TEST(test_fastostring);
54 2 : CPPUNIT_TEST(test_read_cstring);
55 2 : CPPUNIT_TEST(test_read_pstring);
56 2 : CPPUNIT_TEST(test_readline);
57 4 : CPPUNIT_TEST_SUITE_END();
58 : };
59 :
60 2 : void Test::test_stdstream()
61 : {
62 2 : char foo[] = "foo";
63 2 : std::istringstream iss(foo, std::istringstream::in);
64 2 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
65 :
66 2 : char std_a(78);
67 2 : iss >> std_a;
68 2 : CPPUNIT_ASSERT(std_a == 'f');
69 :
70 2 : char tools_a(78);
71 2 : aMemStream >> tools_a;
72 2 : CPPUNIT_ASSERT(tools_a == 'f');
73 :
74 2 : iss.seekg(0, std::ios_base::end);
75 : //seeking to end doesn't set eof, reading past eof does
76 2 : CPPUNIT_ASSERT(!iss.eof());
77 2 : CPPUNIT_ASSERT(iss.good());
78 :
79 2 : aMemStream.Seek(STREAM_SEEK_TO_END);
80 : //seeking to end doesn't set eof, reading past eof does
81 2 : CPPUNIT_ASSERT(!aMemStream.eof());
82 2 : CPPUNIT_ASSERT(aMemStream.good());
83 :
84 2 : std_a = 78;
85 2 : iss >> std_a;
86 : //so, now eof is set
87 2 : CPPUNIT_ASSERT(iss.eof());
88 : //a failed read doesn't change the data, it remains unchanged
89 2 : CPPUNIT_ASSERT(std_a == 78);
90 : //nothing wrong with the stream, so not bad
91 2 : CPPUNIT_ASSERT(!iss.bad());
92 : //yet, the read didn't succeed
93 2 : CPPUNIT_ASSERT(!iss.good());
94 2 : CPPUNIT_ASSERT(iss.rdstate() == (std::ios::failbit|std::ios::eofbit));
95 :
96 2 : tools_a = 78;
97 2 : aMemStream >> tools_a;
98 : //so, now eof is set
99 2 : CPPUNIT_ASSERT(aMemStream.eof());
100 : //a failed read doesn't change the data, it remains unchanged
101 2 : CPPUNIT_ASSERT(tools_a == 78);
102 : //nothing wrong with the stream, so not bad
103 2 : CPPUNIT_ASSERT(!aMemStream.bad());
104 : //yet, the read didn't succeed
105 2 : CPPUNIT_ASSERT(!aMemStream.good());
106 :
107 : //set things up so that there is only one byte available on an attempt
108 : //to read a two-byte sal_uInt16. The byte should be consumed, but the
109 : //operation should fail, and tools_b should remain unchanged,
110 2 : sal_uInt16 tools_b = 0x1122;
111 2 : aMemStream.SeekRel(-1);
112 2 : CPPUNIT_ASSERT(!aMemStream.eof());
113 2 : CPPUNIT_ASSERT(aMemStream.good());
114 2 : aMemStream >> tools_b;
115 2 : CPPUNIT_ASSERT(!aMemStream.good());
116 2 : CPPUNIT_ASSERT(aMemStream.eof());
117 2 : CPPUNIT_ASSERT(tools_b == 0x1122);
118 :
119 2 : iss.clear();
120 2 : iss.seekg(0);
121 2 : CPPUNIT_ASSERT(iss.good());
122 2 : iss >> std_a;
123 2 : CPPUNIT_ASSERT(std_a == 'f');
124 :
125 2 : aMemStream.Seek(0);
126 2 : CPPUNIT_ASSERT(aMemStream.good());
127 2 : aMemStream >> tools_a;
128 2 : CPPUNIT_ASSERT(tools_a == 'f');
129 :
130 : //failbit is rather subtle wrt e.g seeks
131 :
132 : char buffer[1024];
133 :
134 2 : iss.clear();
135 2 : iss.seekg(0);
136 2 : CPPUNIT_ASSERT(iss.good());
137 2 : iss.read(buffer, sizeof(buffer));
138 2 : CPPUNIT_ASSERT(iss.gcount() == 3);
139 2 : CPPUNIT_ASSERT(!iss.good());
140 2 : CPPUNIT_ASSERT(!iss.bad());
141 2 : CPPUNIT_ASSERT(iss.eof());
142 :
143 2 : aMemStream.Seek(0);
144 2 : CPPUNIT_ASSERT(aMemStream.good());
145 2 : sal_Size nRet = aMemStream.Read(buffer, sizeof(buffer));
146 2 : CPPUNIT_ASSERT(nRet == 3);
147 2 : CPPUNIT_ASSERT(!aMemStream.good());
148 2 : CPPUNIT_ASSERT(!aMemStream.bad());
149 2 : CPPUNIT_ASSERT(aMemStream.eof());
150 2 : }
151 :
152 2 : void Test::test_fastostring()
153 : {
154 2 : char foo[] = "foobar";
155 2 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
156 :
157 2 : rtl::OString aOne = read_uInt8s_ToOString(aMemStream, 3);
158 2 : CPPUNIT_ASSERT(aOne.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
159 :
160 2 : rtl::OString aTwo = read_uInt8s_ToOString(aMemStream, 3);
161 2 : CPPUNIT_ASSERT(aTwo.equalsL(RTL_CONSTASCII_STRINGPARAM("bar")));
162 :
163 2 : rtl::OString aThree = read_uInt8s_ToOString(aMemStream, 3);
164 2 : CPPUNIT_ASSERT(aThree.isEmpty());
165 :
166 2 : aMemStream.Seek(0);
167 :
168 2 : rtl::OString aFour = read_uInt8s_ToOString(aMemStream, 100);
169 2 : CPPUNIT_ASSERT(aFour.equalsL(RTL_CONSTASCII_STRINGPARAM(foo)));
170 2 : }
171 :
172 2 : void Test::test_read_cstring()
173 : {
174 2 : char foo[] = "foobar";
175 2 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
176 :
177 2 : rtl::OString aOne = read_zeroTerminated_uInt8s_ToOString(aMemStream);
178 2 : CPPUNIT_ASSERT(aOne.equalsL(RTL_CONSTASCII_STRINGPARAM("foobar")));
179 2 : CPPUNIT_ASSERT(!aMemStream.good());
180 2 : CPPUNIT_ASSERT(!aMemStream.bad());
181 2 : CPPUNIT_ASSERT(aMemStream.eof());
182 :
183 2 : aMemStream.Seek(0);
184 2 : foo[3] = 0;
185 2 : rtl::OString aTwo = read_zeroTerminated_uInt8s_ToOString(aMemStream);
186 2 : CPPUNIT_ASSERT(aTwo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
187 2 : CPPUNIT_ASSERT(aMemStream.good());
188 2 : }
189 :
190 2 : void Test::test_read_pstring()
191 : {
192 2 : char foo[] = "\3foobar";
193 2 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
194 :
195 2 : rtl::OString aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt8>(aMemStream);
196 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
197 2 : CPPUNIT_ASSERT(aMemStream.good());
198 2 : CPPUNIT_ASSERT(!aMemStream.bad());
199 2 : CPPUNIT_ASSERT(!aMemStream.eof());
200 :
201 2 : aMemStream.Seek(0);
202 2 : foo[0] = 10;
203 2 : aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt8>(aMemStream);
204 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foobar")));
205 2 : CPPUNIT_ASSERT(!aMemStream.good());
206 2 : CPPUNIT_ASSERT(!aMemStream.bad());
207 2 : CPPUNIT_ASSERT(aMemStream.eof());
208 :
209 2 : aMemStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
210 2 : aMemStream.Seek(0);
211 2 : foo[0] = 0;
212 2 : foo[1] = 3;
213 2 : aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(aMemStream);
214 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("oob")));
215 2 : CPPUNIT_ASSERT(aMemStream.good());
216 2 : CPPUNIT_ASSERT(!aMemStream.bad());
217 2 : CPPUNIT_ASSERT(!aMemStream.eof());
218 :
219 2 : aMemStream.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
220 2 : aMemStream.Seek(0);
221 2 : foo[0] = 3;
222 2 : foo[1] = 0;
223 2 : foo[2] = 0;
224 2 : foo[3] = 0;
225 2 : aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt32>(aMemStream);
226 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("bar")));
227 2 : CPPUNIT_ASSERT(aMemStream.good());
228 2 : CPPUNIT_ASSERT(!aMemStream.bad());
229 2 : CPPUNIT_ASSERT(!aMemStream.eof());
230 2 : }
231 :
232 2 : void Test::test_readline()
233 : {
234 2 : char foo[] = "foo\nbar\n\n";
235 2 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
236 :
237 2 : rtl::OString aFoo;
238 : sal_Bool bRet;
239 :
240 2 : bRet = aMemStream.ReadLine(aFoo);
241 2 : CPPUNIT_ASSERT(bRet);
242 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
243 2 : CPPUNIT_ASSERT(aMemStream.good());
244 :
245 2 : bRet = aMemStream.ReadLine(aFoo);
246 2 : CPPUNIT_ASSERT(bRet);
247 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("bar")));
248 2 : CPPUNIT_ASSERT(aMemStream.good());
249 :
250 2 : bRet = aMemStream.ReadLine(aFoo);
251 2 : CPPUNIT_ASSERT(bRet);
252 2 : CPPUNIT_ASSERT(aFoo.isEmpty());
253 2 : CPPUNIT_ASSERT(aMemStream.good());
254 :
255 2 : bRet = aMemStream.ReadLine(aFoo);
256 2 : CPPUNIT_ASSERT(!bRet);
257 2 : CPPUNIT_ASSERT(aFoo.isEmpty());
258 2 : CPPUNIT_ASSERT(aMemStream.eof());
259 :
260 2 : foo[3] = 0; //test reading embedded nulls
261 :
262 2 : aMemStream.Seek(0);
263 2 : bRet = aMemStream.ReadLine(aFoo);
264 2 : CPPUNIT_ASSERT(bRet);
265 2 : CPPUNIT_ASSERT(aFoo.getLength() == 7 && aFoo[3] == 0);
266 2 : CPPUNIT_ASSERT(aMemStream.good());
267 :
268 2 : std::string sStr(RTL_CONSTASCII_STRINGPARAM(foo));
269 2 : std::istringstream iss(sStr, std::istringstream::in);
270 2 : std::getline(iss, sStr, '\n');
271 : //embedded null read as expected
272 2 : CPPUNIT_ASSERT(sStr.size() == 7 && sStr[3] == 0);
273 2 : CPPUNIT_ASSERT(iss.good());
274 :
275 2 : bRet = aMemStream.ReadLine(aFoo);
276 2 : CPPUNIT_ASSERT(bRet);
277 2 : CPPUNIT_ASSERT(aFoo.isEmpty());
278 2 : CPPUNIT_ASSERT(aMemStream.good());
279 :
280 2 : std::getline(iss, sStr, '\n');
281 2 : CPPUNIT_ASSERT(sStr.empty());
282 2 : CPPUNIT_ASSERT(iss.good());
283 :
284 2 : bRet = aMemStream.ReadLine(aFoo);
285 2 : CPPUNIT_ASSERT(!bRet);
286 2 : CPPUNIT_ASSERT(aFoo.isEmpty());
287 2 : CPPUNIT_ASSERT(aMemStream.eof() && !aMemStream.bad());
288 :
289 2 : std::getline(iss, sStr, '\n');
290 2 : CPPUNIT_ASSERT(sStr.empty());
291 2 : CPPUNIT_ASSERT(iss.eof() && !iss.bad());
292 :
293 2 : char bar[] = "foo";
294 2 : SvMemoryStream aMemStreamB(RTL_CONSTASCII_STRINGPARAM(bar), STREAM_READ);
295 2 : bRet = aMemStreamB.ReadLine(aFoo);
296 2 : CPPUNIT_ASSERT(bRet);
297 2 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
298 2 : CPPUNIT_ASSERT(!aMemStreamB.eof()); //<-- diff A
299 :
300 2 : std::istringstream issB(bar, std::istringstream::in);
301 2 : std::getline(issB, sStr, '\n');
302 2 : CPPUNIT_ASSERT(sStr == "foo");
303 2 : CPPUNIT_ASSERT(issB.eof()); //<-- diff A
304 2 : }
305 :
306 2 : CPPUNIT_TEST_SUITE_REGISTRATION(Test);
307 6 : }
308 :
309 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|