Line data Source code
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 final : public SkNVRefCnt<SkData> {
23 : public:
24 : /**
25 : * Returns the number of bytes stored.
26 : */
27 0 : size_t size() const { return fSize; }
28 :
29 : bool isEmpty() const { return 0 == fSize; }
30 :
31 : /**
32 : * Returns the ptr to the data.
33 : */
34 167 : 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 : */
40 0 : const uint8_t* bytes() const {
41 0 : 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 : */
49 0 : void* writable_data() {
50 0 : if (fSize) {
51 : // only assert we're unique if we're not empty
52 0 : SkASSERT(this->unique());
53 : }
54 0 : 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 sk_sp<SkData> MakeWithCopy(const void* data, size_t length);
81 :
82 :
83 : /**
84 : * Create a new data with uninitialized contents. The caller should call writable_data()
85 : * to write into the buffer, but this must be done before another ref() is made.
86 : */
87 : static sk_sp<SkData> MakeUninitialized(size_t length);
88 :
89 : /**
90 : * Create a new dataref by copying the specified c-string
91 : * (a null-terminated array of bytes). The returned SkData will have size()
92 : * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
93 : * as "".
94 : */
95 : static sk_sp<SkData> MakeWithCString(const char cstr[]);
96 :
97 : /**
98 : * Create a new dataref, taking the ptr as is, and using the
99 : * releaseproc to free it. The proc may be NULL.
100 : */
101 : static sk_sp<SkData> MakeWithProc(const void* ptr, size_t length, ReleaseProc proc, void* ctx);
102 :
103 : /**
104 : * Call this when the data parameter is already const and will outlive the lifetime of the
105 : * SkData. Suitable for with const globals.
106 : */
107 0 : static sk_sp<SkData> MakeWithoutCopy(const void* data, size_t length) {
108 0 : return MakeWithProc(data, length, DummyReleaseProc, nullptr);
109 : }
110 :
111 : /**
112 : * Create a new dataref from a pointer allocated by malloc. The Data object
113 : * takes ownership of that allocation, and will handling calling sk_free.
114 : */
115 : static sk_sp<SkData> MakeFromMalloc(const void* data, size_t length);
116 :
117 : /**
118 : * Create a new dataref the file with the specified path.
119 : * If the file cannot be opened, this returns NULL.
120 : */
121 : static sk_sp<SkData> MakeFromFileName(const char path[]);
122 :
123 : /**
124 : * Create a new dataref from a stdio FILE.
125 : * This does not take ownership of the FILE, nor close it.
126 : * The caller is free to close the FILE at its convenience.
127 : * The FILE must be open for reading only.
128 : * Returns NULL on failure.
129 : */
130 : static sk_sp<SkData> MakeFromFILE(FILE* f);
131 :
132 : /**
133 : * Create a new dataref from a file descriptor.
134 : * This does not take ownership of the file descriptor, nor close it.
135 : * The caller is free to close the file descriptor at its convenience.
136 : * The file descriptor must be open for reading only.
137 : * Returns NULL on failure.
138 : */
139 : static sk_sp<SkData> MakeFromFD(int fd);
140 :
141 : /**
142 : * Attempt to read size bytes into a SkData. If the read succeeds, return the data,
143 : * else return NULL. Either way the stream's cursor may have been changed as a result
144 : * of calling read().
145 : */
146 : static sk_sp<SkData> MakeFromStream(SkStream*, size_t size);
147 :
148 : /**
149 : * Create a new dataref using a subset of the data in the specified
150 : * src dataref.
151 : */
152 : static sk_sp<SkData> MakeSubset(const SkData* src, size_t offset, size_t length);
153 :
154 : /**
155 : * Returns a new empty dataref (or a reference to a shared empty dataref).
156 : * New or shared, the caller must see that unref() is eventually called.
157 : */
158 : static sk_sp<SkData> MakeEmpty();
159 :
160 : private:
161 : friend class SkNVRefCnt<SkData>;
162 : ReleaseProc fReleaseProc;
163 : void* fReleaseProcContext;
164 : void* fPtr;
165 : size_t fSize;
166 :
167 : SkData(const void* ptr, size_t size, ReleaseProc, void* context);
168 : explicit SkData(size_t size); // inplace new/delete
169 : ~SkData();
170 :
171 : // Ensure the unsized delete is called.
172 296 : void operator delete(void* p) { ::operator delete(p); }
173 :
174 : // Called the first time someone calls NewEmpty to initialize the singleton.
175 : friend SkData* sk_new_empty_data();
176 :
177 : // shared internal factory
178 : static sk_sp<SkData> PrivateNewWithCopy(const void* srcOrNull, size_t length);
179 :
180 : static void DummyReleaseProc(const void*, void*); // {}
181 :
182 : typedef SkRefCnt INHERITED;
183 : };
184 :
185 : #endif
|