/*
You may freely copy, distribute, modify and use this class as long
as the original author attribution remains intact. See message
below.
Copyright (C) 2003 Christian Pesch. All Rights Reserved.
*/
package slash.metamusic.mp3.sections;
import slash.metamusic.mp3.ID3v2Header;
import slash.metamusic.util.StringHelper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* A section that contains a string in C format, i.e.
* it ends with a zero 0x00 byte.
*
* @author Christian Pesch
* @version $Id: CStringSection.java 958 2007-02-28 14:44:37Z cpesch $
*/
public abstract class CStringSection extends AbstractSection {
private int findNullBytesIndex(byte[] bytes, int startIndex, int nullByteCount) {
int endIndex = startIndex;
int nullBytesFound = 0;
for (; endIndex < bytes.length; endIndex++) {
byte aByte = bytes[endIndex];
// count null bytes
if (aByte == 0)
nullBytesFound++;
else
nullBytesFound = 0;
// if found return
if (nullByteCount == nullBytesFound)
break;
}
return endIndex;
}
protected ParseResult parse(byte[] data, int startIndex, String encoding) throws IOException {
int nullByteLength = encoding.equals(ID3v2Header.ISO_8859_1_ENCODING) ? 1 : 2;
int endIndex = findNullBytesIndex(data, startIndex, nullByteLength);
if (endIndex == data.length) {
// there are files out there that claim to be encoded in UTF-8
// but which use only one $00 as termination
if (nullByteLength == 2 && findNullBytesIndex(data, startIndex, 1) == startIndex) {
log.warning("Only one null byte at the end of " + encoding + " string");
nullByteLength = 1;
}
return new ParseResult(null, nullByteLength);
}
String string = StringHelper.trim(new String(data, startIndex, endIndex - startIndex, encoding));
return new ParseResult(string, endIndex - startIndex + nullByteLength);
}
protected byte[] getBytes(String string, String encoding) throws UnsupportedEncodingException {
if (string != null) {
// for Unicode, Strings have to start with the Unicode byte order mark (BOM)
// this is $FF FE or $FE FF; they are always finished by a null byte $00 00
if (!encoding.equals(ID3v2Header.ISO_8859_1_ENCODING))
string = "\uFFFE" + string;
string = string + "\u0000";
}
byte[] bytes = string != null ? string.getBytes(encoding) : new byte[0];
return bytes;
}
protected class ParseResult {
private String string;
private int length;
private ParseResult(String string, int length) {
this.string = string;
this.length = length;
}
protected String getString() {
return string;
}
protected int getLength() {
return length;
}
}
}