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