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