forked from TrueCloudLab/distribution
a685e3fc98
Vndr has a simpler configuration and allows pointing to forked packages. Additionally other docker projects are now using vndr making vendoring in distribution more consistent. Updates letsencrypt to use fork. No longer uses sub-vendored packages. Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
141 lines
3.4 KiB
Go
141 lines
3.4 KiB
Go
// Copyright 2010 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package json
|
|
|
|
import "bytes"
|
|
|
|
// Compact appends to dst the JSON-encoded src with
|
|
// insignificant space characters elided.
|
|
func Compact(dst *bytes.Buffer, src []byte) error {
|
|
return compact(dst, src, false)
|
|
}
|
|
|
|
func compact(dst *bytes.Buffer, src []byte, escape bool) error {
|
|
origLen := dst.Len()
|
|
var scan scanner
|
|
scan.reset()
|
|
start := 0
|
|
for i, c := range src {
|
|
if escape && (c == '<' || c == '>' || c == '&') {
|
|
if start < i {
|
|
dst.Write(src[start:i])
|
|
}
|
|
dst.WriteString(`\u00`)
|
|
dst.WriteByte(hex[c>>4])
|
|
dst.WriteByte(hex[c&0xF])
|
|
start = i + 1
|
|
}
|
|
// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
|
|
if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
|
|
if start < i {
|
|
dst.Write(src[start:i])
|
|
}
|
|
dst.WriteString(`\u202`)
|
|
dst.WriteByte(hex[src[i+2]&0xF])
|
|
start = i + 3
|
|
}
|
|
v := scan.step(&scan, c)
|
|
if v >= scanSkipSpace {
|
|
if v == scanError {
|
|
break
|
|
}
|
|
if start < i {
|
|
dst.Write(src[start:i])
|
|
}
|
|
start = i + 1
|
|
}
|
|
}
|
|
if scan.eof() == scanError {
|
|
dst.Truncate(origLen)
|
|
return scan.err
|
|
}
|
|
if start < len(src) {
|
|
dst.Write(src[start:])
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
|
|
dst.WriteByte('\n')
|
|
dst.WriteString(prefix)
|
|
for i := 0; i < depth; i++ {
|
|
dst.WriteString(indent)
|
|
}
|
|
}
|
|
|
|
// Indent appends to dst an indented form of the JSON-encoded src.
|
|
// Each element in a JSON object or array begins on a new,
|
|
// indented line beginning with prefix followed by one or more
|
|
// copies of indent according to the indentation nesting.
|
|
// The data appended to dst does not begin with the prefix nor
|
|
// any indentation, to make it easier to embed inside other formatted JSON data.
|
|
// Although leading space characters (space, tab, carriage return, newline)
|
|
// at the beginning of src are dropped, trailing space characters
|
|
// at the end of src are preserved and copied to dst.
|
|
// For example, if src has no trailing spaces, neither will dst;
|
|
// if src ends in a trailing newline, so will dst.
|
|
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
|
|
origLen := dst.Len()
|
|
var scan scanner
|
|
scan.reset()
|
|
needIndent := false
|
|
depth := 0
|
|
for _, c := range src {
|
|
scan.bytes++
|
|
v := scan.step(&scan, c)
|
|
if v == scanSkipSpace {
|
|
continue
|
|
}
|
|
if v == scanError {
|
|
break
|
|
}
|
|
if needIndent && v != scanEndObject && v != scanEndArray {
|
|
needIndent = false
|
|
depth++
|
|
newline(dst, prefix, indent, depth)
|
|
}
|
|
|
|
// Emit semantically uninteresting bytes
|
|
// (in particular, punctuation in strings) unmodified.
|
|
if v == scanContinue {
|
|
dst.WriteByte(c)
|
|
continue
|
|
}
|
|
|
|
// Add spacing around real punctuation.
|
|
switch c {
|
|
case '{', '[':
|
|
// delay indent so that empty object and array are formatted as {} and [].
|
|
needIndent = true
|
|
dst.WriteByte(c)
|
|
|
|
case ',':
|
|
dst.WriteByte(c)
|
|
newline(dst, prefix, indent, depth)
|
|
|
|
case ':':
|
|
dst.WriteByte(c)
|
|
dst.WriteByte(' ')
|
|
|
|
case '}', ']':
|
|
if needIndent {
|
|
// suppress indent in empty object/array
|
|
needIndent = false
|
|
} else {
|
|
depth--
|
|
newline(dst, prefix, indent, depth)
|
|
}
|
|
dst.WriteByte(c)
|
|
|
|
default:
|
|
dst.WriteByte(c)
|
|
}
|
|
}
|
|
if scan.eof() == scanError {
|
|
dst.Truncate(origLen)
|
|
return scan.err
|
|
}
|
|
return nil
|
|
}
|