org.apache.mina.util.byteaccess.CompositeByteArrayRelativeWriter Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.mina.util.byteaccess;
import org.apache.mina.core.buffer.IoBuffer;
/**
* Provides restricted, relative, write-only access to the bytes in a
* CompositeByteArray
.
*
* Using this interface has the advantage that it can be automatically
* determined when a component ByteArray
can no longer be written
* to, and thus components can be automatically flushed. This makes it easier to
* use pooling for underlying ByteArray
s.
*
* By providing an appropriate Expander
it is also possible to
* automatically add more backing storage as more data is written.
*
* TODO: Get flushing working.
*
* @author Apache MINA Project
*/
public class CompositeByteArrayRelativeWriter extends CompositeByteArrayRelativeBase implements IoRelativeWriter
{
/**
* An object that knows how to expand a CompositeByteArray
.
*/
public interface Expander
{
void expand( CompositeByteArray cba, int minSize );
}
/**
* No-op expander. The overridden method does nothing.
*
*/
public static class NopExpander implements Expander
{
public void expand( CompositeByteArray cba, int minSize )
{
// Do nothing.
}
}
/**
* Expands the supplied {@link CompositeByteArray} by the number of
* bytes provided in the constructor
*
*/
public static class ChunkedExpander implements Expander
{
private final ByteArrayFactory baf;
private final int newComponentSize;
public ChunkedExpander( ByteArrayFactory baf, int newComponentSize )
{
this.baf = baf;
this.newComponentSize = newComponentSize;
}
public void expand( CompositeByteArray cba, int minSize )
{
int remaining = minSize;
while ( remaining > 0 )
{
ByteArray component = baf.create( newComponentSize );
cba.addLast( component );
remaining -= newComponentSize;
}
}
}
/**
* An object that knows how to flush a ByteArray
.
*/
public interface Flusher
{
// document free() behaviour
void flush( ByteArray ba );
}
/**
* The expander to use when the array underflows.
*/
private final Expander expander;
/**
* The flusher to use when flushing component ByteArray
s.
*/
private final Flusher flusher;
/**
* Whether or not to automatically flush a component once the cursor moves
* past it.
*/
private final boolean autoFlush;
/**
*
* Creates a new instance of CompositeByteArrayRelativeWriter.
*
* @param cba
* The CompositeByteArray to use to back this class
* @param expander
* The expander. Will increase the size of the internal ByteArray
* @param flusher
* Flushed the ByteArray when necessary
* @param autoFlush
* Should this class automatically flush?
*/
public CompositeByteArrayRelativeWriter( CompositeByteArray cba, Expander expander, Flusher flusher,
boolean autoFlush )
{
super( cba );
this.expander = expander;
this.flusher = flusher;
this.autoFlush = autoFlush;
}
private void prepareForAccess( int size )
{
int underflow = cursor.getIndex() + size - last();
if ( underflow > 0 )
{
expander.expand( cba, underflow );
}
}
/**
* Flush to the current index.
*/
public void flush()
{
flushTo( cursor.getIndex() );
}
/**
* Flush to the given index.
*/
public void flushTo( int index )
{
ByteArray removed = cba.removeTo( index );
flusher.flush( removed );
}
/**
* @inheritDoc
*/
public void skip( int length )
{
cursor.skip( length );
}
@Override
protected void cursorPassedFirstComponent()
{
if ( autoFlush )
{
flushTo( cba.first() + cba.getFirst().length() );
}
}
/**
* @inheritDoc
*/
public void put( byte b )
{
prepareForAccess( 1 );
cursor.put( b );
}
/**
* @inheritDoc
*/
public void put( IoBuffer bb )
{
prepareForAccess( bb.remaining() );
cursor.put( bb );
}
/**
* @inheritDoc
*/
public void putShort( short s )
{
prepareForAccess( 2 );
cursor.putShort( s );
}
/**
* @inheritDoc
*/
public void putInt( int i )
{
prepareForAccess( 4 );
cursor.putInt( i );
}
/**
* @inheritDoc
*/
public void putLong( long l )
{
prepareForAccess( 8 );
cursor.putLong( l );
}
/**
* @inheritDoc
*/
public void putFloat( float f )
{
prepareForAccess( 4 );
cursor.putFloat( f );
}
/**
* @inheritDoc
*/
public void putDouble( double d )
{
prepareForAccess( 8 );
cursor.putDouble( d );
}
/**
* @inheritDoc
*/
public void putChar( char c )
{
prepareForAccess( 2 );
cursor.putChar( c );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy