Add FLAC identifier and fix comments.
[sonitus.git] / src / main / java / net / pterodactylus / sonitus / io / IdentifyingInputStream.java
index 537c9a4..3a4a9fb 100644 (file)
 
 package net.pterodactylus.sonitus.io;
 
+import java.io.EOFException;
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
-import net.pterodactylus.sonitus.data.Format;
+import net.pterodactylus.sonitus.data.Metadata;
 
 import com.google.common.base.Optional;
+import com.google.common.io.ByteStreams;
 
 /**
- * Wrapper around an {@link InputStream} that identifies the {@link Format} of
+ * Wrapper around an {@link InputStream} that identifies the {@link Metadata} of
  * the wrapped stream.
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
 public class IdentifyingInputStream extends FilterInputStream {
 
-       /** The identified format. */
-       private final Format format;
+       /** The identified metadata. */
+       private final Metadata metadata;
 
        /**
         * Creates a new identifying input stream.
         *
         * @param inputStream
         *              The input stream to wrap
-        * @param format
-        *              The format of the stream
+        * @param metadata
+        *              The metadata of the stream
         */
-       private IdentifyingInputStream(InputStream inputStream, Format format) {
+       private IdentifyingInputStream(InputStream inputStream, Metadata metadata) {
                super(inputStream);
-               this.format = format;
+               this.metadata = metadata;
        }
 
        //
@@ -54,12 +56,12 @@ public class IdentifyingInputStream extends FilterInputStream {
        //
 
        /**
-        * Returns the identified format.
+        * Returns the identified metadata.
         *
-        * @return The identified format
+        * @return The identified metadata
         */
-       public Format format() {
-               return format;
+       public Metadata metadata() {
+               return metadata;
        }
 
        //
@@ -72,8 +74,8 @@ public class IdentifyingInputStream extends FilterInputStream {
         * @param inputStream
         *              The input stream to identify
         * @return An identifying input stream that delivers the original stream and
-        *         the format it detected, or {@link com.google.common.base.Optional#absent()}
-        *         if no format could be identified
+        *         the metadata it detected, or {@link Optional#absent()} if no
+        *         metadata could be identified
         * @throws IOException
         *              if an I/O error occurs
         */
@@ -82,12 +84,37 @@ public class IdentifyingInputStream extends FilterInputStream {
                /* remember everything we read here. */
                RememberingInputStream rememberingInputStream = new RememberingInputStream(inputStream);
 
-               /* try Ogg Vorbis first. */
+               /* first, try formats with unambiguous layouts. */
+               try {
+                       Optional<Metadata> metadata = FlacIdentifier.identify(rememberingInputStream);
+                       if (metadata.isPresent()) {
+                               return Optional.of(new IdentifyingInputStream(rememberingInputStream.remembered(), metadata.get()));
+                       }
+               } catch (EOFException eofe1) {
+                       /* ignore. */
+               }
+
+               /* try Ogg Vorbis next. */
+               try {
+                       rememberingInputStream = new RememberingInputStream(rememberingInputStream.remembered());
+                       Optional<Metadata> metadata = OggVorbisIdentifier.identify(rememberingInputStream);
+                       if (metadata.isPresent()) {
+                               return Optional.of(new IdentifyingInputStream(rememberingInputStream.remembered(), metadata.get()));
+                       }
+               } catch (EOFException eofe1) {
+                       /* ignore. */
+               }
+
+               /* finally, try MP3. */
                try {
-                       Format format = OggVorbisIdentifier.identify(rememberingInputStream);
-                       return Optional.of(new IdentifyingInputStream(rememberingInputStream.remembered(), format));
-               } catch (IdentifierException ie1) {
                        rememberingInputStream = new RememberingInputStream(rememberingInputStream.remembered());
+                       InputStream limitedInputStream = ByteStreams.limit(rememberingInputStream, 1048576);
+                       Optional<Metadata> metadata = Mp3Identifier.identify(limitedInputStream);
+                       if (metadata.isPresent()) {
+                               return Optional.of(new IdentifyingInputStream(rememberingInputStream.remembered(), metadata.get()));
+                       }
+               } catch (EOFException eofe1) {
+                       /* ignore. */
                }
 
                return Optional.absent();