/** * Scans an external ID. * * @param f full flag * @param r root flag * @return id * @throws IOException I/O exception */ private byte[] externalID(final boolean f, final boolean r) throws IOException { byte[] cont = null; final boolean pub = consume(PUBLIC); if (pub || consume(SYSTEM)) { checkS(); if (pub) { pubidLit(); if (f) checkS(); } final int qu = consume(); // [11] if (qu == '\'' || qu == '"') { int ch; final TokenBuilder tok = new TokenBuilder(); while ((ch = nextChar()) != qu) tok.add(ch); if (!f) return null; final String name = string(tok.finish()); if (!dtd && r) return cont; final XMLInput tin = input; try { final IO file = input.io().merge(name); cont = file.read(); } catch (final IOException ex) { Util.debug(ex); // skip unknown DTDs/entities cont = new byte[] {'?'}; } input = new XMLInput(new IOContent(cont, name)); if (consume(XDECL)) { check(XML); s(); if (version()) checkS(); s(); if (encoding() == null) error(TEXTENC); ch = nextChar(); if (s(ch)) ch = nextChar(); if (ch != '?') error(WRONGCHAR, '?', ch); ch = nextChar(); if (ch != '>') error(WRONGCHAR, '>', ch); cont = Arrays.copyOfRange(cont, input.pos(), cont.length); } s(); if (r) { extSubsetDecl(); if (!consume((char) 0)) error(INVEND); } input = tin; } else { if (f) error(SCANQUOTE, (char) qu); prev(1); } } return cont; }
@Override public double prog() { final double l = input.length(); return l <= 0 ? 0 : input.pos() / l; }