OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "Resources.h" | 8 #include "Resources.h" |
9 #include "SkData.h" | 9 #include "SkData.h" |
10 #include "SkFrontBufferedStream.h" | 10 #include "SkFrontBufferedStream.h" |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 | 190 |
191 DEF_TEST(Stream, reporter) { | 191 DEF_TEST(Stream, reporter) { |
192 TestWStream(reporter); | 192 TestWStream(reporter); |
193 TestPackedUInt(reporter); | 193 TestPackedUInt(reporter); |
194 TestNullData(); | 194 TestNullData(); |
195 } | 195 } |
196 | 196 |
197 /** | 197 /** |
198 * Tests peeking and then reading the same amount. The two should provide the | 198 * Tests peeking and then reading the same amount. The two should provide the |
199 * same results. | 199 * same results. |
200 * Returns whether the stream could peek. | 200 * Returns the amount successfully read minus the amount successfully peeked. |
201 */ | 201 */ |
202 static bool compare_peek_to_read(skiatest::Reporter* reporter, | 202 static size_t compare_peek_to_read(skiatest::Reporter* reporter, |
203 SkStream* stream, size_t bytesToPeek) { | 203 SkStream* stream, size_t bytesToPeek) { |
204 // The rest of our tests won't be very interesting if bytesToPeek is zero. | 204 // The rest of our tests won't be very interesting if bytesToPeek is zero. |
205 REPORTER_ASSERT(reporter, bytesToPeek > 0); | 205 REPORTER_ASSERT(reporter, bytesToPeek > 0); |
206 SkAutoMalloc peekStorage(bytesToPeek); | 206 SkAutoMalloc peekStorage(bytesToPeek); |
207 SkAutoMalloc readStorage(bytesToPeek); | 207 SkAutoMalloc readStorage(bytesToPeek); |
208 void* peekPtr = peekStorage.get(); | 208 void* peekPtr = peekStorage.get(); |
209 void* readPtr = peekStorage.get(); | 209 void* readPtr = peekStorage.get(); |
210 | 210 |
211 if (!stream->peek(peekPtr, bytesToPeek)) { | 211 const size_t bytesPeeked = stream->peek(peekPtr, bytesToPeek); |
212 return false; | |
213 } | |
214 const size_t bytesRead = stream->read(readPtr, bytesToPeek); | 212 const size_t bytesRead = stream->read(readPtr, bytesToPeek); |
215 | 213 |
216 // bytesRead should only be less than attempted if the stream is at the | 214 // bytesRead should only be less than attempted if the stream is at the |
217 // end. | 215 // end. |
218 REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd()); | 216 REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd()); |
219 | 217 |
220 // peek and read should behave the same, except peek returned to the | 218 // peek and read should behave the same, except peek returned to the |
221 // original position, so they read the same data. | 219 // original position, so they read the same data. |
222 REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesRead)); | 220 REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesPeeked)); |
223 | 221 |
224 return true; | 222 // A stream should never be able to peek more than it can read. |
| 223 REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked); |
| 224 |
| 225 return bytesRead - bytesPeeked; |
225 } | 226 } |
226 | 227 |
227 static void test_peeking_stream(skiatest::Reporter* r, SkStream* stream, size_t
limit) { | 228 static void test_fully_peekable_stream(skiatest::Reporter* r, SkStream* stream,
size_t limit) { |
228 size_t peeked = 0; | |
229 for (size_t i = 1; !stream->isAtEnd(); i++) { | 229 for (size_t i = 1; !stream->isAtEnd(); i++) { |
230 const bool couldPeek = compare_peek_to_read(r, stream, i); | 230 REPORTER_ASSERT(r, compare_peek_to_read(r, stream, i) == 0); |
231 if (!couldPeek) { | |
232 REPORTER_ASSERT(r, peeked + i > limit); | |
233 // No more peeking is supported. | |
234 break; | |
235 } | |
236 peeked += i; | |
237 } | 231 } |
238 } | 232 } |
239 | 233 |
240 static void test_peeking_front_buffered_stream(skiatest::Reporter* r, | 234 static void test_peeking_front_buffered_stream(skiatest::Reporter* r, |
241 const SkStream& original, | 235 const SkStream& original, |
242 size_t bufferSize) { | 236 size_t bufferSize) { |
243 SkStream* dupe = original.duplicate(); | 237 SkStream* dupe = original.duplicate(); |
244 REPORTER_ASSERT(r, dupe != nullptr); | 238 REPORTER_ASSERT(r, dupe != nullptr); |
245 SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, b
ufferSize)); | 239 SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, b
ufferSize)); |
246 REPORTER_ASSERT(r, bufferedStream != nullptr); | 240 REPORTER_ASSERT(r, bufferedStream != nullptr); |
247 test_peeking_stream(r, bufferedStream, bufferSize); | 241 |
| 242 size_t peeked = 0; |
| 243 for (size_t i = 1; !bufferedStream->isAtEnd(); i++) { |
| 244 const size_t unpeekableBytes = compare_peek_to_read(r, bufferedStream, i
); |
| 245 if (unpeekableBytes > 0) { |
| 246 // This could not have returned a number greater than i. |
| 247 REPORTER_ASSERT(r, unpeekableBytes <= i); |
| 248 |
| 249 // We have reached the end of the buffer. Verify that it was at leas
t |
| 250 // bufferSize. |
| 251 REPORTER_ASSERT(r, peeked + i - unpeekableBytes >= bufferSize); |
| 252 // No more peeking is supported. |
| 253 break; |
| 254 } |
| 255 peeked += i; |
| 256 } |
| 257 |
| 258 // Test that attempting to peek beyond the length of the buffer does not pre
vent rewinding. |
| 259 bufferedStream.reset(SkFrontBufferedStream::Create(original.duplicate(), buf
ferSize)); |
| 260 REPORTER_ASSERT(r, bufferedStream != nullptr); |
| 261 |
| 262 const size_t bytesToPeek = bufferSize + 1; |
| 263 SkAutoMalloc peekStorage(bytesToPeek); |
| 264 SkAutoMalloc readStorage(bytesToPeek); |
| 265 |
| 266 for (size_t start = 0; start <= bufferSize; start++) { |
| 267 // Skip to the starting point |
| 268 REPORTER_ASSERT(r, bufferedStream->skip(start) == start); |
| 269 REPORTER_ASSERT(r, bufferedStream->getPosition() == start); |
| 270 |
| 271 const size_t bytesPeeked = bufferedStream->peek(peekStorage.get(), bytes
ToPeek); |
| 272 if (0 == bytesPeeked) { |
| 273 // Peeking should only fail completely if we have read beyond the bu
ffer. |
| 274 REPORTER_ASSERT(r, bufferedStream->getPosition() >= bufferSize); |
| 275 break; |
| 276 } |
| 277 |
| 278 // Only read the amount that was successfully peeked. |
| 279 const size_t bytesRead = bufferedStream->read(readStorage.get(), bytesPe
eked); |
| 280 REPORTER_ASSERT(r, bytesRead == bytesPeeked); |
| 281 REPORTER_ASSERT(r, !memcmp(peekStorage.get(), readStorage.get(), bytesPe
eked)); |
| 282 |
| 283 // This should be safe to rewind. |
| 284 REPORTER_ASSERT(r, bufferedStream->rewind()); |
| 285 } |
248 } | 286 } |
249 | 287 |
250 // This test uses file system operations that don't work out of the | 288 // This test uses file system operations that don't work out of the |
251 // box on iOS. It's likely that we don't need them on iOS. Ignoring for now. | 289 // box on iOS. It's likely that we don't need them on iOS. Ignoring for now. |
252 // TODO(stephana): Re-evaluate if we need this in the future. | 290 // TODO(stephana): Re-evaluate if we need this in the future. |
253 #ifndef SK_BUILD_FOR_IOS | 291 #ifndef SK_BUILD_FOR_IOS |
254 DEF_TEST(StreamPeek, reporter) { | 292 DEF_TEST(StreamPeek, reporter) { |
255 // Test a memory stream. | 293 // Test a memory stream. |
256 const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz"; | 294 const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz"; |
257 SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); | 295 SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); |
258 test_peeking_stream(reporter, &memStream, memStream.getLength()); | 296 test_fully_peekable_stream(reporter, &memStream, memStream.getLength()); |
259 | 297 |
260 // Test an arbitrary file stream. file streams do not support peeking. | 298 // Test an arbitrary file stream. file streams do not support peeking. |
261 SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str()); | 299 SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str()); |
262 REPORTER_ASSERT(reporter, fileStream.isValid()); | 300 REPORTER_ASSERT(reporter, fileStream.isValid()); |
263 if (!fileStream.isValid()) { | 301 if (!fileStream.isValid()) { |
264 return; | 302 return; |
265 } | 303 } |
266 SkAutoMalloc storage(fileStream.getLength()); | 304 SkAutoMalloc storage(fileStream.getLength()); |
267 for (size_t i = 1; i < fileStream.getLength(); i++) { | 305 for (size_t i = 1; i < fileStream.getLength(); i++) { |
268 REPORTER_ASSERT(reporter, !fileStream.peek(storage.get(), i)); | 306 REPORTER_ASSERT(reporter, fileStream.peek(storage.get(), i) == 0); |
269 } | 307 } |
270 | 308 |
271 // Now test some FrontBufferedStreams | 309 // Now test some FrontBufferedStreams |
272 for (size_t i = 1; i < memStream.getLength(); i++) { | 310 for (size_t i = 1; i < memStream.getLength(); i++) { |
273 test_peeking_front_buffered_stream(reporter, memStream, i); | 311 test_peeking_front_buffered_stream(reporter, memStream, i); |
274 } | 312 } |
275 } | 313 } |
276 #endif | 314 #endif |
277 | 315 |
278 // Asserts that asset == expected and is peekable. | 316 // Asserts that asset == expected and is peekable. |
279 static void stream_peek_test(skiatest::Reporter* rep, | 317 static void stream_peek_test(skiatest::Reporter* rep, |
280 SkStreamAsset* asset, | 318 SkStreamAsset* asset, |
281 const SkData* expected) { | 319 const SkData* expected) { |
282 if (asset->getLength() != expected->size()) { | 320 if (asset->getLength() != expected->size()) { |
283 ERRORF(rep, "Unexpected length."); | 321 ERRORF(rep, "Unexpected length."); |
284 return; | 322 return; |
285 } | 323 } |
286 SkRandom rand; | 324 SkRandom rand; |
287 uint8_t buffer[4096]; | 325 uint8_t buffer[4096]; |
288 const uint8_t* expect = expected->bytes(); | 326 const uint8_t* expect = expected->bytes(); |
289 for (size_t i = 0; i < asset->getLength(); ++i) { | 327 for (size_t i = 0; i < asset->getLength(); ++i) { |
290 uint32_t maxSize = | 328 uint32_t maxSize = |
291 SkToU32(SkTMin(sizeof(buffer), asset->getLength() - i)); | 329 SkToU32(SkTMin(sizeof(buffer), asset->getLength() - i)); |
292 size_t size = rand.nextRangeU(1, maxSize); | 330 size_t size = rand.nextRangeU(1, maxSize); |
293 SkASSERT(size >= 1); | 331 SkASSERT(size >= 1); |
294 SkASSERT(size <= sizeof(buffer)); | 332 SkASSERT(size <= sizeof(buffer)); |
295 SkASSERT(size + i <= asset->getLength()); | 333 SkASSERT(size + i <= asset->getLength()); |
296 if (!asset->peek(buffer, size)) { | 334 if (asset->peek(buffer, size) < size) { |
297 ERRORF(rep, "Peek Failed!"); | 335 ERRORF(rep, "Peek Failed!"); |
298 return; | 336 return; |
299 } | 337 } |
300 if (0 != memcmp(buffer, &expect[i], size)) { | 338 if (0 != memcmp(buffer, &expect[i], size)) { |
301 ERRORF(rep, "Peek returned wrong bytes!"); | 339 ERRORF(rep, "Peek returned wrong bytes!"); |
302 return; | 340 return; |
303 } | 341 } |
304 uint8_t value; | 342 uint8_t value; |
305 REPORTER_ASSERT(rep, 1 == asset->read(&value, 1)); | 343 REPORTER_ASSERT(rep, 1 == asset->read(&value, 1)); |
306 if (value != expect[i]) { | 344 if (value != expect[i]) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 SkMemoryStream smartStream(src.get(), (size_t)N); | 430 SkMemoryStream smartStream(src.get(), (size_t)N); |
393 stream_copy_test(reporter, src, N, &smartStream); | 431 stream_copy_test(reporter, src, N, &smartStream); |
394 } | 432 } |
395 | 433 |
396 DEF_TEST(StreamEmptyStreamMemoryBase, r) { | 434 DEF_TEST(StreamEmptyStreamMemoryBase, r) { |
397 SkDynamicMemoryWStream tmp; | 435 SkDynamicMemoryWStream tmp; |
398 SkAutoTDelete<SkStreamAsset> asset(tmp.detachAsStream()); | 436 SkAutoTDelete<SkStreamAsset> asset(tmp.detachAsStream()); |
399 REPORTER_ASSERT(r, nullptr == asset->getMemoryBase()); | 437 REPORTER_ASSERT(r, nullptr == asset->getMemoryBase()); |
400 } | 438 } |
401 | 439 |
OLD | NEW |