17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/* 27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc. 37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file. 67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifndef SkDataTable_DEFINED 97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define SkDataTable_DEFINED 107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkChunkAlloc.h" 127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkData.h" 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkString.h" 147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkTDArray.h" 157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/** 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Like SkData, SkDataTable holds an immutable data buffer. The data buffer is 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * organized into a table of entries, each with a length, so the entries are 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * not required to all be the same size. 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass SK_API SkDataTable : public SkRefCnt { 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic: 237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SK_DECLARE_INST_COUNT(SkDataTable) 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Returns true if the table is empty (i.e. has no entries). 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool isEmpty() const { return 0 == fCount; } 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Return the number of entries in the table. 0 for an empty table 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int count() const { return fCount; } 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Return the size of the index'th entry in the table. The caller must 377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * ensure that index is valid for this table. 387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t atSize(int index) const; 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Return a pointer to the data of the index'th entry in the table. 437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * The caller must ensure that index is valid for this table. 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param size If non-null, this returns the byte size of this entry. This 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * will be the same value that atSize(index) would return. 477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const void* at(int index, size_t* size = NULL) const; 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger template <typename T> 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const T* atT(int index, size_t* size = NULL) const { 527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return reinterpret_cast<const T*>(this->at(index, size)); 537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Returns the index'th entry as a c-string, and assumes that the trailing 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * null byte had been copied into the table as well. 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const char* atStr(int index) const { 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t size; 617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const char* str = this->atT<const char>(index, &size); 627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(strlen(str) + 1 == size); 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return str; 647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger typedef void (*FreeProc)(void* context); 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static SkDataTable* NewEmpty(); 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Return a new DataTable that contains a copy of the data stored in each 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * "array". 737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param ptrs array of points to each element to be copied into the table. 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param sizes array of byte-lengths for each entry in the corresponding 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * ptrs[] array. 777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param count the number of array elements in ptrs[] and sizes[] to copy. 787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static SkDataTable* NewCopyArrays(const void * const * ptrs, 807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const size_t sizes[], int count); 817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Return a new table that contains a copy of the data in array. 847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param array contiguous array of data for all elements to be copied. 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param elemSize byte-length for a given element. 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * @param count the number of entries to be copied out of array. The number 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * of bytes that will be copied is count * elemSize. 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static SkDataTable* NewCopyArray(const void* array, size_t elemSize, 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int count); 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static SkDataTable* NewArrayProc(const void* array, size_t elemSize, 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int count, FreeProc proc, void* context); 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate: 977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger struct Dir { 987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const void* fPtr; 997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger uintptr_t fSize; 1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger }; 1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int fCount; 1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t fElemSize; 1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger union { 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const Dir* fDir; 1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const char* fElems; 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } fU; 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger FreeProc fFreeProc; 1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void* fFreeProcContext; 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDataTable(); 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDataTable(const void* array, size_t elemSize, int count, 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger FreeProc, void* context); 1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDataTable(const Dir*, int count, FreeProc, void* context); 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual ~SkDataTable(); 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger friend class SkDataTableBuilder; // access to Dir 1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger typedef SkRefCnt INHERITED; 1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/** 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Helper class that allows for incrementally building up the data needed to 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * create a SkDataTable. 1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass SK_API SkDataTableBuilder : SkNoncopyable { 1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic: 1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDataTableBuilder(size_t minChunkSize); 1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ~SkDataTableBuilder(); 1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int count() const { return fDir.count(); } 1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t minChunkSize() const { return fMinChunkSize; } 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Forget any previously appended entries, setting count() back to 0. 1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void reset(size_t minChunkSize); 1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void reset() { 1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->reset(fMinChunkSize); 1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copy size-bytes from data, and append it to the growing SkDataTable. 1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void append(const void* data, size_t size); 1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Helper version of append() passes strlen() + 1 for the size, 1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * so the trailing-zero will be copied as well. 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void appendStr(const char str[]) { 1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->append(str, strlen(str) + 1); 1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Helper version of append() passes string.size() + 1 for the size, 1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * so the trailing-zero will be copied as well. 1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void appendString(const SkString& string) { 1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->append(string.c_str(), string.size() + 1); 1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Return an SkDataTable from the accumulated entries that were added by 1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * calls to append(). This call also clears any accumluated entries from 1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * this builder, so its count() will be 0 after this call. 1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDataTable* detachDataTable(); 1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate: 1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTDArray<SkDataTable::Dir> fDir; 1737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkChunkAlloc* fHeap; 1747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t fMinChunkSize; 1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 1767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 178