1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkData.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,162 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkData.h" 1.12 +#include "SkReadBuffer.h" 1.13 +#include "SkWriteBuffer.h" 1.14 +#include "SkOSFile.h" 1.15 +#include "SkOnce.h" 1.16 + 1.17 +SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) { 1.18 + fPtr = ptr; 1.19 + fSize = size; 1.20 + fReleaseProc = proc; 1.21 + fReleaseProcContext = context; 1.22 +} 1.23 + 1.24 +SkData::~SkData() { 1.25 + if (fReleaseProc) { 1.26 + fReleaseProc(fPtr, fSize, fReleaseProcContext); 1.27 + } 1.28 +} 1.29 + 1.30 +bool SkData::equals(const SkData* other) const { 1.31 + if (NULL == other) { 1.32 + return false; 1.33 + } 1.34 + 1.35 + return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize); 1.36 +} 1.37 + 1.38 +size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const { 1.39 + size_t available = fSize; 1.40 + if (offset >= available || 0 == length) { 1.41 + return 0; 1.42 + } 1.43 + available -= offset; 1.44 + if (length > available) { 1.45 + length = available; 1.46 + } 1.47 + SkASSERT(length > 0); 1.48 + 1.49 + memcpy(buffer, this->bytes() + offset, length); 1.50 + return length; 1.51 +} 1.52 + 1.53 +/////////////////////////////////////////////////////////////////////////////// 1.54 + 1.55 +static SkData* gEmptyDataRef = NULL; 1.56 +static void cleanup_gEmptyDataRef() { gEmptyDataRef->unref(); } 1.57 + 1.58 +void SkData::NewEmptyImpl(int) { 1.59 + gEmptyDataRef = new SkData(NULL, 0, NULL, NULL); 1.60 +} 1.61 + 1.62 +SkData* SkData::NewEmpty() { 1.63 + SK_DECLARE_STATIC_ONCE(once); 1.64 + SkOnce(&once, SkData::NewEmptyImpl, 0, cleanup_gEmptyDataRef); 1.65 + gEmptyDataRef->ref(); 1.66 + return gEmptyDataRef; 1.67 +} 1.68 + 1.69 +// assumes fPtr was allocated via sk_malloc 1.70 +static void sk_free_releaseproc(const void* ptr, size_t, void*) { 1.71 + sk_free((void*)ptr); 1.72 +} 1.73 + 1.74 +SkData* SkData::NewFromMalloc(const void* data, size_t length) { 1.75 + return new SkData(data, length, sk_free_releaseproc, NULL); 1.76 +} 1.77 + 1.78 +SkData* SkData::NewWithCopy(const void* data, size_t length) { 1.79 + if (0 == length) { 1.80 + return SkData::NewEmpty(); 1.81 + } 1.82 + 1.83 + void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc 1.84 + memcpy(copy, data, length); 1.85 + return new SkData(copy, length, sk_free_releaseproc, NULL); 1.86 +} 1.87 + 1.88 +SkData* SkData::NewWithProc(const void* data, size_t length, 1.89 + ReleaseProc proc, void* context) { 1.90 + return new SkData(data, length, proc, context); 1.91 +} 1.92 + 1.93 +// assumes fPtr was allocated with sk_fmmap 1.94 +static void sk_mmap_releaseproc(const void* addr, size_t length, void*) { 1.95 + sk_fmunmap(addr, length); 1.96 +} 1.97 + 1.98 +SkData* SkData::NewFromFILE(SkFILE* f) { 1.99 + size_t size; 1.100 + void* addr = sk_fmmap(f, &size); 1.101 + if (NULL == addr) { 1.102 + return NULL; 1.103 + } 1.104 + 1.105 + return SkData::NewWithProc(addr, size, sk_mmap_releaseproc, NULL); 1.106 +} 1.107 + 1.108 +SkData* SkData::NewFromFileName(const char path[]) { 1.109 + SkFILE* f = path ? sk_fopen(path, kRead_SkFILE_Flag) : NULL; 1.110 + if (NULL == f) { 1.111 + return NULL; 1.112 + } 1.113 + SkData* data = NewFromFILE(f); 1.114 + sk_fclose(f); 1.115 + return data; 1.116 +} 1.117 + 1.118 +SkData* SkData::NewFromFD(int fd) { 1.119 + size_t size; 1.120 + void* addr = sk_fdmmap(fd, &size); 1.121 + if (NULL == addr) { 1.122 + return NULL; 1.123 + } 1.124 + 1.125 + return SkData::NewWithProc(addr, size, sk_mmap_releaseproc, NULL); 1.126 +} 1.127 + 1.128 +// assumes context is a SkData 1.129 +static void sk_dataref_releaseproc(const void*, size_t, void* context) { 1.130 + SkData* src = reinterpret_cast<SkData*>(context); 1.131 + src->unref(); 1.132 +} 1.133 + 1.134 +SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) { 1.135 + /* 1.136 + We could, if we wanted/need to, just make a deep copy of src's data, 1.137 + rather than referencing it. This would duplicate the storage (of the 1.138 + subset amount) but would possibly allow src to go out of scope sooner. 1.139 + */ 1.140 + 1.141 + size_t available = src->size(); 1.142 + if (offset >= available || 0 == length) { 1.143 + return SkData::NewEmpty(); 1.144 + } 1.145 + available -= offset; 1.146 + if (length > available) { 1.147 + length = available; 1.148 + } 1.149 + SkASSERT(length > 0); 1.150 + 1.151 + src->ref(); // this will be balanced in sk_dataref_releaseproc 1.152 + return new SkData(src->bytes() + offset, length, sk_dataref_releaseproc, 1.153 + const_cast<SkData*>(src)); 1.154 +} 1.155 + 1.156 +SkData* SkData::NewWithCString(const char cstr[]) { 1.157 + size_t size; 1.158 + if (NULL == cstr) { 1.159 + cstr = ""; 1.160 + size = 1; 1.161 + } else { 1.162 + size = strlen(cstr) + 1; 1.163 + } 1.164 + return NewWithCopy(cstr, size); 1.165 +}