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

📄 fscodec.java

📁 利用opensource的开源jar实现生成flash文件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* 
 * FSCodec.java
 * Transform Utilities
 *
 * Copyright (c) 2001-2006 Flagstone Software Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *  * Neither the name of Flagstone Software Ltd. nor the names of its contributors 
 *    may be used to endorse or promote products derived from this software 
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.flagstone.transform.util;

/**
 * @deprecated FSCoded is replaced by FSCoder from com.flagstone.transform so
 * there is only one class for reading and writing data.
 * 
 * FSCodec is a similar to Java stream classes, allowing words and bit fields to be read
 * and written from an internal array of bytes. FSCodec supports both little-endian
 * and big-endian byte ordering. The primary use of the class is to support post-processing
 * of sound files loaded using the FSSoundConstructor class where the encoded sound samples
 * contain bits fields. For example compressing 16-bit, byte-aligned sound samples to the 
 * ADPCM format. However the class may be used in any situation where data must be encoded
 * or decoded to an array of bytes.
 * 
 * The FSCodec class maintains an internal pointer which points to the next bit in the internal
 * array where data will be read or written. When calculating an offset in bytes to jump to
 * simply multiply the offset by 8 for the correct bit position. The class provides accessor
 * methods, getPosition() and setPosition() to change the location of the internal pointer.
 * 
 * When writing to an array the size of the array is changed dynamically should a write 
 * operation cause a buffer overflow. For reads if an overflow results then the bits/bytes
 * that overflowed will be set to zero, rather than throwing an exception. The eof() method 
 * can be used to determine whether the end of the buffer has been reached.
 */
public class FSCodec
{
    /** 
     * Identifies that multibyte words are stored in little-endian format with the least
     * significant byte in a word stored first.
     */
    public static final int LITTLE_ENDIAN = 0;

    /** 
     * Identifies that multibyte words are stored in big-endian format with the most
     * significant byte in a word stored first.
     */
    public static final int BIG_ENDIAN = 1;
    
    private int byteOrder = LITTLE_ENDIAN;
    private byte[] data = null;
    private int ptr = 0;
    private int end = 0;
    
    /**
     * Constructs and FSCodec object containing an array of bytes with the specified byte 
     * ordering.
     * 
     * @param order the byte-order for words, either FSCodec.LITTLE_ENDIAN or FSCodec.BIG_ENDIAN.
     * @param bytes an array of bytes where the data will be read or written.
     */
    public FSCodec(int order, byte[] bytes)
    {
        byteOrder = order;
        
        data = new byte[bytes.length];
        System.arraycopy(bytes, 0, data, 0, bytes.length);
        end = data.length << 3;
    }
    
    /**
     * Constructs and FSCodec object containing an array of bytes with the specified byte 
     * ordering.
     * 
     * @param order the byte-order for words, either FSCodec.LITTLE_ENDIAN or FSCodec.BIG_ENDIAN.
     * @param size the size of the internal buffer to be created.
     */
    public FSCodec(int order, int size)
    {
        byteOrder = order;
        
        data = new byte[size];
        end = data.length << 3;
    }
    
    /**
     * Returns a copy of the array of bytes.
     * 
     * @return a copy of the internal buffer.
     */
    public byte[] getData()
    {
        int length = (ptr + 7) >> 3;
        
        byte[] bytes = new byte[length];
        System.arraycopy(data, 0, bytes, 0, length);
        
        return bytes;
    }

    /**
     * Sets the array of bytes used to read or write data to. The size of the array must be 
     * calculated in advance to avoid buffer overflows.
     * 
     * @param bytes a byte array that will be used as the internal buffer.
     */
    public void setData(byte[] bytes)
    {
        data = bytes;
        ptr = 0;
        end = data.length << 3;
    }
    
    /**
     * Sets the array of bytes used to read or write data to. The byte-order for words read
     * or written is also specified. The size of the array must be calculated in advance to 
     * avoid buffer overflows.
     * 
     * @param order the byte-order for words, either FSCodec.LITTLE_ENDIAN or FSCodec.BIG_ENDIAN.
     * @param bytes a byte array that will be used as the internal buffer.
     */
    public void setData(int order, byte[] bytes)
    {
        byteOrder = order;
        data = bytes;
        ptr = 0;
        end = data.length << 3;
    }
    
    /**
     * Returns the offset, in bits, from the start of the buffer where the next value will be 
     * read or written.
     * 
     * @return the offset in bits where the next value will be read or written. 
     */
    public int getPosition()
    {
        return ptr;
    }

