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 "include/core/SkRefCnt.h"
14
15class 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 */
22class SK_API SkData final : public SkNVRefCnt<SkData> {
23public:
24 /**
25 * Returns the number of bytes stored.
26 */
27 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 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 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 */
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 const_cast<void*>(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 static sk_sp<SkData> MakeWithoutCopy(const void* data, size_t length) {
108 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
160private:
161 friend class SkNVRefCnt<SkData>;
162 ReleaseProc fReleaseProc;
163 void* fReleaseProcContext;
164 const 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 void operator delete(void* p);
173
174 // shared internal factory
175 static sk_sp<SkData> PrivateNewWithCopy(const void* srcOrNull, size_t length);
176
177 static void DummyReleaseProc(const void*, void*); // {}
178
179 typedef SkRefCnt INHERITED;
180};
181
182#endif
183