StreamTest.cpp revision 58190644c30e1c4aa8e527f3503c58f841e0fcf3
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Test.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRandom.h" 1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkOSFile.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkData.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#ifndef SK_BUILD_FOR_WIN 15096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <unistd.h> 16096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <fcntl.h> 17096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif 18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define MAX_SIZE (256 * 1024) 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void test_loop_stream(skiatest::Reporter* reporter, SkStream* stream, 22096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const void* src, size_t len, int repeat) { 23096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkAutoSMalloc<256> storage(len); 24096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void* tmp = storage.get(); 25096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 26096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int i = 0; i < repeat; ++i) { 27096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger size_t bytes = stream->read(tmp, len); 28096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger REPORTER_ASSERT(reporter, bytes == len); 29096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger REPORTER_ASSERT(reporter, !memcmp(tmp, src, len)); 30096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 31096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 32096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // expect EOF 33096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger size_t bytes = stream->read(tmp, 1); 34096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger REPORTER_ASSERT(reporter, 0 == bytes); 3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // isAtEnd might not return true until after the first failing read. 3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, stream->isAtEnd()); 37096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 38096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 39096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) { 4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkString path = SkOSPath::SkPathJoin(tmpDir, "wstream_test"); 41096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const char s[] = "abcdefghijklmnopqrstuvwxyz"; 43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 44096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger { 45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkFILEWStream writer(path.c_str()); 46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!writer.isValid()) { 47096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkString msg; 48096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger msg.printf("Failed to create tmp file %s\n", path.c_str()); 4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger reporter->reportFailed(msg); 50096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return; 51096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 52096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 53096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int i = 0; i < 100; ++i) { 54096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger writer.write(s, 26); 55096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 56096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 57096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 58096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger { 59096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkFILEStream stream(path.c_str()); 60096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger REPORTER_ASSERT(reporter, stream.isValid()); 61096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger test_loop_stream(reporter, &stream, s, 26, 100); 6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate()); 6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream2.get(), s, 26, 100); 65096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 66096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 67096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger { 6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger FILE* file = ::fopen(path.c_str(), "rb"); 6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkFILEStream stream(file, SkFILEStream::kCallerPasses_Ownership); 70096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger REPORTER_ASSERT(reporter, stream.isValid()); 71096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger test_loop_stream(reporter, &stream, s, 26, 100); 7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate()); 7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream2.get(), s, 26, 100); 75096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 76096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 77096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestWStream(skiatest::Reporter* reporter) { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDynamicMemoryWStream ds; 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char s[] = "abcdefghijklmnopqrstuvwxyz"; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int i; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (i = 0; i < 100; i++) { 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, ds.write(s, 26)); 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26); 8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* dst = new char[100 * 26 + 1]; 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[100*26] = '*'; 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ds.copyTo(dst); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, dst[100*26] == '*'); 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (i = 0; i < 100; i++) { 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream(ds.detachAsStream()); 9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, 100 * 26 == stream->getLength()); 9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, ds.getOffset() == 0); 9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream.get(), s, 26, 100); 10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate()); 10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream2.get(), s, 26, 100); 10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream3(stream->fork()); 10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, stream3->isAtEnd()); 10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger char tmp; 10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t bytes = stream->read(&tmp, 1); 10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, 0 == bytes); 10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger stream3->rewind(); 11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream3.get(), s, 26, 100); 11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger for (i = 0; i < 100; i++) { 11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, ds.write(s, 26)); 11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 11658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26); 11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger { 11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkData> data(ds.copyToData()); 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, 100 * 26 == data->size()); 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, memcmp(dst, data->data(), data->size()) == 0); 12258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger { 12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Test that this works after a copyToData. 12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream(ds.detachAsStream()); 12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger REPORTER_ASSERT(reporter, ds.getOffset() == 0); 12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream.get(), s, 26, 100); 12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate()); 13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_loop_stream(reporter, stream2.get(), s, 26, 100); 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete[] dst; 134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkString tmpDir = skiatest::Test::GetTmpDir(); 13658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!tmpDir.isEmpty()) { 13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger test_filestreams(reporter, tmpDir.c_str()); 138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestPackedUInt(skiatest::Reporter* reporter) { 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we know that packeduint tries to write 1, 2 or 4 bytes for the length, 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // so we test values around each of those transitions (and a few others) 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const size_t sizes[] = { 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769, 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001, 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001, 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t i; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char buffer[sizeof(sizes) * 4]; 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMemoryWStream wstream(buffer, sizeof(buffer)); 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) { 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool success = wstream.writePackedUInt(sizes[i]); 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, success); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wstream.flush(); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMemoryStream rstream(buffer, sizeof(buffer)); 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) { 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t n = rstream.readPackedUInt(); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sizes[i] != n) { 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("-- %d: sizes:%x n:%x\n", i, sizes[i], n); 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru REPORTER_ASSERT(reporter, sizes[i] == n); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 172d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger// Test that setting an SkMemoryStream to a NULL data does not result in a crash when calling 173d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger// methods that access fData. 174d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void TestDereferencingData(SkMemoryStream* memStream) { 175d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger memStream->read(NULL, 0); 176d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger memStream->getMemoryBase(); 177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoDataUnref data(memStream->copyToData()); 178d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 179d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 180d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void TestNullData() { 181d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkData* nullData = NULL; 182d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkMemoryStream memStream(nullData); 183d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger TestDereferencingData(&memStream); 184d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 185d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger memStream.setData(nullData); 186d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger TestDereferencingData(&memStream); 187d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 188d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 189d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestStreams(skiatest::Reporter* reporter) { 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestWStream(reporter); 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TestPackedUInt(reporter); 193d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger TestNullData(); 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "TestClassDef.h" 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruDEFINE_TESTCLASS("Stream", StreamTestClass, TestStreams) 198