-
Notifications
You must be signed in to change notification settings - Fork 694
/
Preprocessor.cs
106 lines (95 loc) · 3.87 KB
/
Preprocessor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace NuGet.Common
{
/// <summary>
/// Simple token replacement system for content files.
/// </summary>
public static class Preprocessor
{
/// <summary>
/// Asynchronously performs token replacement on a file stream.
/// </summary>
/// <param name="streamTaskFactory">A stream task factory.</param>
/// <param name="tokenReplacement">A token replacement function.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>A task that represents the asynchronous operation.
/// The task result (<see cref="Task{TResult}.Result" />) returns a <see cref="string" />.</returns>
/// <exception cref="ArgumentException">Thrown if <paramref name="streamTaskFactory" />
/// is either <see langword="null" /> or empty.</exception>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="tokenReplacement" />
/// is <see langword="null" />.</exception>
/// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
/// is cancelled.</exception>
public static async Task<string> ProcessAsync(
Func<Task<Stream>> streamTaskFactory,
Func<string, string> tokenReplacement,
CancellationToken cancellationToken)
{
if (streamTaskFactory == null)
{
throw new ArgumentNullException(nameof(streamTaskFactory));
}
if (tokenReplacement == null)
{
throw new ArgumentNullException(nameof(tokenReplacement));
}
cancellationToken.ThrowIfCancellationRequested();
using (var stream = await streamTaskFactory())
{
return Process(stream, tokenReplacement);
}
}
/// <summary>
/// Performs token replacement on a stream and returns the result.
/// </summary>
/// <param name="stream">A stream.</param>
/// <param name="tokenReplacement">A token replacement funciton.</param>
/// <returns>The token-replaced stream content.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="stream" />
/// is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="tokenReplacement" />
/// is <see langword="null" />.</exception>
public static string Process(Stream stream, Func<string, string> tokenReplacement)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
if (tokenReplacement == null)
{
throw new ArgumentNullException(nameof(tokenReplacement));
}
string text;
using (var streamReader = new StreamReader(stream))
{
text = streamReader.ReadToEnd();
}
var tokenizer = new Tokenizer(text);
var result = new StringBuilder();
for (; ; )
{
var token = tokenizer.Read();
if (token == null)
{
break;
}
if (token.Category == TokenCategory.Variable)
{
var replaced = tokenReplacement(token.Value);
result.Append(replaced);
}
else
{
result.Append(token.Value);
}
}
return result.ToString();
}
}
}