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 "SkRefCnt.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 */ 21class SkData : public SkRefCnt { 22public: 23 /** 24 * Returns the number of bytes stored. 25 */ 26 size_t size() const { return fSize; } 27 28 /** 29 * Returns the ptr to the data. 30 */ 31 const void* data() const { return fPtr; } 32 33 /** 34 * Like data(), returns a read-only ptr into the data, but in this case 35 * it is cast to uint8_t*, to make it easy to add an offset to it. 36 */ 37 const uint8_t* bytes() const { 38 return reinterpret_cast<const uint8_t*>(fPtr); 39 } 40 41 /** 42 * Helper to copy a range of the data into a caller-provided buffer. 43 * Returns the actual number of bytes copied, after clamping offset and 44 * length to the size of the data. If buffer is NULL, it is ignored, and 45 * only the computed number of bytes is returned. 46 */ 47 size_t copyRange(size_t offset, size_t length, void* buffer) const; 48 49 /** 50 * Function that, if provided, will be called when the SkData goes out 51 * of scope, allowing for custom allocation/freeing of the data. 52 */ 53 typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); 54 55 /** 56 * Create a new dataref by copying the specified data 57 */ 58 static SkData* NewWithCopy(const void* data, size_t length); 59 60 /** 61 * Create a new dataref, taking the data ptr as is, and using the 62 * releaseproc to free it. The proc may be NULL. 63 */ 64 static SkData* NewWithProc(const void* data, size_t length, 65 ReleaseProc proc, void* context); 66 67 /** 68 * Create a new dataref, reference the data ptr as is, and calling 69 * sk_free to delete it. 70 */ 71 static SkData* NewFromMalloc(const void* data, size_t length); 72 73 /** 74 * Create a new dataref using a subset of the data in the specified 75 * src dataref. 76 */ 77 static SkData* NewSubset(const SkData* src, size_t offset, size_t length); 78 79 /** 80 * Returns a new empty dataref (or a reference to a shared empty dataref). 81 * New or shared, the caller must see that unref() is eventually called. 82 */ 83 static SkData* NewEmpty(); 84 85private: 86 ReleaseProc fReleaseProc; 87 void* fReleaseProcContext; 88 89 const void* fPtr; 90 size_t fSize; 91 92 SkData(const void* ptr, size_t size, ReleaseProc, void* context); 93 ~SkData(); 94}; 95 96/** 97 * Specialized version of SkAutoTUnref<SkData> for automatically unref-ing a 98 * SkData. If the SkData is null, data(), bytes() and size() will return 0. 99 */ 100class SkAutoDataUnref : SkNoncopyable { 101public: 102 SkAutoDataUnref(SkData* data) : fRef(data) { 103 if (data) { 104 fData = data->data(); 105 fSize = data->size(); 106 } else { 107 fData = NULL; 108 fSize = 0; 109 } 110 } 111 ~SkAutoDataUnref() { 112 SkSafeUnref(fRef); 113 } 114 115 const void* data() const { return fData; } 116 const uint8_t* bytes() const { 117 return reinterpret_cast<const uint8_t*> (fData); 118 } 119 size_t size() const { return fSize; } 120 SkData* get() const { return fRef; } 121 122 void release() { 123 if (fRef) { 124 fRef->unref(); 125 fRef = NULL; 126 fData = NULL; 127 fSize = 0; 128 } 129 } 130 131private: 132 SkData* fRef; 133 const void* fData; 134 size_t fSize; 135}; 136 137#endif 138