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