Coverage Report - org.jaudiotagger.tag.vorbiscomment.VorbisCommentReader
 
Classes in this File Line Coverage Branch Coverage Complexity
VorbisCommentReader
95%
43/45
91%
11/12
3.333
 
 1  
 /*
 2  
  * Entagged Audio Tag library
 3  
  * Copyright (c) 2003-2005 RaphaĆ«l Slinckx <raphael@slinckx.net>
 4  
  * Copyright (c) 2004-2005 Christian Laireiter <liree@web.de>
 5  
  * 
 6  
  * This library is free software; you can redistribute it and/or
 7  
  * modify it under the terms of the GNU Lesser General Public
 8  
  * License as published by the Free Software Foundation; either
 9  
  * version 2.1 of the License, or (at your option) any later version.
 10  
  *  
 11  
  * This library is distributed in the hope that it will be useful,
 12  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  
  * Lesser General Public License for more details.
 15  
  * 
 16  
  * You should have received a copy of the GNU Lesser General Public
 17  
  * License along with this library; if not, write to the Free Software
 18  
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 19  
  */
 20  
 package org.jaudiotagger.tag.vorbiscomment;
 21  
 
 22  
 import org.jaudiotagger.audio.exceptions.CannotReadException;
 23  
 import org.jaudiotagger.audio.generic.Utils;
 24  
 import org.jaudiotagger.audio.ogg.util.VorbisHeader;
 25  
 import org.jaudiotagger.fix.Fix;
 26  
 import org.jaudiotagger.logging.ErrorMessage;
 27  
 
 28  
 import java.io.IOException;
 29  
 import java.util.logging.Logger;
 30  
 
 31  
 /**
 32  
  * Create the VorbisCommentTag by reading from the raw packet data
 33  
  * <p/>
 34  
  * <p>This is in the same format whether encoded with Ogg or Flac
 35  
  * except the framing bit is only present when used within Ogg Vorbis
 36  
  * <p/>
 37  
  * <pre>
 38  
  * From the http://xiph.org/vorbis/doc/Vorbis_I_spec.html#vorbis-spec-comment
 39  
  * Read decodes the packet data using the following algorithm:
 40  
  *  [vendor_length] = read an unsigned integer of 32 bits
 41  
  *  [vendor_string] = read a UTF-8 vector as [vendor_length] octets
 42  
  *  [user_comment_list_length] = read an unsigned integer of 32 bits
 43  
  *  iterate [user_comment_list_length] times {
 44  
  *      5) [length] = read an unsigned integer of 32 bits
 45  
  *      6) this iteration's user comment = read a UTF-8 vector as [length] octets
 46  
  *    }
 47  
  *  [framing_bit] = read a single bit as boolean
 48  
  *  if ( [framing_bit] unset or end-of-packet ) then ERROR
 49  
  *  done.
 50  
  * </pre>
 51  
  */
 52  
 public class VorbisCommentReader
 53  
 {
 54  
     // Logger Object
 55  4
     public static Logger logger = Logger.getLogger("org.jaudiotagger.tag.vorbiscomment.VorbisCommentReader");
 56  
 
 57  
     public static final int FIELD_VENDOR_LENGTH_POS = 0;
 58  
     public static final int FIELD_VENDOR_STRING_POS = 4;
 59  
 
 60  
     public static final int FIELD_VENDOR_LENGTH_LENGTH = 4;
 61  
     public static final int FIELD_USER_COMMENT_LIST_LENGTH = 4;
 62  
     public static final int FIELD_COMMENT_LENGTH_LENGTH = 4;
 63  
 
 64  
     private Fix fix;
 65  
 
 66  
     /**
 67  
      * max comment length that jaudiotagger can handle, this isnt the maximum column length allowed but we dont
 68  
      * dont allow comments larger than this because of problem with allocating memory  (10MB shoudl be fine for all apps)
 69  
      */
 70  
     private static final int JAUDIOTAGGER_MAX_COMMENT_LENGTH = 10000000;
 71  
 
 72  
     public VorbisCommentReader()
 73  60
     {
 74  
 
 75  60
     }
 76  
 
 77  
     public VorbisCommentReader(Fix fix)
 78  1
     {
 79  1
         this.fix = fix;
 80  1
     }
 81  
 
 82  
     /**
 83  
      * @param rawdata
 84  
      * @param isFramingBit
 85  
      * @return logical representation of VorbisCommentTag
 86  
      * @throws IOException
 87  
      * @throws CannotReadException
 88  
      */
 89  
     public VorbisCommentTag read(byte[] rawdata, boolean isFramingBit) throws IOException, CannotReadException
 90  
     {
 91  
 
 92  258
         VorbisCommentTag tag = new VorbisCommentTag();
 93  
 
 94  258
         byte[] b = new byte[FIELD_VENDOR_LENGTH_LENGTH];
 95  258
         System.arraycopy(rawdata, FIELD_VENDOR_LENGTH_POS, b, FIELD_VENDOR_LENGTH_POS, FIELD_VENDOR_LENGTH_LENGTH);
 96  258
         int pos = FIELD_VENDOR_LENGTH_LENGTH;
 97  258
         int vendorStringLength = Utils.getIntLE(b);
 98  
 
 99  258
         b = new byte[vendorStringLength];
 100  258
         System.arraycopy(rawdata, pos, b, 0, vendorStringLength);
 101  258
         pos += vendorStringLength;
 102  258
         tag.setVendor(new String(b, VorbisHeader.CHARSET_UTF_8));
 103  258
         logger.info("Vendor is:"+tag.getVendor());
 104  
         
 105  258
         b = new byte[FIELD_USER_COMMENT_LIST_LENGTH];
 106  258
         System.arraycopy(rawdata, pos, b, 0, FIELD_USER_COMMENT_LIST_LENGTH);
 107  258
         pos += FIELD_USER_COMMENT_LIST_LENGTH;
 108  
 
 109  258
         int userComments = Utils.getIntLE(b);
 110  258
         logger.info("Number of user comments:" + userComments);
 111  258
         if (fix == Fix.FIX_OGG_VORBIS_COMMENT_NOT_COUNTING_EMPTY_COLUMNS)
 112  
         {
 113  1
             userComments++;
 114  
         }
 115  1682
         for (int i = 0; i < userComments; i++)
 116  
         {
 117  1425
             b = new byte[FIELD_COMMENT_LENGTH_LENGTH];
 118  1425
             System.arraycopy(rawdata, pos, b, 0, FIELD_COMMENT_LENGTH_LENGTH);
 119  1425
             pos += FIELD_COMMENT_LENGTH_LENGTH;
 120  
 
 121  1425
             int commentLength = Utils.getIntLE(b);
 122  1425
             logger.info("Next Comment Length:" + commentLength);
 123  
 
 124  1425
             if(commentLength> JAUDIOTAGGER_MAX_COMMENT_LENGTH)
 125  
             {
 126  0
                 logger.warning(ErrorMessage.VORBIS_COMMENT_LENGTH_TOO_LARGE.getMsg(commentLength));
 127  0
                 break;
 128  
             }
 129  1425
             else if(commentLength>rawdata.length)
 130  
             {
 131  1
                 logger.warning(ErrorMessage.VORBIS_COMMENT_LENGTH_LARGE_THAN_HEADER.getMsg(commentLength,rawdata.length));
 132  1
                 break;
 133  
             }
 134  
             else
 135  
             {
 136  1424
                 b = new byte[commentLength];
 137  1424
                 System.arraycopy(rawdata, pos, b, 0, commentLength);
 138  1424
                 pos += commentLength;
 139  
 
 140  1424
                 VorbisCommentTagField fieldComment = new VorbisCommentTagField(b);
 141  1424
                 logger.info("Adding:" + fieldComment.getId());
 142  1424
                 tag.addField(fieldComment);
 143  
             }
 144  
         }
 145  
 
 146  
         //Check framing bit, only exists when vorbisComment used within OggVorbis       
 147  258
         if (isFramingBit)
 148  
         {
 149  180
             if ((rawdata[pos] & 0x01) != 1)
 150  
             {
 151  1
                 throw new CannotReadException(ErrorMessage.OGG_VORBIS_NO_FRAMING_BIT.getMsg((rawdata[pos] & 0x01)));
 152  
             }
 153  
         }
 154  257
         return tag;
 155  
     }
 156  
 }
 157