Author: trustin Date: Fri Jan 14 17:15:31 2005 New Revision: 125240 URL: http://svn.apache.org/viewcvs?view=rev&rev=125240 Log: * Added unsigned getters * Added string getters and putters * Added skip & fill methods Modified: incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java
Modified: incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java Url: http://svn.apache.org/viewcvs/incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java?view=diff&rev=125240&p1=incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java&r1=125239&p2=incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java&r2=125240 ============================================================================== --- incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java (original) +++ incubator/directory/network/trunk/mina/src/java/org/apache/mina/common/ByteBuffer.java Fri Jan 14 17:15:31 2005 @@ -3,6 +3,7 @@ */ package org.apache.mina.common; +import java.nio.BufferOverflowException; import java.nio.ByteOrder; import java.nio.CharBuffer; import java.nio.DoubleBuffer; @@ -10,6 +11,8 @@ import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.ShortBuffer; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; import org.apache.mina.util.Stack; @@ -236,6 +239,11 @@ return buf.get(); } + public short getUnsigned() + { + return ( short ) ( get() & 0xff ); + } + public ByteBuffer put( byte b ) { buf.put( b ); @@ -247,6 +255,11 @@ return buf.get( index ); } + public short getUnsigned( int index ) + { + return ( short ) ( get( index ) & 0xff ); + } + public ByteBuffer put( int index, byte b ) { buf.put( index, b ); @@ -362,6 +375,11 @@ return buf.getShort(); } + public int getUnsignedShort() + { + return getShort() & 0xffff; + } + public ByteBuffer putShort( short value ) { buf.putShort( value ); @@ -373,6 +391,11 @@ return buf.getShort( index ); } + public int getUnsignedShort( int index ) + { + return getShort( index ) & 0xffff; + } + public ByteBuffer putShort( int index, short value ) { buf.putShort( index, value ); @@ -389,6 +412,11 @@ return buf.getInt(); } + public long getUnsignedInt() + { + return getInt() & 0xffffffffL; + } + public ByteBuffer putInt( int value ) { buf.putInt( value ); @@ -400,6 +428,11 @@ return buf.getInt( index ); } + public long getUnsignedInt( int index ) + { + return getInt( index ) & 0xffffffffL; + } + public ByteBuffer putInt( int index, int value ) { buf.putInt( index, value ); @@ -498,5 +531,327 @@ public String getHexDump() { return ByteBufferHexDumper.getHexdump( this ); + } + + //////////////////////////////// + // String getters and putters // + //////////////////////////////// + + /** + * Reads a <code>NUL</code>-terminated string from this buffer and puts it + * into <code>out</code> using the specified <code>decoder</code>. + * + * @param fieldSize the maximum number of bytes to read + */ + public ByteBuffer getString( CharBuffer out, int fieldSize, + CharsetDecoder decoder ) + { + checkFieldSize( fieldSize ); + + if( fieldSize == 0 ) + return this; + + boolean utf16 = decoder.charset().name().startsWith( "UTF-16" ); + + if( utf16 && ( ( fieldSize & 1 ) != 0 ) ) + { + throw new IllegalArgumentException( "fieldSize is not even." ); + } + + int i; + int oldLimit = buf.limit(); + int limit = buf.position() + fieldSize; + + if( oldLimit < limit ) + { + throw new BufferOverflowException(); + } + + buf.mark(); + + if( !utf16 ) + { + for( i = 0; i < fieldSize; i++ ) + { + if( buf.get() == 0 ) + { + break; + } + } + + if( i == fieldSize ) + { + buf.limit( limit ); + } + else + { + buf.limit( buf.position() - 1 ); + } + } + else + { + for( i = 0; i < fieldSize; i += 2 ) + { + if( ( buf.get() == 0 ) && ( buf.get() == 0 ) ) + { + break; + } + } + + if( i == fieldSize ) + { + buf.limit( limit ); + } + else + { + buf.limit( buf.position() - 2 ); + } + } + + buf.reset(); + decoder.decode( buf, out, true ); + buf.limit( oldLimit ); + buf.position( limit ); + return this; + } + + /** + * Reads a <code>NUL</code>-terminated string from this buffer using the + * specified <code>decoder</code> and returns it. + * + * @param fieldSize the maximum number of bytes to read + */ + public String getString( int fieldSize, CharsetDecoder decoder ) + { + CharBuffer out = CharBuffer.allocate( ( int ) ( decoder + .maxCharsPerByte() * fieldSize ) + 1 ); + getString( out, fieldSize, decoder ); + return out.flip().toString(); + } + + /** + * Writes the content of <code>in</code> into this buffer as a + * <code>NUL</code>-terminated string using the specified + * <code>encoder</code>. + * <p> + * If the charset name of the encoder is UTF-16, you cannot specify + * odd <code>fieldSize</code>, and this method will append two + * <code>NUL</code>s as a terminator. + * <p> + * Please note that this method doesn't terminate with <code>NUL</code> + * if the input string is too long. + * + * @param fieldSize the maximum number of bytes to write + */ + public ByteBuffer putString( CharBuffer in, int fieldSize, + CharsetEncoder encoder ) + { + checkFieldSize( fieldSize ); + + if( fieldSize == 0 ) + return this; + + boolean utf16 = encoder.charset().name().startsWith( "UTF-16" ); + + if( utf16 && ( ( fieldSize & 1 ) != 0 ) ) + { + throw new IllegalArgumentException( "fieldSize is not even." ); + } + + int oldLimit = buf.limit(); + int limit = buf.position() + fieldSize; + + if( oldLimit < limit ) + { + throw new BufferOverflowException(); + } + + buf.limit( limit ); + encoder.encode( in, buf, true ); + buf.limit( oldLimit ); + + if( limit > buf.position() ) + { + if( !utf16 ) + { + buf.put( ( byte ) 0x00 ); + } + else + { + buf.put( ( byte ) 0x00 ); + buf.put( ( byte ) 0x00 ); + } + } + + buf.position( limit ); + return this; + } + + /** + * Writes the content of <code>in</code> into this buffer as a + * <code>NUL</code>-terminated string using the specified + * <code>encoder</code>. + * <p> + * If the charset name of the encoder is UTF-16, you cannot specify + * odd <code>fieldSize</code>, and this method will append two + * <code>NUL</code>s as a terminator. + * <p> + * Please note that this method doesn't terminate with <code>NUL</code> + * if the input string is too long. + * + * @param fieldSize the maximum number of bytes to write + */ + public ByteBuffer putString( CharSequence in, int fieldSize, + CharsetEncoder encoder ) + { + return putString( CharBuffer.wrap( in ), fieldSize, encoder ); + } + + ////////////////////////// + // Skip or fill methods // + ////////////////////////// + + /** + * Forwards the position of this buffer as the specified <code>size</code> + * bytes. + */ + public ByteBuffer skip( int size ) + { + return position(position() + size); + } + + /** + * Fills this buffer with the specified value. + * This method moves buffer position forward. + */ + public ByteBuffer fill( byte value, int size ) + { + int q = size >>> 3; + int r = size & 7; + + if( q > 0 ) + { + int intValue = value | ( value << 8 ) | ( value << 16 ) + | ( value << 24 ); + long longValue = intValue; + longValue <<= 32; + longValue |= intValue; + + for( int i = q; i > 0; i-- ) + { + buf.putLong( longValue ); + } + } + + q = r >>> 2; + r = r & 3; + + if( q > 0 ) + { + int intValue = value | ( value << 8 ) | ( value << 16 ) + | ( value << 24 ); + buf.putInt( intValue ); + } + + q = r >> 1; + r = r & 1; + + if( q > 0 ) + { + short shortValue = ( short ) ( value | ( value << 8 ) ); + buf.putShort( shortValue ); + } + + if( r > 0 ) + { + buf.put( value ); + } + + return this; + } + + /** + * Fills this buffer with the specified value. + * This method does not change buffer position. + */ + public ByteBuffer fillAndReset( byte value, int size ) + { + int pos = buf.position(); + try + { + fill( value, size ); + } + finally + { + buf.position( pos ); + } + return this; + } + + /** + * Fills this buffer with <code>NUL (0x00)</code>. + * This method moves buffer position forward. + */ + public ByteBuffer fill( int size ) + { + int q = size >>> 3; + int r = size & 7; + + for( int i = q; i > 0; i-- ) + { + buf.putLong( 0L ); + } + + q = r >>> 2; + r = r & 3; + + if( q > 0 ) + { + buf.putInt( 0 ); + } + + q = r >> 1; + r = r & 1; + + if( q > 0 ) + { + buf.putShort( ( short ) 0 ); + } + + if( r > 0 ) + { + buf.put( ( byte ) 0 ); + } + + return this; + } + + /** + * Fills this buffer with <code>NUL (0x00)</code>. + * This method does not change buffer position. + */ + public ByteBuffer fillAndReset( int size ) + { + int pos = buf.position(); + try + { + fill( size ); + } + finally + { + buf.position( pos ); + } + + return this; + } + + private static void checkFieldSize( int fieldSize ) + { + if( fieldSize < 0 ) + { + throw new IllegalArgumentException( + "fieldSize cannot be negative: " + + fieldSize ); + } } }
