Index: include/core/SkData.h |
=================================================================== |
--- include/core/SkData.h (revision 9702) |
+++ include/core/SkData.h (working copy) |
@@ -1,4 +1,3 @@ |
- |
/* |
* Copyright 2011 Google Inc. |
* |
@@ -6,8 +5,6 @@ |
* found in the LICENSE file. |
*/ |
- |
- |
#ifndef SkData_DEFINED |
#define SkData_DEFINED |
@@ -59,12 +56,6 @@ |
bool equals(const SkData* other) const; |
/** |
- * Function that, if provided, will be called when the SkData goes out |
- * of scope, allowing for custom allocation/freeing of the data. |
- */ |
- typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); |
- |
- /** |
* Create a new dataref by copying the specified data |
*/ |
static SkData* NewWithCopy(const void* data, size_t length); |
@@ -78,11 +69,15 @@ |
static SkData* NewWithCString(const char cstr[]); |
/** |
- * Create a new dataref, taking the data ptr as is, and using the |
- * releaseproc to free it. The proc may be NULL. |
+ * Creates a new SkData which takes ownership of the data, using the |
+ * releaseProc to free it. |
+ * |
+ * The releaseProc must be of a type where |
+ * releaseProc(const void* ptr, size_t length); |
+ * is valid. |
*/ |
- static SkData* NewWithProc(const void* data, size_t length, |
- ReleaseProc proc, void* context); |
+ template <typename T> |
+ static SkData* NewWithProc(const void* data, size_t length, T releaseProc); |
/** |
* Create a new dataref from a pointer allocated by malloc. The Data object |
@@ -126,25 +121,136 @@ |
*/ |
static SkData* NewEmpty(); |
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData) |
+ /** |
+ * Creates an SkData which does not delete the data. |
+ * Such an SkData is just a pointer and length. |
reed1
2013/06/21 19:00:36
Not sure what this 2nd sentence means.
"The calle
|
+ */ |
+ static SkData* NewUnowned(const void* data, size_t length); |
reed1
2013/06/21 19:00:36
NewUnmanaged() ?
maybe unowned is better.
I presu
|
+ //SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData) |
+ virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } |
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer); |
+ |
protected: |
SkData(SkFlattenableReadBuffer&); |
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; |
private: |
- ReleaseProc fReleaseProc; |
- void* fReleaseProcContext; |
+ size_t const fSize; |
+ void const * const fPtr; |
- const void* fPtr; |
- size_t fSize; |
+ SkData(const void* ptr, size_t size); |
- SkData(const void* ptr, size_t size, ReleaseProc, void* context); |
- virtual ~SkData(); |
- |
+ template <typename Release, typename Deleter> friend class SkManagedData; |
typedef SkFlattenable INHERITED; |
}; |
+namespace SkManagedDataProcs { |
+ typedef void (*ReleaseProc)(const void* ptr, size_t length); |
+ typedef void (*DeleterProc)(const void* obj); |
+} |
+ |
+/** |
+ * The Release and Deleter types must allow |
+ * |
+ * release(const void* data, size_t length); |
+ * deleter(const void* obj); |
+ * |
+ * to be valid, respectively. If these are function pointers, |
+ * Release and Deleter should be specified to have one of the types in |
+ * SkManagedDataProcs. |
+ */ |
+template <typename Release, typename Deleter> |
+class SkManagedData : public SkData { |
+public: |
+ /** |
+ * Constructs an SkManagedData at the given memory. |
+ * When destroyed, release(ptr, size) will be called. |
+ * When the reference count goes to zero, deleter(memory) will be called. |
+ */ |
+ static SkData* Place(void* memory, const void* data, size_t length, |
+ Release release, Deleter deleter) { |
+ return SkNEW_PLACEMENT_ARGS(memory, SkManagedData, ( |
+ data, length, release, deleter)); |
+ } |
+ |
+private: |
+ SkManagedData(const void* p, size_t size, Release release, Deleter deleter) |
+ : SkData(p, size), fRelease(release), fDeleter(deleter) |
+ { } |
+ |
+ virtual ~SkManagedData() { |
+ fRelease(fPtr, fSize); |
+ } |
+ |
+ /** Called when the reference count goes to zero. */ |
+ virtual void internal_dispose() const SK_OVERRIDE { |
+ Deleter deleter = fDeleter; |
+ this->internal_dispose_restore_refcnt_to_1(); |
+ this->~SkData(); |
+ deleter(this); |
+ return; |
+ } |
+ |
+ Release const fRelease; |
+ Deleter const fDeleter; |
+ |
+ typedef SkData INHERITED; |
+}; |
+ |
+template <typename Deleter> class SkManagedData<void, Deleter> : public SkData { |
+public: |
+ /** |
+ * Constructs an SkManagedData at the given memory. |
+ * When the reference count goes to zero, deleter(memory) will be called. |
+ */ |
+ static SkData* Place(void* memory, const void* data, size_t length, |
+ Deleter deleter) |
+ { |
+ return SkNEW_PLACEMENT_ARGS(memory, SkManagedData, ( |
+ data, length, deleter)); |
+ } |
+ |
+private: |
+ SkManagedData(const void* ptr, size_t size, Deleter deleter) |
+ : SkData(ptr, size), fDeleter(deleter) |
+ { } |
+ |
+ /** Called when the reference count goes to zero. */ |
+ virtual void internal_dispose() const SK_OVERRIDE { |
+ Deleter deleter = fDeleter; |
+ this->internal_dispose_restore_refcnt_to_1(); |
+ this->~SkData(); |
+ deleter(this); |
+ return; |
+ } |
+ |
+ Deleter const fDeleter; |
+ |
+ typedef SkData INHERITED; |
+}; |
+ |
+template <typename Release> class SkManagedData<Release, void> : public SkData { |
+ /** When destroyed, release(ptr, size) will be called. */ |
+ SkManagedData(const void* ptr, size_t size, Release release) |
+ : SkData(ptr, size), fRelease(release) |
+ { } |
+ |
+ virtual ~SkManagedData() { |
+ fRelease(fPtr, fSize); |
+ } |
+ |
+ Release const fRelease; |
+ |
+ typedef SkData INHERITED; |
+ friend class SkData; |
+}; |
+ |
+template <typename T> |
+SkData* SkData::NewWithProc(const void* data, size_t length, T releaseProc) { |
+ return new SkManagedData<T, void>(data, length, releaseProc); |
+} |
+ |
/** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */ |
typedef SkAutoTUnref<SkData> SkAutoDataUnref; |