// 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.//go:build goexperiment.jsonv2package jsonimport ()// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029// so that the JSON will be safe to embed inside HTML <script> tags.// For historical reasons, web browsers don't honor standard HTML// escaping within <script> tags, so an alternative JSON encoding must be used.func ( *bytes.Buffer, []byte) { .Grow(len()) .Write(appendHTMLEscape(.AvailableBuffer(), ))}func appendHTMLEscape(, []byte) []byte {const = "0123456789abcdef"// The characters can only appear in string literals, // so just scan the string one byte at a time. := 0for , := range {if == '<' || == '>' || == '&' { = append(, [:]...) = append(, '\\', 'u', '0', '0', [>>4], [&0xF]) = + 1 }// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).if == 0xE2 && +2 < len() && [+1] == 0x80 && [+2]&^1 == 0xA8 { = append(, [:]...) = append(, '\\', 'u', '2', '0', '2', [[+2]&0xF]) = + len("\u2029") } }returnappend(, [:]...)}// Compact appends to dst the JSON-encoded src with// insignificant space characters elided.func ( *bytes.Buffer, []byte) error { .Grow(len()) := .AvailableBuffer() , := jsontext.AppendFormat(, ,jsontext.AllowDuplicateNames(true),jsontext.AllowInvalidUTF8(true),jsontext.PreserveRawStrings(true))if != nil {returntransformSyntacticError() } .Write()returnnil}// indentGrowthFactor specifies the growth factor of indenting JSON input.// Empirically, the growth factor was measured to be between 1.4x to 1.8x// for some set of compacted JSON with the indent being a single tab.// Specify a growth factor slightly larger than what is observed// to reduce probability of allocation in appendIndent.// A factor no higher than 2 ensures that wasted space never exceeds 50%.const indentGrowthFactor = 2// 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 ( *bytes.Buffer, []byte, , string) error { .Grow(indentGrowthFactor * len()) := .AvailableBuffer() , := appendIndent(, , , ) .Write()return}func appendIndent(, []byte, , string) ([]byte, error) {// In v2, trailing whitespace is discarded, while v1 preserved it. := len()if := len() - len(bytes.TrimRight(, " \n\r\t")); > 0 {// Append the trailing whitespace afterwards.deferfunc() {iflen() > { = append(, [len()-:]...) } }() }// In v2, only spaces and tabs are allowed, while v1 allowed any character.iflen(strings.Trim(, " \t"))+len(strings.Trim(, " \t")) > 0 {// Use placeholder spaces of correct length, and replace afterwards. , := , = strings.Repeat(" ", len()) = strings.Repeat(" ", len())deferfunc() { := [:]for := bytes.IndexByte(, '\n'); >= 0; = bytes.IndexByte(, '\n') { = [+len("\n"):] := len() - len(bytes.TrimLeft(, " ")) // len(prefix)+n*len(indent) := [:] = [copy(, ):]forlen() > 0 { = [copy(, ):] } = [:] } }() } , := jsontext.AppendFormat(, ,jsontext.AllowDuplicateNames(true),jsontext.AllowInvalidUTF8(true),jsontext.PreserveRawStrings(true),jsontext.Multiline(true),jsontext.WithIndentPrefix(),jsontext.WithIndent())if != nil {return [:], transformSyntacticError() }return , nil}
The pages are generated with Goldsv0.7.7-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.