Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/InputLexer.java
41161 views
/*1* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.debugger;2526import java.io.*;2728/** InputLexer is the lexer through which the current set of debuggers29see the debug server. It provides the ability to read all of the30types the debuggers are interested in. All read operations are31blocking. */3233public class InputLexer {34public InputLexer(BufferedInputStream in) throws IOException {35this.in = in;36pushedBack = false;37}3839public void close() throws IOException {40in.close();41}4243/** Parses a boolean (really either a 0 or 1 integer in US-ASCII44encoding) on the input stream */45public boolean parseBoolean() throws IOException {46int val = parseInt();47return (val != 0);48}4950/** Parses an int in US-ASCII encoding on the input stream */51public int parseInt() throws IOException {52long l = parseLong();53long mask = 0xFFFFFFFF00000000L;54if ((l & mask) != 0) {55throw new IOException("Overflow error reading int from debug server (read " + l + ")");56}57return (int) l;58}5960/** Parses a long in US-ASCII encoding on the input stream */61public long parseLong() throws IOException {62skipWhitespace();63byte b = readByte();64if (!Character.isDigit((char) b)) {65error();66}67long l = 0;68while (Character.isDigit((char) b)) {69l *= 10;70l += (b - '0');71b = readByte();72}73pushBack(b);74return l;75}7677/** Parses an address in the form 0x12345678 in US-ASCII encoding on78the input stream */79public long parseAddress() throws IOException {80skipWhitespace();81byte b;82if ((b = readByte()) != '0') {83error();84}85b = readByte();86if (b != 'x') {87error();88}89long val = 0;90while (isHexDigit((char) (b = readByte()))) {91val *= 16;92val += Character.digit((char) b, 16);93}94pushBack(b);95return val;96}9798public void skipByte() throws IOException {99readByte();100}101102/** Reads binary data; one byte */103public byte readByte() throws IOException {104if (pushedBack) {105pushedBack = false;106return backBuf;107}108return readByteInternal();109}110111/** Reads a block of binary data in BLOCKING fashion */112public void readBytes(byte[] buf, int off, int len) throws IOException {113int startIdx = off;114int numRead = 0;115if (pushedBack) {116buf[startIdx] = backBuf;117pushedBack = false;118++startIdx;119++numRead;120}121while (numRead < len) {122numRead += in.read(buf, startIdx + numRead, len - numRead);123}124// if (numRead != len) {125// throw new IOException("Only read " + numRead + " out of " +126// len + " bytes requested");127// }128}129130/** Reads binary data; one 16-bit character in big-endian format */131public char readChar() throws IOException {132int hi = ((int) readByte()) & 0xFF;133int lo = ((int) readByte()) & 0xFF;134return (char) ((hi << 8) | lo);135}136137/** Reads binary data; one 32-bit unsigned int in big-endian format.138Returned as a long. */139public long readUnsignedInt() throws IOException {140long b1 = ((long) readByte()) & 0xFF;141long b2 = ((long) readByte()) & 0xFF;142long b3 = ((long) readByte()) & 0xFF;143long b4 = ((long) readByte()) & 0xFF;144145return ((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);146}147148/** Reads binary data; a US-ASCII string of the specified length */149public String readByteString(int len) throws IOException {150byte[] b = new byte[len];151for (int i = 0; i < len; i++) {152b[i] = readByte();153}154try {155return new String(b, "US-ASCII");156}157catch (UnsupportedEncodingException e) {158throw new IOException(e.toString());159}160}161162/** Reads binary data; a Unicode string of the specified length */163public String readCharString(int len) throws IOException {164char[] c = new char[len];165for (int i = 0; i < len; i++) {166c[i] = readChar();167}168return new String(c);169}170171//----------------------------------------------------------------------172// Internals only below this point173//174175private void skipWhitespace() throws IOException {176byte b;177while (Character.isWhitespace((char) (b = readByte()))) {178}179pushBack(b);180}181182private boolean isHexDigit(char c) {183return (('0' <= c && c <= '9') ||184('a' <= c && c <= 'f') ||185('A' <= c && c <= 'F'));186}187188private void pushBack(byte b) {189if (pushedBack) {190throw new InternalError("Only one character pushback supported");191}192backBuf = b;193pushedBack = true;194}195196private byte readByteInternal() throws IOException {197int i = in.read();198if (i == -1) {199throw new IOException("End-of-file reached while reading from server");200}201return (byte) i;202}203204private void error() throws IOException {205throw new IOException("Error parsing output of debug server");206}207208private BufferedInputStream in;209private boolean pushedBack;210private byte backBuf;211}212213214