text: 
  /*
   * 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;
  }
  