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 "SkFlattenable.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 SK_API SkData : public SkFlattenable {
     22 public:
     23     SK_DECLARE_INST_COUNT(SkData)
     24 
     25     /**
     26      *  Returns the number of bytes stored.
     27      */
     28     size_t size() const { return fSize; }
     29 
     30     bool isEmpty() const { return 0 == fSize; }
     31 
     32     /**
     33      *  Returns the ptr to the data.
     34      */
     35     const void* data() const { return fPtr; }
     36 
     37     /**
     38      *  Like data(), returns a read-only ptr into the data, but in this case
     39      *  it is cast to uint8_t*, to make it easy to add an offset to it.
     40      */
     41     const uint8_t* bytes() const {
     42         return reinterpret_cast<const uint8_t*>(fPtr);
     43     }
     44 
     45     /**
     46      *  Helper to copy a range of the data into a caller-provided buffer.
     47      *  Returns the actual number of bytes copied, after clamping offset and
     48      *  length to the size of the data. If buffer is NULL, it is ignored, and
     49      *  only the computed number of bytes is returned.
     50      */
     51     size_t copyRange(size_t offset, size_t length, void* buffer) const;
     52 
     53     /**
     54      *  Returns true if these two objects have the same length and contents,
     55      *  effectively returning 0 == memcmp(...)
     56      */
     57     bool equals(const SkData* other) const;
     58 
     59     /**
     60      *  Function that, if provided, will be called when the SkData goes out
     61      *  of scope, allowing for custom allocation/freeing of the data.
     62      */
     63     typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context);
     64 
     65     /**
     66      *  Create a new dataref by copying the specified data
     67      */
     68     static SkData* NewWithCopy(const void* data, size_t length);
     69 
     70     /**
     71      *  Create a new dataref by copying the specified c-string
     72      *  (a null-terminated array of bytes). The returned SkData will have size()
     73      *  equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
     74      *  as "".
     75      */
     76     static SkData* NewWithCString(const char cstr[]);
     77 
     78     /**
     79      *  Create a new dataref, taking the data ptr as is, and using the
     80      *  releaseproc to free it. The proc may be NULL.
     81      */
     82     static SkData* NewWithProc(const void* data, size_t length,
     83                                ReleaseProc proc, void* context);
     84 
     85     /**
     86      *  Create a new dataref from a pointer allocated by malloc. The Data object
     87      *  takes ownership of that allocation, and will handling calling sk_free.
     88      */
     89     static SkData* NewFromMalloc(const void* data, size_t length);
     90 
     91     /**
     92      *  Create a new dataref using a subset of the data in the specified
     93      *  src dataref.
     94      */
     95     static SkData* NewSubset(const SkData* src, size_t offset, size_t length);
     96 
     97     /**
     98      *  Returns a new empty dataref (or a reference to a shared empty dataref).
     99      *  New or shared, the caller must see that unref() is eventually called.
    100      */
    101     static SkData* NewEmpty();
    102 
    103     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData)
    104 
    105 protected:
    106     SkData(SkFlattenableReadBuffer&);
    107     virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
    108 
    109 private:
    110     ReleaseProc fReleaseProc;
    111     void*       fReleaseProcContext;
    112 
    113     const void* fPtr;
    114     size_t      fSize;
    115 
    116     SkData(const void* ptr, size_t size, ReleaseProc, void* context);
    117     virtual ~SkData();
    118 
    119     // This is here because SkAutoTUnref creates an internal helper class
    120     // that derives from SkData (i.e., BlockRef) to prevent refs\unrefs.
    121     // This helper class generates a compiler warning on Windows since the
    122     // SkData's destructor is private. This friending gives the helper class
    123     // access to the destructor.
    124     friend class SkAutoTUnref<SkData>::BlockRef<SkData>;
    125 
    126     typedef SkFlattenable INHERITED;
    127 };
    128 
    129 /**
    130  *  Specialized version of SkAutoTUnref<SkData> for automatically unref-ing a
    131  *  SkData.
    132  */
    133 class SkAutoDataUnref : SkNoncopyable {
    134 public:
    135     SkAutoDataUnref(SkData* data) : fRef(data) {}
    136     ~SkAutoDataUnref() {
    137         SkSafeUnref(fRef);
    138     }
    139 
    140     SkData* get() const { return fRef; }
    141 
    142     void release() {
    143         if (fRef) {
    144             fRef->unref();
    145             fRef = NULL;
    146         }
    147     }
    148 
    149     SkData *operator->() const { return fRef; }
    150     operator SkData*() { return fRef; }
    151 
    152 private:
    153     SkData*     fRef;
    154 };
    155 
    156 #endif
    157