140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkRefDict.h" 1140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkString.h" 1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstruct SkRefDict::Impl { 1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Impl* fNext; 1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkString fName; 1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkRefCnt* fData; 1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 1840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRefDict::SkRefDict() : fImpl(NULL) {} 2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRefDict::~SkRefDict() { 2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->removeAll(); 2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRefCnt* SkRefDict::find(const char name[]) const { 2640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == name) { 2740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 2840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Impl* rec = fImpl; 3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (rec) { 3240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (rec->fName.equals(name)) { 3340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return rec->fData; 3440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec = rec->fNext; 3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 3740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 3940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRefDict::set(const char name[], SkRefCnt* data) { 4140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == name) { 4240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return; 4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 4440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Impl* rec = fImpl; 4640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Impl* prev = NULL; 4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (rec) { 4840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (rec->fName.equals(name)) { 4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (data) { 5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // replace 5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger data->ref(); 5240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fData->unref(); 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fData = data; 5440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 5540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // remove 5640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fData->unref(); 5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (prev) { 5840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger prev->fNext = rec->fNext; 5940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 6040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fImpl = rec->fNext; 6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return; 6440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger prev = rec; 6640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec = rec->fNext; 6740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // if get here, name was not found, so add it 7040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger data->ref(); 7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec = new Impl; 7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fName.set(name); 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fData = data; 7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // prepend to the head of our list 7540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fNext = fImpl; 7640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fImpl = rec; 7740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRefDict::removeAll() { 8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Impl* rec = fImpl; 8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (rec) { 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Impl* next = rec->fNext; 8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fData->unref(); 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger delete rec; 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec = next; 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fImpl = NULL; 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 90