replace detach/getStream apis on dynamicwstream with SkData
http://codereview.appspot.com/4657046/
git-svn-id: http://skia.googlecode.com/svn/trunk@1714 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/animator/SkScriptTokenizer.cpp b/src/animator/SkScriptTokenizer.cpp
index edcc2af..17f1e87 100644
--- a/src/animator/SkScriptTokenizer.cpp
+++ b/src/animator/SkScriptTokenizer.cpp
@@ -1,4 +1,5 @@
#include "SkScript2.h"
+#include "SkData.h"
#include "SkFloatingPoint.h"
#include "SkMath.h"
#include "SkParse.h"
@@ -736,11 +737,12 @@
}
if (fStream.getOffset() > 0) {
addToken(kEnd);
+ SkAutoDataUnref data(fStream.copyToData());
#ifdef SK_DEBUG
- decompile((const unsigned char*)fStream.getStream(), fStream.getOffset());
+ decompile(data.bytes(), data.size());
#endif
SkScriptRuntime runtime(fCallBackArray);
- runtime.executeTokens((unsigned char*) fStream.getStream());
+ runtime.executeTokens((unsigned char*) data.bytes());
SkScriptValue2 value1;
runtime.getResult(&value1.fOperand);
value1.fType = fReturnType;
@@ -1142,11 +1144,12 @@
addToken(typeOp);
if (constantOperands) {
addToken(kEnd);
+ SkAutoDataUnref data(fStream.copyToData());
#ifdef SK_DEBUG
- decompile((const unsigned char*) stream.getStream(), stream.getOffset());
+ decompile(data.bytes(), data.size());
#endif
SkScriptRuntime runtime(fCallBackArray);
- runtime.executeTokens((unsigned char*) stream.getStream());
+ runtime.executeTokens((unsigned char*)data.bytes());
runtime.getResult(&value1.fOperand);
if (attributes->fResultIsBoolean == kResultIsBoolean)
value1.fType = SkOperand2::kS32;
diff --git a/src/core/SkData.cpp b/src/core/SkData.cpp
index d7ab3c5..791e858 100644
--- a/src/core/SkData.cpp
+++ b/src/core/SkData.cpp
@@ -57,22 +57,26 @@
}
// assumes fPtr was allocated via sk_malloc
-static void sk_malloc_releaseproc(const void* ptr, size_t, void*) {
+static void sk_free_releaseproc(const void* ptr, size_t, void*) {
sk_free((void*)ptr);
}
+SkData* SkData::NewFromMalloc(const void* data, size_t length) {
+ return new SkData(data, length, sk_free_releaseproc, NULL);
+}
+
SkData* SkData::NewWithCopy(const void* data, size_t length) {
if (0 == length) {
return SkData::NewEmpty();
}
- void* copy = sk_malloc_throw(length); // balanced in sk_malloc_releaseproc
+ void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
memcpy(copy, data, length);
- return new SkData(copy, length, sk_malloc_releaseproc, NULL);
+ return new SkData(copy, length, sk_free_releaseproc, NULL);
}
SkData* SkData::NewWithProc(const void* data, size_t length,
- ReleaseProc proc, void* context) {
+ ReleaseProc proc, void* context) {
return new SkData(data, length, proc, context);
}
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp
index eb06452..16ff98a 100644
--- a/src/core/SkStream.cpp
+++ b/src/core/SkStream.cpp
@@ -191,7 +191,14 @@
return true;
}
-////////////////////////////////////////////////////////////////////////////
+bool SkWStream::writeData(const SkData* data) {
+ if (data) {
+ this->write(data->data(), data->size());
+ }
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
SkFILEStream::SkFILEStream(const char file[]) : fName(file)
{
@@ -246,112 +253,105 @@
return 0;
}
-////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-SkMemoryStream::SkMemoryStream()
-{
- fWeOwnTheData = false;
- this->setMemory(NULL, 0);
+SkMemoryStream::SkMemoryStream() {
+ fData = SkData::NewEmpty();
+ fOffset = 0;
}
SkMemoryStream::SkMemoryStream(size_t size) {
- fWeOwnTheData = true;
+ fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
fOffset = 0;
- fSize = size;
- fSrc = sk_malloc_throw(size);
}
-SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData)
-{
- fWeOwnTheData = false;
- this->setMemory(src, size, copyData);
-}
-
-SkMemoryStream::~SkMemoryStream()
-{
- if (fWeOwnTheData)
- sk_free((void*)fSrc);
-}
-
-void SkMemoryStream::setMemoryOwned(const void* src, size_t size)
-{
- if (fWeOwnTheData)
- sk_free((void*)fSrc);
-
- fSize = size;
- fOffset = 0;
- fWeOwnTheData = true;
-
- fSrc = src;
-}
-
-void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData)
-{
- if (fWeOwnTheData)
- sk_free((void*)fSrc);
-
- fSize = size;
- fOffset = 0;
- fWeOwnTheData = copyData;
-
- if (copyData)
- {
- void* copy = sk_malloc_throw(size);
- memcpy(copy, src, size);
- src = copy;
+SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
+ if (copyData) {
+ fData = SkData::NewWithCopy(src, size);
+ } else {
+ fData = SkData::NewWithProc(src, size, NULL, NULL);
}
- fSrc = src;
+ fOffset = 0;
}
-void SkMemoryStream::skipToAlign4()
-{
+SkMemoryStream::~SkMemoryStream() {
+ fData->unref();
+}
+
+void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
+ fData->unref();
+ fData = SkData::NewFromMalloc(src, size);
+ fOffset = 0;
+}
+
+void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
+ fData->unref();
+ if (copyData) {
+ fData = SkData::NewWithCopy(src, size);
+ } else {
+ fData = SkData::NewWithProc(src, size, NULL, NULL);
+ }
+ fOffset = 0;
+}
+
+SkData* SkMemoryStream::copyToData() const {
+ fData->ref();
+ return fData;
+}
+
+SkData* SkMemoryStream::setData(SkData* data) {
+ SkRefCnt_SafeAssign(fData, data);
+ return data;
+}
+
+void SkMemoryStream::skipToAlign4() {
// cast to remove unary-minus warning
fOffset += -(int)fOffset & 0x03;
}
-bool SkMemoryStream::rewind()
-{
+bool SkMemoryStream::rewind() {
fOffset = 0;
return true;
}
-size_t SkMemoryStream::read(void* buffer, size_t size)
-{
+size_t SkMemoryStream::read(void* buffer, size_t size) {
+ size_t dataSize = fData->size();
+
if (buffer == NULL && size == 0) // special signature, they want the total size
- return fSize;
+ return dataSize;
// if buffer is NULL, seek ahead by size
- if (size == 0)
+ if (size == 0) {
return 0;
- if (size > fSize - fOffset)
- size = fSize - fOffset;
+ }
+ if (size > dataSize - fOffset) {
+ size = dataSize - fOffset;
+ }
if (buffer) {
- memcpy(buffer, (const char*)fSrc + fOffset, size);
+ memcpy(buffer, fData->bytes() + fOffset, size);
}
fOffset += size;
return size;
}
-const void* SkMemoryStream::getMemoryBase()
-{
- return fSrc;
+const void* SkMemoryStream::getMemoryBase() {
+ return fData->data();
}
-const void* SkMemoryStream::getAtPos()
-{
- return (const char*)fSrc + fOffset;
+const void* SkMemoryStream::getAtPos() {
+ return fData->bytes() + fOffset;
}
-size_t SkMemoryStream::seek(size_t offset)
-{
- if (offset > fSize)
- offset = fSize;
+size_t SkMemoryStream::seek(size_t offset) {
+ if (offset > fData->size()) {
+ offset = fData->size();
+ }
fOffset = offset;
return offset;
}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
SkBufferStream::SkBufferStream(SkStream* proxy, size_t bufferSize)
: fProxy(proxy)
@@ -586,7 +586,8 @@
}
};
-SkDynamicMemoryWStream::SkDynamicMemoryWStream() : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopyToCache(NULL)
+SkDynamicMemoryWStream::SkDynamicMemoryWStream()
+ : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
{
}
@@ -595,16 +596,10 @@
reset();
}
-const char* SkDynamicMemoryWStream::detach() const
-{
- const char* result = getStream();
- fCopyToCache = NULL;
- return result;
-}
-
void SkDynamicMemoryWStream::reset()
{
- sk_free(fCopyToCache);
+ this->invalidateCopy();
+
Block* block = fHead;
while (block != NULL) {
@@ -614,17 +609,13 @@
}
fHead = fTail = NULL;
fBytesWritten = 0;
- fCopyToCache = NULL;
}
bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
{
if (count > 0) {
+ this->invalidateCopy();
- if (fCopyToCache) {
- sk_free(fCopyToCache);
- fCopyToCache = NULL;
- }
fBytesWritten += count;
size_t size;
@@ -654,8 +645,12 @@
bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
{
- if (offset + count > fBytesWritten)
+ if (offset + count > fBytesWritten) {
return false; // test does not partially modify
+ }
+
+ this->invalidateCopy();
+
Block* block = fHead;
while (block != NULL) {
size_t size = block->written();
@@ -696,25 +691,20 @@
void SkDynamicMemoryWStream::copyTo(void* dst) const
{
- Block* block = fHead;
-
- while (block != NULL) {
- size_t size = block->written();
- memcpy(dst, block->start(), size);
- dst = (void*)((char*)dst + size);
- block = block->fNext;
+ if (fCopy) {
+ memcpy(dst, fCopy->data(), fBytesWritten);
+ } else {
+ Block* block = fHead;
+
+ while (block != NULL) {
+ size_t size = block->written();
+ memcpy(dst, block->start(), size);
+ dst = (void*)((char*)dst + size);
+ block = block->fNext;
+ }
}
}
-const char* SkDynamicMemoryWStream::getStream() const
-{
- if (fCopyToCache == NULL) {
- fCopyToCache = (char*)sk_malloc_throw(fBytesWritten);
- this->copyTo(fCopyToCache);
- }
- return fCopyToCache;
-}
-
void SkDynamicMemoryWStream::padToAlign4()
{
// cast to remove unary-minus warning
@@ -725,17 +715,24 @@
write(&zero, padBytes);
}
-static void sk_free_release_proc(const void* ptr, size_t length, void*) {
- sk_free((void*)ptr);
-}
-
SkData* SkDynamicMemoryWStream::copyToData() const {
- // should rewrite when we remove detach()
- return SkData::NewWithProc(this->detach(), fBytesWritten,
- sk_free_release_proc, NULL);
+ if (NULL == fCopy) {
+ void* buffer = sk_malloc_throw(fBytesWritten);
+ this->copyTo(buffer);
+ fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
+ }
+ fCopy->ref();
+ return fCopy;
}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
+void SkDynamicMemoryWStream::invalidateCopy() {
+ if (fCopy) {
+ fCopy->unref();
+ fCopy = NULL;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
void SkDebugWStream::newline()
{
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 67bc64a..8ead3c8 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -18,6 +18,7 @@
#include "SkColor.h"
#include "SkClipStack.h"
+#include "SkData.h"
#include "SkDraw.h"
#include "SkGlyphCache.h"
#include "SkPaint.h"
@@ -1080,6 +1081,9 @@
return mediaBox;
}
+/**
+ * Can this return SkData instead of SkStream?
+ */
SkStream* SkPDFDevice::content() const {
SkDynamicMemoryWStream data;
if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) {
@@ -1104,12 +1108,14 @@
translation);
gsState.updateMatrix(entry->fState.fMatrix);
gsState.updateDrawingState(entry->fState);
- data.write(entry->fContent.getStream(), entry->fContent.getOffset());
+
+ SkAutoDataUnref copy(entry->fContent.copyToData());
+ data.write(copy.data(), copy.size());
}
gsState.drainStack();
SkMemoryStream* result = new SkMemoryStream;
- result->setMemoryOwned(data.detach(), data.getOffset());
+ result->setData(data.copyToData())->unref();
return result;
}
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index f570a1f..d0d31e3 100755
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -16,6 +16,7 @@
#include <ctype.h>
+#include "SkData.h"
#include "SkFontHost.h"
#include "SkGlyphCache.h"
#include "SkPaint.h"
@@ -140,6 +141,7 @@
// Make as few copies as possible given these constraints.
SkDynamicMemoryWStream dynamicStream;
SkRefPtr<SkMemoryStream> staticStream;
+ SkData* data = NULL;
const uint8_t* src;
size_t srcLen;
if ((srcLen = srcStream->getLength()) > 0) {
@@ -168,11 +170,15 @@
dynamicStream.write(buf, amount);
amount = 0;
dynamicStream.write(&amount, 1); // NULL terminator.
- // getStream makes another copy, but we couldn't do any better.
- src = (const uint8_t*)dynamicStream.getStream();
- srcLen = dynamicStream.getOffset() - 1;
+ data = dynamicStream.copyToData();
+ src = data->bytes();
+ srcLen = data->size() - 1;
}
+ // this handles releasing the data we may have gotten from dynamicStream.
+ // if data is null, it is a no-op
+ SkAutoDataUnref aud(data);
+
if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
SkMemoryStream* result =
new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
@@ -616,7 +622,7 @@
append_cmap_footer(&cmap);
SkRefPtr<SkMemoryStream> cmapStream = new SkMemoryStream();
cmapStream->unref(); // SkRefPtr and new took a reference.
- cmapStream->setMemoryOwned(cmap.detach(), cmap.getOffset());
+ cmapStream->setData(cmap.copyToData())->unref();
SkRefPtr<SkPDFStream> pdfCmap = new SkPDFStream(cmapStream.get());
fResources.push(pdfCmap.get()); // Pass reference from new.
insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
@@ -792,7 +798,7 @@
}
SkRefPtr<SkMemoryStream> glyphStream = new SkMemoryStream();
glyphStream->unref(); // SkRefPtr and new both took a ref.
- glyphStream->setMemoryOwned(content.detach(), content.getOffset());
+ glyphStream->setData(content.copyToData())->unref();
SkRefPtr<SkPDFStream> glyphDescription =
new SkPDFStream(glyphStream.get());
diff --git a/src/pdf/SkPDFStream.cpp b/src/pdf/SkPDFStream.cpp
index b1bd5ff..11afa32 100644
--- a/src/pdf/SkPDFStream.cpp
+++ b/src/pdf/SkPDFStream.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "SkData.h"
#include "SkFlate.h"
#include "SkPDFCatalog.h"
#include "SkPDFStream.h"
@@ -45,10 +46,12 @@
this->INHERITED::emitObject(stream, catalog, false);
stream->writeText(" stream\n");
- if (fPlainData.get())
+ if (fPlainData.get()) {
stream->write(fPlainData->getMemoryBase(), fLength);
- else
- stream->write(fCompressedData.getStream(), fLength);
+ } else {
+ SkAutoDataUnref data(fCompressedData.copyToData());
+ stream->write(data.data(), fLength);
+ }
stream->writeText("\nendstream");
}
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 18c3e60..1ff7d45 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -16,6 +16,7 @@
#include "SkCanvas.h"
+#include "SkData.h"
#include "SkDevice.h"
#include "SkPaint.h"
#include "SkGPipe.h"
@@ -68,7 +69,8 @@
size_t size = stream.getOffset();
if (writer) {
writer->write32(size);
- writer->write(stream.getStream(), size);
+ SkAutoDataUnref data(stream.copyToData());
+ writer->write(data.data(), size);
}
return 4 + size;
}
diff --git a/src/svg/SkSVGParser.cpp b/src/svg/SkSVGParser.cpp
index f4ad198..fec3493 100644
--- a/src/svg/SkSVGParser.cpp
+++ b/src/svg/SkSVGParser.cpp
@@ -90,6 +90,7 @@
return -1;
}
+#if 0
const char* SkSVGParser::getFinal() {
_startElement("screenplay");
// generate defs
@@ -114,6 +115,7 @@
fStream.write("", 1);
return fStream.getStream();
}
+#endif
SkString& SkSVGParser::getPaintLast(SkSVGPaint::Field field) {
SkSVGPaint* state = fHead;