/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkFlattenable.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "Test.h"
class IntFlattenable : public SkFlattenable {
public:
IntFlattenable(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
: fA(a)
, fB(b)
, fC(c)
, fD(d)
{}
void flatten(SkWriteBuffer& buffer) const override {
buffer.writeUInt(fA);
buffer.writeUInt(fB);
buffer.writeUInt(fC);
buffer.writeUInt(fD);
}
Factory getFactory() const override { return nullptr; }
Type getFlattenableType() const override { return SkFlattenable::kSkUnused_Type; }
uint32_t a() const { return fA; }
uint32_t b() const { return fB; }
uint32_t c() const { return fC; }
uint32_t d() const { return fD; }
const char* getTypeName() const override { return "IntFlattenable"; }
private:
uint32_t fA;
uint32_t fB;
uint32_t fC;
uint32_t fD;
};
static sk_sp<SkFlattenable> custom_create_proc(SkReadBuffer& buffer) {
uint32_t a = buffer.readUInt();
uint32_t b = buffer.readUInt();
uint32_t c = buffer.readUInt();
uint32_t d = buffer.readUInt();
return sk_sp<SkFlattenable>(new IntFlattenable(a + 1, b + 1, c + 1, d + 1));
}
DEF_TEST(UnflattenWithCustomFactory, r) {
// Create and flatten the test flattenable
SkBinaryWriteBuffer writeBuffer;
sk_sp<SkFlattenable> flattenable1(new IntFlattenable(1, 2, 3, 4));
writeBuffer.writeFlattenable(flattenable1.get());
sk_sp<SkFlattenable> flattenable2(new IntFlattenable(2, 3, 4, 5));
writeBuffer.writeFlattenable(flattenable2.get());
sk_sp<SkFlattenable> flattenable3(new IntFlattenable(3, 4, 5, 6));
writeBuffer.writeFlattenable(flattenable3.get());
// Copy the contents of the write buffer into a read buffer
sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
writeBuffer.writeToMemory(data->writable_data());
SkReadBuffer readBuffer(data->data(), data->size());
// Register a custom factory with the read buffer
readBuffer.setCustomFactory(SkString("IntFlattenable"), &custom_create_proc);
// Unflatten and verify the flattenables
sk_sp<IntFlattenable> out1((IntFlattenable*) readBuffer.readFlattenable(
SkFlattenable::kSkUnused_Type));
REPORTER_ASSERT(r, out1);
REPORTER_ASSERT(r, 2 == out1->a());
REPORTER_ASSERT(r, 3 == out1->b());
REPORTER_ASSERT(r, 4 == out1->c());
REPORTER_ASSERT(r, 5 == out1->d());
sk_sp<IntFlattenable> out2((IntFlattenable*) readBuffer.readFlattenable(
SkFlattenable::kSkUnused_Type));
REPORTER_ASSERT(r, out2);
REPORTER_ASSERT(r, 3 == out2->a());
REPORTER_ASSERT(r, 4 == out2->b());
REPORTER_ASSERT(r, 5 == out2->c());
REPORTER_ASSERT(r, 6 == out2->d());
sk_sp<IntFlattenable> out3((IntFlattenable*) readBuffer.readFlattenable(
SkFlattenable::kSkUnused_Type));
REPORTER_ASSERT(r, out3);
REPORTER_ASSERT(r, 4 == out3->a());
REPORTER_ASSERT(r, 5 == out3->b());
REPORTER_ASSERT(r, 6 == out3->c());
REPORTER_ASSERT(r, 7 == out3->d());
}