1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 63a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 73a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 83a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com#ifndef SkData_DEFINED 93a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com#define SkData_DEFINED 103a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 11da30055b296faa5a100e474e0406ef4296c14241reed@google.com#include "SkRefCnt.h" 123a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 139711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.orgstruct SkFILE; 149594da111dc1c36c1912eb61207aaa54c17ea550reedclass SkStream; 159711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.org 163a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com/** 173a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * SkData holds an immutable data buffer. Not only is the data immutable, 183a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * but the actual ptr that is returned (by data() or bytes()) is guaranteed 193a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * to always be the same for the life of this instance. 203a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 21da30055b296faa5a100e474e0406ef4296c14241reed@google.comclass SK_API SkData : public SkRefCnt { 223a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.compublic: 2315e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com SK_DECLARE_INST_COUNT(SkData) 2415e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 253a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 263a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Returns the number of bytes stored. 273a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 283a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com size_t size() const { return fSize; } 293a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 30dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com bool isEmpty() const { return 0 == fSize; } 31dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com 323a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 333a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Returns the ptr to the data. 343a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 353a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com const void* data() const { return fPtr; } 363a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 373a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 383a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Like data(), returns a read-only ptr into the data, but in this case 393a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * it is cast to uint8_t*, to make it easy to add an offset to it. 403a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 413a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com const uint8_t* bytes() const { 423a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com return reinterpret_cast<const uint8_t*>(fPtr); 433a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com } 443a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 453a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 4633a30503d76fdd989358cedd78445ba96bb809ddreed * USE WITH CAUTION. 4733a30503d76fdd989358cedd78445ba96bb809ddreed * This call will assert that the refcnt is 1, as a precaution against modifying the 4833a30503d76fdd989358cedd78445ba96bb809ddreed * contents when another client/thread has access to the data. 4933a30503d76fdd989358cedd78445ba96bb809ddreed */ 5033a30503d76fdd989358cedd78445ba96bb809ddreed void* writable_data() { 5133a30503d76fdd989358cedd78445ba96bb809ddreed if (fSize) { 5233a30503d76fdd989358cedd78445ba96bb809ddreed // only assert we're unique if we're not empty 5333a30503d76fdd989358cedd78445ba96bb809ddreed SkASSERT(this->unique()); 5433a30503d76fdd989358cedd78445ba96bb809ddreed } 5533a30503d76fdd989358cedd78445ba96bb809ddreed return fPtr; 5633a30503d76fdd989358cedd78445ba96bb809ddreed } 5733a30503d76fdd989358cedd78445ba96bb809ddreed 5833a30503d76fdd989358cedd78445ba96bb809ddreed /** 593a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Helper to copy a range of the data into a caller-provided buffer. 603a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Returns the actual number of bytes copied, after clamping offset and 613a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * length to the size of the data. If buffer is NULL, it is ignored, and 623a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * only the computed number of bytes is returned. 633a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 643a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com size_t copyRange(size_t offset, size_t length, void* buffer) const; 653a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 663a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 67dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com * Returns true if these two objects have the same length and contents, 68dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com * effectively returning 0 == memcmp(...) 69dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com */ 70dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com bool equals(const SkData* other) const; 71dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com 72dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com /** 733a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Function that, if provided, will be called when the SkData goes out 743a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * of scope, allowing for custom allocation/freeing of the data. 753a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 763a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); 77fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 783a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 793a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Create a new dataref by copying the specified data 803a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 813a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com static SkData* NewWithCopy(const void* data, size_t length); 82fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 83dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com /** 8433a30503d76fdd989358cedd78445ba96bb809ddreed * Create a new data with uninitialized contents. The caller should call writable_data() 8533a30503d76fdd989358cedd78445ba96bb809ddreed * to write into the buffer, but this must be done before another ref() is made. 8633a30503d76fdd989358cedd78445ba96bb809ddreed */ 8733a30503d76fdd989358cedd78445ba96bb809ddreed static SkData* NewUninitialized(size_t length); 8833a30503d76fdd989358cedd78445ba96bb809ddreed 8933a30503d76fdd989358cedd78445ba96bb809ddreed /** 90dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com * Create a new dataref by copying the specified c-string 91fd59d1200073604c0a5dafe14edbb6f3833e1c3dreed@google.com * (a null-terminated array of bytes). The returned SkData will have size() 92fd59d1200073604c0a5dafe14edbb6f3833e1c3dreed@google.com * equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same 93fd59d1200073604c0a5dafe14edbb6f3833e1c3dreed@google.com * as "". 94dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com */ 95dbc936dff3357f74fc60e124d912a2179b909b0dreed@google.com static SkData* NewWithCString(const char cstr[]); 96fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 973a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 983a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Create a new dataref, taking the data ptr as is, and using the 993a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * releaseproc to free it. The proc may be NULL. 1003a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 10133a30503d76fdd989358cedd78445ba96bb809ddreed static SkData* NewWithProc(const void* data, size_t length, ReleaseProc proc, void* context); 10233a30503d76fdd989358cedd78445ba96bb809ddreed 10333a30503d76fdd989358cedd78445ba96bb809ddreed /** 10433a30503d76fdd989358cedd78445ba96bb809ddreed * Call this when the data parameter is already const and will outlive the lifetime of the 10533a30503d76fdd989358cedd78445ba96bb809ddreed * SkData. Suitable for with const globals. 10633a30503d76fdd989358cedd78445ba96bb809ddreed */ 10733a30503d76fdd989358cedd78445ba96bb809ddreed static SkData* NewWithoutCopy(const void* data, size_t length) { 10833a30503d76fdd989358cedd78445ba96bb809ddreed return NewWithProc(data, length, NULL, NULL); 10933a30503d76fdd989358cedd78445ba96bb809ddreed } 1103a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 1113a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 1121f1db4cc5b62fc74efc01a4c92cbc1f7bddce241reed@google.com * Create a new dataref from a pointer allocated by malloc. The Data object 1131f1db4cc5b62fc74efc01a4c92cbc1f7bddce241reed@google.com * takes ownership of that allocation, and will handling calling sk_free. 1148a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com */ 1158a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com static SkData* NewFromMalloc(const void* data, size_t length); 1167fb5373fb76951b7e8b534f04d508dd51e21be6eskia.committer@gmail.com 117792bbd14c63f217f2de0e6b2f8df99acb1928eeamike@reedtribe.org /** 118792bbd14c63f217f2de0e6b2f8df99acb1928eeamike@reedtribe.org * Create a new dataref the file with the specified path. 119792bbd14c63f217f2de0e6b2f8df99acb1928eeamike@reedtribe.org * If the file cannot be opened, this returns NULL. 120792bbd14c63f217f2de0e6b2f8df99acb1928eeamike@reedtribe.org */ 121792bbd14c63f217f2de0e6b2f8df99acb1928eeamike@reedtribe.org static SkData* NewFromFileName(const char path[]); 1227fb5373fb76951b7e8b534f04d508dd51e21be6eskia.committer@gmail.com 1238a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com /** 1249711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.org * Create a new dataref from a SkFILE. 1259711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.org * This does not take ownership of the SkFILE, nor close it. 12611c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com * The caller is free to close the SkFILE at its convenience. 1279711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.org * The SkFILE must be open for reading only. 1289711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.org * Returns NULL on failure. 129e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com */ 1309711e446676e6bf84b3fff916fd1d7537933a110commit-bot@chromium.org static SkData* NewFromFILE(SkFILE* f); 1318eaddb0089a170760e157646192813bd940c26e7skia.committer@gmail.com 132e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com /** 13311c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com * Create a new dataref from a file descriptor. 13411c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com * This does not take ownership of the file descriptor, nor close it. 13511c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com * The caller is free to close the file descriptor at its convenience. 13611c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com * The file descriptor must be open for reading only. 13711c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com * Returns NULL on failure. 13811c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com */ 13911c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com static SkData* NewFromFD(int fd); 14011f2b444500d552031fcae0b381a0770600400fdskia.committer@gmail.com 14111c9a55afd95078d14ab8cd7c1c5c0032af2a498bungeman@google.com /** 1429594da111dc1c36c1912eb61207aaa54c17ea550reed * Attempt to read size bytes into a SkData. If the read succeeds, return the data, 1439594da111dc1c36c1912eb61207aaa54c17ea550reed * else return NULL. Either way the stream's cursor may have been changed as a result 1449594da111dc1c36c1912eb61207aaa54c17ea550reed * of calling read(). 1459594da111dc1c36c1912eb61207aaa54c17ea550reed */ 1469594da111dc1c36c1912eb61207aaa54c17ea550reed static SkData* NewFromStream(SkStream*, size_t size); 1479594da111dc1c36c1912eb61207aaa54c17ea550reed 1489594da111dc1c36c1912eb61207aaa54c17ea550reed /** 1493a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Create a new dataref using a subset of the data in the specified 1503a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * src dataref. 1513a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 1523a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com static SkData* NewSubset(const SkData* src, size_t offset, size_t length); 1533a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 1543a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com /** 1553a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * Returns a new empty dataref (or a reference to a shared empty dataref). 1563a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com * New or shared, the caller must see that unref() is eventually called. 1573a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com */ 1583a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com static SkData* NewEmpty(); 1593a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 1603a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.comprivate: 1613a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com ReleaseProc fReleaseProc; 1623a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com void* fReleaseProcContext; 1633a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 16433a30503d76fdd989358cedd78445ba96bb809ddreed void* fPtr; 1653a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com size_t fSize; 1663a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 1673a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com SkData(const void* ptr, size_t size, ReleaseProc, void* context); 16833a30503d76fdd989358cedd78445ba96bb809ddreed SkData(size_t size); // inplace new/delete 16959f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com virtual ~SkData(); 17059f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com 17133a30503d76fdd989358cedd78445ba96bb809ddreed virtual void internal_dispose() const SK_OVERRIDE; 17233a30503d76fdd989358cedd78445ba96bb809ddreed 1731f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.org // Called the first time someone calls NewEmpty to initialize the singleton. 17497de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org static SkData* NewEmptyImpl(); 17597de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org static void DeleteEmpty(SkData*); 1761f81fd6546c111e21bc665657e976b9d842192dfcommit-bot@chromium.org 17733a30503d76fdd989358cedd78445ba96bb809ddreed // shared internal factory 17833a30503d76fdd989358cedd78445ba96bb809ddreed static SkData* PrivateNewWithCopy(const void* srcOrNull, size_t length); 17933a30503d76fdd989358cedd78445ba96bb809ddreed 180da30055b296faa5a100e474e0406ef4296c14241reed@google.com typedef SkRefCnt INHERITED; 1813a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com}; 1823a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com 1836f4cf2a19553b69d5bb10c5cd1005706a9fc6e22bungeman@google.com/** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */ 1846f4cf2a19553b69d5bb10c5cd1005706a9fc6e22bungeman@google.comtypedef SkAutoTUnref<SkData> SkAutoDataUnref; 1858a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com 1863a31ac1cf5d7d37da5a77ce18c43a62bf0781154reed@google.com#endif 187