private TokenType lexString ( Bytes jsonText ) { TokenType tok = ERROR ; boolean hasEscapes = false ; finish_string_lex : for ( ; ; ) { int curChar ; /* now jump into a faster scanning routine to skip as much * of the buffers as possible */ { if ( bufInUse && buf . readRemaining ( ) > 0 ) { stringScan ( buf ) ; } else if ( jsonText . readRemaining ( ) > 0 ) { stringScan ( jsonText ) ; } } if ( jsonText . readRemaining ( ) == 0 ) { tok = EOF ; break ; } curChar = readChar ( jsonText ) ; /* quote terminates */ if ( curChar == ' ' ) { tok = STRING ; break ; } /* backslash escapes a set of control chars, */ else if ( curChar == ' ' ) { hasEscapes = true ; if ( jsonText . readRemaining ( ) == 0 ) { tok = EOF ; break ; } /* special case \\u */ curChar = readChar ( jsonText ) ; if ( curChar == ' ' ) { for ( int i = 0 ; i < 4 ; i ++ ) { if ( jsonText . readRemaining ( ) == 0 ) { tok = EOF ; break finish_string_lex ; } curChar = readChar ( jsonText ) ; if ( ( CHAR_LOOKUP_TABLE [ curChar ] & VHC ) == 0 ) { /* back up to offending char */ unreadChar ( jsonText ) ; error = STRING_INVALID_HEX_CHAR ; break finish_string_lex ; } } } else if ( ( CHAR_LOOKUP_TABLE [ curChar ] & VEC ) == 0 ) { /* back up to offending char */ unreadChar ( jsonText ) ; error = STRING_INVALID_ESCAPED_CHAR ; break ; } } /* when not validating UTF8 it's a simple table lookup to determine * if the present character is invalid */ else if ( ( CHAR_LOOKUP_TABLE [ curChar ] & IJC ) != 0 ) { /* back up to offending char */ unreadChar ( jsonText ) ; error = STRING_INVALID_JSON_CHAR ; break ; } /* when in validate UTF8 mode we need to do some extra work */ else if ( validateUTF8 ) { TokenType t = lexUtf8Char ( jsonText , curChar ) ; if ( t == EOF ) { tok = EOF ; break ; } else if ( t == ERROR ) { error = STRING_INVALID_UTF8 ; break ; } } /* accept it, and move on */ } /* tell our buddy, the parser, whether he needs to process this string again */ if ( hasEscapes && tok == STRING ) { tok = STRING_WITH_ESCAPES ; } return tok ; }
Lex a string .