⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textencodedstringsizeterminated.java

📁 java+eclipse做的TTPlayer
💻 JAVA
字号:
package com.hadeslee.audiotag.tag.datatype;

import com.hadeslee.audiotag.tag.id3.AbstractTagFrameBody;
import com.hadeslee.audiotag.tag.InvalidDataTypeException;
import com.hadeslee.audiotag.tag.TagOptionSingleton;
import com.hadeslee.audiotag.tag.id3.valuepair.TextEncoding;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Represents a String which is not delimited by null character.
 * <p/>
 * This type of String will usually only be used when it is the last field within a frame, when reading the remainder of
 * the byte array will be read, when writing the frame will be accomodate the required size for the String. The String
 * will be encoded based upon the text encoding of the frame that it belongs to.
 *
 * All TextInformation frames support multiple strings, stored as a null separated list, where null is represented by
 * the termination code for the character encoding. This functionality is only officially support in ID3v24.  Itunes
 * write null terminators characters even though only writes a single value.
 */
public class TextEncodedStringSizeTerminated
    extends AbstractString
{

    /**
     * Creates a new empty TextEncodedStringSizeTerminated datatype.
     *
     * @param identifier identifies the frame type
     */
    public TextEncodedStringSizeTerminated(String identifier, AbstractTagFrameBody frameBody)
    {
        super(identifier, frameBody);
    }

    /**
     * Copy constructor
     *
     * @param object
     */
    public TextEncodedStringSizeTerminated(TextEncodedStringSizeTerminated object)
    {
        super(object);
    }

    public boolean equals(Object obj)
    {
        if (obj instanceof TextEncodedStringSizeTerminated == false)
        {
            return false;
        }
        return super.equals(obj);
    }

    /**
     * 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.
     * <p/>
     * 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.
     *
     * @param arr    this is the buffer for the frame
     * @param offset this is where to start reading in the buffer for this field
     * @throws NullPointerException
     * @throws IndexOutOfBoundsException
     */
    public void readByteArray(byte[] arr, int offset) throws InvalidDataTypeException
    {
        logger.finest("Reading from array from offset:" + offset);

        //Get the Specified Decoder
        String charSetName = getTextEncodingCharSet();
        CharsetDecoder decoder = Charset.forName(charSetName).newDecoder();

        //Decode sliced inBuffer
        ByteBuffer inBuffer = ByteBuffer.wrap(arr, offset, arr.length - offset).slice();
        CharBuffer outBuffer = CharBuffer.allocate(arr.length - offset);
        decoder.reset();
        CoderResult coderResult = decoder.decode(inBuffer, outBuffer, true);
        if (coderResult.isError())
        {
            logger.warning("Decoding error:" + coderResult.toString());
        }
        decoder.flush(outBuffer);
        outBuffer.flip();

        //Store value
        value=outBuffer.toString();


        //SetSize, important this is correct for finding the next datatype
        setSize(arr.length - offset);
        logger.info("Read SizeTerminatedString:" + value + " size:" + size);
    }

    /**
     * Write String into byte array
     *
     * It will remove a trailing null terminator if exists if the option
     * RemoveTrailingTerminatorOnWrite has been set.
     *
     * @return the data as a byte array in format to write to file
     */
    public byte[] writeByteArray()
    {
        byte[] data = null;
        //Try and write to buffer using the CharSet defined by getTextEncodingCharSet()
        try
        {
            String charSetName = getTextEncodingCharSet();
            CharsetEncoder encoder = Charset.forName(charSetName).newEncoder();

            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;
                    }
                }
            }
            ByteBuffer bb = encoder.encode(CharBuffer.wrap((String) value));
            data = new byte[bb.limit()];
            bb.get(data, 0, bb.limit());
        }
        //Should never happen so if does throw a RuntimeException
        catch (CharacterCodingException ce)
        {
            logger.severe(ce.getMessage());
            throw new RuntimeException(ce);
        }
        setSize(data.length);
        return data;
    }

    /**
     * Get the text encoding being used.
     *
     * The text encoding is defined by the frame body that the text field belongs to.
     *
     * @return the text encoding charset
     */
    protected String getTextEncodingCharSet()
    {
        byte textEncoding = this.getBody().getTextEncoding();
        String charSetName = TextEncoding.getInstanceOf().getValueForId(textEncoding);
        logger.finest("text encoding:" + textEncoding + " charset:" + charSetName);
        return charSetName;
    }

    /**
     * Split the values seperated by null character
     *
     * @param value the raw value
     * @return list of values, guaranteed to be at least one value
     */
    private static List splitByNullSeperator(String value)
    {
        String[]valuesarray = value.split("\\u0000");
        List values = Arrays.asList(valuesarray);
        //Read only list so if empty have to create new list
        if(values.size()==0)
        {
            values = new ArrayList(1);
            values.add("");
        }
        return values;
    }

    /**
     * Add an additional String to the current String value
     *
     * @param value
     */
    public void addValue(String value)
    {
        setValue(this.value + "\u0000" + value);
    }

    /**
     * How many values are held, each value is seperated by a null terminator
     *
     * @return number of values held, usually this will be one.
     */
    public int getNumberOfValues()
    {
        return splitByNullSeperator(((String)value)).size();
    }

    /**
     * Get the nth value
     *
     * @param index
     *
     * @throws IndexOutOfBoundsException if value does not exist
     *
     * @return the nth value
     */
    public String getValueAtIndex(int index)
    {
       //Split String into seperate components
       List values = splitByNullSeperator((String)value);
       return (String)values.get(index);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -