text: // Copyright 2016 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #include "services/service_manager/service_overrides.h"
  
  #include "base/base_paths.h"
  #include "base/path_service.h"
  #include "base/strings/string_util.h"
  #include "base/strings/utf_string_conversions.h"
  
  namespace service_manager {
  
  namespace {
  
  const char kExecutablePathKey[] = "executable_path";
  const char kPackageNameKey[] = "package_name";
  
  }  // namespace
  
  ServiceOverrides::Entry::Entry() {}
  
  ServiceOverrides::Entry::~Entry() {}
  
  ServiceOverrides::ServiceOverrides(std::unique_ptr<base::Value> overrides) {
    const base::DictionaryValue* services;
    if (!overrides->GetAsDictionary(&services)) {
      LOG(ERROR) << "Expected top-level dictionary.";
      return;
    }
  
    base::DictionaryValue::Iterator service_iter(*services);
    for (; !service_iter.IsAtEnd(); service_iter.Advance()) {
      Entry& new_entry = entries_[service_iter.key()];
  
      const base::DictionaryValue* value;
      if (!service_iter.value().GetAsDictionary(&value)) {
        LOG(ERROR) << "Expected service entry to be a dictionary.";
        return;
      }
  
      std::string executable_path_value;
      if (value->GetString(kExecutablePathKey, &executable_path_value)) {
        base::FilePath exe_dir;
        CHECK(base::PathService::Get(base::DIR_EXE, &exe_dir));
  #if defined(OS_WIN)
        executable_path_value += ".exe";
        base::ReplaceFirstSubstringAfterOffset(
            &executable_path_value, 0, "@EXE_DIR",
            base::UTF16ToUTF8(exe_dir.value()));
        new_entry.executable_path =
            base::FilePath(base::UTF8ToUTF16(executable_path_value));
  #else
        base::ReplaceFirstSubstringAfterOffset(
            &executable_path_value, 0, "@EXE_DIR",
            exe_dir.value());
        new_entry.executable_path = base::FilePath(executable_path_value);
  #endif
      }
  
      value->GetString(kPackageNameKey, &new_entry.package_name);
    }
  }
  
  ServiceOverrides::~ServiceOverrides() {}
  
  bool ServiceOverrides::GetExecutablePathOverride(
      const std::string& service_name,
      base::FilePath* path) const {
    auto iter = entries_.find(service_name);
    if (iter == entries_.end() || iter->second.executable_path.empty())
      return false;
  
    *path = iter->second.executable_path;
    return true;
  }
  
  }  // namespace service_manager
  