-
Notifications
You must be signed in to change notification settings - Fork 7.1k
/
ConvertToJsonCommand.cs
141 lines (123 loc) · 4.98 KB
/
ConvertToJsonCommand.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Threading;
using Newtonsoft.Json;
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The ConvertTo-Json command.
/// This command converts an object to a Json string representation.
/// </summary>
[Cmdlet(VerbsData.ConvertTo, "Json", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096925", RemotingCapability = RemotingCapability.None)]
public class ConvertToJsonCommand : PSCmdlet
{
/// <summary>
/// Gets or sets the InputObject property.
/// </summary>
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)]
[AllowNull]
public object InputObject { get; set; }
private int _depth = 2;
private const int maxDepthAllowed = 100;
private readonly CancellationTokenSource _cancellationSource = new CancellationTokenSource();
/// <summary>
/// Gets or sets the Depth property.
/// </summary>
[Parameter]
[ValidateRange(1, int.MaxValue)]
public int Depth
{
get { return _depth; }
set { _depth = value; }
}
/// <summary>
/// Gets or sets the Compress property.
/// If the Compress property is set to be true, the Json string will
/// be output in the compressed way. Otherwise, the Json string will
/// be output with indentations.
/// </summary>
[Parameter]
public SwitchParameter Compress { get; set; }
/// <summary>
/// Gets or sets the EnumsAsStrings property.
/// If the EnumsAsStrings property is set to true, enum values will
/// be converted to their string equivalent. Otherwise, enum values
/// will be converted to their numeric equivalent.
/// </summary>
[Parameter]
public SwitchParameter EnumsAsStrings { get; set; }
/// <summary>
/// Gets or sets the AsArray property.
/// If the AsArray property is set to be true, the result JSON string will
/// be returned with surrounding '[', ']' chars. Otherwise,
/// the array symbols will occur only if there is more than one input object.
/// </summary>
[Parameter]
public SwitchParameter AsArray { get; set; }
/// <summary>
/// Specifies how strings are escaped when writing JSON text.
/// If the EscapeHandling property is set to EscapeHtml, the result JSON string will
/// be returned with HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped.
/// </summary>
[Parameter]
public StringEscapeHandling EscapeHandling { get; set; } = StringEscapeHandling.Default;
/// <summary>
/// Prerequisite checks.
/// </summary>
protected override void BeginProcessing()
{
if (_depth > maxDepthAllowed)
{
string errorMessage = StringUtil.Format(WebCmdletStrings.ReachedMaximumDepthAllowed, maxDepthAllowed);
ThrowTerminatingError(new ErrorRecord(
new InvalidOperationException(errorMessage),
"ReachedMaximumDepthAllowed",
ErrorCategory.InvalidOperation,
null));
}
}
private List<object> _inputObjects = new List<object>();
/// <summary>
/// Caching the input objects for the command.
/// </summary>
protected override void ProcessRecord()
{
_inputObjects.Add(InputObject);
}
/// <summary>
/// Do the conversion to json and write output.
/// </summary>
protected override void EndProcessing()
{
if (_inputObjects.Count > 0)
{
object objectToProcess = (_inputObjects.Count > 1 || AsArray) ? (_inputObjects.ToArray() as object) : _inputObjects[0];
var context = new JsonObject.ConvertToJsonContext(
Depth,
EnumsAsStrings.IsPresent,
Compress.IsPresent,
_cancellationSource.Token,
EscapeHandling,
targetCmdlet: this);
// null is returned only if the pipeline is stopping (e.g. ctrl+c is signaled).
// in that case, we shouldn't write the null to the output pipe.
string output = JsonObject.ConvertToJson(objectToProcess, in context);
if (output != null)
{
WriteObject(output);
}
}
}
/// <summary>
/// Process the Ctrl+C signal.
/// </summary>
protected override void StopProcessing()
{
_cancellationSource.Cancel();
}
}
}