1 | /* |
2 | * Copyright 2013 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 SkDataTable_DEFINED |
9 | #define SkDataTable_DEFINED |
10 | |
11 | #include "include/core/SkData.h" |
12 | #include "include/private/SkTDArray.h" |
13 | |
14 | /** |
15 | * Like SkData, SkDataTable holds an immutable data buffer. The data buffer is |
16 | * organized into a table of entries, each with a length, so the entries are |
17 | * not required to all be the same size. |
18 | */ |
19 | class SK_API SkDataTable : public SkRefCnt { |
20 | public: |
21 | /** |
22 | * Returns true if the table is empty (i.e. has no entries). |
23 | */ |
24 | bool isEmpty() const { return 0 == fCount; } |
25 | |
26 | /** |
27 | * Return the number of entries in the table. 0 for an empty table |
28 | */ |
29 | int count() const { return fCount; } |
30 | |
31 | /** |
32 | * Return the size of the index'th entry in the table. The caller must |
33 | * ensure that index is valid for this table. |
34 | */ |
35 | size_t atSize(int index) const; |
36 | |
37 | /** |
38 | * Return a pointer to the data of the index'th entry in the table. |
39 | * The caller must ensure that index is valid for this table. |
40 | * |
41 | * @param size If non-null, this returns the byte size of this entry. This |
42 | * will be the same value that atSize(index) would return. |
43 | */ |
44 | const void* at(int index, size_t* size = nullptr) const; |
45 | |
46 | template <typename T> |
47 | const T* atT(int index, size_t* size = nullptr) const { |
48 | return reinterpret_cast<const T*>(this->at(index, size)); |
49 | } |
50 | |
51 | /** |
52 | * Returns the index'th entry as a c-string, and assumes that the trailing |
53 | * null byte had been copied into the table as well. |
54 | */ |
55 | const char* atStr(int index) const { |
56 | size_t size; |
57 | const char* str = this->atT<const char>(index, &size); |
58 | SkASSERT(strlen(str) + 1 == size); |
59 | return str; |
60 | } |
61 | |
62 | typedef void (*FreeProc)(void* context); |
63 | |
64 | static sk_sp<SkDataTable> MakeEmpty(); |
65 | |
66 | /** |
67 | * Return a new DataTable that contains a copy of the data stored in each |
68 | * "array". |
69 | * |
70 | * @param ptrs array of points to each element to be copied into the table. |
71 | * @param sizes array of byte-lengths for each entry in the corresponding |
72 | * ptrs[] array. |
73 | * @param count the number of array elements in ptrs[] and sizes[] to copy. |
74 | */ |
75 | static sk_sp<SkDataTable> MakeCopyArrays(const void * const * ptrs, |
76 | const size_t sizes[], int count); |
77 | |
78 | /** |
79 | * Return a new table that contains a copy of the data in array. |
80 | * |
81 | * @param array contiguous array of data for all elements to be copied. |
82 | * @param elemSize byte-length for a given element. |
83 | * @param count the number of entries to be copied out of array. The number |
84 | * of bytes that will be copied is count * elemSize. |
85 | */ |
86 | static sk_sp<SkDataTable> MakeCopyArray(const void* array, size_t elemSize, int count); |
87 | |
88 | static sk_sp<SkDataTable> MakeArrayProc(const void* array, size_t elemSize, int count, |
89 | FreeProc proc, void* context); |
90 | |
91 | private: |
92 | struct Dir { |
93 | const void* fPtr; |
94 | uintptr_t fSize; |
95 | }; |
96 | |
97 | int fCount; |
98 | size_t fElemSize; |
99 | union { |
100 | const Dir* fDir; |
101 | const char* fElems; |
102 | } fU; |
103 | |
104 | FreeProc fFreeProc; |
105 | void* fFreeProcContext; |
106 | |
107 | SkDataTable(); |
108 | SkDataTable(const void* array, size_t elemSize, int count, |
109 | FreeProc, void* context); |
110 | SkDataTable(const Dir*, int count, FreeProc, void* context); |
111 | virtual ~SkDataTable(); |
112 | |
113 | friend class SkDataTableBuilder; // access to Dir |
114 | |
115 | typedef SkRefCnt INHERITED; |
116 | }; |
117 | |
118 | #endif |
119 | |