package logfmtimport ()// Taken from Go's encoding/json and modified for use here.// 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.var hex = "0123456789abcdef"var bufferPool = sync.Pool{New: func() interface{} {return &bytes.Buffer{} },}func getBuffer() *bytes.Buffer {returnbufferPool.Get().(*bytes.Buffer)}func poolBuffer( *bytes.Buffer) { .Reset()bufferPool.Put()}// NOTE: keep in sync with writeQuotedBytes below.func writeQuotedString( io.Writer, string) (int, error) { := getBuffer() .WriteByte('"') := 0for := 0; < len(); {if := []; < utf8.RuneSelf {if0x20 <= && != '\\' && != '"' { ++continue }if < { .WriteString([:]) }switch {case'\\', '"': .WriteByte('\\') .WriteByte()case'\n': .WriteByte('\\') .WriteByte('n')case'\r': .WriteByte('\\') .WriteByte('r')case'\t': .WriteByte('\\') .WriteByte('t')default:// This encodes bytes < 0x20 except for \n, \r, and \t. .WriteString(`\u00`) .WriteByte(hex[>>4]) .WriteByte(hex[&0xF]) } ++ = continue } , := utf8.DecodeRuneInString([:])if == utf8.RuneError {if < { .WriteString([:]) } .WriteString(`\ufffd`) += = continue } += }if < len() { .WriteString([:]) } .WriteByte('"') , := .Write(.Bytes())poolBuffer()return , }// NOTE: keep in sync with writeQuoteString above.func writeQuotedBytes( io.Writer, []byte) (int, error) { := getBuffer() .WriteByte('"') := 0for := 0; < len(); {if := []; < utf8.RuneSelf {if0x20 <= && != '\\' && != '"' { ++continue }if < { .Write([:]) }switch {case'\\', '"': .WriteByte('\\') .WriteByte()case'\n': .WriteByte('\\') .WriteByte('n')case'\r': .WriteByte('\\') .WriteByte('r')case'\t': .WriteByte('\\') .WriteByte('t')default:// This encodes bytes < 0x20 except for \n, \r, and \t. .WriteString(`\u00`) .WriteByte(hex[>>4]) .WriteByte(hex[&0xF]) } ++ = continue } , := utf8.DecodeRune([:])if == utf8.RuneError {if < { .Write([:]) } .WriteString(`\ufffd`) += = continue } += }if < len() { .Write([:]) } .WriteByte('"') , := .Write(.Bytes())poolBuffer()return , }// getu4 decodes \uXXXX from the beginning of s, returning the hex value,// or it returns -1.func getu4( []byte) rune {iflen() < 6 || [0] != '\\' || [1] != 'u' {return -1 } , := strconv.ParseUint(string([2:6]), 16, 64)if != nil {return -1 }returnrune()}func unquoteBytes( []byte) ( []byte, bool) {iflen() < 2 || [0] != '"' || [len()-1] != '"' {return } = [1 : len()-1]// Check for unusual characters. If there are none, // then no unquoting is needed, so return a slice of the // original bytes. := 0for < len() { := []if == '\\' || == '"' || < ' ' {break }if < utf8.RuneSelf { ++continue } , := utf8.DecodeRune([:])if == utf8.RuneError {break } += }if == len() {return , true } := make([]byte, len()+2*utf8.UTFMax) := copy(, [0:])for < len() {// Out of room? Can only happen if s is full of // malformed UTF-8 and we're replacing each // byte with RuneError.if >= len()-2*utf8.UTFMax { := make([]byte, (len()+utf8.UTFMax)*2)copy(, [0:]) = }switch := []; {case == '\\': ++if >= len() {return }switch [] {default:returncase'"', '\\', '/', '\'': [] = [] ++ ++case'b': [] = '\b' ++ ++case'f': [] = '\f' ++ ++case'n': [] = '\n' ++ ++case'r': [] = '\r' ++ ++case't': [] = '\t' ++ ++case'u': -- := getu4([:])if < 0 {return } += 6ifutf16.IsSurrogate() { := getu4([:])if := utf16.DecodeRune(, ); != unicode.ReplacementChar {// A valid pair; consume. += 6 += utf8.EncodeRune([:], )break }// Invalid surrogate; fall back to replacement rune. = unicode.ReplacementChar } += utf8.EncodeRune([:], ) }// Quote, control characters are invalid.case == '"', < ' ':return// ASCIIcase < utf8.RuneSelf: [] = ++ ++// Coerce to well-formed UTF-8.default: , := utf8.DecodeRune([:]) += += utf8.EncodeRune([:], ) } }return [0:], true}
The pages are generated with Goldsv0.8.2. (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.