/** * Constructs a new extra field. * * @param headerId an unsigned short integer (two bytes) indicating the * type of the extra field. */ DefaultExtraField(final int headerId) { assert UShort.check(headerId); this.headerId = (short) headerId; }
/** Sets the General Purpose Bit Flags. */ final void setGeneralPurposeBitFlags(final int general) { assert UShort.check(general); this.general = (short) general; }
void setMethod(final int compressionMethod) { assert UShort.check(compressionMethod); this.method = (short) compressionMethod; }
/** * Checks the parameter range. * * @param i The integer to check to be in the range of an unsigned short * integer ({@value SIZE} bits). * @return {@code true} * @throws IllegalArgumentException If {@code i} is less than * {@link #MIN_VALUE} or greater than {@link #MAX_VALUE}. */ public static boolean check(final int i) { return check(i, "Integer out of range", null); } }
/** Constructs a new ZIP entry with the given name. */ public ZipEntry(final String name) { UShort.check(name.length()); this.name = name; }
@Override void readFrom(final byte[] buf, final int off, final int len) { assert UShort.check(len); arraycopy(buf, off, this.data = new byte[len], 0, len); }
final void setRawComment(final String comment) { assert UShort.check(comment.length()); this.comment = comment; }
/** * Sets the entry comment. * Note that this method limits the comment size to 64 KB. * Therefore, this property should not be used to hold arbitrary * (application) data. * Consider storing such data in a separate entry instead. * * @param comment The entry comment. * @throws RuntimeException if the entry comment exceeds 64 KB. */ public final void setComment(final @CheckForNull String comment) { if (null != comment) UShort.check(comment.length(), name, "Comment too long"); this.comment = comment; }
final void setRawMethod(final int method) { assert UShort.check(method); this.method = (short) method; setInit(METHOD, true); }
/** * Sets the file comment. * * @param comment the file comment. * @throws IllegalArgumentException if the encoded comment is longer than * {@link UShort#MAX_VALUE} bytes. */ public void setComment(final @CheckForNull String comment) { if (null != comment && !comment.isEmpty()) { final byte[] bytes = encode(comment); UShort.check(bytes.length); this.comment = bytes; } else { this.comment = null; } }
/** * Removes the Extra Field with the given Header ID. * * @param headerId The requested Header ID. * @return The Extra Field with the given Header ID or {@code null} * if no such Extra Field exists. * @throws IllegalArgumentException If {@code headerID} is not in * the range of {@code 0} to {@link UShort#MAX_VALUE} * ({@value de.schlichtherle.truezip.zip.UShort#MAX_VALUE}). */ @Nullable ExtraField remove(final int headerId) { assert UShort.check(headerId); final ExtraField ef = extra.remove(headerId); assert null == ef || ef.getHeaderId() == headerId; return ef; }
/** * Returns the Extra Field with the given Header ID or {@code null} * if no such Extra Field exists. * * @param headerId The requested Header ID. * @return The Extra Field with the given Header ID or {@code null} * if no such Extra Field exists. * @throws IllegalArgumentException If {@code headerID} is not in * the range of {@code 0} to {@link UShort#MAX_VALUE} * ({@value de.schlichtherle.truezip.zip.UShort#MAX_VALUE}). */ @CheckForNull ExtraField get(final int headerId) { assert UShort.check(headerId); final ExtraField ef = extra.get(headerId); assert null == ef || ef.getHeaderId() == headerId; return ef; }
/** * Stores the given Extra Field in this collection. * * @param ef The Extra Field to store in this collection. * @return The Extra Field previously associated with the Header ID of * of the given Extra Field or {@code null} if no such * Extra Field existed. * @throws NullPointerException If {@code ef} is {@code null}. * @throws IllegalArgumentException If the Header ID of the given Extra * Field is not in the range of {@code 0} to * {@link UShort#MAX_VALUE} * ({@value de.schlichtherle.truezip.zip.UShort#MAX_VALUE}). */ ExtraField add(final ExtraField ef) { final int headerId = ef.getHeaderId(); assert UShort.check(headerId); return extra.put(headerId, ef); }
/** * Sets the serialized extra fields by making a protective copy. * Note that this method parses the serialized extra fields according to * the ZIP File Format Specification and limits its size to 64 KB. * Therefore, this property cannot not be used to hold arbitrary * (application) data. * Consider storing such data in a separate entry instead. * * @param buf The byte array holding the serialized extra fields. * @throws IllegalArgumentException if the serialized extra fields exceed * 64 KB or do not conform to the ZIP File Format Specification. */ public final void setExtra(final @CheckForNull byte[] buf) throws IllegalArgumentException { if (null != buf) UShort.check(buf.length, "extra fields too large", null); if (null == buf || buf.length <= 0) this.fields = null; else setExtraFields(buf, false); }
/** * Constructs a new ZIP entry with the given name and all other properties * copied from the given template. */ @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") protected ZipEntry(final String name, final ZipEntry template) { UShort.check(name.length()); this.init = template.init; this.name = name; this.platform = template.platform; this.general = template.general; this.method = template.method; this.dtime = template.dtime; this.crc = template.crc; this.csize = template.csize; this.size = template.size; this.eattr = template.eattr; this.offset = template.offset; final ExtraFields templateFields = template.fields; this.fields = templateFields == null ? null : templateFields.clone(); this.comment = template.comment; }
/** * Registers a concrete implementation of this abstract base class for * use with the static factory method {@link #create}. * * @param c the implementation class of this abstract base class. * @throws IllegalArgumentException if {@code c} cannot get instantiated, * is not a subclass of {@code ExtraField} or its Header ID is out * of range. * A more descriptive exception may be associated to it as its * cause. * @see #create */ static void register(final Class<? extends ExtraField> c) { final ExtraField ef; try { ef = (ExtraField) c.newInstance(); } catch (NullPointerException ex) { throw ex; } catch (Exception ex) { throw new IllegalArgumentException(ex); } final int headerId = ef.getHeaderId(); assert UShort.check(headerId); registry.put(headerId, c); }
/** * Returns a protective copy of the Extra Fields. * {@code null} is never returned. * * @see #getExtraLength */ byte[] getExtra() { final int size = getExtraLength(); assert UShort.check(size); if (0 == size) return EMPTY; final byte[] data = new byte[size]; writeTo(data, 0); return data; }
/** * A static contrstructor which creates a new extra field based on the * given header id. * The returned extra field still requires proper initialization, for * example by calling {@link #readFrom}. * * @param headerId An unsigned short integer (two bytes) which indicates * the type of the returned extra field. * @return A new extra field * @see #register */ static ExtraField create(final int headerId) { assert UShort.check(headerId); final Class<? extends ExtraField> c = registry.get(headerId); final ExtraField ef; try { ef = null != c ? (ExtraField) c.newInstance() : new DefaultExtraField(headerId); } catch (Exception cannotHappen) { throw new AssertionError(cannotHappen); } assert headerId == ef.getHeaderId(); return ef; }
/** * Returns a protective copy of the data block. * * @see #getDataSize */ final byte[] getDataBlock() { final int size = getDataSize(); assert UShort.check(size); if (0 == size) return EMPTY; final byte[] data = new byte[size]; writeTo(data, 0); return data; }
@Test public void testCheck() { try { UShort.check(UShort.MIN_VALUE - 1); fail("Expected IllegalArgumentException!"); } catch (IllegalArgumentException expected) { } UShort.check(UShort.MIN_VALUE); UShort.check(UShort.MAX_VALUE); try { UShort.check(UShort.MAX_VALUE + 1); fail("Expected IllegalArgumentException!"); } catch (IllegalArgumentException expected) { } } }