Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/core/SkData.h
Line
Count
Source
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
18
class 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
 */
25
class SK_API SkData final : public SkNVRefCnt<SkData> {
26
public:
27
    /**
28
     *  Returns the number of bytes stored.
29
     */
30
206M
    size_t size() const { return fSize; }
31
32
420k
    bool isEmpty() const { return 0 == fSize; }
33
34
    /**
35
     *  Returns the ptr to the data.
36
     */
37
848k
    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
153M
    const uint8_t* bytes() const {
44
153M
        return reinterpret_cast<const uint8_t*>(fPtr);
45
153M
    }
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
1.10M
    void* writable_data() {
53
1.10M
        if (fSize) {
54
            // only assert we're unique if we're not empty
55
1.09M
            SkASSERT(this->unique());
56
1.09M
        }
57
1.10M
        return const_cast<void*>(fPtr);
58
1.10M
    }
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
211k
    static sk_sp<SkData> MakeWithoutCopy(const void* data, size_t length) {
117
211k
        return MakeWithProc(data, length, NoopReleaseProc, nullptr);
118
211k
    }
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
169
private:
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