/** * Creates a new archive. * * @param ctx query context * @return archive * @throws QueryException query exception */ private B64 create(final QueryContext ctx) throws QueryException { final Iter entr = ctx.iter(expr[0]); final Iter cont = ctx.iter(expr[1]); final Item opt = expr.length > 2 ? expr[2].item(ctx, info) : null; final TokenMap map = new FuncParams(Q_OPTIONS, info).parse(opt); final byte[] f = map.get(FORMAT); final String format = f != null ? string(lc(f)) : "zip"; final ArchiveOut out = ArchiveOut.get(format, info); // check algorithm final byte[] alg = map.get(ALGORITHM); int level = ZipEntry.DEFLATED; if (alg != null) { if (format.equals("zip") && !eq(alg, STORED, DEFLATE) || format.equals("gzip") && !eq(alg, DEFLATE)) { ARCH_SUPP.thrw(info, ALGORITHM, alg); } if (eq(alg, STORED)) level = ZipEntry.STORED; else if (eq(alg, DEFLATE)) level = ZipEntry.DEFLATED; } out.level(level); try { int e = 0; int c = 0; Item en, cn; while (true) { en = entr.next(); cn = cont.next(); if (en == null || cn == null) break; if (out instanceof GZIPOut && c > 0) ARCH_ONE.thrw(info, format.toUpperCase(Locale.ENGLISH)); add(checkElmStr(en), cn, out, level); e++; c++; } // count remaining entries if (cn != null) do c++; while (cont.next() != null); if (en != null) do e++; while (entr.next() != null); if (e != c) throw ARCH_DIFF.thrw(info, e, c); } catch (final IOException ex) { Util.debug(ex); throw ARCH_FAIL.thrw(info, ex); } finally { out.close(); } return new B64(out.toArray()); }
/** * Scans a PEReference. [69] * * @return entity * @throws IOException I/O exception */ private byte[] peRef() throws IOException { // scans predefined entities final byte[] name = name(true); consume(';'); final byte[] en = pents.get(name); if (en != null) return en; return name; }
/** * 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; }
/** * Reads next character or throws an exception if all bytes have been read. * * @return next character * @throws IOException I/O exception */ private int consume() throws IOException { while (true) { final int ch = input.read(); if (ch == -1) return 0; if (ch == '%' && pe) { // [69] final byte[] key = name(true); final byte[] val = pents.get(key); if (val == null) error(UNKNOWNPE, key); check(';'); input.add(val, true); } else { return ch; } } }
/** * Builds the thesaurus. * * @param value input nodes * @throws QueryException query exception */ private void build(final Value value) throws QueryException { final Value synonyms = nodes("*:synonym", value); if (synonyms.isEmpty()) return; final ThesNode term = node(text("*:term", value)); for (final Item synonym : synonyms) { final ThesNode sterm = node(text("*:term", synonym)); final byte[] rs = text("*:relationship", synonym); term.add(sterm, rs); final byte[] srs = RSHIPS.get(rs); if (srs != null) sterm.add(term, srs); build(synonyms); } }