Read an Erlang atom from the stream.

@return a String containing the value of the atom.

@exception OtpErlangDecodeException
if the next term in the stream is not an atom.
969177
@SuppressWarnings("fallthrough")
    public String read_atom() throws OtpErlangDecodeException {
        int tag;
        int len = -1;
        byte[] strbuf;
        String atom;

        tag = read1skip_version();

        switch (tag) {

        case OtpExternal.atomTag:
            len = read2BE();
            strbuf = new byte[len];
            this.readN(strbuf);
            try {
                atom = new String(strbuf, "ISO-8859-1");
            } catch (final java.io.UnsupportedEncodingException e) {
                throw new OtpErlangDecodeException(
                        "Failed to decode ISO-8859-1 atom");
            }
            if (atom.length() > OtpExternal.maxAtomLength) {
                /*
                 * Throwing an exception would be better I think, but truncation
                 * seems to be the way it has been done in other parts of OTP...
                 */
                atom = atom.substring(0, OtpExternal.maxAtomLength);
            }
            break;

        case OtpExternal.smallAtomUtf8Tag:
            len = read1();
            // fall-through
        case OtpExternal.atomUtf8Tag:
            if (len < 0) {
                len = read2BE();
            }
            strbuf = new byte[len];
            this.readN(strbuf);
            try {
                atom = new String(strbuf, "UTF-8");
            } catch (final java.io.UnsupportedEncodingException e) {
                throw new OtpErlangDecodeException(
                        "Failed to decode UTF-8 atom");
            }
            if (atom.codePointCount(0, atom.length()) > OtpExternal.maxAtomLength) {
                /*
                 * Throwing an exception would be better I think, but truncation
                 * seems to be the way it has been done in other parts of OTP...
                 */
                final int[] cps = OtpErlangString.stringToCodePoints(atom);
                atom = new String(cps, 0, OtpExternal.maxAtomLength);
            }
            break;

        default:
            throw new OtpErlangDecodeException(
                    "wrong tag encountered, expected " + OtpExternal.atomTag
                            + ", or " + OtpExternal.atomUtf8Tag + ", got "
                            + tag);
        }

        return atom;
    }
589083
public String readType()
        throws IOException
    {
        int code = read();

        if (code != 't') {
            _peek = code;
            return "";
        }

        _isLastChunk = true;
        _chunkLength = (read() << 8) + read();

        _sbuf.setLength(0);
        int ch;
        while ((ch = parseChar()) >= 0)
            _sbuf.append((char) ch);

        return _sbuf.toString();
    }
632855
public double read_double() throws OtpErlangDecodeException {
        int tag;

        // parse the stream
        tag = read1skip_version();

        switch (tag) {
        case OtpExternal.newFloatTag: {
            return Double.longBitsToDouble(readBE(8));
        }
        case OtpExternal.floatTag: {
            BigDecimal val;
            int epos;
            int exp;
            final byte[] strbuf = new byte[31];
            String str;

            // get the string
            this.readN(strbuf);
            str = OtpErlangString.newString(strbuf);

            // find the exponent prefix 'e' in the string
            epos = str.indexOf('e', 0);

            if (epos < 0) {
                throw new OtpErlangDecodeException("Invalid float format: '"
                        + str + "'");
            }

            // remove the sign from the exponent, if positive
            String estr = str.substring(epos + 1).trim();

            if (estr.substring(0, 1).equals("+")) {
                estr = estr.substring(1);
            }

            // now put the mantissa and exponent together
            exp = Integer.valueOf(estr).intValue();
            val = new BigDecimal(str.substring(0, epos)).movePointRight(exp);

            return val.doubleValue();
        }
        default:
            throw new OtpErlangDecodeException(
                    "Wrong tag encountered, expected "
                            + OtpExternal.newFloatTag + ", got " + tag);
        }
    }
