396
									
								
								vendor/github.com/json-iterator/go/feature_stream_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								vendor/github.com/json-iterator/go/feature_stream_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,396 @@
 | 
			
		||||
package jsoniter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// htmlSafeSet holds the value true if the ASCII character with the given
 | 
			
		||||
// array position can be safely represented inside a JSON string, embedded
 | 
			
		||||
// inside of HTML <script> tags, without any additional escaping.
 | 
			
		||||
//
 | 
			
		||||
// All values are true except for the ASCII control characters (0-31), the
 | 
			
		||||
// double quote ("), the backslash character ("\"), HTML opening and closing
 | 
			
		||||
// tags ("<" and ">"), and the ampersand ("&").
 | 
			
		||||
var htmlSafeSet = [utf8.RuneSelf]bool{
 | 
			
		||||
	' ':      true,
 | 
			
		||||
	'!':      true,
 | 
			
		||||
	'"':      false,
 | 
			
		||||
	'#':      true,
 | 
			
		||||
	'$':      true,
 | 
			
		||||
	'%':      true,
 | 
			
		||||
	'&':      false,
 | 
			
		||||
	'\'':     true,
 | 
			
		||||
	'(':      true,
 | 
			
		||||
	')':      true,
 | 
			
		||||
	'*':      true,
 | 
			
		||||
	'+':      true,
 | 
			
		||||
	',':      true,
 | 
			
		||||
	'-':      true,
 | 
			
		||||
	'.':      true,
 | 
			
		||||
	'/':      true,
 | 
			
		||||
	'0':      true,
 | 
			
		||||
	'1':      true,
 | 
			
		||||
	'2':      true,
 | 
			
		||||
	'3':      true,
 | 
			
		||||
	'4':      true,
 | 
			
		||||
	'5':      true,
 | 
			
		||||
	'6':      true,
 | 
			
		||||
	'7':      true,
 | 
			
		||||
	'8':      true,
 | 
			
		||||
	'9':      true,
 | 
			
		||||
	':':      true,
 | 
			
		||||
	';':      true,
 | 
			
		||||
	'<':      false,
 | 
			
		||||
	'=':      true,
 | 
			
		||||
	'>':      false,
 | 
			
		||||
	'?':      true,
 | 
			
		||||
	'@':      true,
 | 
			
		||||
	'A':      true,
 | 
			
		||||
	'B':      true,
 | 
			
		||||
	'C':      true,
 | 
			
		||||
	'D':      true,
 | 
			
		||||
	'E':      true,
 | 
			
		||||
	'F':      true,
 | 
			
		||||
	'G':      true,
 | 
			
		||||
	'H':      true,
 | 
			
		||||
	'I':      true,
 | 
			
		||||
	'J':      true,
 | 
			
		||||
	'K':      true,
 | 
			
		||||
	'L':      true,
 | 
			
		||||
	'M':      true,
 | 
			
		||||
	'N':      true,
 | 
			
		||||
	'O':      true,
 | 
			
		||||
	'P':      true,
 | 
			
		||||
	'Q':      true,
 | 
			
		||||
	'R':      true,
 | 
			
		||||
	'S':      true,
 | 
			
		||||
	'T':      true,
 | 
			
		||||
	'U':      true,
 | 
			
		||||
	'V':      true,
 | 
			
		||||
	'W':      true,
 | 
			
		||||
	'X':      true,
 | 
			
		||||
	'Y':      true,
 | 
			
		||||
	'Z':      true,
 | 
			
		||||
	'[':      true,
 | 
			
		||||
	'\\':     false,
 | 
			
		||||
	']':      true,
 | 
			
		||||
	'^':      true,
 | 
			
		||||
	'_':      true,
 | 
			
		||||
	'`':      true,
 | 
			
		||||
	'a':      true,
 | 
			
		||||
	'b':      true,
 | 
			
		||||
	'c':      true,
 | 
			
		||||
	'd':      true,
 | 
			
		||||
	'e':      true,
 | 
			
		||||
	'f':      true,
 | 
			
		||||
	'g':      true,
 | 
			
		||||
	'h':      true,
 | 
			
		||||
	'i':      true,
 | 
			
		||||
	'j':      true,
 | 
			
		||||
	'k':      true,
 | 
			
		||||
	'l':      true,
 | 
			
		||||
	'm':      true,
 | 
			
		||||
	'n':      true,
 | 
			
		||||
	'o':      true,
 | 
			
		||||
	'p':      true,
 | 
			
		||||
	'q':      true,
 | 
			
		||||
	'r':      true,
 | 
			
		||||
	's':      true,
 | 
			
		||||
	't':      true,
 | 
			
		||||
	'u':      true,
 | 
			
		||||
	'v':      true,
 | 
			
		||||
	'w':      true,
 | 
			
		||||
	'x':      true,
 | 
			
		||||
	'y':      true,
 | 
			
		||||
	'z':      true,
 | 
			
		||||
	'{':      true,
 | 
			
		||||
	'|':      true,
 | 
			
		||||
	'}':      true,
 | 
			
		||||
	'~':      true,
 | 
			
		||||
	'\u007f': true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// safeSet holds the value true if the ASCII character with the given array
 | 
			
		||||
// position can be represented inside a JSON string without any further
 | 
			
		||||
// escaping.
 | 
			
		||||
//
 | 
			
		||||
// All values are true except for the ASCII control characters (0-31), the
 | 
			
		||||
// double quote ("), and the backslash character ("\").
 | 
			
		||||
var safeSet = [utf8.RuneSelf]bool{
 | 
			
		||||
	' ':      true,
 | 
			
		||||
	'!':      true,
 | 
			
		||||
	'"':      false,
 | 
			
		||||
	'#':      true,
 | 
			
		||||
	'$':      true,
 | 
			
		||||
	'%':      true,
 | 
			
		||||
	'&':      true,
 | 
			
		||||
	'\'':     true,
 | 
			
		||||
	'(':      true,
 | 
			
		||||
	')':      true,
 | 
			
		||||
	'*':      true,
 | 
			
		||||
	'+':      true,
 | 
			
		||||
	',':      true,
 | 
			
		||||
	'-':      true,
 | 
			
		||||
	'.':      true,
 | 
			
		||||
	'/':      true,
 | 
			
		||||
	'0':      true,
 | 
			
		||||
	'1':      true,
 | 
			
		||||
	'2':      true,
 | 
			
		||||
	'3':      true,
 | 
			
		||||
	'4':      true,
 | 
			
		||||
	'5':      true,
 | 
			
		||||
	'6':      true,
 | 
			
		||||
	'7':      true,
 | 
			
		||||
	'8':      true,
 | 
			
		||||
	'9':      true,
 | 
			
		||||
	':':      true,
 | 
			
		||||
	';':      true,
 | 
			
		||||
	'<':      true,
 | 
			
		||||
	'=':      true,
 | 
			
		||||
	'>':      true,
 | 
			
		||||
	'?':      true,
 | 
			
		||||
	'@':      true,
 | 
			
		||||
	'A':      true,
 | 
			
		||||
	'B':      true,
 | 
			
		||||
	'C':      true,
 | 
			
		||||
	'D':      true,
 | 
			
		||||
	'E':      true,
 | 
			
		||||
	'F':      true,
 | 
			
		||||
	'G':      true,
 | 
			
		||||
	'H':      true,
 | 
			
		||||
	'I':      true,
 | 
			
		||||
	'J':      true,
 | 
			
		||||
	'K':      true,
 | 
			
		||||
	'L':      true,
 | 
			
		||||
	'M':      true,
 | 
			
		||||
	'N':      true,
 | 
			
		||||
	'O':      true,
 | 
			
		||||
	'P':      true,
 | 
			
		||||
	'Q':      true,
 | 
			
		||||
	'R':      true,
 | 
			
		||||
	'S':      true,
 | 
			
		||||
	'T':      true,
 | 
			
		||||
	'U':      true,
 | 
			
		||||
	'V':      true,
 | 
			
		||||
	'W':      true,
 | 
			
		||||
	'X':      true,
 | 
			
		||||
	'Y':      true,
 | 
			
		||||
	'Z':      true,
 | 
			
		||||
	'[':      true,
 | 
			
		||||
	'\\':     false,
 | 
			
		||||
	']':      true,
 | 
			
		||||
	'^':      true,
 | 
			
		||||
	'_':      true,
 | 
			
		||||
	'`':      true,
 | 
			
		||||
	'a':      true,
 | 
			
		||||
	'b':      true,
 | 
			
		||||
	'c':      true,
 | 
			
		||||
	'd':      true,
 | 
			
		||||
	'e':      true,
 | 
			
		||||
	'f':      true,
 | 
			
		||||
	'g':      true,
 | 
			
		||||
	'h':      true,
 | 
			
		||||
	'i':      true,
 | 
			
		||||
	'j':      true,
 | 
			
		||||
	'k':      true,
 | 
			
		||||
	'l':      true,
 | 
			
		||||
	'm':      true,
 | 
			
		||||
	'n':      true,
 | 
			
		||||
	'o':      true,
 | 
			
		||||
	'p':      true,
 | 
			
		||||
	'q':      true,
 | 
			
		||||
	'r':      true,
 | 
			
		||||
	's':      true,
 | 
			
		||||
	't':      true,
 | 
			
		||||
	'u':      true,
 | 
			
		||||
	'v':      true,
 | 
			
		||||
	'w':      true,
 | 
			
		||||
	'x':      true,
 | 
			
		||||
	'y':      true,
 | 
			
		||||
	'z':      true,
 | 
			
		||||
	'{':      true,
 | 
			
		||||
	'|':      true,
 | 
			
		||||
	'}':      true,
 | 
			
		||||
	'~':      true,
 | 
			
		||||
	'\u007f': true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var hex = "0123456789abcdef"
 | 
			
		||||
 | 
			
		||||
// WriteStringWithHTMLEscaped write string to stream with html special characters escaped
 | 
			
		||||
func (stream *Stream) WriteStringWithHTMLEscaped(s string) {
 | 
			
		||||
	stream.ensure(32)
 | 
			
		||||
	valLen := len(s)
 | 
			
		||||
	toWriteLen := valLen
 | 
			
		||||
	bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
 | 
			
		||||
	if stream.n+toWriteLen > bufLengthMinusTwo {
 | 
			
		||||
		toWriteLen = bufLengthMinusTwo - stream.n
 | 
			
		||||
	}
 | 
			
		||||
	n := stream.n
 | 
			
		||||
	stream.buf[n] = '"'
 | 
			
		||||
	n++
 | 
			
		||||
	// write string, the fast path, without utf8 and escape support
 | 
			
		||||
	i := 0
 | 
			
		||||
	for ; i < toWriteLen; i++ {
 | 
			
		||||
		c := s[i]
 | 
			
		||||
		if c < utf8.RuneSelf && htmlSafeSet[c] {
 | 
			
		||||
			stream.buf[n] = c
 | 
			
		||||
			n++
 | 
			
		||||
		} else {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if i == valLen {
 | 
			
		||||
		stream.buf[n] = '"'
 | 
			
		||||
		n++
 | 
			
		||||
		stream.n = n
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	stream.n = n
 | 
			
		||||
	writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen int) {
 | 
			
		||||
	start := i
 | 
			
		||||
	// for the remaining parts, we process them char by char
 | 
			
		||||
	for i < valLen {
 | 
			
		||||
		if b := s[i]; b < utf8.RuneSelf {
 | 
			
		||||
			if htmlSafeSet[b] {
 | 
			
		||||
				i++
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if start < i {
 | 
			
		||||
				stream.WriteRaw(s[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			switch b {
 | 
			
		||||
			case '\\', '"':
 | 
			
		||||
				stream.writeTwoBytes('\\', b)
 | 
			
		||||
			case '\n':
 | 
			
		||||
				stream.writeTwoBytes('\\', 'n')
 | 
			
		||||
			case '\r':
 | 
			
		||||
				stream.writeTwoBytes('\\', 'r')
 | 
			
		||||
			case '\t':
 | 
			
		||||
				stream.writeTwoBytes('\\', 't')
 | 
			
		||||
			default:
 | 
			
		||||
				// This encodes bytes < 0x20 except for \t, \n and \r.
 | 
			
		||||
				// If escapeHTML is set, it also escapes <, >, and &
 | 
			
		||||
				// because they can lead to security holes when
 | 
			
		||||
				// user-controlled strings are rendered into JSON
 | 
			
		||||
				// and served to some browsers.
 | 
			
		||||
				stream.WriteRaw(`\u00`)
 | 
			
		||||
				stream.writeTwoBytes(hex[b>>4], hex[b&0xF])
 | 
			
		||||
			}
 | 
			
		||||
			i++
 | 
			
		||||
			start = i
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		c, size := utf8.DecodeRuneInString(s[i:])
 | 
			
		||||
		if c == utf8.RuneError && size == 1 {
 | 
			
		||||
			if start < i {
 | 
			
		||||
				stream.WriteRaw(s[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			stream.WriteRaw(`\ufffd`)
 | 
			
		||||
			i++
 | 
			
		||||
			start = i
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// U+2028 is LINE SEPARATOR.
 | 
			
		||||
		// U+2029 is PARAGRAPH SEPARATOR.
 | 
			
		||||
		// They are both technically valid characters in JSON strings,
 | 
			
		||||
		// but don't work in JSONP, which has to be evaluated as JavaScript,
 | 
			
		||||
		// and can lead to security holes there. It is valid JSON to
 | 
			
		||||
		// escape them, so we do so unconditionally.
 | 
			
		||||
		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
 | 
			
		||||
		if c == '\u2028' || c == '\u2029' {
 | 
			
		||||
			if start < i {
 | 
			
		||||
				stream.WriteRaw(s[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			stream.WriteRaw(`\u202`)
 | 
			
		||||
			stream.writeByte(hex[c&0xF])
 | 
			
		||||
			i += size
 | 
			
		||||
			start = i
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		i += size
 | 
			
		||||
	}
 | 
			
		||||
	if start < len(s) {
 | 
			
		||||
		stream.WriteRaw(s[start:])
 | 
			
		||||
	}
 | 
			
		||||
	stream.writeByte('"')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteString write string to stream without html escape
 | 
			
		||||
func (stream *Stream) WriteString(s string) {
 | 
			
		||||
	stream.ensure(32)
 | 
			
		||||
	valLen := len(s)
 | 
			
		||||
	toWriteLen := valLen
 | 
			
		||||
	bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
 | 
			
		||||
	if stream.n+toWriteLen > bufLengthMinusTwo {
 | 
			
		||||
		toWriteLen = bufLengthMinusTwo - stream.n
 | 
			
		||||
	}
 | 
			
		||||
	n := stream.n
 | 
			
		||||
	stream.buf[n] = '"'
 | 
			
		||||
	n++
 | 
			
		||||
	// write string, the fast path, without utf8 and escape support
 | 
			
		||||
	i := 0
 | 
			
		||||
	for ; i < toWriteLen; i++ {
 | 
			
		||||
		c := s[i]
 | 
			
		||||
		if c > 31 && c != '"' && c != '\\' {
 | 
			
		||||
			stream.buf[n] = c
 | 
			
		||||
			n++
 | 
			
		||||
		} else {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if i == valLen {
 | 
			
		||||
		stream.buf[n] = '"'
 | 
			
		||||
		n++
 | 
			
		||||
		stream.n = n
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	stream.n = n
 | 
			
		||||
	writeStringSlowPath(stream, i, s, valLen)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeStringSlowPath(stream *Stream, i int, s string, valLen int) {
 | 
			
		||||
	start := i
 | 
			
		||||
	// for the remaining parts, we process them char by char
 | 
			
		||||
	for i < valLen {
 | 
			
		||||
		if b := s[i]; b < utf8.RuneSelf {
 | 
			
		||||
			if safeSet[b] {
 | 
			
		||||
				i++
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if start < i {
 | 
			
		||||
				stream.WriteRaw(s[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			switch b {
 | 
			
		||||
			case '\\', '"':
 | 
			
		||||
				stream.writeTwoBytes('\\', b)
 | 
			
		||||
			case '\n':
 | 
			
		||||
				stream.writeTwoBytes('\\', 'n')
 | 
			
		||||
			case '\r':
 | 
			
		||||
				stream.writeTwoBytes('\\', 'r')
 | 
			
		||||
			case '\t':
 | 
			
		||||
				stream.writeTwoBytes('\\', 't')
 | 
			
		||||
			default:
 | 
			
		||||
				// This encodes bytes < 0x20 except for \t, \n and \r.
 | 
			
		||||
				// If escapeHTML is set, it also escapes <, >, and &
 | 
			
		||||
				// because they can lead to security holes when
 | 
			
		||||
				// user-controlled strings are rendered into JSON
 | 
			
		||||
				// and served to some browsers.
 | 
			
		||||
				stream.WriteRaw(`\u00`)
 | 
			
		||||
				stream.writeTwoBytes(hex[b>>4], hex[b&0xF])
 | 
			
		||||
			}
 | 
			
		||||
			i++
 | 
			
		||||
			start = i
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		i++
 | 
			
		||||
		continue
 | 
			
		||||
	}
 | 
			
		||||
	if start < len(s) {
 | 
			
		||||
		stream.WriteRaw(s[start:])
 | 
			
		||||
	}
 | 
			
		||||
	stream.writeByte('"')
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user