summaryrefslogtreecommitdiffstats
path: root/skia/images/SkStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'skia/images/SkStream.cpp')
-rw-r--r--skia/images/SkStream.cpp114
1 files changed, 89 insertions, 25 deletions
diff --git a/skia/images/SkStream.cpp b/skia/images/SkStream.cpp
index 5c1eebe..b199a1b 100644
--- a/skia/images/SkStream.cpp
+++ b/skia/images/SkStream.cpp
@@ -1,6 +1,6 @@
/* libs/graphics/images/SkStream.cpp
**
-** Copyright 2006, Google Inc.
+** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -248,7 +248,7 @@ size_t SkFILEStream::read(void* buffer, size_t size)
return 0;
}
-////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
SkMemoryStream::SkMemoryStream()
{
@@ -343,19 +343,20 @@ size_t SkMemoryStream::seek(size_t offset)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
-SkBufferStream::SkBufferStream(SkStream& proxy, size_t bufferSize)
+SkBufferStream::SkBufferStream(SkStream* proxy, size_t bufferSize)
: fProxy(proxy)
{
- SkASSERT(&proxy != NULL);
+ SkASSERT(proxy != NULL);
+ proxy->ref();
this->init(NULL, bufferSize);
}
-SkBufferStream::SkBufferStream(SkStream& proxy, void* buffer, size_t bufferSize)
+SkBufferStream::SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize)
: fProxy(proxy)
{
- SkASSERT(&proxy != NULL);
+ SkASSERT(proxy != NULL);
SkASSERT(buffer == NULL || bufferSize != 0); // init(addr, 0) makes no sense, we must know how big their buffer is
-
+ proxy->ref();
this->init(buffer, bufferSize);
}
@@ -382,6 +383,7 @@ void SkBufferStream::init(void* buffer, size_t bufferSize)
SkBufferStream::~SkBufferStream()
{
+ fProxy->unref();
if (fWeOwnTheBuffer)
sk_free(fBuffer);
}
@@ -389,31 +391,43 @@ SkBufferStream::~SkBufferStream()
bool SkBufferStream::rewind()
{
fBufferOffset = fBufferSize = fOrigBufferSize;
- return fProxy.rewind();
+ return fProxy->rewind();
}
const char* SkBufferStream::getFileName()
{
- return fProxy.getFileName();
+ return fProxy->getFileName();
}
#ifdef SK_DEBUG
// #define SK_TRACE_BUFFERSTREAM
#endif
-size_t SkBufferStream::read(void* buffer, size_t size)
-{
+size_t SkBufferStream::read(void* buffer, size_t size) {
#ifdef SK_TRACE_BUFFERSTREAM
SkDebugf("Request %d", size);
#endif
- if (buffer == NULL && size == 0)
- return fProxy.read(buffer, size); // requesting total size
+ if (buffer == NULL && size == 0) {
+ return fProxy->read(buffer, size); // requesting total size
+ }
+
+ if (0 == size) {
+ return 0;
+ }
- if (buffer == NULL || size == 0)
- {
- fBufferOffset += size;
- return fProxy.read(buffer, size);
+ // skip size bytes
+ if (NULL == buffer) {
+ size_t remaining = fBufferSize - fBufferOffset;
+ if (remaining >= size) {
+ fBufferOffset += size;
+ return size;
+ }
+ // if we get here, we are being asked to skip beyond our current buffer
+ // so reset our offset to force a read next time, and skip the diff
+ // in our proxy
+ fBufferOffset = fOrigBufferSize;
+ return remaining + fProxy->read(NULL, size - remaining);
}
size_t s = size;
@@ -441,7 +455,7 @@ size_t SkBufferStream::read(void* buffer, size_t size)
if (size < fBufferSize) // lets try to read more than the request
{
- s = fProxy.read(fBuffer, fBufferSize);
+ s = fProxy->read(fBuffer, fBufferSize);
#ifdef SK_TRACE_BUFFERSTREAM
SkDebugf(" read %d into fBuffer", s);
#endif
@@ -461,7 +475,7 @@ size_t SkBufferStream::read(void* buffer, size_t size)
}
else // just do a direct read
{
- actuallyRead += fProxy.read(buffer, size);
+ actuallyRead += fProxy->read(buffer, size);
#ifdef SK_TRACE_BUFFERSTREAM
SkDebugf(" direct read %d", size);
#endif
@@ -475,7 +489,7 @@ size_t SkBufferStream::read(void* buffer, size_t size)
const void* SkBufferStream::getMemoryBase()
{
- return fProxy.getMemoryBase();
+ return fProxy->getMemoryBase();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -729,20 +743,63 @@ bool SkDebugWStream::write(const void* buffer, size_t size)
#include "SkRandom.h"
-void SkWStream::UnitTest()
-{
+#ifdef SK_SUPPORT_UNITTEST
+#define MAX_SIZE (256 * 1024)
+
+static void random_fill(SkRandom& rand, void* buffer, size_t size) {
+ char* p = (char*)buffer;
+ char* stop = p + size;
+ while (p < stop) {
+ *p++ = (char)(rand.nextU() >> 8);
+ }
+}
+
+static void test_buffer() {
+ SkRandom rand;
+ SkAutoMalloc am(MAX_SIZE * 2);
+ char* storage = (char*)am.get();
+ char* storage2 = storage + MAX_SIZE;
+
+ random_fill(rand, storage, MAX_SIZE);
+
+ for (int sizeTimes = 0; sizeTimes < 100; sizeTimes++) {
+ int size = rand.nextU() % MAX_SIZE;
+ if (size == 0) {
+ size = MAX_SIZE;
+ }
+ for (int times = 0; times < 100; times++) {
+ int bufferSize = 1 + (rand.nextU() & 0xFFFF);
+ SkMemoryStream mstream(storage, size);
+ SkBufferStream bstream(&mstream, bufferSize);
+
+ int bytesRead = 0;
+ while (bytesRead < size) {
+ int s = 17 + (rand.nextU() & 0xFFFF);
+ int ss = bstream.read(storage2, s);
+ SkASSERT(ss > 0 && ss <= s);
+ SkASSERT(bytesRead + ss <= size);
+ SkASSERT(memcmp(storage + bytesRead, storage2, ss) == 0);
+ bytesRead += ss;
+ }
+ SkASSERT(bytesRead == size);
+ }
+ }
+}
+#endif
+
+void SkStream::UnitTest() {
#ifdef SK_SUPPORT_UNITTEST
{
static const char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char copy[sizeof(s)];
SkRandom rand;
-
+
for (int i = 0; i < 65; i++)
{
char* copyPtr = copy;
SkMemoryStream mem(s, sizeof(s));
- SkBufferStream buff(mem, i);
-
+ SkBufferStream buff(&mem, i);
+
do {
copyPtr += buff.read(copyPtr, rand.nextU() & 15);
} while (copyPtr < copy + sizeof(s));
@@ -750,6 +807,13 @@ void SkWStream::UnitTest()
SkASSERT(memcmp(s, copy, sizeof(s)) == 0);
}
}
+ test_buffer();
+#endif
+}
+
+void SkWStream::UnitTest()
+{
+#ifdef SK_SUPPORT_UNITTEST
{
SkDebugWStream s;