Coverage Report - org.jaudiotagger.tag.vorbiscomment.VorbisCommentTagField
 
Classes in this File Line Coverage Branch Coverage Complexity
VorbisCommentTagField
74%
43/58
67%
19/28
1.882
 
 1  
 /*
 2  
  * Entagged Audio Tag library
 3  
  * Copyright (c) 2003-2005 RaphaĆ«l Slinckx <raphael@slinckx.net>
 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.tag.vorbiscomment;
 20  
 
 21  
 import org.jaudiotagger.audio.generic.Utils;
 22  
 import org.jaudiotagger.audio.ogg.util.VorbisHeader;
 23  
 import org.jaudiotagger.tag.TagField;
 24  
 import org.jaudiotagger.tag.TagTextField;
 25  
 import static org.jaudiotagger.tag.vorbiscomment.VorbisCommentFieldKey.*;
 26  
 
 27  
 import java.io.UnsupportedEncodingException;
 28  
 
 29  
 /**
 30  
  * This class represents the name and content of a tag entry in ogg-files.
 31  
  * <br>
 32  
  *
 33  
  * @author @author Raphael Slinckx (KiKiDonK)
 34  
  * @author Christian Laireiter (liree)
 35  
  */
 36  
 public class VorbisCommentTagField implements TagTextField
 37  
 {
 38  
 
 39  
     /**
 40  
      * If <code>true</code>, the id of the current encapsulated tag field is
 41  
      * specified as a common field. <br>
 42  
      * Example is "ARTIST" which should be interpreted by any application as the
 43  
      * artist of the media content. <br>
 44  
      * Will be set during construction with {@link #checkCommon()}.
 45  
      */
 46  
     private boolean common;
 47  
 
 48  
     /**
 49  
      * Stores the content of the tag field. <br>
 50  
      */
 51  
     private String content;
 52  
 
 53  
     /**
 54  
      * Stores the id (name) of the tag field. <br>
 55  
      */
 56  
     private String id;
 57  
 
 58  
     /**
 59  
      * If id is invalid
 60  
      */
 61  
     private static final String ERRONEOUS_ID = "ERRONEOUS";
 62  
 
 63  
     /**
 64  
      * Creates an instance.
 65  
      *
 66  
      * @param raw Raw byte data of the tagfield.
 67  
      * @throws UnsupportedEncodingException If the data doesn't conform "UTF-8" specification.
 68  
      */
 69  
     public VorbisCommentTagField(byte[] raw) throws UnsupportedEncodingException
 70  1424
     {
 71  1424
         String field = new String(raw, "UTF-8");
 72  1424
         int i = field.indexOf("=");
 73  1424
         if (i == -1)
 74  
         {
 75  
             //Beware that ogg ID, must be capitalized and contain no space..
 76  1
             this.id = ERRONEOUS_ID;
 77  1
             this.content = field;
 78  
         }
 79  
         else
 80  
         {
 81  1423
             this.id = field.substring(0, i).toUpperCase();
 82  1423
             if (field.length() > i)
 83  
             {
 84  1423
                 this.content = field.substring(i + 1);
 85  
             }
 86  
             else
 87  
             {
 88  
                 //We have "XXXXXX=" with nothing after the "="
 89  0
                 this.content = "";
 90  
             }
 91  
         }
 92  1424
         checkCommon();
 93  1424
     }
 94  
 
 95  
     /**
 96  
      * Creates an instance.
 97  
      *
 98  
      * @param fieldId      ID (name) of the field.
 99  
      * @param fieldContent Content of the field.
 100  
      */
 101  
     public VorbisCommentTagField(String fieldId, String fieldContent)
 102  616
     {
 103  616
         this.id = fieldId.toUpperCase();
 104  616
         this.content = fieldContent;
 105  616
         checkCommon();
 106  616
     }
 107  
 
 108  
     /**
 109  
      * This method examines the ID of the current field and modifies
 110  
      * {@link #common}in order to reflect if the tag id is a commonly used one.
 111  
      * <br>
 112  
      */
 113  
     private void checkCommon()
 114  
     {
 115  2040
         this.common = id.equals(TITLE.getFieldName()) || id.equals(ALBUM.getFieldName()) || id.equals(ARTIST.getFieldName())
 116  
                 || id.equals(GENRE.getFieldName()) || id.equals(TRACKNUMBER.getFieldName()) || id.equals(DATE.getFieldName())
 117  
         || id.equals(DESCRIPTION.getFieldName()) || id.equals(COMMENT.getFieldName());
 118  
 
 119  2040
     }
 120  
 
 121  
     /**
 122  
      * This method will copy all bytes of <code>src</code> to <code>dst</code>
 123  
      * at the specified location.
 124  
      *
 125  
      * @param src       bytes to copy.
 126  
      * @param dst       where to copy to.
 127  
      * @param dstOffset at which position of <code>dst</code> the data should be
 128  
      *                  copied.
 129  
      */
 130  
     protected void copy(byte[] src, byte[] dst, int dstOffset)
 131  
     {
 132  
         //        for (int i = 0; i < src.length; i++)
 133  
         //            dst[i + dstOffset] = src[i];
 134  
         /*
 135  
          * Heared that this method is optimized and does its job very near of
 136  
          * the system.
 137  
          */
 138  3888
         System.arraycopy(src, 0, dst, dstOffset, src.length);
 139  3888
     }
 140  
 
 141  
     /**
 142  
      * @see TagField#copyContent(TagField)
 143  
      */
 144  
     public void copyContent(TagField field)
 145  
     {
 146  0
         if (field instanceof TagTextField)
 147  
         {
 148  0
             this.content = ((TagTextField) field).getContent();
 149  
         }
 150  0
     }
 151  
 
 152  
     /**
 153  
      * This method will try to return the byte representation of the given
 154  
      * string after it has been converted to the given encoding. <br>
 155  
      *
 156  
      * @param s        The string whose converted bytes should be returned.
 157  
      * @param encoding The encoding type to which the string should be converted.
 158  
      * @return If <code>encoding</code> is supported the byte data of the
 159  
      *         given string is returned in that encoding.
 160  
      * @throws UnsupportedEncodingException If the requested encoding is not available.
 161  
      */
 162  
     protected byte[] getBytes(String s, String encoding) throws UnsupportedEncodingException
 163  
     {
 164  1296
         return s.getBytes(encoding);
 165  
     }
 166  
 
 167  
     /**
 168  
      * @see TagTextField#getContent()
 169  
      */
 170  
     public String getContent()
 171  
     {
 172  1119
         return content;
 173  
     }
 174  
 
 175  
     /**
 176  
      * @see TagTextField#getEncoding()
 177  
      */
 178  
     public String getEncoding()
 179  
     {
 180  0
         return VorbisHeader.CHARSET_UTF_8;
 181  
     }
 182  
 
 183  
     /**
 184  
      * @see TagField#getId()
 185  
      */
 186  
     public String getId()
 187  
     {
 188  8417
         return this.id;
 189  
     }
 190  
 
 191  
     /**
 192  
      * @see TagField#getRawContent()
 193  
      */
 194  
     public byte[] getRawContent() throws UnsupportedEncodingException
 195  
     {
 196  1296
         byte[] size = new byte[VorbisCommentReader.FIELD_COMMENT_LENGTH_LENGTH];
 197  1296
         byte[] idBytes = Utils.getDefaultBytes(this.id, "ISO-8859-1");
 198  1296
         byte[] contentBytes = getBytes(this.content, "UTF-8");
 199  1296
         byte[] b = new byte[4 + idBytes.length + 1 + contentBytes.length];
 200  
 
 201  1296
         int length = idBytes.length + 1 + contentBytes.length;
 202  1296
         size[3] = (byte) ((length & 0xFF000000) >> 24);
 203  1296
         size[2] = (byte) ((length & 0x00FF0000) >> 16);
 204  1296
         size[1] = (byte) ((length & 0x0000FF00) >> 8);
 205  1296
         size[0] = (byte) (length & 0x000000FF);
 206  
 
 207  1296
         int offset = 0;
 208  1296
         copy(size, b, offset);
 209  1296
         offset += 4;
 210  1296
         copy(idBytes, b, offset);
 211  1296
         offset += idBytes.length;
 212  1296
         b[offset] = (byte) 0x3D;
 213  1296
         offset++;// "="
 214  1296
         copy(contentBytes, b, offset);
 215  
 
 216  1296
         return b;
 217  
     }
 218  
 
 219  
     /**
 220  
      * @see TagField#isBinary()
 221  
      */
 222  
     public boolean isBinary()
 223  
     {
 224  0
         return false;
 225  
     }
 226  
 
 227  
     /**
 228  
      * @see TagField#isBinary(boolean)
 229  
      */
 230  
     public void isBinary(boolean b)
 231  
     {
 232  0
         if (b)
 233  
         {
 234  
             // Only throw if binary = true requested.
 235  0
             throw new UnsupportedOperationException("OggTagFields cannot be changed to binary.\n" + "binary data should be stored elsewhere" + " according to Vorbis_I_spec.");
 236  
         }
 237  0
     }
 238  
 
 239  
     /**
 240  
      * @see TagField#isCommon()
 241  
      */
 242  
     public boolean isCommon()
 243  
     {
 244  1986
         return common;
 245  
     }
 246  
 
 247  
     /**
 248  
      * @see TagField#isEmpty()
 249  
      */
 250  
     public boolean isEmpty()
 251  
     {
 252  0
         return this.content.equals("");
 253  
     }
 254  
 
 255  
     /**
 256  
      * @see TagTextField#setContent(String)
 257  
      */
 258  
     public void setContent(String s)
 259  
     {
 260  0
         this.content = s;
 261  0
     }
 262  
 
 263  
     /**
 264  
      * @see TagTextField#setEncoding(String)
 265  
      */
 266  
     public void setEncoding(String s)
 267  
     {
 268  0
         if (s == null || !s.equalsIgnoreCase("UTF-8"))
 269  
         {
 270  0
             throw new UnsupportedOperationException("The encoding of OggTagFields cannot be " + "changed.(specified to be UTF-8)");
 271  
         }
 272  0
     }
 273  
 
 274  
     public String toString()
 275  
     {
 276  1119
         return getContent();
 277  
     }
 278  
 }