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 */
19class SK_API SkDataTable : public SkRefCnt {
20public:
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
91private:
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 ~SkDataTable() override;
112
113 friend class SkDataTableBuilder; // access to Dir
114
115 typedef SkRefCnt INHERITED;
116};
117
118#endif
119