Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #ifndef SkData_DEFINED
     12 #define SkData_DEFINED
     13 
     14 #include "SkRefCnt.h"
     15 
     16 /**
     17  *  SkData holds an immutable data buffer. Not only is the data immutable,
     18  *  but the actual ptr that is returned (by data() or bytes()) is guaranteed
     19  *  to always be the same for the life of this instance.
     20  */
     21 class SkData : public SkRefCnt {
     22 public:
     23     /**
     24      *  Returns the number of bytes stored.
     25      */
     26     size_t size() const { return fSize; }
     27 
     28     /**
     29      *  Returns the ptr to the data.
     30      */
     31     const void* data() const { return fPtr; }
     32 
     33     /**
     34      *  Like data(), returns a read-only ptr into the data, but in this case
     35      *  it is cast to uint8_t*, to make it easy to add an offset to it.
     36      */
     37     const uint8_t* bytes() const {
     38         return reinterpret_cast<const uint8_t*>(fPtr);
     39     }
     40 
     41     /**
     42      *  Helper to copy a range of the data into a caller-provided buffer.
     43      *  Returns the actual number of bytes copied, after clamping offset and
     44      *  length to the size of the data. If buffer is NULL, it is ignored, and
     45      *  only the computed number of bytes is returned.
     46      */
     47     size_t copyRange(size_t offset, size_t length, void* buffer) const;
     48 
     49     /**
     50      *  Function that, if provided, will be called when the SkData goes out
     51      *  of scope, allowing for custom allocation/freeing of the data.
     52      */
     53     typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context);
     54 
     55     /**
     56      *  Create a new dataref by copying the specified data
     57      */
     58     static SkData* NewWithCopy(const void* data, size_t length);
     59 
     60     /**
     61      *  Create a new dataref, taking the data ptr as is, and using the
     62      *  releaseproc to free it. The proc may be NULL.
     63      */
     64     static SkData* NewWithProc(const void* data, size_t length,
     65                                ReleaseProc proc, void* context);
     66 
     67     /**
     68      *  Create a new dataref, reference the data ptr as is, and calling
     69      *  sk_free to delete it.
     70      */
     71     static SkData* NewFromMalloc(const void* data, size_t length);
     72 
     73     /**
     74      *  Create a new dataref using a subset of the data in the specified
     75      *  src dataref.
     76      */
     77     static SkData* NewSubset(const SkData* src, size_t offset, size_t length);
     78 
     79     /**
     80      *  Returns a new empty dataref (or a reference to a shared empty dataref).
     81      *  New or shared, the caller must see that unref() is eventually called.
     82      */
     83     static SkData* NewEmpty();
     84 
     85 private:
     86     ReleaseProc fReleaseProc;
     87     void*       fReleaseProcContext;
     88 
     89     const void* fPtr;
     90     size_t      fSize;
     91 
     92     SkData(const void* ptr, size_t size, ReleaseProc, void* context);
     93     ~SkData();
     94 };
     95 
     96 /**
     97  *  Specialized version of SkAutoTUnref<SkData> for automatically unref-ing a
     98  *  SkData. If the SkData is null, data(), bytes() and size() will return 0.
     99  */
    100 class SkAutoDataUnref : SkNoncopyable {
    101 public:
    102     SkAutoDataUnref(SkData* data) : fRef(data) {
    103         if (data) {
    104             fData = data->data();
    105             fSize = data->size();
    106         } else {
    107             fData = NULL;
    108             fSize = 0;
    109         }
    110     }
    111     ~SkAutoDataUnref() {
    112         SkSafeUnref(fRef);
    113     }
    114 
    115     const void* data() const { return fData; }
    116     const uint8_t* bytes() const {
    117         return reinterpret_cast<const uint8_t*> (fData);
    118     }
    119     size_t size() const { return fSize; }
    120     SkData* get() const { return fRef; }
    121 
    122     void release() {
    123         if (fRef) {
    124             fRef->unref();
    125             fRef = NULL;
    126             fData = NULL;
    127             fSize = 0;
    128         }
    129     }
    130 
    131 private:
    132     SkData*     fRef;
    133     const void* fData;
    134     size_t      fSize;
    135 };
    136 
    137 #endif
    138