1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkData_DEFINED 9 #define SkData_DEFINED 10 11 #include <stdio.h> 12 13 #include "SkRefCnt.h" 14 15 class SkStream; 16 17 /** 18 * SkData holds an immutable data buffer. Not only is the data immutable, 19 * but the actual ptr that is returned (by data() or bytes()) is guaranteed 20 * to always be the same for the life of this instance. 21 */ 22 class SK_API SkData : public SkRefCnt { 23 public: 24 /** 25 * Returns the number of bytes stored. 26 */ size()27 size_t size() const { return fSize; } 28 isEmpty()29 bool isEmpty() const { return 0 == fSize; } 30 31 /** 32 * Returns the ptr to the data. 33 */ data()34 const void* data() const { return fPtr; } 35 36 /** 37 * Like data(), returns a read-only ptr into the data, but in this case 38 * it is cast to uint8_t*, to make it easy to add an offset to it. 39 */ bytes()40 const uint8_t* bytes() const { 41 return reinterpret_cast<const uint8_t*>(fPtr); 42 } 43 44 /** 45 * USE WITH CAUTION. 46 * This call will assert that the refcnt is 1, as a precaution against modifying the 47 * contents when another client/thread has access to the data. 48 */ writable_data()49 void* writable_data() { 50 if (fSize) { 51 // only assert we're unique if we're not empty 52 SkASSERT(this->unique()); 53 } 54 return fPtr; 55 } 56 57 /** 58 * Helper to copy a range of the data into a caller-provided buffer. 59 * Returns the actual number of bytes copied, after clamping offset and 60 * length to the size of the data. If buffer is NULL, it is ignored, and 61 * only the computed number of bytes is returned. 62 */ 63 size_t copyRange(size_t offset, size_t length, void* buffer) const; 64 65 /** 66 * Returns true if these two objects have the same length and contents, 67 * effectively returning 0 == memcmp(...) 68 */ 69 bool equals(const SkData* other) const; 70 71 /** 72 * Function that, if provided, will be called when the SkData goes out 73 * of scope, allowing for custom allocation/freeing of the data's contents. 74 */ 75 typedef void (*ReleaseProc)(const void* ptr, void* context); 76 77 /** 78 * Create a new dataref by copying the specified data 79 */ 80 static SkData* NewWithCopy(const void* data, size_t length); 81 82 /** 83 * Create a new data with uninitialized contents. The caller should call writable_data() 84 * to write into the buffer, but this must be done before another ref() is made. 85 */ 86 static SkData* NewUninitialized(size_t length); 87 88 /** 89 * Create a new dataref by copying the specified c-string 90 * (a null-terminated array of bytes). The returned SkData will have size() 91 * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same 92 * as "". 93 */ 94 static SkData* NewWithCString(const char cstr[]); 95 96 /** 97 * Create a new dataref, taking the ptr as is, and using the 98 * releaseproc to free it. The proc may be NULL. 99 */ 100 static SkData* NewWithProc(const void* ptr, size_t length, ReleaseProc proc, void* context); 101 102 /** 103 * Call this when the data parameter is already const and will outlive the lifetime of the 104 * SkData. Suitable for with const globals. 105 */ NewWithoutCopy(const void * data,size_t length)106 static SkData* NewWithoutCopy(const void* data, size_t length) { 107 return NewWithProc(data, length, DummyReleaseProc, NULL); 108 } 109 110 /** 111 * Create a new dataref from a pointer allocated by malloc. The Data object 112 * takes ownership of that allocation, and will handling calling sk_free. 113 */ 114 static SkData* NewFromMalloc(const void* data, size_t length); 115 116 /** 117 * Create a new dataref the file with the specified path. 118 * If the file cannot be opened, this returns NULL. 119 */ 120 static SkData* NewFromFileName(const char path[]); 121 122 /** 123 * Create a new dataref from a stdio FILE. 124 * This does not take ownership of the FILE, nor close it. 125 * The caller is free to close the FILE at its convenience. 126 * The FILE must be open for reading only. 127 * Returns NULL on failure. 128 */ 129 static SkData* NewFromFILE(FILE* f); 130 131 /** 132 * Create a new dataref from a file descriptor. 133 * This does not take ownership of the file descriptor, nor close it. 134 * The caller is free to close the file descriptor at its convenience. 135 * The file descriptor must be open for reading only. 136 * Returns NULL on failure. 137 */ 138 static SkData* NewFromFD(int fd); 139 140 /** 141 * Attempt to read size bytes into a SkData. If the read succeeds, return the data, 142 * else return NULL. Either way the stream's cursor may have been changed as a result 143 * of calling read(). 144 */ 145 static SkData* NewFromStream(SkStream*, size_t size); 146 147 /** 148 * Create a new dataref using a subset of the data in the specified 149 * src dataref. 150 */ 151 static SkData* NewSubset(const SkData* src, size_t offset, size_t length); 152 153 /** 154 * Returns a new empty dataref (or a reference to a shared empty dataref). 155 * New or shared, the caller must see that unref() is eventually called. 156 */ 157 static SkData* NewEmpty(); 158 159 private: 160 ReleaseProc fReleaseProc; 161 void* fReleaseProcContext; 162 void* fPtr; 163 size_t fSize; 164 165 SkData(const void* ptr, size_t size, ReleaseProc, void* context); 166 explicit SkData(size_t size); // inplace new/delete 167 virtual ~SkData(); 168 169 170 // Objects of this type are sometimes created in a custom fashion using sk_malloc_throw and 171 // therefore must be sk_freed. We overload new to also call sk_malloc_throw so that memory 172 // can be unconditionally released using sk_free in an overloaded delete. Overloading regular 173 // new means we must also overload placement new. new(size_t size)174 void* operator new(size_t size) { return sk_malloc_throw(size); } new(size_t,void * p)175 void* operator new(size_t, void* p) { return p; } delete(void * p)176 void operator delete(void* p) { sk_free(p); } 177 178 // Called the first time someone calls NewEmpty to initialize the singleton. 179 friend SkData* sk_new_empty_data(); 180 181 // shared internal factory 182 static SkData* PrivateNewWithCopy(const void* srcOrNull, size_t length); 183 DummyReleaseProc(const void *,void *)184 static void DummyReleaseProc(const void*, void*) {} 185 186 typedef SkRefCnt INHERITED; 187 }; 188 189 /** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */ 190 typedef SkAutoTUnref<SkData> SkAutoDataUnref; 191 192 #endif 193