Methods Summary |
---|
public void | addValue(java.lang.String value)Add an additional String to the current String value
setValue(this.value + "\u0000" + value);
|
private void | checkTrailingNull(java.util.List values, java.lang.String stringValue)Because nulls are stripped we need to check if not removing trailing nulls whether the original
value ended with a null and if so add it back in.
if(!TagOptionSingleton.getInstance().isRemoveTrailingTerminatorOnWrite())
{
if (stringValue.length() > 0 && stringValue.charAt(stringValue.length() - 1) == '\0")
{
String lastVal = values.get(values.size() - 1);
String newLastVal = lastVal + '\0";
values.set(values.size() - 1,newLastVal);
}
}
|
public boolean | equals(java.lang.Object obj)
if(this==obj)
{
return true;
}
return obj instanceof TextEncodedStringSizeTerminated && super.equals(obj);
|
public int | getNumberOfValues()How many values are held, each value is separated by a null terminator
return splitByNullSeperator(((String) value)).size();
|
protected java.lang.String | getTextEncodingCharSet()Get the text encoding being used.
The text encoding is defined by the frame body that the text field belongs to.
byte textEncoding = this.getBody().getTextEncoding();
String charSetName = TextEncoding.getInstanceOf().getValueForId(textEncoding);
logger.finest("text encoding:" + textEncoding + " charset:" + charSetName);
return charSetName;
|
public java.lang.String | getValueAtIndex(int index)Get the nth value
//Split String into separate components
List values = splitByNullSeperator((String) value);
return (String) values.get(index);
|
public java.lang.String | getValueWithoutTrailingNull()Get value(s) whilst removing any trailing nulls
List<String> values = splitByNullSeperator((String) value);
StringBuffer sb = new StringBuffer();
for(int i=0;i<values.size();i++)
{
if(i!=0)
{
sb.append("\u0000");
}
sb.append(values.get(i));
}
return sb.toString();
|
public java.util.List | getValues()
return splitByNullSeperator((String) value);
|
public void | readByteArray(byte[] arr, int offset)Read a 'n' bytes from buffer into a String where n is the framesize - offset
so thefore cannot use this if there are other objects after it because it has no
delimiter.
Must take into account the text encoding defined in the Encoding Object
ID3 Text Frames often allow multiple strings seperated by the null char
appropriate for the encoding.
logger.finest("Reading from array from offset:" + offset);
//Get the Specified Decoder
String charSetName = getTextEncodingCharSet();
CharsetDecoder decoder = Charset.forName(charSetName).newDecoder();
decoder.reset();
//Decode sliced inBuffer
ByteBuffer inBuffer;
if(TagOptionSingleton.getInstance().isAndroid())
{
//#302 [dallen] truncating array manually since the decoder.decode() does not honor the offset in the in buffer
byte[] truncArr = new byte[arr.length - offset];
System.arraycopy(arr, offset, truncArr, 0, truncArr.length);
inBuffer = ByteBuffer.wrap(truncArr);
}
else
{
inBuffer = ByteBuffer.wrap(arr, offset, arr.length - offset).slice();
}
CharBuffer outBuffer = CharBuffer.allocate(arr.length - offset);
CoderResult coderResult = decoder.decode(inBuffer, outBuffer, true);
if (coderResult.isError())
{
logger.warning("Decoding error:" + coderResult.toString());
}
decoder.flush(outBuffer);
outBuffer.flip();
//If using UTF16 with BOM we then search through the text removing any BOMs that could exist
//for multiple values, BOM could be Big Endian or Little Endian
if (charSetName.equals(TextEncoding.CHARSET_UTF_16))
{
value = outBuffer.toString().replace("\ufeff","").replace("\ufffe","");
}
else
{
value = outBuffer.toString();
}
//SetSize, important this is correct for finding the next datatype
setSize(arr.length - offset);
logger.config("Read SizeTerminatedString:" + value + " size:" + size);
|
public static java.util.List | splitByNullSeperator(java.lang.String value)Split the values separated by null character
String[] valuesarray = value.split("\\u0000");
List<String> values = Arrays.asList(valuesarray);
//Read only list so if empty have to create new list
if (values.size() == 0)
{
values = new ArrayList<String>(1);
values.add("");
}
return values;
|
private void | stripTrailingNull()Removing trailing null from end of String, this should be there but some applications continue to write
this unnecessary null char.
if (TagOptionSingleton.getInstance().isRemoveTrailingTerminatorOnWrite())
{
String stringValue = (String) value;
if (stringValue.length() > 0)
{
if (stringValue.charAt(stringValue.length() - 1) == '\0")
{
stringValue = (stringValue).substring(0, stringValue.length() - 1);
value = stringValue;
}
}
}
|
public byte[] | writeByteArray()Write String into byte array
It will remove a trailing null terminator if exists if the option
RemoveTrailingTerminatorOnWrite has been set.
byte[] data;
//Try and write to buffer using the CharSet defined by getTextEncodingCharSet()
try
{
stripTrailingNull();
//Special Handling because there is no UTF16 BOM LE charset
String stringValue = (String)value;
String charSetName = getTextEncodingCharSet();
String actualCharSet = null;
if (charSetName.equals(TextEncoding.CHARSET_UTF_16))
{
if(TagOptionSingleton.getInstance().isEncodeUTF16BomAsLittleEndian())
{
actualCharSet = TextEncoding.CHARSET_UTF_16_LE_ENCODING_FORMAT;
}
else
{
actualCharSet = TextEncoding.CHARSET_UTF_16_BE_ENCODING_FORMAT;
}
}
//Ensure large enough for any encoding
ByteBuffer outputBuffer = ByteBuffer.allocate((stringValue.length() + 3)* 3);
//Ensure each string (if multiple values) is written with BOM by writing separately
List<String> values = splitByNullSeperator(stringValue);
checkTrailingNull(values, stringValue);
//For each value
for(int i=0;i<values.size();i++)
{
String next = values.get(i);
if(actualCharSet!=null)
{
if (actualCharSet.equals(TextEncoding.CHARSET_UTF_16_LE_ENCODING_FORMAT))
{
outputBuffer.put(writeStringUTF16LEBOM( next, i, values.size()));
}
else if (actualCharSet.equals(TextEncoding.CHARSET_UTF_16_BE_ENCODING_FORMAT))
{
outputBuffer.put(writeStringUTF16BEBOM( next, i, values.size()));
}
}
else
{
outputBuffer.put(writeString( Charset.forName(charSetName).newEncoder(), next, i, values.size()));
}
}
outputBuffer.flip();
data = new byte[outputBuffer.limit()];
outputBuffer.rewind();
outputBuffer.get(data, 0, outputBuffer.limit());
setSize(data.length);
}
//Should never happen so if does throw a RuntimeException
catch (CharacterCodingException ce)
{
logger.severe(ce.getMessage());
throw new RuntimeException(ce);
}
return data;
|
private java.nio.ByteBuffer | writeString(java.nio.charset.CharsetEncoder encoder, java.lang.String next, int i, int noOfValues)Write String using specified encoding
When this is called multiple times, all but the last value has a trailing null
ByteBuffer bb;
if(( i + 1) == noOfValues )
{
bb = encoder.encode(CharBuffer.wrap(next));
}
else
{
bb = encoder.encode(CharBuffer.wrap(next + '\0"));
}
bb.rewind();
return bb;
|
private java.nio.ByteBuffer | writeStringUTF16BEBOM(java.lang.String next, int i, int noOfValues)Write String in UTF-BEBOM format
When this is called multiple times, all but the last value has a trailing null
CharsetEncoder encoder = Charset.forName(TextEncoding.CHARSET_UTF_16_BE_ENCODING_FORMAT).newEncoder();
ByteBuffer bb = null;
//Add BOM
if(( i + 1)==noOfValues)
{
bb = encoder.encode(CharBuffer.wrap('\ufeff" + next ));
}
else
{
bb = encoder.encode(CharBuffer.wrap('\ufeff" + next + '\0"));
}
bb.rewind();
return bb;
|
private java.nio.ByteBuffer | writeStringUTF16LEBOM(java.lang.String next, int i, int noOfValues)Write String in UTF-LEBOM format
When this is called multiple times, all but the last value has a trailing null
Remember we are using this charset because the charset that writes BOM does it the wrong way for us
so we use this none and then manually add the BOM ourselves.
CharsetEncoder encoder = Charset.forName(TextEncoding.CHARSET_UTF_16_LE_ENCODING_FORMAT).newEncoder();
ByteBuffer bb = null;
//Note remember LE BOM is ff fe but this is handled by encoder Unicode char is fe ff
if(( i + 1)==noOfValues)
{
bb = encoder.encode(CharBuffer.wrap('\ufeff" + next ));
}
else
{
bb = encoder.encode(CharBuffer.wrap('\ufeff" + next + '\0"));
}
bb.rewind();
return bb;
|