1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkDataTable.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,177 @@ 1.4 +/* 1.5 + * Copyright 2013 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkDataTable_DEFINED 1.12 +#define SkDataTable_DEFINED 1.13 + 1.14 +#include "SkChunkAlloc.h" 1.15 +#include "SkData.h" 1.16 +#include "SkString.h" 1.17 +#include "SkTDArray.h" 1.18 + 1.19 +/** 1.20 + * Like SkData, SkDataTable holds an immutable data buffer. The data buffer is 1.21 + * organized into a table of entries, each with a length, so the entries are 1.22 + * not required to all be the same size. 1.23 + */ 1.24 +class SK_API SkDataTable : public SkRefCnt { 1.25 +public: 1.26 + SK_DECLARE_INST_COUNT(SkDataTable) 1.27 + 1.28 + /** 1.29 + * Returns true if the table is empty (i.e. has no entries). 1.30 + */ 1.31 + bool isEmpty() const { return 0 == fCount; } 1.32 + 1.33 + /** 1.34 + * Return the number of entries in the table. 0 for an empty table 1.35 + */ 1.36 + int count() const { return fCount; } 1.37 + 1.38 + /** 1.39 + * Return the size of the index'th entry in the table. The caller must 1.40 + * ensure that index is valid for this table. 1.41 + */ 1.42 + size_t atSize(int index) const; 1.43 + 1.44 + /** 1.45 + * Return a pointer to the data of the index'th entry in the table. 1.46 + * The caller must ensure that index is valid for this table. 1.47 + * 1.48 + * @param size If non-null, this returns the byte size of this entry. This 1.49 + * will be the same value that atSize(index) would return. 1.50 + */ 1.51 + const void* at(int index, size_t* size = NULL) const; 1.52 + 1.53 + template <typename T> 1.54 + const T* atT(int index, size_t* size = NULL) const { 1.55 + return reinterpret_cast<const T*>(this->at(index, size)); 1.56 + } 1.57 + 1.58 + /** 1.59 + * Returns the index'th entry as a c-string, and assumes that the trailing 1.60 + * null byte had been copied into the table as well. 1.61 + */ 1.62 + const char* atStr(int index) const { 1.63 + size_t size; 1.64 + const char* str = this->atT<const char>(index, &size); 1.65 + SkASSERT(strlen(str) + 1 == size); 1.66 + return str; 1.67 + } 1.68 + 1.69 + typedef void (*FreeProc)(void* context); 1.70 + 1.71 + static SkDataTable* NewEmpty(); 1.72 + 1.73 + /** 1.74 + * Return a new DataTable that contains a copy of the data stored in each 1.75 + * "array". 1.76 + * 1.77 + * @param ptrs array of points to each element to be copied into the table. 1.78 + * @param sizes array of byte-lengths for each entry in the corresponding 1.79 + * ptrs[] array. 1.80 + * @param count the number of array elements in ptrs[] and sizes[] to copy. 1.81 + */ 1.82 + static SkDataTable* NewCopyArrays(const void * const * ptrs, 1.83 + const size_t sizes[], int count); 1.84 + 1.85 + /** 1.86 + * Return a new table that contains a copy of the data in array. 1.87 + * 1.88 + * @param array contiguous array of data for all elements to be copied. 1.89 + * @param elemSize byte-length for a given element. 1.90 + * @param count the number of entries to be copied out of array. The number 1.91 + * of bytes that will be copied is count * elemSize. 1.92 + */ 1.93 + static SkDataTable* NewCopyArray(const void* array, size_t elemSize, 1.94 + int count); 1.95 + 1.96 + static SkDataTable* NewArrayProc(const void* array, size_t elemSize, 1.97 + int count, FreeProc proc, void* context); 1.98 + 1.99 +private: 1.100 + struct Dir { 1.101 + const void* fPtr; 1.102 + uintptr_t fSize; 1.103 + }; 1.104 + 1.105 + int fCount; 1.106 + size_t fElemSize; 1.107 + union { 1.108 + const Dir* fDir; 1.109 + const char* fElems; 1.110 + } fU; 1.111 + 1.112 + FreeProc fFreeProc; 1.113 + void* fFreeProcContext; 1.114 + 1.115 + SkDataTable(); 1.116 + SkDataTable(const void* array, size_t elemSize, int count, 1.117 + FreeProc, void* context); 1.118 + SkDataTable(const Dir*, int count, FreeProc, void* context); 1.119 + virtual ~SkDataTable(); 1.120 + 1.121 + friend class SkDataTableBuilder; // access to Dir 1.122 + 1.123 + typedef SkRefCnt INHERITED; 1.124 +}; 1.125 + 1.126 +/** 1.127 + * Helper class that allows for incrementally building up the data needed to 1.128 + * create a SkDataTable. 1.129 + */ 1.130 +class SK_API SkDataTableBuilder : SkNoncopyable { 1.131 +public: 1.132 + SkDataTableBuilder(size_t minChunkSize); 1.133 + ~SkDataTableBuilder(); 1.134 + 1.135 + int count() const { return fDir.count(); } 1.136 + size_t minChunkSize() const { return fMinChunkSize; } 1.137 + 1.138 + /** 1.139 + * Forget any previously appended entries, setting count() back to 0. 1.140 + */ 1.141 + void reset(size_t minChunkSize); 1.142 + void reset() { 1.143 + this->reset(fMinChunkSize); 1.144 + } 1.145 + 1.146 + /** 1.147 + * Copy size-bytes from data, and append it to the growing SkDataTable. 1.148 + */ 1.149 + void append(const void* data, size_t size); 1.150 + 1.151 + /** 1.152 + * Helper version of append() passes strlen() + 1 for the size, 1.153 + * so the trailing-zero will be copied as well. 1.154 + */ 1.155 + void appendStr(const char str[]) { 1.156 + this->append(str, strlen(str) + 1); 1.157 + } 1.158 + 1.159 + /** 1.160 + * Helper version of append() passes string.size() + 1 for the size, 1.161 + * so the trailing-zero will be copied as well. 1.162 + */ 1.163 + void appendString(const SkString& string) { 1.164 + this->append(string.c_str(), string.size() + 1); 1.165 + } 1.166 + 1.167 + /** 1.168 + * Return an SkDataTable from the accumulated entries that were added by 1.169 + * calls to append(). This call also clears any accumluated entries from 1.170 + * this builder, so its count() will be 0 after this call. 1.171 + */ 1.172 + SkDataTable* detachDataTable(); 1.173 + 1.174 +private: 1.175 + SkTDArray<SkDataTable::Dir> fDir; 1.176 + SkChunkAlloc* fHeap; 1.177 + size_t fMinChunkSize; 1.178 +}; 1.179 + 1.180 +#endif