?? outstream.java
字號:
/****************************************************************
* Copyright (c) 2001, David N. Main, All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. 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.
*
* 3. The name of the author may not be used to endorse or
* promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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
* AUTHOR 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.anotherbigidea.io;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
/**
* Output Stream Wrapper
*/
public class OutStream extends OutputStreamWrapper
{
//--Bit buffer..
private int mBitBuf;
private int mBitPos;
public OutStream( OutputStream out )
{
super( out );
initBits();
}
protected OutStream() {
super(null);
}
/**
* Write a signed value to the output stream in the given number of bits.
* The value must actually fit in that number of bits or it will be garbled
*/
public void writeSBits( int numBits, int value ) throws IOException
{
//--Mask out any sign bit
long lval = value & 0x7FFFFFFF;
if( value < 0 ) //add the sign bit
{
lval |= 1L << (numBits-1);
}
//--Write the bits as if unsigned
writeUBits( numBits, lval );
}
public void flush() throws IOException
{
flushBits();
super.flush();
}
/**
* Compress all subsequent data
*/
public void writeCompressed() {
setOutputStream( new DeflaterOutputStream( getOutputStream(),
new Deflater( Deflater.BEST_COMPRESSION )));
}
/**
* Flush the bit buffer to the output stream and reset values
*/
public void flushBits() throws IOException
{
if( mBitPos == 0 ) return; //nothing to flush
super.write( mBitBuf );
mBitBuf = 0;
mBitPos = 0;
}
/**
* Write an unsigned value to the output stream in the given number of bits
*/
public void writeUBits( int numBits, long value ) throws IOException
{
if( numBits == 0 ) return;
if( mBitPos == 0 ) mBitPos = 8; //bitBuf was empty
int bitNum = numBits;
while( bitNum > 0 ) //write all bits
{
while( mBitPos > 0 && bitNum > 0 ) //write into all position of the bit buffer
{
if( getBit( bitNum, value ) ) mBitBuf = setBit( mBitPos, mBitBuf );
bitNum--;
mBitPos--;
}
if( mBitPos == 0 ) //bit buffer is full - write it
{
writeUI8( mBitBuf );
mBitBuf = 0;
if( bitNum > 0 ) mBitPos = 8; //prepare for more bits
}
}
}
/**
* Get the given bit (where lowest bit is numbered 1)
*/
public static boolean getBit( int bitNum, long value )
{
return (value & (1L << (bitNum - 1))) != 0;
}
/**
* Set the given bit (where lowest bit is numbered 1)
*/
public static int setBit( int bitNum, int value )
{
return value | ( 1 << (bitNum-1) );
}
/**
* Write the given bytes to the output stream
*/
public void write( byte[] bytes ) throws IOException
{
flushBits();
if( bytes != null && bytes.length > 0 )
{
super.write( bytes );
}
}
/**
* Write the given bytes to the output stream
*/
public void write( byte[] bytes, int start, int length ) throws IOException
{
flushBits();
if( bytes != null && length > 0 )
{
super.write( bytes, start, length );
}
}
/**
* Write an 8 bit unsigned value to the out stream
*/
public void writeUI8( int value ) throws IOException
{
flushBits();
super.write( value );
}
/**
* Write a 16 bit unsigned value to the out stream
*/
public void writeUI16( int value ) throws IOException
{
flushBits();
super.write( value & 0xff );
super.write( value >> 8 );
}
/**
* Write a 16 bit signed value to the out stream
*/
public void writeSI16( short value ) throws IOException
{
flushBits();
super.write( value & 0xff );
super.write( value >> 8 );
}
/**
* Write a 32 bit unsigned value to the out stream
*/
public void writeUI32( long value ) throws IOException
{
flushBits();
super.write( (int)( value & 0xff ) );
super.write( (int)( value >> 8 ) );
super.write( (int)( value >> 16 ) );
super.write( (int)( value >> 24 ) );
}
/**
* Write a string to the output stream using the default encoding and add terminating null
*/
public void writeString( String s, String encoding ) throws IOException
{
if( s == null ) s = "";
writeString( s.getBytes( encoding ) );
}
/**
* Write a string to the output stream and add terminating null
*/
public void writeString( byte[] string ) throws IOException
{
flushBits();
if( string != null ) super.write( string );
super.write( 0 ); //terminate string
}
/**
* Calculate the byte length of a string as it would be written to the
* output stream
*/
public static int getStringLength( byte[] string )
{
if( string == null ) return 1;
return string.length + 1; //to include the terminating null
}
/**
* Calculate the byte length of a string as it would be written to the
* output stream using the default character encoding
*/
public static int getStringLength( String string )
{
if( string == null ) return 1;
byte[] bytes = string.getBytes();
return bytes.length + 1; //to include the terminating null
}
/**
* Reset the bit buffer
*/
private void initBits()
{
mBitBuf = 0;
mBitPos = 0;
}
/**
* Determine the minimum number of bits required to hold the given
* signed value
*/
public static int determineSignedBitSize( int value )
{
if( value >= 0 ) return determineUnsignedBitSize( value ) + 1;
//--This is probably a really bad way of doing this...
int topBit = 31;
long mask = 0x40000000L;
while( topBit > 0 )
{
if( (value & mask) == 0 ) break;
mask >>= 1;
topBit--;
}
if( topBit == 0 ) return 2; //must have been -1
//HACK: Flash represents -16 as 110000 rather than 10000 etc..
int val2 = value & (( 1 << topBit) - 1 );
if( val2 == 0 )
{
topBit++;
}
return topBit + 1;
}
/**
* Determine the minimum number of bits required to hold the given
* unsigned value (may be zero)
*/
public static int determineUnsignedBitSize( long value )
{
//--This is probably a really bad way of doing this...
int topBit = 32;
long mask = 0x80000000L;
while( topBit > 0 )
{
if( (value & mask) != 0 ) return topBit;
mask >>= 1;
topBit--;
}
return 0;
}
/**
* Write a float value
*/
public void writeFloat( float value ) throws IOException
{
writeSI32( Float.floatToIntBits( value ) );
}
/**
* Write a double value
*/
public void writeDouble( double value ) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream( baos );
dout.writeDouble( value );
dout.flush();
byte[] bytes = baos.toByteArray();
byte[] bytes2 = new byte[8];
bytes2[0] = bytes[3];
bytes2[1] = bytes[2];
bytes2[2] = bytes[1];
bytes2[3] = bytes[0];
bytes2[4] = bytes[7];
bytes2[5] = bytes[6];
bytes2[6] = bytes[5];
bytes2[7] = bytes[4];
write( bytes2 );
}
/**
* Write a 32 bit signed value
*/
public void writeSI32( int value ) throws IOException
{
flushBits();
super.write( value & 0xff );
super.write( value >> 8 );
super.write( value >> 16 );
super.write( value >> 24 );
}
/**
* Util to convert a signed int to 2 bytes
*/
public static byte[] sintTo2Bytes( int value )
{
return new byte[]
{
uintToByte( value & 0xff ),
uintToByte( value >> 8 )
};
}
/**
* Util to convert an unsigned int to 2 bytes
*/
public static byte[] uintTo2Bytes( int value )
{
return new byte[]
{
uintToByte( value & 0xff ),
uintToByte( value >> 8 )
};
}
/**
* Util to convert an unsigned int to 4 bytes
*/
public static byte[] uintTo4Bytes( int value )
{
return new byte[]
{
uintToByte( value & 0xff ),
uintToByte( value >> 8 ),
uintToByte( value >> 16 ),
uintToByte( value >> 24 )
};
}
/**
* Util to convert an unsigned int to an unsigned byte
*/
public static byte uintToByte( int value )
{
int lowbit = value & 1;
value >>= 1;
byte b = (byte)value;
b <<= 1;
b |= (byte)lowbit;
return b;
}
/**
* @see java.io.OutputStream#write(int)
*/
public void write( int b ) throws IOException {
flushBits();
super.write( b );
}
/**
* Override to ensure that bits are flushed
*/
public void close() throws IOException {
flush();
super.close();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -