dotnet-installer/src/corehost/cli/servicing_index.cpp
Senthil f615f74a39 Shared FX and Portable Support for Unified Host
- Add Casablanca CPP Rest SDK to corehost
    - Correct understanding of portable runtimeTargets section
    - Fix minor issues and automation for RID
    - CLI Build Integration
    - Add API to consume deps files
    - Unix doesn't like major as a variable name
    - Define NOMINMAX for Windows.h
    - Support APP_CONTEXT_DEPS_FILES
    - mscorlib.ni can come from native
    - Append Dotnet.dll to sdk path
    - Muxer vs standalone distinction based on own name.dll
2016-03-15 01:03:52 -07:00

144 lines
4.1 KiB
C++

// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "trace.h"
#include "servicing_index.h"
static const pal::char_t* DOTNET_SERVICING_INDEX_TXT = _X("dotnet_servicing_index.txt");
servicing_index_t::servicing_index_t(const pal::string_t& svc_dir)
{
m_patch_root = svc_dir;
if (!m_patch_root.empty())
{
m_index_file.assign(m_patch_root);
append_path(&m_index_file, DOTNET_SERVICING_INDEX_TXT);
}
m_parsed = m_index_file.empty() || !pal::file_exists(m_index_file);
}
bool servicing_index_t::find_redirection(
const pal::string_t& package_name,
const pal::string_t& package_version,
const pal::string_t& package_relative,
pal::string_t* redirection)
{
ensure_redirections();
redirection->clear();
if (m_redirections.empty())
{
return false;
}
pal::stringstream_t stream;
stream << package_name << _X("|") << package_version << _X("|") << package_relative;
auto iter = m_redirections.find(stream.str());
if (iter != m_redirections.end())
{
pal::string_t ni_root = m_patch_root;
append_path(&ni_root, get_arch());
// First prefer the architecture specific NI image.
pal::string_t paths[2] = { ni_root, m_patch_root };
for (pal::string_t& full_path : paths)
{
append_path(&full_path, iter->second.c_str());
if (pal::file_exists(full_path))
{
*redirection = full_path;
if (trace::is_enabled())
{
pal::string_t stream_str = stream.str();
trace::verbose(_X("Servicing %s with %s"), stream_str.c_str(), redirection->c_str());
}
return true;
}
trace::verbose(_X("Serviced file %s doesn't exist"), full_path.c_str());
}
}
if (trace::is_enabled())
{
auto stream_str = stream.str();
trace::verbose(_X("Entry %s not serviced or file doesn't exist"), stream_str.c_str());
}
return false;
}
void servicing_index_t::ensure_redirections()
{
if (m_parsed)
{
return;
}
pal::ifstream_t fstream(m_index_file);
if (!fstream.good())
{
return;
}
pal::stringstream_t sstream;
std::string line;
while (std::getline(fstream, line))
{
pal::string_t str;
pal::to_palstring(line.c_str(), &str);
// Can interpret line as "package"?
pal::string_t prefix = _X("package|");
if (str.find(prefix) != 0)
{
continue;
}
pal::string_t name, version, relative;
pal::string_t* tokens[] = { &name, &version, &relative };
pal::string_t delim[] = { pal::string_t(_X("|")), pal::string_t(_X("|")), pal::string_t(_X("=")) };
bool bad_line = false;
size_t from = prefix.length();
for (size_t cur = 0; cur < (sizeof(delim) / sizeof(delim[0])); ++cur)
{
size_t pos = str.find(delim[cur], from);
if (pos == pal::string_t::npos)
{
bad_line = true;
break;
}
tokens[cur]->assign(str.substr(from, pos - from));
from = pos + 1;
}
if (bad_line)
{
trace::error(_X("Invalid line in servicing index. Skipping..."));
continue;
}
// Save redirection for this package.
sstream.str(_X(""));
sstream << name << _X("|") << version << _X("|") << relative;
if (trace::is_enabled())
{
auto stream_str = sstream.str();
trace::verbose(_X("Adding servicing entry %s => %s"), stream_str.c_str(), str.substr(from).c_str());
}
// Store just the filename.
pal::string_t redir = str.substr(from);
if (_X('/') != DIR_SEPARATOR)
{
replace_char(&redir, _X('/'), DIR_SEPARATOR);
}
m_redirections.emplace(sstream.str(), redir);
}
m_parsed = true;
}