Home | History | Annotate | Download | only in core
      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