| 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 |