test data.equals with empty

Change-Id: Ib79fb2ba099a0d094ab16b1d7307c03e64b1fd1f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271240
Commit-Queue: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
Mike Reed 2020-02-17 11:54:25 -05:00
parent c65cd5c8db
commit 706f6b4069
4 changed files with 46 additions and 16 deletions

View File

@ -51,7 +51,7 @@ public:
// only assert we're unique if we're not empty
SkASSERT(this->unique());
}
return fPtr;
return const_cast<void*>(fPtr);
}
/**
@ -161,7 +161,7 @@ private:
friend class SkNVRefCnt<SkData>;
ReleaseProc fReleaseProc;
void* fReleaseProcContext;
void* fPtr;
const void* fPtr;
size_t fSize;
SkData(const void* ptr, size_t size, ReleaseProc, void* context);

View File

@ -133,4 +133,13 @@ static inline void* sk_careful_memmove(void* dst, const void* src, size_t len) {
return dst;
}
static inline int sk_careful_memcmp(const void* a, const void* b, size_t len) {
// When we pass >0 len we had better already be passing valid pointers.
// So we just need to skip calling memcmp when len == 0.
if (len == 0) {
return 0; // we treat zero-length buffers as "equal"
}
return memcmp(a, b, len);
}
#endif // SkMalloc_DEFINED

View File

@ -13,22 +13,22 @@
#include "src/core/SkWriteBuffer.h"
#include <new>
SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
fPtr = const_cast<void*>(ptr);
fSize = size;
fReleaseProc = proc;
fReleaseProcContext = context;
}
SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context)
: fReleaseProc(proc)
, fReleaseProcContext(context)
, fPtr(ptr)
, fSize(size)
{}
/** This constructor means we are inline with our fPtr's contents.
* Thus we set fPtr to point right after this.
*/
SkData::SkData(size_t size) {
fPtr = (char*)(this + 1); // contents are immediately after this
fSize = size;
fReleaseProc = nullptr;
fReleaseProcContext = nullptr;
}
SkData::SkData(size_t size)
: fReleaseProc(nullptr)
, fReleaseProcContext(nullptr)
, fPtr((const char*)(this + 1))
, fSize(size)
{}
SkData::~SkData() {
if (fReleaseProc) {
@ -37,11 +37,13 @@ SkData::~SkData() {
}
bool SkData::equals(const SkData* other) const {
if (this == other) {
return true;
}
if (nullptr == other) {
return false;
}
return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize);
return fSize == other->fSize && !sk_careful_memcmp(fPtr, other->fPtr, fSize);
}
size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {

View File

@ -208,6 +208,25 @@ DEF_TEST(Data, reporter) {
test_files(reporter);
}
DEF_TEST(Data_empty, reporter) {
sk_sp<SkData> array[] = {
SkData::MakeEmpty(),
SkData::MakeUninitialized(0),
SkData::MakeFromMalloc(sk_malloc_throw(0), 0),
SkData::MakeWithCopy("", 0),
SkData::MakeWithProc(nullptr, 0, [](const void*, void*){}, nullptr),
SkData::MakeWithoutCopy(nullptr, 0),
};
constexpr int N = SK_ARRAY_COUNT(array);
for (int i = 0; i < N; ++i) {
REPORTER_ASSERT(reporter, array[i]->size() == 0);
for (int j = 0; j < N; ++j) {
REPORTER_ASSERT(reporter, array[i]->equals(array[j].get()));
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
const char gABC[] = "abcdefghijklmnopqrstuvwxyz";