Coverage Report - org.jaudiotagger.tag.datatype.MultipleTextEncodedStringNullTerminated
 
Classes in this File Line Coverage Branch Coverage Complexity
MultipleTextEncodedStringNullTerminated
39%
19/49
17%
2/12
0
MultipleTextEncodedStringNullTerminated$Values
100%
15/15
100%
4/4
0
 
 1  
 package org.jaudiotagger.tag.datatype;
 2  
 
 3  
 import org.jaudiotagger.tag.InvalidDataTypeException;
 4  
 import org.jaudiotagger.tag.id3.AbstractTagFrameBody;
 5  
 
 6  
 import java.io.ByteArrayOutputStream;
 7  
 import java.io.IOException;
 8  
 import java.util.ArrayList;
 9  
 import java.util.List;
 10  
 import java.util.ListIterator;
 11  
 import java.util.logging.Level;
 12  
 
 13  
 /**
 14  
  * Represents a datatype that supports multiple terminated Strings (there may only be one)
 15  
  */
 16  
 public class MultipleTextEncodedStringNullTerminated extends AbstractDataType
 17  
 {
 18  
 
 19  
     /**
 20  
      * Creates a new ObjectStringSizeTerminated datatype.
 21  
      *
 22  
      * @param identifier identifies the frame type
 23  
      */
 24  
     public MultipleTextEncodedStringNullTerminated(String identifier, AbstractTagFrameBody frameBody)
 25  
     {
 26  1
         super(identifier, frameBody);
 27  1
         value = new MultipleTextEncodedStringNullTerminated.Values();
 28  1
     }
 29  
 
 30  
     public MultipleTextEncodedStringNullTerminated(TextEncodedStringSizeTerminated object)
 31  
     {
 32  0
         super(object);
 33  0
         value = new MultipleTextEncodedStringNullTerminated.Values();
 34  0
     }
 35  
 
 36  
     public MultipleTextEncodedStringNullTerminated(MultipleTextEncodedStringNullTerminated object)
 37  
     {
 38  1
         super(object);        
 39  1
     }
 40  
 
 41  
     public boolean equals(Object obj)
 42  
     {
 43  0
         if (obj instanceof MultipleTextEncodedStringNullTerminated == false)
 44  
         {
 45  0
             return false;
 46  
         }
 47  0
         return super.equals(obj);
 48  
     }
 49  
 
 50  
     /**
 51  
      * Returns the size in bytes of this datatype when written to file
 52  
      *
 53  
      * @return size of this datatype
 54  
      */
 55  
     public int getSize()
 56  
     {
 57  1
         return size;
 58  
     }
 59  
 
 60  
     /**
 61  
      * Check the value can be encoded with the specified encoding
 62  
      */
 63  
     public boolean canBeEncoded()
 64  
     {
 65  0
         for (ListIterator<String> li = ((Values) value).getList().listIterator(); li.hasNext();)
 66  
         {
 67  0
             TextEncodedStringNullTerminated next = new TextEncodedStringNullTerminated(identifier, frameBody, li.next());
 68  0
             if (!next.canBeEncoded())
 69  
             {
 70  0
                 return false;
 71  
             }
 72  0
         }
 73  0
         return true;
 74  
     }
 75  
 
 76  
     /**
 77  
      * Read Null Terminated Strings from the array starting at offset, continue until unable to find any null terminated
 78  
      * Strings or until reached the end of the array. The offset should be set to byte after the last null terminated
 79  
      * String found.
 80  
      *
 81  
      * @param arr    to read the Strings from
 82  
      * @param offset in the array to start reading from
 83  
      * @throws InvalidDataTypeException if unable to find any null terminated Strings
 84  
      */
 85  
     public void readByteArray(byte[] arr, int offset) throws InvalidDataTypeException
 86  
     {
 87  1
         logger.finer("Reading MultipleTextEncodedStringNullTerminated from array from offset:" + offset);
 88  
         //Continue until unable to read a null terminated String
 89  
         while (true)
 90  
         {
 91  
             try
 92  
             {
 93  
                 //Read String
 94  3
                 TextEncodedStringNullTerminated next = new TextEncodedStringNullTerminated(identifier, frameBody);
 95  3
                 next.readByteArray(arr, offset);
 96  
 
 97  2
                 if (next.getSize() == 0)
 98  
                 {
 99  0
                     break;
 100  
                 }
 101  
                 else
 102  
                 {
 103  
                     //Add to value
 104  2
                     ((Values) value).add((String) next.getValue());
 105  
 
 106  
                     //Add to size calculation
 107  2
                     size += next.getSize();
 108  
 
 109  
                     //Increment Offset to start of next datatype.
 110  2
                     offset += next.getSize();
 111  
                 }
 112  
             }
 113  1
             catch (InvalidDataTypeException idte)
 114  
             {
 115  1
                 break;
 116  2
             }
 117  
 
 118  2
             if (size == 0)
 119  
             {
 120  0
                 logger.warning("No null terminated Strings found");
 121  0
                 throw new InvalidDataTypeException("No null terminated Strings found");
 122  
             }
 123  
         }
 124  1
         logger.finer("Read  MultipleTextEncodedStringNullTerminated:" + value + " size:" + size);
 125  1
     }
 126  
 
 127  
     /**
 128  
      * For every String write to bytebuffer
 129  
      *
 130  
      * @return bytebuffer that should be written to file to persist this datatype.
 131  
      */
 132  
     public byte[] writeByteArray()
 133  
     {
 134  0
         logger.finer("Writing MultipleTextEncodedStringNullTerminated");
 135  
 
 136  0
         int localSize = 0;
 137  0
         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 138  
         try
 139  
         {
 140  0
             for (ListIterator<String> li = ((Values) value).getList().listIterator(); li.hasNext();)
 141  
             {
 142  0
                 TextEncodedStringNullTerminated next = new TextEncodedStringNullTerminated(identifier, frameBody, li.next());
 143  0
                 buffer.write(next.writeByteArray());
 144  0
                 localSize += next.getSize();
 145  0
             }
 146  
         }
 147  0
         catch (IOException ioe)
 148  
         {
 149  
             //This should never happen because the write is internal with the JVM it is not to a file
 150  0
             logger.log(Level.SEVERE, "IOException in MultipleTextEncodedStringNullTerminated when writing byte array", ioe);
 151  0
             throw new RuntimeException(ioe);
 152  0
         }
 153  
 
 154  
         //Update size member variable
 155  0
         size = localSize;
 156  
 
 157  0
         logger.finer("Written MultipleTextEncodedStringNullTerminated");
 158  0
         return buffer.toByteArray();
 159  
     }
 160  
 
 161  
     /**
 162  
      * This holds the values held by a MultipleTextEncodedDatatype
 163  
      */
 164  
     public static class Values
 165  
     {
 166  2
         private List<String> valueList = new ArrayList<String>();
 167  
 
 168  
         public Values()
 169  2
         {
 170  
 
 171  2
         }
 172  
 
 173  
         /**
 174  
          * Add String Datatype to the value list
 175  
          *
 176  
          * @param value to add to the list
 177  
          */
 178  
         public void add(String value)
 179  
         {
 180  2
             valueList.add(value);
 181  2
         }
 182  
 
 183  
 
 184  
         /**
 185  
          * Return the list of values
 186  
          *
 187  
          * @return the list of values
 188  
          */
 189  
         public List<String> getList()
 190  
         {
 191  2
             return valueList;
 192  
         }
 193  
 
 194  
         /**
 195  
          *
 196  
          * @return no of values
 197  
          */
 198  
         public int getNumberOfValues()
 199  
         {
 200  3
             return valueList.size();
 201  
         }
 202  
 
 203  
         /**
 204  
          * Return the list of values as a single string seperated by a comma
 205  
          *
 206  
          * @return a string representation of the value
 207  
          */
 208  
         public String toString()
 209  
         {
 210  2
             StringBuffer sb = new StringBuffer();
 211  2
             for (ListIterator<String> li = valueList.listIterator(); li.hasNext();)
 212  
             {
 213  4
                 String next = li.next();
 214  4
                 sb.append(next);
 215  4
                 if (li.hasNext())
 216  
                 {
 217  2
                     sb.append(",");
 218  
                 }
 219  4
             }
 220  2
             return sb.toString();
 221  
         }
 222  
     }
 223  
 }