1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11 #ifndef SkData_DEFINED 12 #define SkData_DEFINED 13 14 #include "SkFlattenable.h" 15 16 /** 17 * SkData holds an immutable data buffer. Not only is the data immutable, 18 * but the actual ptr that is returned (by data() or bytes()) is guaranteed 19 * to always be the same for the life of this instance. 20 */ 21 class SK_API SkData : public SkFlattenable { 22 public: 23 SK_DECLARE_INST_COUNT(SkData) 24 25 /** 26 * Returns the number of bytes stored. 27 */ 28 size_t size() const { return fSize; } 29 30 bool isEmpty() const { return 0 == fSize; } 31 32 /** 33 * Returns the ptr to the data. 34 */ 35 const void* data() const { return fPtr; } 36 37 /** 38 * Like data(), returns a read-only ptr into the data, but in this case 39 * it is cast to uint8_t*, to make it easy to add an offset to it. 40 */ 41 const uint8_t* bytes() const { 42 return reinterpret_cast<const uint8_t*>(fPtr); 43 } 44 45 /** 46 * Helper to copy a range of the data into a caller-provided buffer. 47 * Returns the actual number of bytes copied, after clamping offset and 48 * length to the size of the data. If buffer is NULL, it is ignored, and 49 * only the computed number of bytes is returned. 50 */ 51 size_t copyRange(size_t offset, size_t length, void* buffer) const; 52 53 /** 54 * Returns true if these two objects have the same length and contents, 55 * effectively returning 0 == memcmp(...) 56 */ 57 bool equals(const SkData* other) const; 58 59 /** 60 * Function that, if provided, will be called when the SkData goes out 61 * of scope, allowing for custom allocation/freeing of the data. 62 */ 63 typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); 64 65 /** 66 * Create a new dataref by copying the specified data 67 */ 68 static SkData* NewWithCopy(const void* data, size_t length); 69 70 /** 71 * Create a new dataref by copying the specified c-string 72 * (a null-terminated array of bytes). The returned SkData will have size() 73 * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same 74 * as "". 75 */ 76 static SkData* NewWithCString(const char cstr[]); 77 78 /** 79 * Create a new dataref, taking the data ptr as is, and using the 80 * releaseproc to free it. The proc may be NULL. 81 */ 82 static SkData* NewWithProc(const void* data, size_t length, 83 ReleaseProc proc, void* context); 84 85 /** 86 * Create a new dataref from a pointer allocated by malloc. The Data object 87 * takes ownership of that allocation, and will handling calling sk_free. 88 */ 89 static SkData* NewFromMalloc(const void* data, size_t length); 90 91 /** 92 * Create a new dataref using a subset of the data in the specified 93 * src dataref. 94 */ 95 static SkData* NewSubset(const SkData* src, size_t offset, size_t length); 96 97 /** 98 * Returns a new empty dataref (or a reference to a shared empty dataref). 99 * New or shared, the caller must see that unref() is eventually called. 100 */ 101 static SkData* NewEmpty(); 102 103 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData) 104 105 protected: 106 SkData(SkFlattenableReadBuffer&); 107 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; 108 109 private: 110 ReleaseProc fReleaseProc; 111 void* fReleaseProcContext; 112 113 const void* fPtr; 114 size_t fSize; 115 116 SkData(const void* ptr, size_t size, ReleaseProc, void* context); 117 virtual ~SkData(); 118 119 // This is here because SkAutoTUnref creates an internal helper class 120 // that derives from SkData (i.e., BlockRef) to prevent refs\unrefs. 121 // This helper class generates a compiler warning on Windows since the 122 // SkData's destructor is private. This friending gives the helper class 123 // access to the destructor. 124 friend class SkAutoTUnref<SkData>::BlockRef<SkData>; 125 126 typedef SkFlattenable INHERITED; 127 }; 128 129 /** 130 * Specialized version of SkAutoTUnref<SkData> for automatically unref-ing a 131 * SkData. 132 */ 133 class SkAutoDataUnref : SkNoncopyable { 134 public: 135 SkAutoDataUnref(SkData* data) : fRef(data) {} 136 ~SkAutoDataUnref() { 137 SkSafeUnref(fRef); 138 } 139 140 SkData* get() const { return fRef; } 141 142 void release() { 143 if (fRef) { 144 fRef->unref(); 145 fRef = NULL; 146 } 147 } 148 149 SkData *operator->() const { return fRef; } 150 operator SkData*() { return fRef; } 151 152 private: 153 SkData* fRef; 154 }; 155 156 #endif 157