AbstractCoder.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.archivers.sevenz;

  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.io.OutputStream;
  21. import java.util.Objects;
  22. import java.util.stream.Stream;

  23. import org.apache.commons.compress.utils.ByteUtils;

  24. /**
  25.  * Abstracts a base Codec class.
  26.  */
  27. abstract class AbstractCoder {

  28.     /**
  29.      * If the option represents a number, return its integer value, otherwise return the given default value.
  30.      *
  31.      * @param options      A Number.
  32.      * @param defaultValue A default value if options is not a number.
  33.      * @return The given number or default value.
  34.      */
  35.     protected static int toInt(final Object options, final int defaultValue) {
  36.         return options instanceof Number ? ((Number) options).intValue() : defaultValue;
  37.     }

  38.     private final Class<?>[] optionClasses;

  39.     /**
  40.      * Constructs a new instance.
  41.      *
  42.      * @param optionClasses types that can be used as options for this codec.
  43.      */
  44.     protected AbstractCoder(final Class<?>... optionClasses) {
  45.         this.optionClasses = Objects.requireNonNull(optionClasses, "optionClasses");
  46.     }

  47.     /**
  48.      * Decodes using stream that reads from in using the configured coder and password.
  49.      *
  50.      * @return a stream that reads from in using the configured coder and password.
  51.      */
  52.     abstract InputStream decode(String archiveName, InputStream in, long uncompressedLength, Coder coder, byte[] password, int maxMemoryLimitInKb)
  53.             throws IOException;

  54.     /**
  55.      * Encodes using a stream that writes to out using the given configuration.
  56.      *
  57.      * @return a stream that writes to out using the given configuration.
  58.      * @throws IOException Optionally thrown by subclassses.
  59.      */
  60.     OutputStream encode(final OutputStream out, final Object options) throws IOException {
  61.         throw new UnsupportedOperationException("Method doesn't support writing");
  62.     }

  63.     /**
  64.      * Gets property bytes to write in a Folder block.
  65.      *
  66.      * @return property bytes to write in a Folder block.
  67.      * @throws IOException Optionally thrown by subclassses.
  68.      */
  69.     byte[] getOptionsAsProperties(final Object options) throws IOException {
  70.         return ByteUtils.EMPTY_BYTE_ARRAY;
  71.     }

  72.     /**
  73.      * Gets configuration options that have been used to create the given InputStream from the given Coder.
  74.      *
  75.      * @return configuration options that have been used to create the given InputStream from the given Coder
  76.      * @throws IOException Optionally thrown by subclassses.
  77.      */
  78.     Object getOptionsFromCoder(final Coder coder, final InputStream in) throws IOException {
  79.         return null;
  80.     }

  81.     /**
  82.      * Tests whether this method can extract options from the given object.
  83.      *
  84.      * @return whether this method can extract options from the given object.
  85.      */
  86.     boolean isOptionInstance(final Object opts) {
  87.         return Stream.of(optionClasses).anyMatch(c -> c.isInstance(opts));
  88.     }
  89. }