001package co.codewizards.cloudstore.core.io;
002
003import java.io.InputStream;
004import java.io.OutputStream;
005
006/**
007 * Utility class for working with {@link IInputStream} and {@link IOutputStream}.
008 * <p>
009 * Most importantly, the methods here are used for conversions:
010 * <ul>
011 * <li>{@link InputStream} &lt;=&gt; {@link IInputStream}
012 * <li>{@link OutputStream} &lt;=&gt; {@link IOutputStream}
013 * </ul>
014 * @author Marco หงุ่ยตระกูล-Schulze - marco at codewizards dot co
015 */
016public final class StreamUtil {
017        private StreamUtil() {
018        }
019
020        /**
021         * Casts an {@link InputStream} as {@link IInputStream}, if possible; or
022         * converts it by instantiating a new bridge instance, if a simple Java cast is not possible.
023         * <p>
024         * Note that the bridge object (if its instantiation was needed) both subclasses {@link InputStream}
025         * and implements {@link IInputStream}. Thus subsequent <code>castStream(...)</code> invocations on
026         * the result object always are simple Java casts.
027         *
028         * @param in the {@link InputStream} to be converted (by Java cast or bridge object). May be <code>null</code>.
029         * @return either the same instance as {@code in}, if a simple Java cast was possible; or a new
030         * bridge object implementing the desired interface and delegating to the underlying object.
031         * May be <code>null</code> (only if the input argument is <code>null</code>).
032         */
033        public static IInputStream castStream(final InputStream in) {
034                if (in instanceof IInputStream)
035                        return (IInputStream) in;
036
037                if (in == null)
038                        return null;
039
040                return new InStream(in);
041        }
042
043        /**
044         * Casts an {@link IInputStream} as {@link InputStream}, if possible; or
045         * converts it by instantiating a new bridge instance, if a simple Java cast is not possible.
046         * <p>
047         * Note that the bridge object (if its instantiation was needed) both subclasses {@link InputStream}
048         * and implements {@link IInputStream}. Thus subsequent <code>castStream(...)</code> invocations on
049         * the result object always are simple Java casts.
050         *
051         * @param in the {@link IInputStream} to be converted (by Java cast or bridge object). May be <code>null</code>.
052         * @return either the same instance as {@code in}, if a simple Java cast was possible; or a new
053         * bridge object extending {@link InputStream} and delegating to the underlying object.
054         * May be <code>null</code> (only if the input argument is <code>null</code>).
055         */
056        public static InputStream castStream(final IInputStream in) {
057                if (in instanceof InputStream)
058                        return (InputStream) in;
059
060                if (in == null)
061                        return null;
062
063                return new InStream.InverseInStream(in);
064        }
065
066        /**
067         * Casts an {@link OutputStream} as {@link IOutputStream}, if possible; or
068         * converts it by instantiating a new bridge instance, if a simple Java cast is not possible.
069         * <p>
070         * Note that the bridge object (if its instantiation was needed) both subclasses {@link OutputStream}
071         * and implements {@link IOutputStream}. Thus subsequent <code>castStream(...)</code> invocations on
072         * the result object always are simple Java casts.
073         *
074         * @param out the {@link OutputStream} to be converted (by Java cast or bridge object). May be <code>null</code>.
075         * @return either the same instance as {@code out}, if a simple Java cast was possible; or a new
076         * bridge object implementing the desired interface and delegating to the underlying object.
077         * May be <code>null</code> (only if the input argument is <code>null</code>).
078         */
079        public static IOutputStream castStream(final OutputStream out) {
080                if (out instanceof IOutputStream)
081                        return (IOutputStream) out;
082
083                if (out == null)
084                        return null;
085
086                return new OutStream(out);
087        }
088
089        /**
090         * Casts an {@link IOutputStream} as {@link OutputStream}, if possible; or
091         * converts it by instantiating a new bridge instance, if a simple Java cast is not possible.
092         * <p>
093         * Note that the bridge object (if its instantiation was needed) both subclasses {@link OutputStream}
094         * and implements {@link IOutputStream}. Thus subsequent <code>castStream(...)</code> invocations on
095         * the result object always are simple Java casts.
096         *
097         * @param out the {@link IOutputStream} to be converted (by Java cast or bridge object). May be <code>null</code>.
098         * @return either the same instance as {@code out}, if a simple Java cast was possible; or a new
099         * bridge object extending {@link OutputStream} and delegating to the underlying object.
100         * May be <code>null</code> (only if the input argument is <code>null</code>).
101         */
102        public static OutputStream castStream(final IOutputStream out) {
103                if (out instanceof OutputStream)
104                        return (OutputStream) out;
105
106                if (out == null)
107                        return null;
108
109                return new OutStream.InverseOutStream(out);
110        }
111}