Coverage Report - org.jaudiotagger.audio.asf.io.AsfHeaderReader
 
Classes in this File Line Coverage Branch Coverage Complexity
AsfHeaderReader
89%
42/47
66%
4/6
1.5
 
 1  
 /*
 2  
  * Entagged Audio Tag library
 3  
  * Copyright (c) 2004-2005 Christian Laireiter <liree@web.de>
 4  
  * 
 5  
  * This library is free software; you can redistribute it and/or
 6  
  * modify it under the terms of the GNU Lesser General Public
 7  
  * License as published by the Free Software Foundation; either
 8  
  * version 2.1 of the License, or (at your option) any later version.
 9  
  *  
 10  
  * This library is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
  * Lesser General Public License for more details.
 14  
  * 
 15  
  * You should have received a copy of the GNU Lesser General Public
 16  
  * License along with this library; if not, write to the Free Software
 17  
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 18  
  */
 19  
 package org.jaudiotagger.audio.asf.io;
 20  
 
 21  
 import org.jaudiotagger.audio.asf.data.AsfHeader;
 22  
 import org.jaudiotagger.audio.asf.data.GUID;
 23  
 import org.jaudiotagger.audio.asf.util.Utils;
 24  
 
 25  
 import java.io.*;
 26  
 import java.math.BigInteger;
 27  
 import java.util.ArrayList;
 28  
 import java.util.List;
 29  
 
 30  
 /**
 31  
  * This <i>class </i> reads an ASF header out of an input stream an creates an
 32  
  * {@link org.jaudiotagger.audio.asf.data.AsfHeader} object if successful. <br>
 33  
  * For now only ASF ver 1.0 is supported, because ver 2.0 seems not to be used
 34  
  * anywhere. <br>
 35  
  * ASF headers contains other chunks. As of this other readers of current
 36  
  * <b>package </b> are called from within.
 37  
  * 
 38  
  * @author Christian Laireiter
 39  
  */
 40  411
 public class AsfHeaderReader extends ChunkContainerReader<AsfHeader> {
 41  
     /**
 42  
      * The GUID this reader {@linkplain #getApplyingIds() applies to}
 43  
      */
 44  4
     private final static GUID[] APPLYING = { GUID.GUID_HEADER };
 45  
 
 46  
     /**
 47  
      * ASF reader configured to extract all information.
 48  
      */
 49  
     private final static AsfHeaderReader FULL_READER;
 50  
     /**
 51  
      * ASF reader configured to just extract information about audio streams.<br>
 52  
      * If the ASF file only contains one audio stream it works fine.<br>
 53  
      */
 54  
     private final static AsfHeaderReader INFO_READER;
 55  
 
 56  
     /**
 57  
      * ASF reader configured to just extract metadata information.<br>
 58  
      */
 59  
     private final static AsfHeaderReader TAG_READER;
 60  
 
 61  
     static {
 62  4
         final List<Class<? extends ChunkReader>> readers = new ArrayList<Class<? extends ChunkReader>>();
 63  4
         readers.add(FileHeaderReader.class);
 64  4
         readers.add(StreamChunkReader.class);
 65  4
         INFO_READER = new AsfHeaderReader(readers, true);
 66  4
         readers.clear();
 67  4
         readers.add(ContentDescriptionReader.class);
 68  4
         readers.add(ContentBrandingReader.class);
 69  4
         readers.add(LanguageListReader.class);
 70  4
         readers.add(MetadataReader.class);
 71  
         /*
 72  
          * Create the header extension object readers with just content
 73  
          * description reader, extended content description reader, language
 74  
          * list reader and both metadata object readers.
 75  
          */
 76  4
         final AsfExtHeaderReader extReader = new AsfExtHeaderReader(readers,
 77  
                 true);
 78  4
         final AsfExtHeaderReader extReader2 = new AsfExtHeaderReader(readers,
 79  
                 true);
 80  4
         TAG_READER = new AsfHeaderReader(readers, true);
 81  4
         TAG_READER.setExtendedHeaderReader(extReader);
 82  4
         readers.add(FileHeaderReader.class);
 83  4
         readers.add(StreamChunkReader.class);
 84  4
         readers.add(EncodingChunkReader.class);
 85  4
         readers.add(EncryptionChunkReader.class);
 86  4
         readers.add(StreamBitratePropertiesReader.class);
 87  4
         FULL_READER = new AsfHeaderReader(readers, false);
 88  4
         FULL_READER.setExtendedHeaderReader(extReader2);
 89  4
     }
 90  
 
 91  
     /**
 92  
      * Creates a Stream that will read from the specified
 93  
      * {@link RandomAccessFile};<br>
 94  
      * 
 95  
      * @param raf
 96  
      *            data source to read from.
 97  
      * @return a stream which accesses the source.
 98  
      */
 99  
     private static InputStream createStream(final RandomAccessFile raf) {
 100  145
         return new FullRequestInputStream(new BufferedInputStream(
 101  
                 new RandomAccessFileInputstream(raf)));
 102  
     }
 103  
 
 104  
     /**
 105  
      * This method extracts the full ASF-Header from the given file.<br>
 106  
      * If no header could be extracted <code>null</code> is returned. <br>
 107  
      * 
 108  
      * @param file
 109  
      *            the ASF file to read.<br>
 110  
      * @return AsfHeader-Wrapper, or <code>null</code> if no supported ASF
 111  
      *         header was found.
 112  
      * @throws IOException
 113  
      *             on I/O Errors.
 114  
      */
 115  
     public static AsfHeader readHeader(final File file) throws IOException {
 116  68
         final InputStream stream = new FileInputStream(file);
 117  68
         final AsfHeader result = FULL_READER.read(Utils.readGUID(stream),
 118  
                 stream, 0);
 119  68
         stream.close();
 120  68
         return result;
 121  
     }
 122  
 
 123  
     /**
 124  
      * This method tries to extract a full ASF-header out of the given stream. <br>
 125  
      * If no header could be extracted <code>null</code> is returned. <br>
 126  
      * 
 127  
      * @param file
 128  
      *            File which contains the ASF header.
 129  
      * @return AsfHeader-Wrapper, or <code>null</code> if no supported ASF
 130  
      *         header was found.
 131  
      * @throws IOException
 132  
      *             Read errors
 133  
      */
 134  
     public static AsfHeader readHeader(final RandomAccessFile file)
 135  
             throws IOException {
 136  12
         final InputStream stream = createStream(file);
 137  12
         return FULL_READER.read(Utils.readGUID(stream), stream, 0);
 138  
     }
 139  
 
 140  
     /**
 141  
      * This method tries to extract an ASF-header out of the given stream, which
 142  
      * only contains information about the audio stream.<br>
 143  
      * If no header could be extracted <code>null</code> is returned. <br>
 144  
      * 
 145  
      * @param file
 146  
      *            File which contains the ASF header.
 147  
      * @return AsfHeader-Wrapper, or <code>null</code> if no supported ASF
 148  
      *         header was found.
 149  
      * @throws IOException
 150  
      *             Read errors
 151  
      */
 152  
     public static AsfHeader readInfoHeader(final RandomAccessFile file)
 153  
             throws IOException {
 154  0
         final InputStream stream = createStream(file);
 155  0
         return INFO_READER.read(Utils.readGUID(stream), stream, 0);
 156  
     }
 157  
 
 158  
     /**
 159  
      * This method tries to extract an ASF-header out of the given stream, which
 160  
      * only contains metadata.<br>
 161  
      * If no header could be extracted <code>null</code> is returned. <br>
 162  
      * 
 163  
      * @param file
 164  
      *            File which contains the ASF header.
 165  
      * @return AsfHeader-Wrapper, or <code>null</code> if no supported ASF
 166  
      *         header was found.
 167  
      * @throws IOException
 168  
      *             Read errors
 169  
      */
 170  
     public static AsfHeader readTagHeader(final RandomAccessFile file)
 171  
             throws IOException {
 172  133
         final InputStream stream = createStream(file);
 173  133
         return TAG_READER.read(Utils.readGUID(stream), stream, 0);
 174  
     }
 175  
 
 176  
     /**
 177  
      * Creates an instance of this reader.
 178  
      * 
 179  
      * @param toRegister
 180  
      *            The chunk readers to utilize.
 181  
      * 
 182  
      * @param readChunkOnce
 183  
      *            if <code>true</code>, each chunk type (identified by chunk
 184  
      *            GUID) will handled only once, if a reader is available, other
 185  
      *            chunks will be discarded.
 186  
      */
 187  
     public AsfHeaderReader(final List<Class<? extends ChunkReader>> toRegister,
 188  
             final boolean readChunkOnce) {
 189  16
         super(toRegister, readChunkOnce);
 190  16
     }
 191  
 
 192  
     /**
 193  
      * {@inheritDoc}
 194  
      */
 195  
     public boolean canFail() {
 196  0
         return false;
 197  
     }
 198  
 
 199  
     /**
 200  
      * {@inheritDoc}
 201  
      */
 202  
     @Override
 203  
     protected AsfHeader createContainer(final long streamPosition,
 204  
             final BigInteger chunkLength, final InputStream stream)
 205  
             throws IOException {
 206  411
         final long chunkCount = Utils.readUINT32(stream);
 207  
         /*
 208  
          * 2 reserved bytes. first should be equal to 0x01 and second 0x02. ASF
 209  
          * specification suggests to not read the content if second byte is not
 210  
          * 0x02.
 211  
          */
 212  411
         if (stream.read() != 1) {
 213  0
             throw new IOException("No ASF"); //$NON-NLS-1$
 214  
         }
 215  411
         if (stream.read() != 2) {
 216  0
             throw new IOException("No ASF"); //$NON-NLS-1$
 217  
         }
 218  
         /*
 219  
          * Creating the resulting object
 220  
          */
 221  411
         return new AsfHeader(streamPosition, chunkLength, chunkCount);
 222  
     }
 223  
     
 224  
     /**
 225  
      * {@inheritDoc}
 226  
      */
 227  
     public GUID[] getApplyingIds() {
 228  411
         return APPLYING.clone();
 229  
     }
 230  
 
 231  
     /**
 232  
      * Sets the {@link AsfExtHeaderReader}, which is to be used, when an header
 233  
      * extension object is found.
 234  
      * 
 235  
      * @param extReader
 236  
      *            header extension object reader.
 237  
      */
 238  
     public void setExtendedHeaderReader(final AsfExtHeaderReader extReader) {
 239  24
         for (final GUID curr : extReader.getApplyingIds()) {
 240  12
             this.readerMap.put(curr, extReader);
 241  
         }
 242  12
     }
 243  
 
 244  
 }