Coverage Report - org.jaudiotagger.audio.asf.io.ExtContentDescReader
 
Classes in this File Line Coverage Branch Coverage Complexity
ExtContentDescReader
88%
36/41
69%
9/13
2.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.Chunk;
 22  
 import org.jaudiotagger.audio.asf.data.ContentDescriptor;
 23  
 import org.jaudiotagger.audio.asf.data.ExtendedContentDescription;
 24  
 import org.jaudiotagger.audio.asf.data.GUID;
 25  
 import org.jaudiotagger.audio.asf.util.Utils;
 26  
 
 27  
 import java.io.IOException;
 28  
 import java.io.InputStream;
 29  
 import java.math.BigInteger;
 30  
 
 31  
 /**
 32  
  * Class for reading Tag information out of the extended content description of
 33  
  * an ASF file. <br>
 34  
  *
 35  
  * @author Christian Laireiter
 36  
  * @see org.jaudiotagger.audio.asf.data.ExtendedContentDescription
 37  
  */
 38  
 public class ExtContentDescReader implements ChunkReader
 39  
 {
 40  
 
 41  
     /**
 42  
      * Should not be used for now.
 43  
      */
 44  
     protected ExtContentDescReader()
 45  252
     {
 46  
         // NOTHING toDo
 47  252
     }
 48  
 
 49  
     /**
 50  
      * {@inheritDoc}
 51  
      */
 52  
     public boolean canFail()
 53  
     {
 54  48
         return false;
 55  
     }
 56  
 
 57  
     /**
 58  
      * {@inheritDoc}
 59  
      */
 60  
     public GUID getApplyingId()
 61  
     {
 62  252
         return GUID.GUID_EXTENDED_CONTENT_DESCRIPTION;
 63  
     }
 64  
 
 65  
     /**
 66  
      * {@inheritDoc}
 67  
      */
 68  
     public Chunk read(final GUID guid, final InputStream stream, final long chunkStart) throws IOException
 69  
     {
 70  48
         BigInteger chunkLen = Utils.readBig64(stream);
 71  
 
 72  
         // Reading Number of Tags.
 73  48
         long descriptorCount = Utils.readUINT16(stream);
 74  
 
 75  
         // Create Result object
 76  48
         final ExtendedContentDescription result = new ExtendedContentDescription(chunkLen);
 77  1311
         for (long i = 0; i < descriptorCount; i++)
 78  
         {
 79  1263
             String tagElement = Utils.readUTF16LEStr(stream);
 80  1263
             int type = Utils.readUINT16(stream);
 81  1263
             ContentDescriptor prop = new ContentDescriptor(tagElement, type);
 82  1263
             switch (type)
 83  
             {
 84  
                 case ContentDescriptor.TYPE_STRING:
 85  1184
                     prop.setStringValue(Utils.readUTF16LEStr(stream));
 86  1184
                     break;
 87  
                 case ContentDescriptor.TYPE_BINARY:
 88  26
                     prop.setBinaryValue(readBinaryData(stream));
 89  26
                     break;
 90  
                 case ContentDescriptor.TYPE_BOOLEAN:
 91  24
                     prop.setBooleanValue(readBoolean(stream));
 92  24
                     break;
 93  
                 case ContentDescriptor.TYPE_DWORD:
 94  27
                     stream.skip(2);
 95  27
                     prop.setDWordValue(Utils.readUINT32(stream));
 96  27
                     break;
 97  
                 case ContentDescriptor.TYPE_WORD:
 98  0
                     stream.skip(2);
 99  0
                     prop.setWordValue(Utils.readUINT16(stream));
 100  0
                     break;
 101  
                 case ContentDescriptor.TYPE_QWORD:
 102  2
                     stream.skip(2);
 103  2
                     prop.setQWordValue(Utils.readUINT64(stream));
 104  2
                     break;
 105  
                 default:
 106  
                     // Unknown, hopefully the convention for the size of the
 107  
                     // value
 108  
                     // is given, so we could read it binary
 109  0
                     prop.setStringValue("Invalid datatype: " + new String(readBinaryData(stream)));
 110  
             }
 111  1263
             result.addDescriptor(prop);
 112  
         }
 113  48
         result.setPosition(chunkStart);
 114  48
         return result;
 115  
     }
 116  
 
 117  
     /**
 118  
      * This method read binary Data. <br>
 119  
      *
 120  
      * @param stream input source.
 121  
      * @return the binary data
 122  
      * @throws IOException read errors.
 123  
      */
 124  
     private byte[] readBinaryData(InputStream stream) throws IOException
 125  
     {
 126  26
         int size = Utils.readUINT16(stream);
 127  26
         byte[] bytes = new byte[size];
 128  26
         stream.read(bytes);
 129  26
         return bytes;
 130  
     }
 131  
 
 132  
     /**
 133  
      * This Method reads a boolean value out of the tag chunk. <br>
 134  
      * A boolean requires 6 bytes. This means we've got 3 16-Bit unsigned
 135  
      * numbers. The first number should always be 4 because the other 2 numbers
 136  
      * needs them. The second number seems to take the values 0 (for
 137  
      * <code>false</code>) and 1 (for <code>true</code>). The third one is
 138  
      * zero, maybe indication the end of the value. <br>
 139  
      *
 140  
      * @param stream input source
 141  
      * @return boolean representation.
 142  
      * @throws IOException read errors.
 143  
      */
 144  
     private boolean readBoolean(InputStream stream) throws IOException
 145  
     {
 146  24
         int size = Utils.readUINT16(stream);
 147  24
         if (size != 4)
 148  
         {
 149  0
             throw new IllegalStateException("Boolean value do require 4 Bytes. (Size value is: " + size + ")");
 150  
         }
 151  24
         long value = Utils.readUINT32(stream);
 152  24
         boolean result = value == 1;
 153  24
         return result;
 154  
     }
 155  
 
 156  
 }