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 15 : 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 2 : CPPUNIT_TEST_SUITE(Test);
52 1 : CPPUNIT_TEST(test_stdstream);
53 1 : CPPUNIT_TEST(test_fastostring);
54 1 : CPPUNIT_TEST(test_read_cstring);
55 1 : CPPUNIT_TEST(test_read_pstring);
56 1 : CPPUNIT_TEST(test_readline);
57 2 : CPPUNIT_TEST_SUITE_END();
58 : };
59 :
60 1 : void Test::test_stdstream()
61 : {
62 1 : char foo[] = "foo";
63 1 : std::istringstream iss(foo, std::istringstream::in);
64 1 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
65 :
66 1 : char std_a(78);
67 1 : iss >> std_a;
68 1 : CPPUNIT_ASSERT(std_a == 'f');
69 :
70 1 : char tools_a(78);
71 1 : aMemStream >> tools_a;
72 1 : CPPUNIT_ASSERT(tools_a == 'f');
73 :
74 1 : iss.seekg(0, std::ios_base::end);
75 : //seeking to end doesn't set eof, reading past eof does
76 1 : CPPUNIT_ASSERT(!iss.eof());
77 1 : CPPUNIT_ASSERT(iss.good());
78 :
79 1 : aMemStream.Seek(STREAM_SEEK_TO_END);
80 : //seeking to end doesn't set eof, reading past eof does
81 1 : CPPUNIT_ASSERT(!aMemStream.eof());
82 1 : CPPUNIT_ASSERT(aMemStream.good());
83 :
84 1 : std_a = 78;
85 1 : iss >> std_a;
86 : //so, now eof is set
87 1 : CPPUNIT_ASSERT(iss.eof());
88 : //a failed read doesn't change the data, it remains unchanged
89 1 : CPPUNIT_ASSERT(std_a == 78);
90 : //nothing wrong with the stream, so not bad
91 1 : CPPUNIT_ASSERT(!iss.bad());
92 : //yet, the read didn't succeed
93 1 : CPPUNIT_ASSERT(!iss.good());
94 1 : CPPUNIT_ASSERT(iss.rdstate() == (std::ios::failbit|std::ios::eofbit));
95 :
96 1 : tools_a = 78;
97 1 : aMemStream >> tools_a;
98 : //so, now eof is set
99 1 : CPPUNIT_ASSERT(aMemStream.eof());
100 : //a failed read doesn't change the data, it remains unchanged
101 1 : CPPUNIT_ASSERT(tools_a == 78);
102 : //nothing wrong with the stream, so not bad
103 1 : CPPUNIT_ASSERT(!aMemStream.bad());
104 : //yet, the read didn't succeed
105 1 : 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 1 : sal_uInt16 tools_b = 0x1122;
111 1 : aMemStream.SeekRel(-1);
112 1 : CPPUNIT_ASSERT(!aMemStream.eof());
113 1 : CPPUNIT_ASSERT(aMemStream.good());
114 1 : aMemStream >> tools_b;
115 1 : CPPUNIT_ASSERT(!aMemStream.good());
116 1 : CPPUNIT_ASSERT(aMemStream.eof());
117 1 : CPPUNIT_ASSERT(tools_b == 0x1122);
118 :
119 1 : iss.clear();
120 1 : iss.seekg(0);
121 1 : CPPUNIT_ASSERT(iss.good());
122 1 : iss >> std_a;
123 1 : CPPUNIT_ASSERT(std_a == 'f');
124 :
125 1 : aMemStream.Seek(0);
126 1 : CPPUNIT_ASSERT(aMemStream.good());
127 1 : aMemStream >> tools_a;
128 1 : CPPUNIT_ASSERT(tools_a == 'f');
129 :
130 : //failbit is rather subtle wrt e.g seeks
131 :
132 : char buffer[1024];
133 :
134 1 : iss.clear();
135 1 : iss.seekg(0);
136 1 : CPPUNIT_ASSERT(iss.good());
137 1 : iss.read(buffer, sizeof(buffer));
138 1 : CPPUNIT_ASSERT(iss.gcount() == 3);
139 1 : CPPUNIT_ASSERT(!iss.good());
140 1 : CPPUNIT_ASSERT(!iss.bad());
141 1 : CPPUNIT_ASSERT(iss.eof());
142 :
143 1 : aMemStream.Seek(0);
144 1 : CPPUNIT_ASSERT(aMemStream.good());
145 1 : sal_Size nRet = aMemStream.Read(buffer, sizeof(buffer));
146 1 : CPPUNIT_ASSERT(nRet == 3);
147 1 : CPPUNIT_ASSERT(!aMemStream.good());
148 1 : CPPUNIT_ASSERT(!aMemStream.bad());
149 1 : CPPUNIT_ASSERT(aMemStream.eof());
150 1 : }
151 :
152 1 : void Test::test_fastostring()
153 : {
154 1 : char foo[] = "foobar";
155 1 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
156 :
157 1 : rtl::OString aOne = read_uInt8s_ToOString(aMemStream, 3);
158 1 : CPPUNIT_ASSERT(aOne.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
159 :
160 1 : rtl::OString aTwo = read_uInt8s_ToOString(aMemStream, 3);
161 1 : CPPUNIT_ASSERT(aTwo.equalsL(RTL_CONSTASCII_STRINGPARAM("bar")));
162 :
163 1 : rtl::OString aThree = read_uInt8s_ToOString(aMemStream, 3);
164 1 : CPPUNIT_ASSERT(aThree.isEmpty());
165 :
166 1 : aMemStream.Seek(0);
167 :
168 1 : rtl::OString aFour = read_uInt8s_ToOString(aMemStream, 100);
169 1 : CPPUNIT_ASSERT(aFour.equalsL(RTL_CONSTASCII_STRINGPARAM(foo)));
170 1 : }
171 :
172 1 : void Test::test_read_cstring()
173 : {
174 1 : char foo[] = "foobar";
175 1 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
176 :
177 1 : rtl::OString aOne = read_zeroTerminated_uInt8s_ToOString(aMemStream);
178 1 : CPPUNIT_ASSERT(aOne.equalsL(RTL_CONSTASCII_STRINGPARAM("foobar")));
179 1 : CPPUNIT_ASSERT(!aMemStream.good());
180 1 : CPPUNIT_ASSERT(!aMemStream.bad());
181 1 : CPPUNIT_ASSERT(aMemStream.eof());
182 :
183 1 : aMemStream.Seek(0);
184 1 : foo[3] = 0;
185 1 : rtl::OString aTwo = read_zeroTerminated_uInt8s_ToOString(aMemStream);
186 1 : CPPUNIT_ASSERT(aTwo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
187 1 : CPPUNIT_ASSERT(aMemStream.good());
188 1 : }
189 :
190 1 : void Test::test_read_pstring()
191 : {
192 1 : char foo[] = "\3foobar";
193 1 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
194 :
195 1 : rtl::OString aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt8>(aMemStream);
196 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
197 1 : CPPUNIT_ASSERT(aMemStream.good());
198 1 : CPPUNIT_ASSERT(!aMemStream.bad());
199 1 : CPPUNIT_ASSERT(!aMemStream.eof());
200 :
201 1 : aMemStream.Seek(0);
202 1 : foo[0] = 10;
203 1 : aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt8>(aMemStream);
204 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foobar")));
205 1 : CPPUNIT_ASSERT(!aMemStream.good());
206 1 : CPPUNIT_ASSERT(!aMemStream.bad());
207 1 : CPPUNIT_ASSERT(aMemStream.eof());
208 :
209 1 : aMemStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
210 1 : aMemStream.Seek(0);
211 1 : foo[0] = 0;
212 1 : foo[1] = 3;
213 1 : aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(aMemStream);
214 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("oob")));
215 1 : CPPUNIT_ASSERT(aMemStream.good());
216 1 : CPPUNIT_ASSERT(!aMemStream.bad());
217 1 : CPPUNIT_ASSERT(!aMemStream.eof());
218 :
219 1 : aMemStream.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
220 1 : aMemStream.Seek(0);
221 1 : foo[0] = 3;
222 1 : foo[1] = 0;
223 1 : foo[2] = 0;
224 1 : foo[3] = 0;
225 1 : aFoo = read_lenPrefixed_uInt8s_ToOString<sal_uInt32>(aMemStream);
226 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("bar")));
227 1 : CPPUNIT_ASSERT(aMemStream.good());
228 1 : CPPUNIT_ASSERT(!aMemStream.bad());
229 1 : CPPUNIT_ASSERT(!aMemStream.eof());
230 1 : }
231 :
232 1 : void Test::test_readline()
233 : {
234 1 : char foo[] = "foo\nbar\n\n";
235 1 : SvMemoryStream aMemStream(RTL_CONSTASCII_STRINGPARAM(foo), STREAM_READ);
236 :
237 1 : rtl::OString aFoo;
238 : sal_Bool bRet;
239 :
240 1 : bRet = aMemStream.ReadLine(aFoo);
241 1 : CPPUNIT_ASSERT(bRet);
242 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
243 1 : CPPUNIT_ASSERT(aMemStream.good());
244 :
245 1 : bRet = aMemStream.ReadLine(aFoo);
246 1 : CPPUNIT_ASSERT(bRet);
247 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("bar")));
248 1 : CPPUNIT_ASSERT(aMemStream.good());
249 :
250 1 : bRet = aMemStream.ReadLine(aFoo);
251 1 : CPPUNIT_ASSERT(bRet);
252 1 : CPPUNIT_ASSERT(aFoo.isEmpty());
253 1 : CPPUNIT_ASSERT(aMemStream.good());
254 :
255 1 : bRet = aMemStream.ReadLine(aFoo);
256 1 : CPPUNIT_ASSERT(!bRet);
257 1 : CPPUNIT_ASSERT(aFoo.isEmpty());
258 1 : CPPUNIT_ASSERT(aMemStream.eof());
259 :
260 1 : foo[3] = 0; //test reading embedded nulls
261 :
262 1 : aMemStream.Seek(0);
263 1 : bRet = aMemStream.ReadLine(aFoo);
264 1 : CPPUNIT_ASSERT(bRet);
265 1 : CPPUNIT_ASSERT(aFoo.getLength() == 7 && aFoo[3] == 0);
266 1 : CPPUNIT_ASSERT(aMemStream.good());
267 :
268 1 : std::string sStr(RTL_CONSTASCII_STRINGPARAM(foo));
269 1 : std::istringstream iss(sStr, std::istringstream::in);
270 1 : std::getline(iss, sStr, '\n');
271 : //embedded null read as expected
272 1 : CPPUNIT_ASSERT(sStr.size() == 7 && sStr[3] == 0);
273 1 : CPPUNIT_ASSERT(iss.good());
274 :
275 1 : bRet = aMemStream.ReadLine(aFoo);
276 1 : CPPUNIT_ASSERT(bRet);
277 1 : CPPUNIT_ASSERT(aFoo.isEmpty());
278 1 : CPPUNIT_ASSERT(aMemStream.good());
279 :
280 1 : std::getline(iss, sStr, '\n');
281 1 : CPPUNIT_ASSERT(sStr.empty());
282 1 : CPPUNIT_ASSERT(iss.good());
283 :
284 1 : bRet = aMemStream.ReadLine(aFoo);
285 1 : CPPUNIT_ASSERT(!bRet);
286 1 : CPPUNIT_ASSERT(aFoo.isEmpty());
287 1 : CPPUNIT_ASSERT(aMemStream.eof() && !aMemStream.bad());
288 :
289 1 : std::getline(iss, sStr, '\n');
290 1 : CPPUNIT_ASSERT(sStr.empty());
291 1 : CPPUNIT_ASSERT(iss.eof() && !iss.bad());
292 :
293 1 : char bar[] = "foo";
294 1 : SvMemoryStream aMemStreamB(RTL_CONSTASCII_STRINGPARAM(bar), STREAM_READ);
295 1 : bRet = aMemStreamB.ReadLine(aFoo);
296 1 : CPPUNIT_ASSERT(bRet);
297 1 : CPPUNIT_ASSERT(aFoo.equalsL(RTL_CONSTASCII_STRINGPARAM("foo")));
298 1 : CPPUNIT_ASSERT(!aMemStreamB.eof()); //<-- diff A
299 :
300 1 : std::istringstream issB(bar, std::istringstream::in);
301 1 : std::getline(issB, sStr, '\n');
302 1 : CPPUNIT_ASSERT(sStr == "foo");
303 1 : CPPUNIT_ASSERT(issB.eof()); //<-- diff A
304 1 : }
305 :
306 1 : CPPUNIT_TEST_SUITE_REGISTRATION(Test);
307 3 : }
308 :
309 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|