1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #include "SkRefDict.h"
10 #include "SkString.h"
11 
12 struct SkRefDict::Impl {
13     Impl*       fNext;
14     SkString    fName;
15     SkRefCnt*   fData;
16 };
17 
18 SkRefDict::SkRefDict() : fImpl(nullptr) {}
19 
20 SkRefDict::~SkRefDict() {
21     this->removeAll();
22 }
23 
24 SkRefCnt* SkRefDict::find(const char name[]) const {
25     if (nullptr == name) {
26         return nullptr;
27     }
28 
29     Impl* rec = fImpl;
30     while (rec) {
31         if (rec->fName.equals(name)) {
32             return rec->fData;
33         }
34         rec = rec->fNext;
35     }
36     return nullptr;
37 }
38 
39 void SkRefDict::set(const char name[], SkRefCnt* data) {
40     if (nullptr == name) {
41         return;
42     }
43 
44     Impl* rec = fImpl;
45     Impl* prev = nullptr;
46     while (rec) {
47         if (rec->fName.equals(name)) {
48             if (data) {
49                 // replace
50                 data->ref();
51                 rec->fData->unref();
52                 rec->fData = data;
53             } else {
54                 // remove
55                 rec->fData->unref();
56                 if (prev) {
57                     prev->fNext = rec->fNext;
58                 } else {
59                     fImpl = rec->fNext;
60                 }
61                 delete rec;
62             }
63             return;
64         }
65         prev = rec;
66         rec = rec->fNext;
67     }
68 
69     // if get here, name was not found, so add it
70     data->ref();
71     rec = new Impl;
72     rec->fName.set(name);
73     rec->fData = data;
74     // prepend to the head of our list
75     rec->fNext = fImpl;
76     fImpl = rec;
77 }
78 
79 void SkRefDict::removeAll() {
80     Impl* rec = fImpl;
81     while (rec) {
82         Impl* next = rec->fNext;
83         rec->fData->unref();
84         delete rec;
85         rec = next;
86     }
87     fImpl = nullptr;
88 }
89