/
ConvertToJsonCommand.cs
147 lines (129 loc) · 5.09 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
142
143
144
145
146
147
// 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)]
[OutputType(typeof(string))]
public class ConvertToJsonCommand : PSCmdlet, IDisposable
{
/// <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 readonly CancellationTokenSource _cancellationSource = new();
/// <summary>
/// Gets or sets the Depth property.
/// </summary>
[Parameter]
[ValidateRange(0, 100)]
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>
/// IDisposable implementation, dispose of any disposable resources created by the cmdlet.
/// </summary>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Implementation of IDisposable for both manual Dispose() and finalizer-called disposal of resources.
/// </summary>
/// <param name="disposing">
/// Specified as true when Dispose() was called, false if this is called from the finalizer.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_cancellationSource.Dispose();
}
}
private readonly List<object> _inputObjects = new();
/// <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,
EscapeHandling,
targetCmdlet: this,
_cancellationSource.Token);
// 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();
}
}
}