1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkFlattenable.h"
9cb93a386Sopenharmony_ci#include "src/core/SkPtrRecorder.h"
10cb93a386Sopenharmony_ci#include "src/core/SkReadBuffer.h"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#include <algorithm>
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ciSkNamedFactorySet::SkNamedFactorySet() : fNextAddedFactory(0) {}
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ciuint32_t SkNamedFactorySet::find(SkFlattenable::Factory factory) {
17cb93a386Sopenharmony_ci    uint32_t index = fFactorySet.find(factory);
18cb93a386Sopenharmony_ci    if (index > 0) {
19cb93a386Sopenharmony_ci        return index;
20cb93a386Sopenharmony_ci    }
21cb93a386Sopenharmony_ci    const char* name = SkFlattenable::FactoryToName(factory);
22cb93a386Sopenharmony_ci    if (nullptr == name) {
23cb93a386Sopenharmony_ci        return 0;
24cb93a386Sopenharmony_ci    }
25cb93a386Sopenharmony_ci    *fNames.append() = name;
26cb93a386Sopenharmony_ci    return fFactorySet.add(factory);
27cb93a386Sopenharmony_ci}
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ciconst char* SkNamedFactorySet::getNextAddedFactoryName() {
30cb93a386Sopenharmony_ci    if (fNextAddedFactory < fNames.count()) {
31cb93a386Sopenharmony_ci        return fNames[fNextAddedFactory++];
32cb93a386Sopenharmony_ci    }
33cb93a386Sopenharmony_ci    return nullptr;
34cb93a386Sopenharmony_ci}
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ciSkRefCntSet::~SkRefCntSet() {
39cb93a386Sopenharmony_ci    // call this now, while our decPtr() is sill in scope
40cb93a386Sopenharmony_ci    this->reset();
41cb93a386Sopenharmony_ci}
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_civoid SkRefCntSet::incPtr(void* ptr) {
44cb93a386Sopenharmony_ci    ((SkRefCnt*)ptr)->ref();
45cb93a386Sopenharmony_ci}
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_civoid SkRefCntSet::decPtr(void* ptr) {
48cb93a386Sopenharmony_ci    ((SkRefCnt*)ptr)->unref();
49cb93a386Sopenharmony_ci}
50cb93a386Sopenharmony_ci
51cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_cinamespace {
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_cistruct Entry {
56cb93a386Sopenharmony_ci    const char*             fName;
57cb93a386Sopenharmony_ci    SkFlattenable::Factory  fFactory;
58cb93a386Sopenharmony_ci};
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_cistruct EntryComparator {
61cb93a386Sopenharmony_ci    bool operator()(const Entry& a, const Entry& b) const {
62cb93a386Sopenharmony_ci        return strcmp(a.fName, b.fName) < 0;
63cb93a386Sopenharmony_ci    }
64cb93a386Sopenharmony_ci    bool operator()(const Entry& a, const char* b) const {
65cb93a386Sopenharmony_ci        return strcmp(a.fName, b) < 0;
66cb93a386Sopenharmony_ci    }
67cb93a386Sopenharmony_ci    bool operator()(const char* a, const Entry& b) const {
68cb93a386Sopenharmony_ci        return strcmp(a, b.fName) < 0;
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci};
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ciint gCount = 0;
73cb93a386Sopenharmony_ciEntry gEntries[128];
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci}  // namespace
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_civoid SkFlattenable::Finalize() {
78cb93a386Sopenharmony_ci    std::sort(gEntries, gEntries + gCount, EntryComparator());
79cb93a386Sopenharmony_ci}
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_civoid SkFlattenable::Register(const char name[], Factory factory) {
82cb93a386Sopenharmony_ci    SkASSERT(name);
83cb93a386Sopenharmony_ci    SkASSERT(factory);
84cb93a386Sopenharmony_ci    SkASSERT(gCount < (int)SK_ARRAY_COUNT(gEntries));
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_ci    gEntries[gCount].fName = name;
87cb93a386Sopenharmony_ci    gEntries[gCount].fFactory = factory;
88cb93a386Sopenharmony_ci    gCount += 1;
89cb93a386Sopenharmony_ci}
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ciSkFlattenable::Factory SkFlattenable::NameToFactory(const char name[]) {
92cb93a386Sopenharmony_ci    RegisterFlattenablesIfNeeded();
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci    SkASSERT(std::is_sorted(gEntries, gEntries + gCount, EntryComparator()));
95cb93a386Sopenharmony_ci    auto pair = std::equal_range(gEntries, gEntries + gCount, name, EntryComparator());
96cb93a386Sopenharmony_ci    if (pair.first == pair.second) {
97cb93a386Sopenharmony_ci        return nullptr;
98cb93a386Sopenharmony_ci    }
99cb93a386Sopenharmony_ci    return pair.first->fFactory;
100cb93a386Sopenharmony_ci}
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ciconst char* SkFlattenable::FactoryToName(Factory fact) {
103cb93a386Sopenharmony_ci    RegisterFlattenablesIfNeeded();
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ci    const Entry* entries = gEntries;
106cb93a386Sopenharmony_ci    for (int i = gCount - 1; i >= 0; --i) {
107cb93a386Sopenharmony_ci        if (entries[i].fFactory == fact) {
108cb93a386Sopenharmony_ci            return entries[i].fName;
109cb93a386Sopenharmony_ci        }
110cb93a386Sopenharmony_ci    }
111cb93a386Sopenharmony_ci    return nullptr;
112cb93a386Sopenharmony_ci}
113cb93a386Sopenharmony_ci
114cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////////////////////////
115cb93a386Sopenharmony_ci
116cb93a386Sopenharmony_cisk_sp<SkData> SkFlattenable::serialize(const SkSerialProcs* procs) const {
117cb93a386Sopenharmony_ci    SkBinaryWriteBuffer writer;
118cb93a386Sopenharmony_ci    if (procs) {
119cb93a386Sopenharmony_ci        writer.setSerialProcs(*procs);
120cb93a386Sopenharmony_ci    }
121cb93a386Sopenharmony_ci    writer.writeFlattenable(this);
122cb93a386Sopenharmony_ci    size_t size = writer.bytesWritten();
123cb93a386Sopenharmony_ci    auto data = SkData::MakeUninitialized(size);
124cb93a386Sopenharmony_ci    writer.writeToMemory(data->writable_data());
125cb93a386Sopenharmony_ci    return data;
126cb93a386Sopenharmony_ci}
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_cisize_t SkFlattenable::serialize(void* memory, size_t memory_size,
129cb93a386Sopenharmony_ci                                const SkSerialProcs* procs) const {
130cb93a386Sopenharmony_ci  SkBinaryWriteBuffer writer(memory, memory_size);
131cb93a386Sopenharmony_ci  if (procs) {
132cb93a386Sopenharmony_ci      writer.setSerialProcs(*procs);
133cb93a386Sopenharmony_ci  }
134cb93a386Sopenharmony_ci  writer.writeFlattenable(this);
135cb93a386Sopenharmony_ci  return writer.usingInitialStorage() ? writer.bytesWritten() : 0u;
136cb93a386Sopenharmony_ci}
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_cisk_sp<SkFlattenable> SkFlattenable::Deserialize(SkFlattenable::Type type, const void* data,
139cb93a386Sopenharmony_ci                                                size_t size, const SkDeserialProcs* procs) {
140cb93a386Sopenharmony_ci    SkReadBuffer buffer(data, size);
141cb93a386Sopenharmony_ci    if (procs) {
142cb93a386Sopenharmony_ci        buffer.setDeserialProcs(*procs);
143cb93a386Sopenharmony_ci    }
144cb93a386Sopenharmony_ci    return sk_sp<SkFlattenable>(buffer.readFlattenable(type));
145cb93a386Sopenharmony_ci}
146