/// <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); }
/// <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); } }
/// <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); } }