📄 fscoder.java
字号:
/*
* FSCoder.java
* Transform
*
* 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;
import java.io.*;
/**
* FSCoder is a similar to Java stream classes, allowing words and bit fields
* to be read and written from an internal array of bytes. FSCoder supports both
* little-endian and big-endian byte ordering.
*
* The FSCoder 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, getPointer() and
* setPointer() 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 FSCoder
{
/**
* 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;
/*
* Methods used to calculate the size of fields when encoded.
*/
/**
* Calculates the minimum number of bits required to encoded an integer
* in a bit field.
*
* @param value the value to be encoded.
*
* @param signed where the value will be encoded as a signed or unsigned
* integer.
*
* @return the number of bits required to encode the value.
*/
static int size(int value, boolean signed)
{
int size = 0, i = 0;
int mask = 0x80000000;
if (signed)
{
value = (value < 0) ? -value : value;
for (i=32; (value & mask) == 0 && i>0; i--)
mask >>>= 1;
size = (i < 32) ? i+1 : i;
}
else
{
for (i=32; (value & mask) == 0 && i>0; i--)
mask >>>= 1;
size = i;
}
return size;
}
/**
* Calculates the minimum number of bits required to encoded an array of
* integer values in a series of bit fields.
*
* @param values the values to be encoded.
*
* @param signed where the values will be encoded as a signed or unsigned
* integers.
*
* @return the minimum number of bits required to encode all the values.
*/
static int size(int[] values, boolean signed)
{
int size = 0;
for (int i=0; i<values.length; i++)
size = Math.max(size, size(values[i], signed));
return size;
}
/**
* Calculates the minimum number of bits required to encoded a floating
* point number as a fixed point number in 8.8 format.
*
* @param value the value to be encoded.
*
* @return the number of bits required to encode the value.
*/
static int fixedShortSize(float aNumber)
{
float floatValue = aNumber * 256.0f;
return size((int)floatValue, true);
}
/**
* Calculates the minimum number of bits required to encoded a series of
* floating point numbers in a fixed point number in 8.8 format.
*
* @param value the values to be encoded.
*
* @return the minimum number of bits required to encode all the values.
*/
static int fixedShortSize(float[] values)
{
int size = 0;
for (int i=0; i<values.length; i++)
size = Math.max(size, fixedShortSize(values[i]));
return size;
}
/**
* Calculates the minimum number of bits required to encoded a floating
* point number as a fixed point number in 16.16 format.
*
* @param value the value to be encoded.
*
* @return the number of bits required to encode the value.
*/
static int fixedSize(float aNumber)
{
float floatValue = aNumber * 65536.0f;
return size((int)floatValue, true);
}
/**
* Calculates the minimum number of bits required to encoded a series of
* floating point numbers in a fixed point number in 16.16 format.
*
* @param value the values to be encoded.
*
* @return the number of bits required to encode the value.
*/
static int fixedSize(float[] values)
{
int size = 0;
for (int i=0; i<values.length; i++)
size = Math.max(size, fixedSize(values[i]));
return size;
}
/**
* Calculates the length of a string when encoded.
*
* @param string the string to be encoded.
*
* @param encoding the format used to encode the string characters.
*
* @param appendNull whether the string should be terminated with a null
* byte.
*
* @return the number of bytes required to encode the string.
*/
static int strlen(String string, String encoding, boolean appendNull)
{
int length = 0;
if (string != null)
{
try
{
length += string.getBytes(encoding).length;
length += appendNull ? 1 : 0;
}
catch (UnsupportedEncodingException e)
{
}
}
return length;
}
/**
* Calculates the length of a string when encoded.
*
* @param string the string to be encoded.
*
* @param appendNull whether the string should be terminated with a null
* byte.
*
* @return the number of bytes required to encode the string.
*/
static int strlen(String string, boolean appendNull)
{
int length = 0;
if (string != null)
{
try
{
length += string.getBytes("UTF8").length;
length += appendNull ? 1 : 0;
}
catch (UnsupportedEncodingException e)
{
}
}
return length;
}
private FSMovieListener listener = null;
String encoding = "UTF8";
private int byteOrder = LITTLE_ENDIAN;
private byte[] data = null;
private int ptr = 0;
private int end = 0;
/**
* Constructs an FSCoder object containing an array of bytes with the
* specified byte ordering.
*
* @param order the byte-order for words, eitherLITTLE_ENDIAN or BIG_ENDIAN.
* @param size the size of the internal buffer to be created.
*/
public FSCoder(int order, int size)
{
clearContext();
byteOrder = order;
data = new byte[size];
for (int i=0; i<size; i++)
data[i] = 0;
ptr = 0;
end = data.length << 3;
}
/**
* Constructs an FSCoder object containing an array of bytes with the
* specified byte order.
*
* @param order the byte-order for words, either LITTLE_ENDIAN or BIG_ENDIAN.
* @param bytes an array of bytes where the data will be read or written.
*/
public FSCoder(int order, byte[] bytes)
{
clearContext();
byteOrder = order;
data = bytes;
ptr = 0;
end = data.length << 3;
}
/**
* @deprecated The FSMovieListener interface does not enable recovery from
* coding errors or corrupt Flash files and therefore will no longer be
* used. Instead errors will be reported through exceptions.
*/
void setListener(FSMovieListener aListener)
{
listener = aListener;
}
/**
* @deprecated The FSMovieListener interface does not enable recovery from
* coding errors or corrupt Flash files and therefore will no longer be
* used. Instead errors will be reported through exceptions.
*/
FSMovieListener getListener()
{
return listener;
}
/**
* @deprecated
*
* @param name
*/
void beginObject(String name)
{
if (listener != null)
listener.logEvent(new FSMovieEvent(context[FSCoder.Action], FSMovieEvent.Begin, ptr, 0, name));
}
/**
* @deprecated
*
* @param name
*/
void endObject(String name)
{
if (listener != null)
listener.logEvent(new FSMovieEvent(context[FSCoder.Action], FSMovieEvent.End, ptr, 0, name));
}
/**
* @deprecated
*
*/
void logValue(Object anObject, int location, int numberOfBits)
{
if (listener != null)
listener.logEvent(new FSMovieEvent(context[FSCoder.Action], FSMovieEvent.Value, location, numberOfBits, anObject));
}
/**
* @deprecated
*
*/
void logError(String errorKey, int location, int length)
{
if (listener != null)
listener.logEvent(new FSMovieEvent(context[FSCoder.Action], FSMovieEvent.Error, location, length, errorKey));
}
/**
* Return the string representation of the character encoding scheme used
* when encoding or decoding strings as a sequence of bytes.
*
* @return the string the name of the encoding schemd for characters.
*/
public String getEncoding()
{
return encoding;
}
/**
* Sets the string representation of the character encoding scheme used
* when encoding or decoding strings as a sequence of bytes.
*
* @return enc, the string the name of the encoding schemd for characters.
*/
public void setEncoding(String enc)
{
encoding = enc;
}
/*
* Methods for accessing the encoded data
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -