Пример #1
0
// ScanEscape writes escaped sequence to buffer.
func ScanEscape(scanner scanner.Scanner, buffer *bytes.Buffer) error {
	escapedRune, err := scanner.PeekRune()
	if err != nil {
		return err
	}
	scanner.NextRune()
	switch escapedRune {
	case '"':
		buffer.WriteString("\"")
	case '\\':
		buffer.WriteString("\\")
	case '/':
		buffer.WriteString("/")
	case 'b':
		buffer.WriteString("\b")
	case 'f':
		buffer.WriteString("\f")
	case 'n':
		buffer.WriteString("\n")
	case 'r':
		buffer.WriteString("\r")
	case 't':
		buffer.WriteString("\t")
	case 'u':
		unicodes, err := ReadUnicodeSequence(scanner)
		if err != nil {
			return err
		}
		buffer.WriteString(unicodes)
	default:
		return fmt.Errorf("%s is invalid escaped rune", string(escapedRune))

	}
	return nil
}
Пример #2
0
// ReadUnicodeSequence returns string.
func ReadUnicodeSequence(scanner scanner.Scanner) (string, error) {
	codes := []uint16{}
	for {
		code, err := ReadUnicode(scanner)
		if err != nil {
			return "", err
		}
		codes = append(codes, code)

		maybeEscape, err := scanner.PeekRuneWithOffset(0)
		if err != nil {
			break
		}
		maybeUnicode, err := scanner.PeekRuneWithOffset(1)
		if err != nil {
			break
		}
		if maybeEscape != '\\' || maybeUnicode != 'u' {
			break
		}
		scanner.NextRune()
		scanner.NextRune()
	}
	return string(utf16.Decode(codes)), nil
}
Пример #3
0
// ScanNumber returns string.
func ScanNumber(scanner scanner.Scanner, firstRune rune) (string, error) {
	nam := NewNAMState()
	err := nam.Input(firstRune)
	if err != nil {
		return "", err
	}
	for {
		peekedRune, err := scanner.PeekRune()
		if err == io.EOF {
			nam.EOF()
			break
		}
		if err != nil {
			return "", err
		}
		err = nam.Input(peekedRune)
		if err != nil {
			return "", err
		}
		if nam.state != -1 {
			scanner.NextRune()
		} else {
			break
		}
	}
	if !nam.Finished() {
		return "", fmt.Errorf("Invalid number")
	}
	return nam.Result(), nil
}
Пример #4
0
// ReadUnicode returns unicode.
func ReadUnicode(scanner scanner.Scanner) (uint16, error) {
	var buffer bytes.Buffer
	for i := 0; i < 4; i++ {
		currentRune, err := scanner.NextRune()
		if err != nil {
			return 0, err
		}
		if unicode.IsDigit(currentRune) ||
			currentRune == 'a' || currentRune == 'A' ||
			currentRune == 'b' || currentRune == 'B' ||
			currentRune == 'c' || currentRune == 'C' ||
			currentRune == 'd' || currentRune == 'D' ||
			currentRune == 'e' || currentRune == 'E' ||
			currentRune == 'f' || currentRune == 'F' {
			buffer.WriteRune(currentRune)
			continue
		}
		return 0, fmt.Errorf("%s is valid unicode", currentRune)
	}
	result, err := strconv.ParseUint(buffer.String(), 16, 16)
	if err != nil {
		return 0, err
	}
	return uint16(result), nil
}
Пример #5
0
// ScanString returns string.
func ScanString(scanner scanner.Scanner) (string, error) {
	var buffer bytes.Buffer
	for {
		peekedRune, err := scanner.PeekRune()
		if err != nil {
			return "", err
		}
		if peekedRune == '"' {
			scanner.NextRune()
			break
		}
		if peekedRune != '\\' {
			scanner.NextRune()
			buffer.WriteRune(peekedRune)
		} else {
			scanner.NextRune()
			ScanEscape(scanner, &buffer)
		}
	}
	return buffer.String(), nil
}