176165
private Object readLiteral() throws JSONException {
        String literal = nextToInternal("{}[]/\\:,=;# \t\f");

        if (literal.length() == 0) {
            throw syntaxError("Expected literal value");
        } else if ("null".equalsIgnoreCase(literal)) {
            return JSONObject.NULL;
        } else if ("true".equalsIgnoreCase(literal)) {
            return Boolean.TRUE;
        } else if ("false".equalsIgnoreCase(literal)) {
            return Boolean.FALSE;
        }

        /* try to parse as an integral type... */
        if (literal.indexOf('.') == -1) {
            int base = 10;
            String number = literal;
            if (number.startsWith("0x") || number.startsWith("0X")) {
                number = number.substring(2);
                base = 16;
            } else if (number.startsWith("0") && number.length() > 1) {
                number = number.substring(1);
                base = 8;
            }
            try {
                long longValue = Long.parseLong(number, base);
                if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
                    return (int) longValue;
                } else {
                    return longValue;
                }
            } catch (NumberFormatException e) {
                /*
                 * This only happens for integral numbers greater than
                 * Long.MAX_VALUE, numbers in exponential form (5e-10) and
                 * unquoted strings. Fall through to try floating point.
                 */
            }
        }

        /* ...next try to parse as a floating point... */
        try {
            return Double.valueOf(literal);
        } catch (NumberFormatException ignored) {
        }

        /* ... finally give up. We have an unquoted string */
        return new String(literal); // a new string avoids leaking memory
    }
143216
public byte byteValue() throws OtpErlangRangeException {
        final long l = longValue();
        final byte i = (byte) l;

        if (i != l) {
            throw new OtpErlangRangeException("Value too large for byte: "
                    + val);
        }

        return i;
    }
336421
public String readLine() throws IOException {
		StringBuilder bldr = new StringBuilder();
		while (true) {
			int b = read();
			if (b == -1 || b == 10) {
				break;
			} else if (b != '\r') {
				bldr.append((char) ((byte) b));
			}
		}
		return bldr.toString();
	}
270950
public Asn1Object read() throws IOException {
        int tag = in.read();

        if (tag == -1)
            throw new IOException("Invalid DER: stream too short, missing tag"); //$NON-NLS-1$

        int length = getLength();

        byte[] value = new byte[length];
        int n = in.read(value);
        if (n < length)
            throw new IOException("Invalid DER: stream too short, missing value"); //$NON-NLS-1$

        Asn1Object o = new Asn1Object(tag, length, value);

        return o;
    }
1048733
public short read_ushort() throws OtpErlangDecodeException {
        final long l = this.read_long(true);
        final short i = (short) l;

        if (l != (i & 0xffffL)) {
            throw new OtpErlangDecodeException("Value does not fit in ushort: "
                    + l);
        }

        return i;
    }
868437
private String readTrimmedLine() throws IOException {
        String line = readLine();
        if (line != null)
            return line.trim();
        else
            throw new EOFException();
    }
984109
public static Reader getReadEncoding(InputStream is, String encoding)
    throws UnsupportedEncodingException
  {
    return getReadFactory(encoding).create(is);
  }
1270841
public long readBELong() throws IOException {
		return EndianNumbers.toBELong(read(), read(), read(), read(), read(), read(), read(), read());
	}
866062
public int readTag() throws IOException {
		byte b = (byte) this.read();

		this.tagClass = (b & Tag.CLASS_MASK) >> 6;
		this.pCBit = (b & Tag.PC_MASK) >> 5;

		this.tag = b & Tag.TAG_MASK;

		// For larger tag values, the first octet has all ones in bits 5 to 1,
		// and the tag value is then encoded in
		// as many following octets as are needed, using only the least
		// significant seven bits of each octet,
		// and using the minimum number of octets for the encoding. The most
		// significant bit (the "more"
		// bit) is set to 1 in the first following octet, and to zero in the
		// last.
		if (tag == Tag.TAG_MASK) {
			byte temp;
			tag = 0;
			do {
				temp = (byte) this.read();
				tag = (tag << 7) | (0x7F & temp);
			} while (0 != (0x80 & temp));
		}

		return tag;
	}
