/** * Adds the specified entry to the output stream. * * @param entry entry descriptor * @param con contents * @param out output archive * @param level default compression level * @throws QueryException query exception * @throws IOException I/O exception */ private void add(final Item entry, final Item con, final ArchiveOut out, final int level) throws QueryException, IOException { // create new zip entry final String name = string(entry.string(info)); if (name.isEmpty()) ARCH_EMPTY.thrw(info); final ZipEntry ze = new ZipEntry(name); String en = null; // compression level byte[] lvl = null; if (entry instanceof ANode) { final ANode el = (ANode) entry; lvl = el.attribute(Q_LEVEL); // last modified final byte[] mod = el.attribute(Q_LAST_MOD); if (mod != null) { try { ze.setTime(new Int(new Dtm(mod, info)).itr()); } catch (final QueryException qe) { ARCH_DATETIME.thrw(info, mod); } } // encoding final byte[] enc = el.attribute(Q_ENCODING); if (enc != null) { en = string(enc); if (!Charset.isSupported(en)) ARCH_ENCODING.thrw(info, enc); } } // data to be compressed byte[] val = checkStrBin(con); if (con instanceof AStr && en != null && en != Token.UTF8) val = encode(val, en); try { out.level(lvl == null ? level : toInt(lvl)); } catch (final IllegalArgumentException ex) { ARCH_LEVEL.thrw(info, lvl); } out.write(ze, val); }
@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()); } }