public Char read ( ) throws IOException { int cp = in . read ( ) ; if ( cp < 0 ) { return null ; } if ( cp == ' ' ) { // We have received an 'esc' and nothing else... if ( ! in . ready ( ) ) { return new Unicode ( cp ) ; } // 'esc' was last char in stream. int c2 = in . read ( ) ; if ( c2 < 0 ) { return new Unicode ( cp ) ; } StringBuilder charBuilder = new StringBuilder ( ) ; charBuilder . append ( ( char ) cp ) ; charBuilder . append ( ( char ) c2 ) ; if ( c2 == ' ' ) { // Treat double 'esc' as a single 'esc'. Otherwise pressing 'esc' // will consistently crash the application. return new Unicode ( cp ) ; } else if ( c2 == ' ' ) { char c3 = expect ( ) ; charBuilder . append ( c3 ) ; if ( ' ' <= c3 && c3 <= ' ' ) { // \033 [ A-Z return new Control ( charBuilder . toString ( ) ) ; } while ( ( ' ' <= c3 && c3 <= ' ' ) || c3 == ' ' ) { c3 = expect ( ) ; charBuilder . append ( c3 ) ; } if ( c3 == ' ' || ( ' ' <= c3 && c3 <= ' ' ) || ( ' ' <= c3 && c3 <= ' ' ) ) { // \033 [ (number) ~ (F1, F2 ... Fx) // \033 [ (number...;) [A-D] (numbered cursor movement) // \033 [ (number...;) [su] (cursor save / restore, ...) // \033 [ (number...;) m (color) if ( c3 == ' ' ) { try { return new Color ( charBuilder . toString ( ) ) ; } catch ( IllegalArgumentException e ) { throw new IOException ( e . getMessage ( ) , e ) ; } } return new Control ( charBuilder . toString ( ) ) ; } } else if ( c2 == ' ' ) { char c3 = expect ( ) ; charBuilder . append ( c3 ) ; if ( ' ' <= c3 && c3 <= ' ' ) { // \033 O [A-Z] return new Control ( charBuilder . toString ( ) ) ; } } else if ( ( ' ' <= c2 && c2 <= ' ' ) || ( ' ' <= c2 && c2 <= ' ' ) || ( ' ' <= c2 && c2 <= ' ' ) ) { // \033 [a-z]: <alt-{c}> aka <M-{c}>. // \033 [0-9]: <alt-{c}> aka <M-{c}>. // \033 [A-N]: <alt-shift-{c}> aka <M-S-{c}>. // \033 [P-Z]: <alt-shift-{c}> aka <M-S-{c}>. return new Control ( charBuilder . toString ( ) ) ; } throw new IOException ( "Invalid escape sequence: \"" + Strings . escape ( charBuilder . toString ( ) ) + "\"" ) ; } else { // Make sure to consume both surrogates on 32-bit code-points. if ( Character . isHighSurrogate ( ( char ) cp ) ) { cp = Character . toCodePoint ( ( char ) cp , expect ( ) ) ; } return new Unicode ( cp ) ; } }
Read the next char .