michael@0: michael@0: /* michael@0: * Copyright 2011 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: michael@0: #ifndef SkData_DEFINED michael@0: #define SkData_DEFINED michael@0: michael@0: #include "SkRefCnt.h" michael@0: michael@0: struct SkFILE; michael@0: michael@0: /** michael@0: * SkData holds an immutable data buffer. Not only is the data immutable, michael@0: * but the actual ptr that is returned (by data() or bytes()) is guaranteed michael@0: * to always be the same for the life of this instance. michael@0: */ michael@0: class SK_API SkData : public SkRefCnt { michael@0: public: michael@0: SK_DECLARE_INST_COUNT(SkData) michael@0: michael@0: /** michael@0: * Returns the number of bytes stored. michael@0: */ michael@0: size_t size() const { return fSize; } michael@0: michael@0: bool isEmpty() const { return 0 == fSize; } michael@0: michael@0: /** michael@0: * Returns the ptr to the data. michael@0: */ michael@0: const void* data() const { return fPtr; } michael@0: michael@0: /** michael@0: * Like data(), returns a read-only ptr into the data, but in this case michael@0: * it is cast to uint8_t*, to make it easy to add an offset to it. michael@0: */ michael@0: const uint8_t* bytes() const { michael@0: return reinterpret_cast(fPtr); michael@0: } michael@0: michael@0: /** michael@0: * Helper to copy a range of the data into a caller-provided buffer. michael@0: * Returns the actual number of bytes copied, after clamping offset and michael@0: * length to the size of the data. If buffer is NULL, it is ignored, and michael@0: * only the computed number of bytes is returned. michael@0: */ michael@0: size_t copyRange(size_t offset, size_t length, void* buffer) const; michael@0: michael@0: /** michael@0: * Returns true if these two objects have the same length and contents, michael@0: * effectively returning 0 == memcmp(...) michael@0: */ michael@0: bool equals(const SkData* other) const; michael@0: michael@0: /** michael@0: * Function that, if provided, will be called when the SkData goes out michael@0: * of scope, allowing for custom allocation/freeing of the data. michael@0: */ michael@0: typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); michael@0: michael@0: /** michael@0: * Create a new dataref by copying the specified data michael@0: */ michael@0: static SkData* NewWithCopy(const void* data, size_t length); michael@0: michael@0: /** michael@0: * Create a new dataref by copying the specified c-string michael@0: * (a null-terminated array of bytes). The returned SkData will have size() michael@0: * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same michael@0: * as "". michael@0: */ michael@0: static SkData* NewWithCString(const char cstr[]); michael@0: michael@0: /** michael@0: * Create a new dataref, taking the data ptr as is, and using the michael@0: * releaseproc to free it. The proc may be NULL. michael@0: */ michael@0: static SkData* NewWithProc(const void* data, size_t length, michael@0: ReleaseProc proc, void* context); michael@0: michael@0: /** michael@0: * Create a new dataref from a pointer allocated by malloc. The Data object michael@0: * takes ownership of that allocation, and will handling calling sk_free. michael@0: */ michael@0: static SkData* NewFromMalloc(const void* data, size_t length); michael@0: michael@0: /** michael@0: * Create a new dataref the file with the specified path. michael@0: * If the file cannot be opened, this returns NULL. michael@0: */ michael@0: static SkData* NewFromFileName(const char path[]); michael@0: michael@0: /** michael@0: * Create a new dataref from a SkFILE. michael@0: * This does not take ownership of the SkFILE, nor close it. michael@0: * The caller is free to close the SkFILE at its convenience. michael@0: * The SkFILE must be open for reading only. michael@0: * Returns NULL on failure. michael@0: */ michael@0: static SkData* NewFromFILE(SkFILE* f); michael@0: michael@0: /** michael@0: * Create a new dataref from a file descriptor. michael@0: * This does not take ownership of the file descriptor, nor close it. michael@0: * The caller is free to close the file descriptor at its convenience. michael@0: * The file descriptor must be open for reading only. michael@0: * Returns NULL on failure. michael@0: */ michael@0: static SkData* NewFromFD(int fd); michael@0: michael@0: /** michael@0: * Create a new dataref using a subset of the data in the specified michael@0: * src dataref. michael@0: */ michael@0: static SkData* NewSubset(const SkData* src, size_t offset, size_t length); michael@0: michael@0: /** michael@0: * Returns a new empty dataref (or a reference to a shared empty dataref). michael@0: * New or shared, the caller must see that unref() is eventually called. michael@0: */ michael@0: static SkData* NewEmpty(); michael@0: michael@0: private: michael@0: ReleaseProc fReleaseProc; michael@0: void* fReleaseProcContext; michael@0: michael@0: const void* fPtr; michael@0: size_t fSize; michael@0: michael@0: SkData(const void* ptr, size_t size, ReleaseProc, void* context); michael@0: virtual ~SkData(); michael@0: michael@0: // Called the first time someone calls NewEmpty to initialize the singleton. michael@0: static void NewEmptyImpl(int/*unused*/); michael@0: michael@0: typedef SkRefCnt INHERITED; michael@0: }; michael@0: michael@0: /** Typedef of SkAutoTUnref for automatically unref-ing a SkData. */ michael@0: typedef SkAutoTUnref SkAutoDataUnref; michael@0: michael@0: #endif