422881
private int get(boolean inStringLiteral) throws IOException {
		int c = theLookahead;
		theLookahead = EOF;
		if (c == EOF) {
			c = in.read();
			if (c != EOF) {
				currentByteIndex++;
			}
		}
		if (c == '\n') {
			line++;
			column = 0;
		} else {
			column++;
		}
		if (c >= ' ' || c == '\n' || c == EOF || (inStringLiteral && c == '\t')) { // Handle
																					// the
																					// case
																					// of
																					// tab
																					// character
																					// in
																					// String
																					// literal
			return c;
		}

		if (c == '\r') {
			return '\n';
		}
		return ' ';
	}
885874
public Reader getReader() throws IOException {
       // we want to remove the BOM windows adds from a file if the encoding is UTF-8
       // in other cases we depend on the charsets 
       Charset cs = Charset.forName(configuration.getSourceEncoding());
       InputStream in = new BufferedInputStream(new FileInputStream(file));
       if (UTF8.name().equalsIgnoreCase(cs.name())) {
           in.mark(3);
           boolean hasBOM = true;
           try {
               int i = in.read();
               hasBOM &= i == 0xEF;
               i = in.read();
               hasBOM &= i == 0xBB;
               i = in.read();
               hasBOM &= i == 0xFF;
           } catch (IOException ioe) {
               hasBOM= false;
           }
           if (!hasBOM) in.reset();
       }
       return new InputStreamReader( in, cs );
    }
329795
@Override
	public int read() throws IOException {
		int ch = super.read();
		if (!escaped && charsToEscape.contains((char) ch)) {
			// special case for non-displayable characters
			switch (ch) {
			case '\n':
				ch = 'n';
				break;
			case '\r':
				ch = 'r';
				break;
			case '\t':
				ch = 't';
				break;
			}
			super.unread(ch);
			escaped = true;
			ch = '\\';
		} else {
			escaped = false;
		}
		return ch;
	}
1271270
public static short readShortLittleEndian(IO.ReadableByteStream io) throws IOException {
		int value = io.read();
		if (value < 0) throw new EOFException();
		int i = io.read();
		if (i < 0) throw new EOFException();
		return (short)(value | (i << 8));
	}
908156
public Char read() throws IOException {
        int cp = in.read();
        if (cp < 0) {
            return null;
        }

        if (cp == '\033') {
            // 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 == '\033') {
                // 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 ('A' <= c3 && c3 <= 'Z') {
                    // \033 [ A-Z
                    return new Control(charBuilder.toString());
                }
                while (('0' <= c3 && c3 <= '9') || c3 == ';') {
                    c3 = expect();
                    charBuilder.append(c3);
                }
                if (c3 == '~' ||
                    ('a' <= c3 && c3 <= 'z') ||
                    ('A' <= c3 && c3 <= 'Z')) {
                    // \033 [ (number) ~ (F1, F2 ... Fx)
                    // \033 [ (number...;) [A-D] (numbered cursor movement)
                    // \033 [ (number...;) [su] (cursor save / restore, ...)
                    // \033 [ (number...;) m (color)
                    if (c3 == 'm') {
                        try {
                            return new Color(charBuilder.toString());
                        } catch (IllegalArgumentException e) {
                            throw new IOException(e.getMessage(), e);
                        }
                    }
                    return new Control(charBuilder.toString());
                }
            } else if (c2 == 'O') {
                char c3 = expect();
                charBuilder.append(c3);
                if ('A' <= c3 && c3 <= 'Z') {
                    // \033 O [A-Z]
                    return new Control(charBuilder.toString());
                }
            } else if (('a' <= c2 && c2 <= 'z') ||
                       ('0' <= c2 && c2 <= '9') ||
                       ('A' <= c2 && c2 <= 'Z')) {
                // \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);
        }
    }