/// <summary> /// Execute the task. /// </summary> public override bool Execute() { if (ItemsToHash != null && ItemsToHash.Length > 0) { using (var sha1 = SHA1.Create()) { var concatenatedItemStringSize = ComputeStringSize(ItemsToHash); var hashStringSize = sha1.HashSize; using (var stringBuilder = new ReuseableStringBuilder(Math.Max(concatenatedItemStringSize, hashStringSize))) { foreach (var item in ItemsToHash) { stringBuilder.Append(item.ItemSpec); stringBuilder.Append(ItemSeparatorCharacter); } var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(stringBuilder.ToString())); stringBuilder.Clear(); foreach (var b in hash) { stringBuilder.Append(b.ToString("x2")); } HashResult = stringBuilder.ToString(); } } } return(true); }
/// <summary> /// Gets a text serialized value of a parameter for logging. /// </summary> internal static string GetParameterText(string prefix, string parameterName, IList parameterValue) { if (parameterValue == null || parameterValue.Count == 0) { return(parameterName); } using (var sb = new ReuseableStringBuilder()) { sb.Append(prefix); bool firstEntryIsTaskItemWithSomeCustomMetadata = false; var firstItem = parameterValue[0] as ITaskItem; if (firstItem != null) { if (firstItem.CloneCustomMetadata().Count > 0) { firstEntryIsTaskItemWithSomeCustomMetadata = true; } } // If it's just one entry in the list, and it's not a task item with metadata, keep it on one line like a scalar bool specialTreatmentForSingle = (parameterValue.Count == 1 && !firstEntryIsTaskItemWithSomeCustomMetadata); if (!specialTreatmentForSingle) { sb.Append("\n "); } sb.Append(parameterName + "="); if (!specialTreatmentForSingle) { sb.Append("\n"); } for (int i = 0; i < parameterValue.Count; i++) { if (parameterValue[i] == null) { continue; } if (!specialTreatmentForSingle) { sb.Append(" "); } sb.Append(GetStringFromParameterValue(parameterValue[i])); if (!specialTreatmentForSingle && i < parameterValue.Count - 1) { sb.Append("\n"); } } return(sb.ToString()); } }
/// <summary> /// Given an object wrapping a scalar value that will be set on a task, /// returns a suitable string to log its value, with a trailing newline. /// First line is already indented. /// Indent of any subsequent line should be 12 spaces. /// </summary> internal static string GetStringFromParameterValue(object parameterValue, bool logItemMetadata = true) { // fast path for the common case if (parameterValue is string valueText) { return(valueText); } using (var sb = new ReuseableStringBuilder()) { AppendStringFromParameterValue(sb, parameterValue, logItemMetadata); return(sb.ToString()); } }
/// <summary> /// Gets a text serialized value of a parameter for logging. /// </summary> internal static string GetParameterText(string prefix, string parameterName, IList parameterValue, bool logItemMetadata = true) { if (parameterValue == null || parameterValue.Count == 0) { return(parameterName); } using (var sb = new ReuseableStringBuilder()) { sb.Append(prefix); bool firstEntryIsTaskItemWithSomeCustomMetadata = false; var firstItem = parameterValue[0] as ITaskItem; if (firstItem != null) { if (firstItem.CloneCustomMetadata().Count > 0) { firstEntryIsTaskItemWithSomeCustomMetadata = true; } } // If it's just one entry in the list, and it's not a task item with metadata, keep it on one line like a scalar bool specialTreatmentForSingle = (parameterValue.Count == 1 && !firstEntryIsTaskItemWithSomeCustomMetadata); // If the parameterName is not specified, no need to have an extra indent. // Without parameterName: // // Input files: // a.txt // b.txt // // With parameterName: // // Input files: // ParamName= // a.txt // b.txt string indent = " "; if (parameterName == null) { indent = " "; } if (!specialTreatmentForSingle) { sb.Append("\n"); if (parameterName != null) { sb.Append(" "); } } if (parameterName != null) { sb.Append(parameterName); sb.Append('='); if (!specialTreatmentForSingle) { sb.Append("\n"); } } bool truncateTaskInputs = Traits.Instance.EscapeHatches.TruncateTaskInputs; for (int i = 0; i < parameterValue.Count; i++) { if (parameterValue[i] == null) { continue; } if (!specialTreatmentForSingle) { sb.Append(indent); } AppendStringFromParameterValue(sb, parameterValue[i], logItemMetadata); if (!specialTreatmentForSingle && i < parameterValue.Count - 1) { sb.Append("\n"); } if (truncateTaskInputs && (sb.Length >= parameterCharacterLimit || i > parameterLimit)) { sb.Append(ResourceUtilities.GetResourceString("LogTaskInputs.Truncated")); break; } } return(sb.ToString()); } }
public override bool Execute() { if (ItemsToHash?.Length > 0) { using (var sha1 = SHA1.Create()) { // Buffer in which bytes of the strings are to be stored until their number reaches the limit size. // Once the limit is reached, the sha1.TransformBlock is to be run on all the bytes of this buffer. byte[] sha1Buffer = null; // Buffer in which bytes of items' ItemSpec are to be stored. byte[] itemSpecChunkByteBuffer = null; try { sha1Buffer = System.Buffers.ArrayPool <byte> .Shared.Rent(Sha1BufferSize); itemSpecChunkByteBuffer = System.Buffers.ArrayPool <byte> .Shared.Rent(s_encoding.GetMaxByteCount(MaxInputChunkLength)); int sha1BufferPosition = 0; for (int i = 0; i < ItemsToHash.Length; i++) { string itemSpec = IgnoreCase ? ItemsToHash[i].ItemSpec.ToUpperInvariant() : ItemsToHash[i].ItemSpec; // Slice the itemSpec string into chunks of reasonable size and add them to sha1 buffer. for (int itemSpecPosition = 0; itemSpecPosition < itemSpec.Length; itemSpecPosition += MaxInputChunkLength) { int charsToProcess = Math.Min(itemSpec.Length - itemSpecPosition, MaxInputChunkLength); int byteCount = s_encoding.GetBytes(itemSpec, itemSpecPosition, charsToProcess, itemSpecChunkByteBuffer, 0); sha1BufferPosition = AddBytesToSha1Buffer(sha1, sha1Buffer, sha1BufferPosition, Sha1BufferSize, itemSpecChunkByteBuffer, byteCount); } sha1BufferPosition = AddBytesToSha1Buffer(sha1, sha1Buffer, sha1BufferPosition, Sha1BufferSize, s_itemSeparatorCharacterBytes, s_itemSeparatorCharacterBytes.Length); } sha1.TransformFinalBlock(sha1Buffer, 0, sha1BufferPosition); using (var stringBuilder = new ReuseableStringBuilder(sha1.HashSize)) { foreach (var b in sha1.Hash) { stringBuilder.Append(b.ToString("x2")); } HashResult = stringBuilder.ToString(); } } finally { if (sha1Buffer != null) { System.Buffers.ArrayPool <byte> .Shared.Return(sha1Buffer); } if (itemSpecChunkByteBuffer != null) { System.Buffers.ArrayPool <byte> .Shared.Return(itemSpecChunkByteBuffer); } } } } return(true); }