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