Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: include/core/SkData.h

Issue 15675025: One allocation for an SkData which makes a copy. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Clean Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | include/core/SkRefCnt.h » ('j') | include/core/SkWeakRefCnt.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | include/core/SkRefCnt.h » ('j') | include/core/SkWeakRefCnt.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698