/** * Performs the test-uris function. * * @param ctx query context * @return resulting value * @throws QueryException query exception */ private Item testUris(final QueryContext ctx) throws QueryException { checkCreate(ctx); final ArrayList<IO> inputs = new ArrayList<>(); final Iter ir = ctx.iter(expr[0]); for (Item it; (it = ir.next()) != null; ) inputs.add(checkPath(it, ctx)); return new Suite(ctx, info).test(inputs); }
/** * Extracts entries from the archive. * * @param ctx query context * @return text entries * @throws QueryException query exception */ private TokenList extract(final QueryContext ctx) throws QueryException { final B64 archive = (B64) checkType(checkItem(expr[0], ctx), AtomType.B64); TokenSet hs = null; if (expr.length > 1) { // filter result to specified entries hs = new TokenSet(); final Iter names = ctx.iter(expr[1]); for (Item en; (en = names.next()) != null; ) { hs.add(checkElmStr(en).string(info)); } } final TokenList tl = new TokenList(); final ArchiveIn in = ArchiveIn.get(archive.input(info), info); try { while (in.more()) { final ZipEntry ze = in.entry(); if (ze.isDirectory()) continue; if (hs == null || hs.delete(token(ze.getName())) != 0) tl.add(in.read()); } } catch (final IOException ex) { Util.debug(ex); ARCH_FAIL.thrw(info, ex); } finally { in.close(); } return tl; }
/** * Performs the assert-equals function. * * @param ctx query context * @return resulting value * @throws QueryException query exception */ private Item assertEquals(final QueryContext ctx) throws QueryException { final byte[] str = expr.length < 3 ? null : checkStr(expr[2], ctx); final Iter iter1 = ctx.iter(expr[0]), iter2 = ctx.iter(expr[1]); final Compare comp = new Compare(info); Item it1, it2; int c = 1; while (true) { it1 = iter1.next(); it2 = iter2.next(); final boolean empty1 = it1 == null, empty2 = it2 == null; if (empty1 && empty2) return null; if (empty1 || empty2 || !comp.deep(it1.iter(), it2.iter())) break; c++; } if (str != null) throw UNIT_MESSAGE.get(info, str); throw new UnitException(info, UNIT_ASSERT_EQUALS, it1, it2, c); }
/** * Performs the test function. * * @param ctx query context * @return resulting value * @throws QueryException query exception */ private Item test(final QueryContext ctx) throws QueryException { final Unit unit = new Unit(ctx, info); if (expr.length == 0) return unit.test(sc); final ArrayList<StaticFunc> funcs = new ArrayList<>(); final Iter ir = ctx.iter(expr[0]); for (Item it; (it = ir.next()) != null; ) { final FItem fi = checkFunc(it, ctx); if (fi.funcName() != null) { final StaticFunc sf = ctx.funcs.get(fi.funcName(), fi.arity(), null, true); if (sf != null) funcs.add(sf); } } return unit.test(sc, funcs); }
/** * 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()); }
/** * Updates an archive. * * @param ctx query context * @return updated archive * @throws QueryException query exception */ private B64 update(final QueryContext ctx) throws QueryException { final B64 archive = (B64) checkType(checkItem(expr[0], ctx), AtomType.B64); // entries to be updated final TokenObjMap<Item[]> hm = new TokenObjMap<Item[]>(); final Iter entr = ctx.iter(expr[1]); final Iter cont = ctx.iter(expr[2]); int e = 0; int c = 0; Item en, cn; while (true) { en = entr.next(); cn = cont.next(); if (en == null || cn == null) break; hm.add(checkElmStr(en).string(info), new Item[] {en, cn}); 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) ARCH_DIFF.thrw(info, e, c); final ArchiveIn in = ArchiveIn.get(archive.input(info), info); final ArchiveOut out = ArchiveOut.get(in.format(), info); try { if (in instanceof GZIPIn) ARCH_MODIFY.thrw(info, in.format().toUpperCase(Locale.ENGLISH)); // delete entries to be updated while (in.more()) if (!hm.contains(token(in.entry().getName()))) out.write(in); // add new and updated entries for (final byte[] h : hm) { if (h == null) continue; final Item[] it = hm.get(h); add(it[0], it[1], out, ZipEntry.DEFLATED); } } catch (final IOException ex) { Util.debug(ex); ARCH_FAIL.thrw(info, ex); } finally { in.close(); out.close(); } return new B64(out.toArray()); }
/** * Deletes files from an archive. * * @param ctx query context * @return updated archive * @throws QueryException query exception */ private B64 delete(final QueryContext ctx) throws QueryException { final B64 archive = (B64) checkType(checkItem(expr[0], ctx), AtomType.B64); // entries to be deleted final TokenObjMap<Item[]> hm = new TokenObjMap<Item[]>(); final Iter names = ctx.iter(expr[1]); for (Item en; (en = names.next()) != null; ) { hm.add(checkElmStr(en).string(info), null); } final ArchiveIn in = ArchiveIn.get(archive.input(info), info); final ArchiveOut out = ArchiveOut.get(in.format(), info); try { if (in instanceof GZIPIn) ARCH_MODIFY.thrw(info, in.format().toUpperCase(Locale.ENGLISH)); while (in.more()) if (!hm.contains(token(in.entry().getName()))) out.write(in); } catch (final IOException ex) { Util.debug(ex); ARCH_FAIL.thrw(info, ex); } finally { in.close(); out.close(); } return new B64(out.toArray()); }
@Override public B64 item(final QueryContext qc, final InputInfo ii) throws QueryException { checkCreate(qc); final IOFile root = new IOFile(toPath(0, qc).toString()); final ArchOptions opts = toOptions(1, Q_OPTIONS, new ArchOptions(), qc); final Iter entries; if (exprs.length > 2) { entries = qc.iter(exprs[2]); } else { final TokenList tl = new TokenList(); for (final String file : root.descendants()) tl.add(file); entries = StrSeq.get(tl).iter(); } final String format = opts.get(ArchOptions.FORMAT); final int level = level(opts); if (!root.isDir()) throw FILE_NO_DIR_X.get(info, root); try (final ArchiveOut out = ArchiveOut.get(format.toLowerCase(Locale.ENGLISH), info)) { out.level(level); try { while (true) { Item en = entries.next(); if (en == null) break; en = checkElemToken(en); final IOFile file = new IOFile(root, string(en.string(info))); if (!file.exists()) throw FILE_NOT_FOUND_X.get(info, file); if (file.isDir()) throw FILE_IS_DIR_X.get(info, file); add(en, new B64(file.read()), out, level, qc); } } catch (final IOException ex) { throw ARCH_FAIL_X.get(info, ex); } return new B64(out.finish()); } }
/** * Returns a result value. * * @return result value * @throws QueryException query exception */ public Value value() throws QueryException { parse(); return qc.iter().value(); }
/** * Returns a result iterator. * * @return result iterator * @throws QueryException query exception */ public Iter iter() throws QueryException { parse(); return qc.iter(); }