• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
21 class SkData : public SkRefCnt {
22 public:
23     /**
24      *  Returns the number of bytes stored.
25      */
size()26     size_t size() const { return fSize; }
27 
28     /**
29      *  Returns the ptr to the data.
30      */
data()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      */
bytes()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 
85 private:
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  */
100 class SkAutoDataUnref : SkNoncopyable {
101 public:
SkAutoDataUnref(SkData * data)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     }
~SkAutoDataUnref()111     ~SkAutoDataUnref() {
112         SkSafeUnref(fRef);
113     }
114 
data()115     const void* data() const { return fData; }
bytes()116     const uint8_t* bytes() const {
117         return reinterpret_cast<const uint8_t*> (fData);
118     }
size()119     size_t size() const { return fSize; }
get()120     SkData* get() const { return fRef; }
121 
release()122     void release() {
123         if (fRef) {
124             fRef->unref();
125             fRef = NULL;
126             fData = NULL;
127             fSize = 0;
128         }
129     }
130 
131 private:
132     SkData*     fRef;
133     const void* fData;
134     size_t      fSize;
135 };
136 
137 #endif
138