// Copyright 2018 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 (
	
	
	
	

	
)

func ( *Decoder) ( []byte) (string, int, error) {
	 := 
	if len() == 0 {
		return "", 0, ErrUnexpectedEOF
	}
	if [0] != '"' {
		return "", 0, .newSyntaxError(.currPos(), "invalid character %q at start of string", [0])
	}
	 = [1:]
	 := indexNeedEscapeInBytes()
	,  := [:], [::] // set cap to prevent mutations
	for len() > 0 {
		switch ,  := utf8.DecodeRune(); {
		case  == utf8.RuneError &&  == 1:
			return "", 0, .newSyntaxError(.currPos(), "invalid UTF-8 in string")
		case  < ' ':
			return "", 0, .newSyntaxError(.currPos(), "invalid character %q in string", )
		case  == '"':
			 = [1:]
			 := len() - len()
			return string(), , nil
		case  == '\\':
			if len() < 2 {
				return "", 0, ErrUnexpectedEOF
			}
			switch  := [1];  {
			case '"', '\\', '/':
				,  = [2:], append(, )
			case 'b':
				,  = [2:], append(, '\b')
			case 'f':
				,  = [2:], append(, '\f')
			case 'n':
				,  = [2:], append(, '\n')
			case 'r':
				,  = [2:], append(, '\r')
			case 't':
				,  = [2:], append(, '\t')
			case 'u':
				if len() < 6 {
					return "", 0, ErrUnexpectedEOF
				}
				,  := strconv.ParseUint(string([2:6]), 16, 16)
				if  != nil {
					return "", 0, .newSyntaxError(.currPos(), "invalid escape code %q in string", [:6])
				}
				 = [6:]

				 := rune()
				if utf16.IsSurrogate() {
					if len() < 6 {
						return "", 0, ErrUnexpectedEOF
					}
					,  := strconv.ParseUint(string([2:6]), 16, 16)
					 = utf16.DecodeRune(, rune())
					if [0] != '\\' || [1] != 'u' ||
						 == unicode.ReplacementChar ||  != nil {
						return "", 0, .newSyntaxError(.currPos(), "invalid escape code %q in string", [:6])
					}
					 = [6:]
				}
				 = append(, string()...)
			default:
				return "", 0, .newSyntaxError(.currPos(), "invalid escape code %q in string", [:2])
			}
		default:
			 := indexNeedEscapeInBytes([:])
			,  = [+:], append(, [:+]...)
		}
	}
	return "", 0, ErrUnexpectedEOF
}

// indexNeedEscapeInBytes returns the index of the character that needs
// escaping. If no characters need escaping, this returns the input length.
func ( []byte) int { return indexNeedEscapeInString(strs.UnsafeString()) }