18c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com/* 28c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Copyright 2013 Google Inc. 38c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * 48c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Use of this source code is governed by a BSD-style license that can be 58c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * found in the LICENSE file. 68c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 78c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 88c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#ifndef SkDataTable_DEFINED 98c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#define SkDataTable_DEFINED 108c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 118c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#include "SkChunkAlloc.h" 128c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#include "SkData.h" 138c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#include "SkString.h" 148c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#include "SkTDArray.h" 158c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 168c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com/** 178c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Like SkData, SkDataTable holds an immutable data buffer. The data buffer is 188c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * organized into a table of entries, each with a length, so the entries are 198c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * not required to all be the same size. 208c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 212f92966c6a2419023570d5951a4234cdaebcc3c9commit-bot@chromium.orgclass SK_API SkDataTable : public SkRefCnt { 228c5c7a905b708f7c0a991ca7c872af645544afefreed@google.compublic: 238c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com SK_DECLARE_INST_COUNT(SkDataTable) 248c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 258c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 268c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Returns true if the table is empty (i.e. has no entries). 278c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 288c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com bool isEmpty() const { return 0 == fCount; } 298c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 308c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 318c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Return the number of entries in the table. 0 for an empty table 328c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 338c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com int count() const { return fCount; } 348c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 358c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 368c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Return the size of the index'th entry in the table. The caller must 378c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * ensure that index is valid for this table. 388c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 39cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org size_t atSize(int index) const; 408c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 418c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 428c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Return a pointer to the data of the index'th entry in the table. 438c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * The caller must ensure that index is valid for this table. 448c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * 458c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param size If non-null, this returns the byte size of this entry. This 468c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * will be the same value that atSize(index) would return. 478c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 48cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const void* at(int index, size_t* size = NULL) const; 498c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 508c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com template <typename T> 51cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const T* atT(int index, size_t* size = NULL) const { 52cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org return reinterpret_cast<const T*>(this->at(index, size)); 538c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com } 548c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 558c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 568c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Returns the index'th entry as a c-string, and assumes that the trailing 578c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * null byte had been copied into the table as well. 588c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 598c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com const char* atStr(int index) const { 608c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com size_t size; 61cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const char* str = this->atT<const char>(index, &size); 628c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com SkASSERT(strlen(str) + 1 == size); 638c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com return str; 648c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com } 658c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 66cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org typedef void (*FreeProc)(void* context); 67cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org 683cceb9f400583be4ec70da526c23fe81b68dc6eereed@google.com static SkDataTable* NewEmpty(); 693cceb9f400583be4ec70da526c23fe81b68dc6eereed@google.com 708c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 718c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Return a new DataTable that contains a copy of the data stored in each 728c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * "array". 738c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * 748c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param ptrs array of points to each element to be copied into the table. 758c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param sizes array of byte-lengths for each entry in the corresponding 768c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * ptrs[] array. 778c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param count the number of array elements in ptrs[] and sizes[] to copy. 788c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 79cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org static SkDataTable* NewCopyArrays(const void * const * ptrs, 80cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const size_t sizes[], int count); 818c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 828c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 838c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Return a new table that contains a copy of the data in array. 848c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * 858c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param array contiguous array of data for all elements to be copied. 868c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param elemSize byte-length for a given element. 878c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * @param count the number of entries to be copied out of array. The number 888c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * of bytes that will be copied is count * elemSize. 898c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 908c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com static SkDataTable* NewCopyArray(const void* array, size_t elemSize, 918c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com int count); 9264b682ca42c75667e49251d3ab04f192f92d0dd8skia.committer@gmail.com 93cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org static SkDataTable* NewArrayProc(const void* array, size_t elemSize, 94cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org int count, FreeProc proc, void* context); 95cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org 968c5c7a905b708f7c0a991ca7c872af645544afefreed@google.comprivate: 97cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org struct Dir { 98cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const void* fPtr; 99cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org uintptr_t fSize; 100cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org }; 101cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org 102cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org int fCount; 103cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org size_t fElemSize; 104cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org union { 105cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const Dir* fDir; 106cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org const char* fElems; 107cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org } fU; 108cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org 109cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org FreeProc fFreeProc; 110cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org void* fFreeProcContext; 111cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org 112cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org SkDataTable(); 113cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org SkDataTable(const void* array, size_t elemSize, int count, 114cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org FreeProc, void* context); 115cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org SkDataTable(const Dir*, int count, FreeProc, void* context); 1168c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com virtual ~SkDataTable(); 1178c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 118cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org friend class SkDataTableBuilder; // access to Dir 1198c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1202f92966c6a2419023570d5951a4234cdaebcc3c9commit-bot@chromium.org typedef SkRefCnt INHERITED; 1218c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com}; 1228c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1238c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com/** 1248c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Helper class that allows for incrementally building up the data needed to 1258c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * create a SkDataTable. 1268c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 127cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.orgclass SK_API SkDataTableBuilder : SkNoncopyable { 1288c5c7a905b708f7c0a991ca7c872af645544afefreed@google.compublic: 1298c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com SkDataTableBuilder(size_t minChunkSize); 1308c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com ~SkDataTableBuilder(); 1318c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 132cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org int count() const { return fDir.count(); } 133cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org size_t minChunkSize() const { return fMinChunkSize; } 1348c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1358c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 1368c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Forget any previously appended entries, setting count() back to 0. 1378c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 138cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org void reset(size_t minChunkSize); 139cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org void reset() { 140cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org this->reset(fMinChunkSize); 141cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org } 1428c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1438c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 1448c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Copy size-bytes from data, and append it to the growing SkDataTable. 1458c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 1468c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com void append(const void* data, size_t size); 1478c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1488c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 1498c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Helper version of append() passes strlen() + 1 for the size, 1508c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * so the trailing-zero will be copied as well. 1518c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 1528c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com void appendStr(const char str[]) { 1538c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com this->append(str, strlen(str) + 1); 1548c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com } 1558c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1568c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 1578c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Helper version of append() passes string.size() + 1 for the size, 1588c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * so the trailing-zero will be copied as well. 1598c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 1608c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com void appendString(const SkString& string) { 1618c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com this->append(string.c_str(), string.size() + 1); 1628c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com } 1638c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1648c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com /** 1658c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com * Return an SkDataTable from the accumulated entries that were added by 166cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org * calls to append(). This call also clears any accumluated entries from 167cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org * this builder, so its count() will be 0 after this call. 1688c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com */ 169cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org SkDataTable* detachDataTable(); 1708c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1718c5c7a905b708f7c0a991ca7c872af645544afefreed@google.comprivate: 172cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org SkTDArray<SkDataTable::Dir> fDir; 173cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org SkChunkAlloc* fHeap; 174cac3ae37522bf070244c723960d1689e53da4dcdmike@reedtribe.org size_t fMinChunkSize; 1758c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com}; 1768c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com 1778c5c7a905b708f7c0a991ca7c872af645544afefreed@google.com#endif 178