/** * Tests peeking and then reading the same amount. The two should provide the * same results. * Returns the amount successfully read minus the amount successfully peeked. */ static size_t compare_peek_to_read(skiatest::Reporter* reporter, SkStream* stream, size_t bytesToPeek) { // The rest of our tests won't be very interesting if bytesToPeek is zero. REPORTER_ASSERT(reporter, bytesToPeek > 0); SkAutoMalloc peekStorage(bytesToPeek); SkAutoMalloc readStorage(bytesToPeek); void* peekPtr = peekStorage.get(); void* readPtr = peekStorage.get(); const size_t bytesPeeked = stream->peek(peekPtr, bytesToPeek); const size_t bytesRead = stream->read(readPtr, bytesToPeek); // bytesRead should only be less than attempted if the stream is at the // end. REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd()); // peek and read should behave the same, except peek returned to the // original position, so they read the same data. REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesPeeked)); // A stream should never be able to peek more than it can read. REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked); return bytesRead - bytesPeeked; }
static void test_peeking_front_buffered_stream(skiatest::Reporter* r, const SkStream& original, size_t bufferSize) { SkStream* dupe = original.duplicate(); REPORTER_ASSERT(r, dupe != nullptr); SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, bufferSize)); REPORTER_ASSERT(r, bufferedStream != nullptr); size_t peeked = 0; for (size_t i = 1; !bufferedStream->isAtEnd(); i++) { const size_t unpeekableBytes = compare_peek_to_read(r, bufferedStream, i); if (unpeekableBytes > 0) { // This could not have returned a number greater than i. REPORTER_ASSERT(r, unpeekableBytes <= i); // We have reached the end of the buffer. Verify that it was at least // bufferSize. REPORTER_ASSERT(r, peeked + i - unpeekableBytes >= bufferSize); // No more peeking is supported. break; } peeked += i; } // Test that attempting to peek beyond the length of the buffer does not prevent rewinding. bufferedStream.reset(SkFrontBufferedStream::Create(original.duplicate(), bufferSize)); REPORTER_ASSERT(r, bufferedStream != nullptr); const size_t bytesToPeek = bufferSize + 1; SkAutoMalloc peekStorage(bytesToPeek); SkAutoMalloc readStorage(bytesToPeek); for (size_t start = 0; start <= bufferSize; start++) { // Skip to the starting point REPORTER_ASSERT(r, bufferedStream->skip(start) == start); const size_t bytesPeeked = bufferedStream->peek(peekStorage.get(), bytesToPeek); if (0 == bytesPeeked) { // Peeking should only fail completely if we have read/skipped beyond the buffer. REPORTER_ASSERT(r, start >= bufferSize); break; } // Only read the amount that was successfully peeked. const size_t bytesRead = bufferedStream->read(readStorage.get(), bytesPeeked); REPORTER_ASSERT(r, bytesRead == bytesPeeked); REPORTER_ASSERT(r, !memcmp(peekStorage.get(), readStorage.get(), bytesPeeked)); // This should be safe to rewind. REPORTER_ASSERT(r, bufferedStream->rewind()); } }
static void testWritePad(skiatest::Reporter* reporter, SkWriter32* writer) { // Create some random data to write. const size_t dataSize = 10; SkAutoTMalloc<uint32_t> originalData(dataSize); { SkRandom rand(0); for (size_t i = 0; i < dataSize; i++) { originalData[(int) i] = rand.nextU(); } // Write the random data to the writer at different lengths for // different alignments. for (size_t len = 0; len < dataSize; len++) { writer->writePad(originalData.get(), len); } } size_t totalBytes = writer->bytesWritten(); SkAutoMalloc readStorage(totalBytes); writer->flatten(readStorage.get()); SkReader32 reader; reader.setMemory(readStorage.get(), totalBytes); for (size_t len = 0; len < dataSize; len++) { const char* readPtr = static_cast<const char*>(reader.skip(len)); // Ensure that the data read is the same as what was written. REPORTER_ASSERT(reporter, memcmp(readPtr, originalData.get(), len) == 0); // Ensure that the rest is padded with zeroes. const char* stop = readPtr + SkAlign4(len); readPtr += len; while (readPtr < stop) { REPORTER_ASSERT(reporter, *readPtr++ == 0); } } }