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 "SkFlattenable.h"
15
16struct SkFILE;
17
18/**
19 *  SkData holds an immutable data buffer. Not only is the data immutable,
20 *  but the actual ptr that is returned (by data() or bytes()) is guaranteed
21 *  to always be the same for the life of this instance.
22 */
23class SK_API SkData : public SkFlattenable {
24public:
25    SK_DECLARE_INST_COUNT(SkData)
26
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     *  Helper to copy a range of the data into a caller-provided buffer.
49     *  Returns the actual number of bytes copied, after clamping offset and
50     *  length to the size of the data. If buffer is NULL, it is ignored, and
51     *  only the computed number of bytes is returned.
52     */
53    size_t copyRange(size_t offset, size_t length, void* buffer) const;
54
55    /**
56     *  Returns true if these two objects have the same length and contents,
57     *  effectively returning 0 == memcmp(...)
58     */
59    bool equals(const SkData* other) const;
60
61    /**
62     *  Function that, if provided, will be called when the SkData goes out
63     *  of scope, allowing for custom allocation/freeing of the data.
64     */
65    typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context);
66
67    /**
68     *  Create a new dataref by copying the specified data
69     */
70    static SkData* NewWithCopy(const void* data, size_t length);
71
72    /**
73     *  Create a new dataref by copying the specified c-string
74     *  (a null-terminated array of bytes). The returned SkData will have size()
75     *  equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
76     *  as "".
77     */
78    static SkData* NewWithCString(const char cstr[]);
79
80    /**
81     *  Create a new dataref, taking the data ptr as is, and using the
82     *  releaseproc to free it. The proc may be NULL.
83     */
84    static SkData* NewWithProc(const void* data, size_t length,
85                               ReleaseProc proc, void* context);
86
87    /**
88     *  Create a new dataref from a pointer allocated by malloc. The Data object
89     *  takes ownership of that allocation, and will handling calling sk_free.
90     */
91    static SkData* NewFromMalloc(const void* data, size_t length);
92
93    /**
94     *  Create a new dataref the file with the specified path.
95     *  If the file cannot be opened, this returns NULL.
96     */
97    static SkData* NewFromFileName(const char path[]);
98
99    /**
100     *  Create a new dataref from a SkFILE.
101     *  This does not take ownership of the SkFILE, nor close it.
102     *  The caller is free to close the SkFILE at its convenience.
103     *  The SkFILE must be open for reading only.
104     *  Returns NULL on failure.
105     */
106    static SkData* NewFromFILE(SkFILE* f);
107
108    /**
109     *  Create a new dataref from a file descriptor.
110     *  This does not take ownership of the file descriptor, nor close it.
111     *  The caller is free to close the file descriptor at its convenience.
112     *  The file descriptor must be open for reading only.
113     *  Returns NULL on failure.
114     */
115    static SkData* NewFromFD(int fd);
116
117    /**
118     *  Create a new dataref using a subset of the data in the specified
119     *  src dataref.
120     */
121    static SkData* NewSubset(const SkData* src, size_t offset, size_t length);
122
123    /**
124     *  Returns a new empty dataref (or a reference to a shared empty dataref).
125     *  New or shared, the caller must see that unref() is eventually called.
126     */
127    static SkData* NewEmpty();
128
129    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData)
130
131protected:
132    SkData(SkFlattenableReadBuffer&);
133    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
134
135private:
136    ReleaseProc fReleaseProc;
137    void*       fReleaseProcContext;
138
139    const void* fPtr;
140    size_t      fSize;
141
142    SkData(const void* ptr, size_t size, ReleaseProc, void* context);
143    virtual ~SkData();
144
145    typedef SkFlattenable INHERITED;
146};
147
148/** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */
149typedef SkAutoTUnref<SkData> SkAutoDataUnref;
150
151#endif
152