/** * Scans a reference. [67] * * @param f dissolve entities * @return entity * @throws IOException I/O exception */ private byte[] ref(final boolean f) throws IOException { // scans numeric entities if (consume('#')) { // [66] final TokenBuilder ent = new TokenBuilder(); int b = 10; int ch = nextChar(); ent.add(ch); if (ch == 'x') { b = 16; ent.add(ch = nextChar()); } int n = 0; do { final boolean m = ch >= '0' && ch <= '9'; final boolean h = b == 16 && (ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F'); if (!m && !h) { completeRef(ent); return QUESTION; } n *= b; n += ch & 15; if (!m) n += 9; ent.add(ch = nextChar()); } while (ch != ';'); if (!valid(n)) return QUESTION; ent.reset(); ent.add(n); return ent.finish(); } // scans predefined entities [68] final byte[] name = name(false); if (!consume(';')) return QUESTION; if (!f) return concat(AMPER, name, SEMI); byte[] en = ents.get(name); if (en == null) { // unknown entity: try HTML entities (lazy initialization) if (HTMLENTS.size() == 0) { for (int s = 0; s < HTMLENTITIES.length; s += 2) { HTMLENTS.add(token(HTMLENTITIES[s]), token(HTMLENTITIES[s + 1])); } } en = HTMLENTS.get(name); } return en == null ? QUESTION : en; }
/** * Converts the path to a string array, containing the single segments. * * @param path path, or {@code null} * @return path depth */ public static String[] toSegments(final String path) { final StringList sl = new StringList(); if (path != null) { final TokenBuilder tb = new TokenBuilder(); for (int s = 0; s < path.length(); s++) { final char ch = path.charAt(s); if (ch == '/') { if (tb.isEmpty()) continue; sl.add(tb.toString()); tb.reset(); } else { tb.add(ch); } } if (!tb.isEmpty()) sl.add(tb.toString()); } return sl.toArray(); }
/** * Performs a test on the specified data. * * @param data data to be tested * @throws IOException I/O exception */ private static void run(final byte[] data) throws IOException { final TokenBuilder tb = new TokenBuilder(); final TextInput ti = new TextInput(new IOContent(data)); ti.read(); ti.reset(); for (int b; (b = ti.read()) != -1; ) tb.add(b); try { ti.reset(); assertTrue( "Mark should not be supported for data size of " + data.length, data.length < IO.BLOCKSIZE); tb.reset(); for (int b; (b = ti.read()) != -1; ) tb.add(b); assertSame(data, tb.finish()); } catch (final IOException ex) { assertTrue( "Mark could not be reset for data size of " + data.length, data.length >= IO.BLOCKSIZE); } }
/** * Reads and interprets the next token from the input stream. * * @return true if the document scanning has been completed * @throws IOException I/O exception */ boolean more() throws IOException { // gets next character from the input stream token.reset(); final int ch = consume(); if (ch == 0) { type = Type.EOF; return false; } // checks the scanner state switch (state) { case CONTENT: scanCONTENT(ch); break; case TAG: case ATT: scanTAG(ch); break; case QUOTE: scanATTVALUE(ch); } return true; }
/** * Adds the error message to the message buffer {@link #info}. * * @param msg error message * @param ext error extension * @return {@code false} */ protected final boolean error(final String msg, final Object... ext) { info.reset(); info.addExt(msg == null ? "" : msg, ext); return false; }