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

source code of flutter_engine/third_party/skia/include/core/SkData.h