| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "include/core/SkFlattenable.h" |
| #include "src/core/SkPtrRecorder.h" |
| #include "src/core/SkReadBuffer.h" |
| |
| #include <algorithm> |
| |
| SkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {} |
| |
| uint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) { |
| uint32_t index = fFactorySet.find(factory); |
| if (index > 0) { |
| return index; |
| } |
| const char* name = SkFlattenable::FactoryToName(factory); |
| if (nullptr == name) { |
| return 0; |
| } |
| *fNames.append() = name; |
| return fFactorySet.add(factory); |
| } |
| |
| const char* SkNamedFactorySet::getNextAddedFactoryName() { |
| if (fNextAddedFactory < fNames.count()) { |
| return fNames[fNextAddedFactory++]; |
| } |
| return nullptr; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| SkRefCntSet::~SkRefCntSet() { |
| // call this now, while our decPtr() is sill in scope |
| this->reset(); |
| } |
| |
| void SkRefCntSet::incPtr(void* ptr) { |
| ((SkRefCnt*)ptr)->ref(); |
| } |
| |
| void SkRefCntSet::decPtr(void* ptr) { |
| ((SkRefCnt*)ptr)->unref(); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| namespace { |
| |
| struct Entry { |
| const char* fName; |
| SkFlattenable::Factory fFactory; |
| }; |
| |
| struct EntryComparator { |
| bool operator()(const Entry& a, const Entry& b) const { |
| return strcmp(a.fName, b.fName) < 0; |
| } |
| bool operator()(const Entry& a, const char* b) const { |
| return strcmp(a.fName, b) < 0; |
| } |
| bool operator()(const char* a, const Entry& b) const { |
| return strcmp(a, b.fName) < 0; |
| } |
| }; |
| |
| int gCount = 0; |
| Entry gEntries[128]; |
| |
| } // namespace |
| |
| void SkFlattenable::Finalize() { |
| std::sort(gEntries, gEntries + gCount, EntryComparator()); |
| } |
| |
| void SkFlattenable::Register(const char name[], Factory factory) { |
| SkASSERT(name); |
| SkASSERT(factory); |
| SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries)); |
| |
| gEntries[gCount].fName = name; |
| gEntries[gCount].fFactory = factory; |
| gCount += 1; |
| } |
| |
| SkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) { |
| RegisterFlattenablesIfNeeded(); |
| |
| SkASSERT(std::is_sorted(gEntries, gEntries + gCount, EntryComparator())); |
| auto pair = std::equal_range(gEntries, gEntries + gCount, name, EntryComparator()); |
| if (pair.first == pair.second) { |
| return nullptr; |
| } |
| return pair.first->fFactory; |
| } |
| |
| const char* SkFlattenable::FactoryToName(Factory fact) { |
| RegisterFlattenablesIfNeeded(); |
| |
| const Entry* entries = gEntries; |
| for (int i = gCount - 1; i >= 0; --i) { |
| if (entries[i].fFactory == fact) { |
| return entries[i].fName; |
| } |
| } |
| return nullptr; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| sk_sp<SkData> SkFlattenable::serialize(const SkSerialProcs* procs) const { |
| SkBinaryWriteBuffer writer; |
| if (procs) { |
| writer.setSerialProcs(*procs); |
| } |
| writer.writeFlattenable(this); |
| size_t size = writer.bytesWritten(); |
| auto data = SkData::MakeUninitialized(size); |
| writer.writeToMemory(data->writable_data()); |
| return data; |
| } |
| |
| size_t SkFlattenable::serialize(void* memory, size_t memory_size, |
| const SkSerialProcs* procs) const { |
| SkBinaryWriteBuffer writer(memory, memory_size); |
| if (procs) { |
| writer.setSerialProcs(*procs); |
| } |
| writer.writeFlattenable(this); |
| return writer.usingInitialStorage() ? writer.bytesWritten() : 0u; |
| } |
| |
| sk_sp<SkFlattenable> SkFlattenable::Deserialize(SkFlattenable::Type type, const void* data, |
| size_t size, const SkDeserialProcs* procs) { |
| SkReadBuffer buffer(data, size); |
| if (procs) { |
| buffer.setDeserialProcs(*procs); |
| } |
| return sk_sp<SkFlattenable>(buffer.readFlattenable(type)); |
| } |