Coverage Report - org.jaudiotagger.tag.id3.framebody.AbstractFrameBodyTextInfo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractFrameBodyTextInfo
100%
34/34
100%
4/4
1.25
 
 1  
 /**
 2  
  *  @author : Paul Taylor
 3  
  *  @author : Eric Farng
 4  
  *
 5  
  *  Version @version:$Id: AbstractFrameBodyTextInfo.java 836 2009-11-12 15:44:07Z paultaylor $
 6  
  *
 7  
  *  MusicTag Copyright (C)2003,2004
 8  
  *
 9  
  *  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
 10  
  *  General Public  License as published by the Free Software Foundation; either version 2.1 of the License,
 11  
  *  or (at your option) any later version.
 12  
  *
 13  
  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 14  
  *  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 15  
  *  See the GNU Lesser General Public License for more details.
 16  
  *
 17  
  *  You should have received a copy of the GNU Lesser General Public License along with this library; if not,
 18  
  *  you can get a copy from http://www.opensource.org/licenses/lgpl-license.php or write to the Free Software
 19  
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 20  
  *
 21  
  * Description:
 22  
  */
 23  
 package org.jaudiotagger.tag.id3.framebody;
 24  
 
 25  
 import org.jaudiotagger.logging.ErrorMessage;
 26  
 import org.jaudiotagger.tag.InvalidTagException;
 27  
 import org.jaudiotagger.tag.datatype.DataTypes;
 28  
 import org.jaudiotagger.tag.datatype.NumberHashMap;
 29  
 import org.jaudiotagger.tag.datatype.TextEncodedStringSizeTerminated;
 30  
 import org.jaudiotagger.tag.id3.ID3TextEncodingConversion;
 31  
 import org.jaudiotagger.tag.id3.valuepair.TextEncoding;
 32  
 
 33  
 import java.io.ByteArrayOutputStream;
 34  
 import java.nio.ByteBuffer;
 35  
 
 36  
 /**
 37  
  * Abstract representation of a Text Frame
 38  
  * <p/>
 39  
  * The text information frames are often the most important frames, containing information like artist, album and
 40  
  * more. There may only be  one text information frame of its kind in an tag. In ID3v24 All text information frames
 41  
  * supports multiple strings, stored as a null separated list, where null is represented by the termination code
 42  
  * for the character encoding. All text frame identifiers begin with "T". Only text frame identifiers begin with "T",
 43  
  * with the exception of the "TXXX" frame. All the text information frames have the following  format:
 44  
  * <Header for 'Text information frame', ID: "T000" - "TZZZ",
 45  
  * excluding "TXXX" described in 4.2.6.>
 46  
  * Text encoding                $xx
 47  
  * Information                  <text string(s) according to encoding>
 48  
  * <p/>
 49  
  * The list of valid text encodings increaded from two in ID3v23 to four in ID3v24
 50  
  * <p/>
 51  
  * iTunes incorrectly writes null terminators at the end of every String, even though it only writes one String.
 52  
  * <p/>
 53  
  * You can retrieve the first value without the null terminator using {@link #getFirstTextValue}
 54  
  */
 55  
 public abstract class AbstractFrameBodyTextInfo extends AbstractID3v2FrameBody
 56  
 {
 57  
 
 58  
     /**
 59  
      * Creates a new FrameBodyTextInformation datatype. The super.super
 60  
      * Constructor sets up the Object list for the frame.
 61  
      */
 62  
     protected AbstractFrameBodyTextInfo()
 63  
     {
 64  1614
         super();
 65  1614
         setObjectValue(DataTypes.OBJ_TEXT_ENCODING, TextEncoding.ISO_8859_1);
 66  1614
         setObjectValue(DataTypes.OBJ_TEXT, "");
 67  1614
     }
 68  
 
 69  
     /**
 70  
      * Copy Constructor
 71  
      *
 72  
      * @param body AbstractFrameBodyTextInformation
 73  
      */
 74  
     protected AbstractFrameBodyTextInfo(AbstractFrameBodyTextInfo body)
 75  
     {
 76  4058
         super(body);
 77  4058
     }
 78  
 
 79  
     /**
 80  
      * Creates a new FrameBodyTextInformation datatype. This is used when user
 81  
      * wants to create a new frame based on data in a user interface.
 82  
      *
 83  
      * @param textEncoding Specifys what encoding should be used to write
 84  
      *                     text to file.
 85  
      * @param text         Specifies the text String.
 86  
      */
 87  
     protected AbstractFrameBodyTextInfo(byte textEncoding, String text)
 88  
     {
 89  184
         super();
 90  184
         setObjectValue(DataTypes.OBJ_TEXT_ENCODING, textEncoding);
 91  184
         setObjectValue(DataTypes.OBJ_TEXT, text);
 92  184
     }
 93  
 
 94  
     /**
 95  
      * Creates a new FrameBodyTextInformation datatype from file.
 96  
      * <p/>
 97  
      * <p>The super.super Constructor sets up the Object list for the frame.
 98  
      *
 99  
      * @param byteBuffer
 100  
      * @param frameSize
 101  
      * @throws InvalidTagException if unable to create framebody from buffer
 102  
      */
 103  
     protected AbstractFrameBodyTextInfo(ByteBuffer byteBuffer, int frameSize) throws InvalidTagException
 104  
     {
 105  4861
         super(byteBuffer, frameSize);
 106  4853
     }
 107  
 
 108  
     /**
 109  
      * Set the Full Text String.
 110  
      * <p/>
 111  
      * <p>If this String contains null terminator characters these are parsed as value
 112  
      * seperators, allowing you to hold multiple strings within one text frame. This functionality is only
 113  
      * officially support in ID3v24.
 114  
      *
 115  
      * @param text to set
 116  
      */
 117  
     public void setText(String text)
 118  
     {
 119  637
         if (text == null)
 120  
         {
 121  24
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 122  
         }
 123  613
         setObjectValue(DataTypes.OBJ_TEXT, text);
 124  613
     }
 125  
 
 126  
 
 127  
     /**
 128  
      * Retrieve the complete Text String.
 129  
      *
 130  
      * @return the text string
 131  
      */
 132  
     public String getText()
 133  
     {
 134  2886
         return (String) getObjectValue(DataTypes.OBJ_TEXT);
 135  
     }
 136  
 
 137  
     /**
 138  
      * Get first value
 139  
      *
 140  
      * @return value at index 0
 141  
      */
 142  
     public String getFirstTextValue()
 143  
     {
 144  625
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 145  625
         return text.getValueAtIndex(0);
 146  
     }
 147  
 
 148  
     /**
 149  
      * Get value at index
 150  
      *
 151  
      * @param index
 152  
      * @return value at index
 153  
      */
 154  
     public String getValueAtIndex(int index)
 155  
     {
 156  9
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 157  9
         return text.getValueAtIndex(index);
 158  
     }
 159  
 
 160  
     /**
 161  
      * Add additional value to value
 162  
      *
 163  
      * @param value at index
 164  
      */
 165  
     public void addTextValue(String value)
 166  
     {
 167  4
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 168  4
         text.addValue(value);
 169  4
     }
 170  
 
 171  
     /**
 172  
      * @return number of text values, usually one
 173  
      */
 174  
     public int getNumberOfValues()
 175  
     {
 176  13
         TextEncodedStringSizeTerminated text = (TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT);
 177  13
         return text.getNumberOfValues();
 178  
     }
 179  
 
 180  
     /**
 181  
      * Because Text frames have a text encoding we need to check the text
 182  
      * String does not contain characters that cannot be encoded in
 183  
      * current encoding before we write data. If there are change the text
 184  
      * encoding.
 185  
      */
 186  
     public void write(ByteArrayOutputStream tagBuffer)
 187  
     {
 188  
         //Ensure valid for type
 189  3132
         setTextEncoding(ID3TextEncodingConversion.getTextEncoding(getHeader(), getTextEncoding()));
 190  
 
 191  
         //Ensure valid for data
 192  3132
         if (!((TextEncodedStringSizeTerminated) getObject(DataTypes.OBJ_TEXT)).canBeEncoded())
 193  
         {
 194  24
             this.setTextEncoding(ID3TextEncodingConversion.getUnicodeTextEncoding(getHeader()));
 195  
         }
 196  3132
         super.write(tagBuffer);
 197  3132
     }
 198  
 
 199  
     /**
 200  
      * Setup the Object List. All text frames contain a text encoding
 201  
      * and then a text string.
 202  
      * <p/>
 203  
      * TODO:would like to make final but cannnot because overriden by FrameBodyTXXX
 204  
      */
 205  
     protected void setupObjectList()
 206  
     {
 207  5334
         objectList.add(new NumberHashMap(DataTypes.OBJ_TEXT_ENCODING, this, TextEncoding.TEXT_ENCODING_FIELD_SIZE));
 208  5334
         objectList.add(new TextEncodedStringSizeTerminated(DataTypes.OBJ_TEXT, this));
 209  5334
     }
 210  
 }