forked from ScoopInstaller/Scoop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.ps1
120 lines (101 loc) · 3.52 KB
/
json.ps1
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
# Convert objects to pretty json
# Only needed until PowerShell ConvertTo-Json will be improved https://github.com/PowerShell/PowerShell/issues/2736
Function ConvertToPrettyJson {
[cmdletbinding()]
Param (
[parameter(Mandatory, ValueFromPipeline)]
$data
)
Process {
[String]$json = $data | ConvertTo-Json -Depth 8 -Compress
[String]$output = ""
# state
[String]$buffer = ""
[Int]$depth = 0
[Bool]$inString = $false
# configuration
[String]$indent = " " * 4
[Bool]$unescapeString = $true
[String]$eol = "`r`n"
for ($i = 0; $i -lt $json.Length; $i++) {
# read current char
$buffer = $json.Substring($i, 1)
#
$objectStart = !$inString -and $buffer.Equals("{")
$objectEnd = !$inString -and $buffer.Equals("}")
$arrayStart = !$inString -and $buffer.Equals("[")
$arrayEnd = !$inString -and $buffer.Equals("]")
$colon = !$inString -and $buffer.Equals(":")
$comma = !$inString -and $buffer.Equals(",")
$quote = $buffer.Equals('"')
$escape = $buffer.Equals('\')
if ($quote) {
$inString = !$inString
}
# skip escape sequences
if ($escape) {
$buffer = $json.Substring($i, 2)
++$i
# Unescape unicode
if ($inString -and $unescapeString) {
if ($buffer.Equals('\n')) {
$buffer = "`n"
} elseif ($buffer.Equals('\r')) {
$buffer = "`r"
} elseif ($buffer.Equals('\t')) {
$buffer = "`t"
} elseif ($buffer.Equals('\u')) {
$buffer = [regex]::Unescape($json.Substring($i - 1, 6))
$i += 4
}
}
$output += $buffer
continue
}
# indent / outdent
if ($objectStart -or $arrayStart) {
++$depth
} elseif ($objectEnd -or $arrayEnd) {
--$depth
$output += $eol + ($indent * $depth)
}
# add content
$output += $buffer
# add whitespace and newlines after the content
if ($colon) {
$output += " "
} elseif ($comma -or $arrayStart -or $objectStart) {
$output += $eol
$output += $indent * $depth
}
}
$output
}
}
function json_path([Object] $json, [String] $jsonpath, [String] $basename) {
$result = $json
$isJsonPath = $jsonpath.StartsWith("`$")
$jsonpath.split(".") | ForEach-Object {
$el = $_
# substitute the base filename into the jsonpath
if($el.Contains("`$basename")) {
$el = $el.Replace("`$basename", $basename)
}
# skip $ if it's jsonpath format
if($el -eq "`$" -and $isJsonPath) {
return
}
# array detection
if($el -match "^(?<property>\w+)\[(?<index>[\w\d.-]+)\]$") {
$property = $matches['property']
if($matches['index'] -is [int]) {
$result = $result.$property[$matches['index']]
} else {
$result = $result.$property.($matches['index'])
}
return
}
$result = $result.$el
}
return $result
}