File: System\Resources\ResXFileRef.cs
Web Access
Project: src\src\System.Windows.Forms\src\System.Windows.Forms.csproj (System.Windows.Forms)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.ComponentModel;
using System.Globalization;
using System.Text;
 
namespace System.Resources;
 
/// <summary>
///  ResX File Reference class. This allows the developer to represent
///  a link to an external resource. When the resource manager asks
///  for the value of the resource item, the external resource is loaded.
/// </summary>
[TypeConverter(typeof(Converter))]
public partial class ResXFileRef
{
    /// <summary>
    ///  Creates a new ResXFileRef that points to the specified file.
    ///  The type refered to by typeName must support a constructor
    ///  that accepts a System.IO.Stream as a parameter.
    /// </summary>
    public ResXFileRef(string fileName, string typeName)
    {
        FileName = fileName.OrThrowIfNull();
        TypeName = typeName.OrThrowIfNull();
    }
 
    /// <summary>
    ///  Creates a new ResXFileRef that points to the specified file.
    ///  The type refered to by typeName must support a constructor
    ///  that accepts a System.IO.Stream as a parameter.
    /// </summary>
    public ResXFileRef(string fileName, string typeName, Encoding textFileEncoding) : this(fileName, typeName)
    {
        TextFileEncoding = textFileEncoding;
    }
 
    internal ResXFileRef Clone()
        => TextFileEncoding is null ? new(FileName, TypeName) : new(FileName, TypeName, TextFileEncoding);
 
    public string FileName { get; private set; }
 
    public string TypeName { get; }
 
    public Encoding? TextFileEncoding { get; }
 
    /// <summary>
    ///  path1+result = path2
    ///  A string which is the relative path difference between path1 and
    ///  path2 such that if path1 and the calculated difference are used
    ///  as arguments to Combine(), path2 is returned
    /// </summary>
    private static string PathDifference(string path1, string path2, bool compareCase)
    {
        int i;
        int si = -1;
 
        for (i = 0; (i < path1.Length) && (i < path2.Length); ++i)
        {
            if ((path1[i] != path2[i])
                && (compareCase || (char.ToLower(path1[i], CultureInfo.InvariantCulture) != char.ToLower(path2[i], CultureInfo.InvariantCulture))))
            {
                break;
            }
 
            if (path1[i] == Path.DirectorySeparatorChar)
            {
                si = i;
            }
        }
 
        if (i == 0)
        {
            return path2;
        }
 
        if ((i == path1.Length) && (i == path2.Length))
        {
            return string.Empty;
        }
 
        StringBuilder relPath = new();
 
        for (; i < path1.Length; ++i)
        {
            if (path1[i] == Path.DirectorySeparatorChar)
            {
                relPath.Append($"..{Path.DirectorySeparatorChar}");
            }
        }
 
        relPath.Append(path2.AsSpan(si + 1));
 
        return relPath.ToString();
    }
 
    internal void MakeFilePathRelative(string basePath)
    {
        if (string.IsNullOrEmpty(basePath))
        {
            return;
        }
 
        FileName = PathDifference(basePath, FileName, false);
    }
 
    public override string ToString()
    {
        string result;
 
        if (FileName.Contains(';') || FileName.Contains('\"'))
        {
            result = $"\"{FileName}\";{TypeName}";
        }
        else
        {
            result = $"{FileName};{TypeName}";
        }
 
        if (TextFileEncoding is not null)
        {
            result += $";{TextFileEncoding.WebName}";
        }
 
        return result;
    }
}