Coverage Report - org.jaudiotagger.audio.asf.io.ContentDescriptionReader
 
Classes in this File Line Coverage Branch Coverage Complexity
ContentDescriptionReader
97%
35/36
75%
18/24
3.167
 
 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.ContentDescription;
 23  
 import org.jaudiotagger.audio.asf.data.GUID;
 24  
 import org.jaudiotagger.audio.asf.util.Utils;
 25  
 
 26  
 import java.io.IOException;
 27  
 import java.io.InputStream;
 28  
 import java.math.BigInteger;
 29  
 
 30  
 /**
 31  
  * Reads and interprets the data of a ASF chunk containing title, author... <br>
 32  
  *
 33  
  * @author Christian Laireiter
 34  
  * @see org.jaudiotagger.audio.asf.data.ContentDescription
 35  
  */
 36  
 public class ContentDescriptionReader implements ChunkReader
 37  
 {
 38  
     /**
 39  
      * This method reads a UTF-16 encoded String. <br>
 40  
      * For the use this method the number of bytes used by current string must
 41  
      * be known. <br>
 42  
      * The ASF specification recommends that those strings end with a terminating zero.
 43  
      * However it also says that it is not always the case.
 44  
      *
 45  
      * @param stream    Input source
 46  
      * @param strLen Number of bytes the String may take.
 47  
      * @return read String.
 48  
      * @throws IOException read errors.
 49  
      */
 50  
     public static String readFixedSizeUTF16Str(InputStream stream, int strLen) throws IOException
 51  
     {
 52  245
         byte[] strBytes = new byte[strLen];
 53  245
         int read = stream.read(strBytes);
 54  245
         if (read == strBytes.length)
 55  
         {
 56  245
             if (strBytes.length >= 2)
 57  
             {
 58  
                 /*
 59  
                  * Zero termination is recommended but optional.
 60  
                  * So check and if, remove.
 61  
                  */
 62  245
                 if (strBytes[strBytes.length - 1] == 0 && strBytes[strBytes.length - 2] == 0)
 63  
                 {
 64  245
                     byte[] copy = new byte[strBytes.length - 2];
 65  245
                     System.arraycopy(strBytes, 0, copy, 0, strBytes.length - 2);
 66  245
                     strBytes = copy;
 67  
                 }
 68  
             }
 69  245
             return new String(strBytes, "UTF-16LE");
 70  
         }
 71  0
         throw new IllegalStateException("Couldn't read the necessary amount of bytes.");
 72  
     }
 73  
 
 74  
     /**
 75  
      * Should not be used for now.
 76  
      */
 77  
     protected ContentDescriptionReader()
 78  252
     {
 79  
         // NOTHING toDo
 80  252
     }
 81  
 
 82  
 
 83  
     /**
 84  
      * {@inheritDoc}
 85  
      */
 86  
     public boolean canFail()
 87  
     {
 88  55
         return false;
 89  
     }
 90  
 
 91  
     /**
 92  
      * {@inheritDoc}
 93  
      */
 94  
     public GUID getApplyingId()
 95  
     {
 96  252
         return GUID.GUID_CONTENTDESCRIPTION;
 97  
     }
 98  
 
 99  
     /**
 100  
      * Returns the next 5 UINT16 values as an array.<br>
 101  
      * @param stream stream to read from
 102  
      * @return 5 int values read from stream.
 103  
      * @throws IOException on I/O Errors.
 104  
      */
 105  
     private int[] getStringSizes(InputStream stream) throws IOException
 106  
     {
 107  55
         int[] result = new int[5];
 108  330
         for (int i = 0; i < result.length; i++)
 109  
         {
 110  275
             result[i] = Utils.readUINT16(stream);
 111  
         }
 112  55
         return result;
 113  
     }
 114  
 
 115  
     /**
 116  
      * {@inheritDoc}
 117  
      */
 118  
     public Chunk read(final GUID guid, final InputStream stream, final long chunkStart) throws IOException
 119  
     {
 120  55
         final BigInteger chunkSize = Utils.readBig64(stream);
 121  
         /*
 122  
          * Now comes 16-Bit values representing the length of the Strings
 123  
          * which follows.
 124  
          */
 125  55
         final int[] stringSizes = getStringSizes(stream);
 126  
 
 127  
         /*
 128  
          * Now we know the String length of each occuring String.
 129  
          */
 130  55
         String[] strings = new String[stringSizes.length];
 131  330
         for (int i = 0; i < strings.length; i++)
 132  
         {
 133  275
             if (stringSizes[i] > 0)
 134  
             {
 135  245
                 strings[i] = readFixedSizeUTF16Str(stream, stringSizes[i]);
 136  
             }
 137  
         }
 138  
         /*
 139  
          * Now create the result
 140  
          */
 141  55
         ContentDescription result = new ContentDescription(chunkStart, chunkSize);
 142  55
         if (stringSizes[0] > 0)
 143  
         {
 144  55
             result.setTitle(strings[0]);
 145  
         }
 146  55
         if (stringSizes[1] > 0)
 147  
         {
 148  55
             result.setAuthor(strings[1]);
 149  
         }
 150  55
         if (stringSizes[2] > 0)
 151  
         {
 152  52
             result.setCopyRight(strings[2]);
 153  
         }
 154  55
         if (stringSizes[3] > 0)
 155  
         {
 156  52
             result.setComment(strings[3]);
 157  
         }
 158  55
         if (stringSizes[4] > 0)
 159  
         {
 160  31
             result.setRating(strings[4]);
 161  
         }
 162  55
         return result;
 163  
     }
 164  
 }