| 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 | |