    /**
     * Sets the offset, in bits, from the start of the buffer where the next value will be 
     * read or written. If the offset falls outside of the bits range supported by the buffer 
     * then the pointer is clamped to either the start or end of the buffer.
     *  
     * @param offset the offset in bits from the start of the array of bytes.
     */
    public void setPosition(int offset)
    {
        if (offset < 0)
            ptr = 0;
        else if (offset > end)
            ptr = end;
        else
            ptr = offset;
    }

    /**
     * Moves the internal pointer forward so it is aligned on a byte boundary. All word
     * values read and written to the internal buffer must be byte-aligned.
     */
    public void alignToByte()
    {
        ptr = (ptr+7) & ~7;
    }
    
    /**
     * Returns true of the internal pointer is at the end of the buffer.
     * 
     * @return true if the pointer is at the end of the buffer, false otherwise.
     */
    public boolean eof()
    {
        return ptr >= end;
    }

    /**
     * Searches the internal buffer for a bit pattern and advances the pointer to
     * the start of the bit field, returning true to signal a successful search.
     * If the bit pattern cannot be found then the method returns false and the 
     * position of the internal pointer is not changed.
     * 
     * The step, in bits, added to the pointer can be specified, allowing the
     * number of bits being searched to be independent of the location in the 
     * internal buffer. This is useful for example when searching for a bit 
     * field that begins on a byte or word boundary.
     *  
     * @param value an integer containing the bit patter to search for.
     * @param numberOfBits least significant n bits in the value to search for.
     * @param step the increment in bits to add to the internal pointer as the buffer
     * is searched.
     * @return true if the pattern was found, false otherwise.
     */
    public boolean findBits(int value, int numberOfBits, int step)
    {
        boolean found = false;
        int start = ptr;
        int val = 0;
        
        if (numberOfBits < 1 || numberOfBits > 32)
            throw new IllegalArgumentException("Number of bits must be in the range 1..32.");
            
        for (; ptr < end; ptr += step)
        {
            val = readBits(numberOfBits, false);
            ptr -= numberOfBits;
            
            if (val == value)
            {
                found = true;
                break;
            }
        }
        
        if (found == false)
            ptr = start;
            
        return found;
    }

    /**
     * Searches the internal buffer for a word and advances the pointer to the location
     * where the word was found, returning true to signal a successful search. The 
     * search will begin on the next byte boundary. If word cannot be found then the 
     * method returns false and the position of the internal pointer is not changed.
     * 
     * Specifying the number of bytes in the search value allows word of either 8, 16,
     * 24 or 32 bits to be searched for. Searches for words are performed faster than 
     * using the findBits() method.
     * 
     * @param value an integer containing the word to search for.
     * @param numberOfBytes least significant n bytes in the value to search for.
     * @param step the increment in bits to add to the internal pointer as the buffer
     * is searched.
     * @return true if the pattern was found, false otherwise.
     */
    public boolean findWord(int value, int numberOfBytes, int step)
    {
        boolean found = false;
        int start = ptr;
        int val = 0;
        
        if (numberOfBytes < 1 || numberOfBytes > 4)
            throw new IllegalArgumentException("Number of bytes must be in the range 1..4.");
        
        if ((ptr & 7) > 0)
            ptr = (ptr+7) & ~7;
        
        for (; ptr < end; ptr += step)
        {
            val = readWord(numberOfBytes, false);
            ptr -= (numberOfBytes*8);
            
            if (val == value)
            {
                found = true;
                break;
            }
        }
        
        if (found == false)
            ptr = start;
            
        return found;
    }

    /**
     * Read a bit field from the internal buffer.
     * 
     * If a buffer overflow occurs then the number of bits which cause the overflow will 
     * be set to zero.
     * 
     * @param numberOfBits the number of bits to read.
     * @param signed a boolean flag indicating whether the value read should be sign extended.
     * @return the value read.
     */
    public int readBits(int numberOfBits, boolean signed)
    {
        int value = 0;
    
        if (numberOfBits < 1 || numberOfBits > 32)
            throw new IllegalArgumentException("Number of bits must be in the range 1..32.");
        
        int index = ptr >> 3;
        int base = (data.length - index > 4) ? 0  : (4 - (data.length - index))*8;
        
        for (int i=32; i>base; i-=8, index++)
            value |= (data[index] & 0x000000FF) << (i-8);

        value <<= ptr % 8;

        if (signed)
            value >>= 32 - numberOfBits;
        else 
            value >>>= 32 - numberOfBits;

        ptr += numberOfBits;

⌨️ 快捷键说明

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