Пример #1
0
        /// <summary>
        /// Returns max possible length of given <paramref name="fragment"/>, when <paramref name="escaping"/>
        /// is used.  Instead of rendering paths and computing actual path lengths, it uses
        /// <paramref name="maxPathLength"/> as the upper bound for path lengths.
        /// </summary>
        public int GetMaxLength(PipFragment fragment, PipDataFragmentEscaping escaping, int maxPathLength)
        {
            Contract.Requires(maxPathLength > 0);

            // StringLiteral
            if (fragment.FragmentType == PipFragmentType.StringLiteral)
            {
                return(GetLength(fragment.GetStringIdValue(), escaping));
            }

            // AbsolutePath
            if (fragment.FragmentType == PipFragmentType.AbsolutePath)
            {
                var numExtraCharactersForEscaping =
                    escaping == PipDataFragmentEscaping.CRuntimeArgumentRules ? 2 : // path gets surrounded by '"' and '"'
                    0;
                return(maxPathLength + numExtraCharactersForEscaping);
            }

            // VsoHash
            if (fragment.FragmentType == PipFragmentType.VsoHash)
            {
                return(MaxVsoHashStringLength); // vso hash should never need any escaping
            }

            if (fragment.FragmentType == PipFragmentType.IpcMoniker)
            {
                return(MaxIpcMonikerLength);
            }

            Contract.Assert(false, I($"Unhandled fragment ('{fragment.FragmentType}') type and/or fragmentEscaping ('{escaping}')"));
            return(0);
        }
Пример #2
0
        /// <summary>
        /// Renders valid scalar pip data entries, i.e., those that do not correspond to <see cref="PipFragmentType.NestedFragment"/>.
        /// </summary>
        /// <remarks>
        /// If a <see cref="HashLookup"/> function is not provided, entries corresponding to <see cref="PipFragmentType.VsoHash"/>
        /// are rendered as a sequence of zeros (<see cref="s_unknownLengthFileInfoString"/>); otherwise, they are rendered as
        /// the return value of the <see cref="FileContentInfo.Render"/> method.
        /// </remarks>
        public string Render(PipFragment fragment)
        {
            Contract.Requires(fragment.FragmentType != PipFragmentType.Invalid);
            Contract.Requires(fragment.FragmentType != PipFragmentType.NestedFragment);

            switch (fragment.FragmentType)
            {
            case PipFragmentType.StringLiteral:
                return(Render(fragment.GetStringIdValue()));

            case PipFragmentType.AbsolutePath:
                return(PathExpander(fragment.GetPathValue()));

            case PipFragmentType.VsoHash:
                return(HashLookup != null
                        ? HashLookup(fragment.GetFileValue()).Render()
                        : s_unknownLengthFileInfoString);

            case PipFragmentType.FileId:
            {
                var file = fragment.GetFileValue();
                return(file.Path.RawValue.ToString() + ":" + file.RewriteCount.ToString());
            }

            case PipFragmentType.DirectoryId:
                var directory = fragment.GetDirectoryValue();
                return(DirectoryId.ToString(directory));

            case PipFragmentType.IpcMoniker:
                string monikerId = fragment.GetIpcMonikerValue().ToString(StringTable);
                var    result    = IpcMonikerRenderer != null
                        ? IpcMonikerRenderer(monikerId)
                        : monikerId;

                if (result.Length > MaxIpcMonikerLength)
                {
                    throw new BuildXLException(I($"Moniker with id '{monikerId}' was rendered to string '{result}' which is longer than the max length for moniker fragments ({MaxIpcMonikerLength})"));
                }

                return(result);

            default:
                Contract.Assert(false, "Can't render fragment type " + fragment.FragmentType);
                return(null);
            }
        }
Пример #3
0
        /// <summary>
        /// Renders valid scalar pip data entries, i.e., those that do not correspond to <see cref="PipFragmentType.NestedFragment"/>.
        /// </summary>
        public string Render(PipFragment fragment)
        {
            Contract.Requires(fragment.FragmentType != PipFragmentType.Invalid);
            Contract.Requires(fragment.FragmentType != PipFragmentType.NestedFragment);

            switch (fragment.FragmentType)
            {
            case PipFragmentType.StringLiteral:
                return(Render(fragment.GetStringIdValue()));

            case PipFragmentType.AbsolutePath:
                return(PathExpander(fragment.GetPathValue()));

            default:
                Contract.Assert(false, "Can't render fragment type " + fragment.FragmentType);
                return(null);
            }
        }