Home | History | Annotate | Download | only in core
      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 "../private/SkTDArray.h"
     12 #include "SkData.h"
     13 #include "SkString.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      */
     25     bool isEmpty() const { return 0 == fCount; }
     26 
     27     /**
     28      *  Return the number of entries in the table. 0 for an empty table
     29      */
     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      */
     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