|  | /* | 
|  | * 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 "SkRefDict.h" | 
|  | #include "SkString.h" | 
|  |  | 
|  | struct SkRefDict::Impl { | 
|  | Impl*       fNext; | 
|  | SkString    fName; | 
|  | SkRefCnt*   fData; | 
|  | }; | 
|  |  | 
|  | SkRefDict::SkRefDict() : fImpl(nullptr) {} | 
|  |  | 
|  | SkRefDict::~SkRefDict() { | 
|  | this->removeAll(); | 
|  | } | 
|  |  | 
|  | SkRefCnt* SkRefDict::find(const char name[]) const { | 
|  | if (nullptr == name) { | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | Impl* rec = fImpl; | 
|  | while (rec) { | 
|  | if (rec->fName.equals(name)) { | 
|  | return rec->fData; | 
|  | } | 
|  | rec = rec->fNext; | 
|  | } | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | void SkRefDict::set(const char name[], SkRefCnt* data) { | 
|  | if (nullptr == name) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | Impl* rec = fImpl; | 
|  | Impl* prev = nullptr; | 
|  | while (rec) { | 
|  | if (rec->fName.equals(name)) { | 
|  | if (data) { | 
|  | // replace | 
|  | data->ref(); | 
|  | rec->fData->unref(); | 
|  | rec->fData = data; | 
|  | } else { | 
|  | // remove | 
|  | rec->fData->unref(); | 
|  | if (prev) { | 
|  | prev->fNext = rec->fNext; | 
|  | } else { | 
|  | fImpl = rec->fNext; | 
|  | } | 
|  | delete rec; | 
|  | } | 
|  | return; | 
|  | } | 
|  | prev = rec; | 
|  | rec = rec->fNext; | 
|  | } | 
|  |  | 
|  | // if get here, name was not found, so add it | 
|  | data->ref(); | 
|  | rec = new Impl; | 
|  | rec->fName.set(name); | 
|  | rec->fData = data; | 
|  | // prepend to the head of our list | 
|  | rec->fNext = fImpl; | 
|  | fImpl = rec; | 
|  | } | 
|  |  | 
|  | void SkRefDict::removeAll() { | 
|  | Impl* rec = fImpl; | 
|  | while (rec) { | 
|  | Impl* next = rec->fNext; | 
|  | rec->fData->unref(); | 
|  | delete rec; | 
|  | rec = next; | 
|  | } | 
|  | fImpl = nullptr; | 
|  | } |