You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/07/06 05:42:14 UTC
svn commit: rev 22607 - in incubator/directory/snickers/trunk/codec-stateful/src: java/org/apache/commons/codec/stateful java/org/apache/commons/codec/stateful/examples test/org/apache/commons/codec/stateful/examples
Author: akarasulu
Date: Mon Jul 5 20:42:13 2004
New Revision: 22607
Added:
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderCallback.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderMonitor.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderMonitorAdapter.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/StatefulEncoder.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/HexDecoder.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/HexEncoder.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/
incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/HexDecoderTest.java (contents, props changed)
incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/HexEncoderTest.java (contents, props changed)
Modified:
incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/CallbackHistory.java
Log:
Commit changes ...
o created symetric encoder analogs for decoder entities
o created an example encoder/decoder pair for a streaming Hex codec
o added test cases for example
Modified: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/CallbackHistory.java
==============================================================================
--- incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/CallbackHistory.java (original)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/CallbackHistory.java Mon Jul 5 20:42:13 2004
@@ -21,16 +21,16 @@
/**
- * A convenience callback which collects decoded objects to audit a decoder's
- * activity. The callback also comes in handy when data is to be pushed
- * through a decoder and grabed immediately afterwords to serialize decoder
+ * A convenience callback which collects decoded or encoded objects to audit a
+ * codecs's activity. The callback also comes in handy when data is to be
+ * pushed through a codec and grabed immediately afterwords to serialize codec
* operation.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">
* Apache Directory Project</a>
* @version $Rev$
*/
-public class CallbackHistory implements DecoderCallback
+public class CallbackHistory implements DecoderCallback, EncoderCallback
{
/** history of decoded objects in cronological order */
private final LinkedList history ;
@@ -79,8 +79,28 @@
history.addFirst( decoded ) ;
}
-
-
+
+
+ /**
+ * Callback to deliver a fully encoded object.
+ *
+ * @param encoder the stateful encoder driving the callback
+ * @param encoded the object that was encoded
+ */
+ public void encodeOccurred( StatefulEncoder encoder, Object encoded )
+ {
+ if ( length > 0 )
+ {
+ while ( history.size() >= length )
+ {
+ history.removeLast() ;
+ }
+ }
+
+ history.addFirst( encoded ) ;
+ }
+
+
/**
* Gets the most recent decoded object if one exists.
*
Added: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderCallback.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderCallback.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful;
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public interface EncoderCallback
+{
+ /**
+ * Callback to deliver a fully encoded object.
+ *
+ * @param encoder the stateful encoder driving the callback
+ * @param encoded the object that was encoded
+ */
+ void encodeOccurred( StatefulEncoder encoder, Object encoded ) ;
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderMonitor.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderMonitor.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful;
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public interface EncoderMonitor
+{
+ /**
+ * Receive notification of a recoverable error. This callback is used to
+ * denote a failure to handle a unit of data to be encoded or decoded. The
+ * entire [en|de]codable unit is lost but the [en|de]coding operation can
+ * still proceed.
+ *
+ * @param encoder the encoder that had the error
+ * @param exception the error information encapsulated in an exception
+ */
+ void error( StatefulEncoder encoder, Exception exception ) ;
+
+ /**
+ * Receive notification of a non-recoverable error. The application must
+ * assume that the stream data is unusable after the encoder has invoked
+ * this method, and should continue (if at all) only for the sake of
+ * collecting addition error messages: in fact, encoders are free to stop
+ * reporting any other events once this method has been invoked.
+ *
+ * @param encoder the encoder that had the failure
+ * @param exception the warning information encapsulated in an exception
+ */
+ void fatalError( StatefulEncoder encoder, Exception exception ) ;
+
+ /**
+ * Receive notification of a warning. The encoder must continue to provide
+ * normal callbacks after invoking this method: it should still be possible
+ * for the application to process the encoded data through to the end.
+ *
+ * @param encoder the encoder that had the error
+ * @param exception the warning information encapsulated in an exception
+ */
+ void warning( StatefulEncoder encoder, Exception exception ) ;
+
+ /**
+ * Monitors callbacks that deliver a fully decoded object.
+ *
+ * @param encoder the stateful encoder driving the callback
+ * @param decoded the object that was decoded
+ */
+ void callbackOccured( StatefulEncoder encoder, EncoderCallback cb,
+ Object decoded ) ;
+
+ /**
+ * Monitors changes to the callback.
+ *
+ * @param encoder the encoder whose callback was set
+ * @param oldcb the unset old callback, or null if none was set
+ * @param newcb the newly set callback, or null if callback is cleared
+ */
+ void callbackSet( StatefulEncoder encoder, EncoderCallback oldcb,
+ EncoderCallback newcb ) ;
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderMonitorAdapter.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/EncoderMonitorAdapter.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful;
+
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class EncoderMonitorAdapter implements EncoderMonitor
+{
+ /**
+ * Receive notification of a recoverable error. This callback is used to
+ * denote a failure to handle a unit of data to be encoded or decoded. The
+ * entire [en|de]codable unit is lost but the [en|de]coding operation can
+ * still proceed.
+ *
+ * @param encoder the encoder that had the error
+ * @param exception the error information encapsulated in an exception
+ */
+ public void error( StatefulEncoder encoder, Exception exception )
+ {
+ }
+
+ /**
+ * Receive notification of a non-recoverable error. The application must
+ * assume that the stream data is unusable after the encoder has invoked
+ * this method, and should continue (if at all) only for the sake of
+ * collecting addition error messages: in fact, encoders are free to stop
+ * reporting any other events once this method has been invoked.
+ *
+ * @param encoder the encoder that had the failure
+ * @param exception the warning information encapsulated in an exception
+ */
+ public void fatalError( StatefulEncoder encoder, Exception exception )
+ {
+ }
+
+ /**
+ * Receive notification of a warning. The encoder must continue to provide
+ * normal callbacks after invoking this method: it should still be possible
+ * for the application to process the encoded data through to the end.
+ *
+ * @param encoder the encoder that had the error
+ * @param exception the warning information encapsulated in an exception
+ */
+ public void warning( StatefulEncoder encoder, Exception exception )
+ {
+ }
+
+ /**
+ * Monitors callbacks that deliver a fully decoded object.
+ *
+ * @param encoder the stateful encoder driving the callback
+ * @param decoded the object that was decoded
+ */
+ public void callbackOccured( StatefulEncoder encoder, EncoderCallback cb, Object decoded )
+ {
+ }
+
+ /**
+ * Monitors changes to the callback.
+ *
+ * @param encoder the encoder whose callback was set
+ * @param oldcb the unset old callback, or null if none was set
+ * @param newcb the newly set callback, or null if callback is cleared
+ */
+ public void callbackSet( StatefulEncoder encoder, EncoderCallback oldcb, EncoderCallback newcb )
+ {
+ }
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/StatefulEncoder.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/StatefulEncoder.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful ;
+
+
+import org.apache.commons.codec.EncoderException ;
+
+
+/**
+ * The StatefulEncoder interface.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public interface StatefulEncoder
+{
+ public void encode( Object obj ) throws EncoderException ;
+
+
+ public void setCallback( EncoderCallback cb ) ;
+
+
+ public void setEncoderMonitor( EncoderMonitor monitor ) ;
+
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/HexDecoder.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/HexDecoder.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful.examples;
+
+import org.apache.commons.codec.stateful.AbstractStatefulDecoder;
+import org.apache.commons.codec.DecoderException;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class HexDecoder extends AbstractStatefulDecoder
+{
+ private ByteBuffer decoded = ByteBuffer.allocate( 128 ) ;
+ private byte lsn ;
+ private byte msn ;
+ private boolean expectingMsn = true ;
+
+
+ public void decode( Object chunk ) throws DecoderException
+ {
+ ByteBuffer encoded = ( ByteBuffer ) chunk;
+
+ if ( encoded == null || !encoded.hasRemaining() )
+ {
+ return;
+ }
+
+ while ( encoded.hasRemaining() )
+ {
+ if ( ! decoded.hasRemaining() )
+ {
+ decoded.flip();
+ super.decodeOccurred( decoded );
+ decoded.clear();
+ }
+
+ if ( expectingMsn )
+ {
+ msn = encoded.get();
+ expectingMsn = false;
+ }
+ else
+ {
+ lsn = encoded.get();
+ expectingMsn = true;
+ }
+
+ /* if we've hit the most significant nibble then we have two hex
+ * characters as bytes so we need to compute and add the byte to
+ * the buffer
+ */
+ if ( expectingMsn )
+ {
+ byte bite = getNibble( lsn );
+ bite |= ( getNibble( msn ) << 4 );
+ decoded.put( bite );
+ }
+ }
+
+ /* only trigger a decode callback if we have seen an even number of
+ * hex character bytes in which case we're in the expectingMsn state
+ * this will flush out what's siting in the buffer automatically
+ */
+ if ( expectingMsn )
+ {
+ decoded.flip();
+ super.decodeOccurred( decoded );
+ decoded.clear();
+ }
+ }
+
+
+
+ private byte getNibble( byte ch ) throws DecoderException
+ {
+ // lowercase the character if it is in upper case
+ if ( ch > 64 && ch < 91 )
+ {
+ ch -= 32;
+ }
+
+ switch(ch)
+ {
+ case 48:
+ return 0 ;
+ case 49:
+ return 1 ;
+ case 50:
+ return 2 ;
+ case 51:
+ return 3 ;
+ case 52:
+ return 4 ;
+ case 53:
+ return 5 ;
+ case 54:
+ return 6 ;
+ case 55:
+ return 7 ;
+ case 56:
+ return 8 ;
+ case 57:
+ return 9 ;
+ case 97:
+ return 10 ;
+ case 98:
+ return 11 ;
+ case 99:
+ return 12 ;
+ case 100:
+ return 13 ;
+ case 101:
+ return 14 ;
+ case 102:
+ return 15 ;
+ default:
+ throw new DecoderException( "non-hex character '" + (char) ch
+ + "' encountered" );
+ }
+ }
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/HexEncoder.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/java/org/apache/commons/codec/stateful/examples/HexEncoder.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful.examples;
+
+import org.apache.commons.codec.stateful.StatefulEncoder;
+import org.apache.commons.codec.stateful.EncoderCallback;
+import org.apache.commons.codec.stateful.EncoderMonitor;
+import org.apache.commons.codec.stateful.EncoderMonitorAdapter;
+import org.apache.commons.codec.EncoderException;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class HexEncoder implements StatefulEncoder
+{
+ private static final int CHUNK_SZ = 128;
+ private ByteBuffer buf = ByteBuffer.allocate( CHUNK_SZ );
+ private EncoderMonitor monitor = new EncoderMonitorAdapter();
+ private EncoderCallback cb = new EncoderCallback() {
+ public void encodeOccurred( StatefulEncoder encoder, Object encoded )
+ {
+ }
+ };
+ private final byte[] HEXCHAR_LUT = {
+ (byte)'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+
+
+ /**
+ * Transforms a decoded ByteArray of binary data into a stream of ASCII hex
+ * characters.
+ *
+ * @param obj
+ * @throws EncoderException
+ */
+ public void encode( Object obj ) throws EncoderException
+ {
+ ByteBuffer raw = ( ByteBuffer ) obj;
+
+ if ( raw == null || ! raw.hasRemaining() )
+ {
+ return;
+ }
+
+ /*
+ * Keep encoding one byte at a time if we have remaining bytes in the
+ * raw buffer and there's space for 2 hex character bytes in the
+ * resultant hex encoded buffer.
+ */
+ while( raw.hasRemaining() )
+ {
+ if ( ! buf.hasRemaining() )
+ {
+ buf.flip();
+ cb.encodeOccurred( this, buf );
+ monitor.callbackOccured( this, cb, buf );
+ buf.clear();
+ }
+
+ byte bite = raw.get();
+ buf.put( HEXCHAR_LUT[( bite >> 4 ) & 0x0000000F] );
+ buf.put( HEXCHAR_LUT[bite & 0x0000000F] );
+ }
+
+ buf.flip();
+ cb.encodeOccurred( this, buf );
+ monitor.callbackOccured( this, cb, buf );
+ buf.clear();
+ }
+
+
+ public void setCallback( EncoderCallback cb )
+ {
+ EncoderCallback old = this.cb;
+ this.cb = cb;
+ monitor.callbackSet( this, old, cb );
+ }
+
+
+ public void setEncoderMonitor( EncoderMonitor monitor )
+ {
+ this.monitor = monitor;
+ }
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/HexDecoderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/HexDecoderTest.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful.examples;
+
+import junit.framework.TestCase;
+
+import java.util.Random;
+import java.nio.ByteBuffer;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.stateful.DecoderCallback;
+import org.apache.commons.codec.stateful.StatefulDecoder;
+import org.apache.commons.codec.DecoderException;
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class HexDecoderTest extends TestCase implements DecoderCallback
+{
+ private HexDecoder decoder = null;
+ byte[] encoded = null;
+ byte[] decoded = null;
+ byte[] original = null;
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ decoder = new HexDecoder();
+ decoder.setCallback( this );
+ }
+
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ decoder = null;
+ encoded = null;
+ decoded = null;
+ original = null;
+ }
+
+
+ private void generateData( int amount )
+ {
+ Random rand = new Random( System.currentTimeMillis() ) ;
+ original = new byte[amount/2];
+ rand.nextBytes( original );
+ char[] chars = Hex.encodeHex( original );
+ encoded = new byte[amount];
+ for ( int ii = 0; ii < amount; ii++ )
+ {
+ encoded[ii] = (byte) chars[ii];
+ }
+ }
+
+
+ public void decodeOccurred( StatefulDecoder decoder, Object obj )
+ {
+ ByteBuffer decodedBuf = ( ByteBuffer ) obj ;
+
+ if ( decoded == null )
+ {
+ decoded = new byte[decodedBuf.remaining()];
+ decodedBuf.get( decoded ) ;
+ }
+ else
+ {
+ byte[] temp = decoded ;
+ decoded = new byte[decodedBuf.remaining() + temp.length];
+ System.arraycopy( temp, 0, decoded, 0, temp.length );
+ decodedBuf.get( decoded, temp.length, decodedBuf.remaining() );
+ }
+ }
+
+
+ public void testDecode0() throws DecoderException
+ {
+ generateData( 0 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+
+ if ( decoded == null )
+ {
+ decoded = new byte[0];
+ }
+
+ assertDecoded();
+ }
+
+
+ public void testDecode2() throws DecoderException
+ {
+ generateData( 2 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+ assertDecoded();
+ }
+
+
+ public void testDecode26() throws DecoderException
+ {
+ generateData( 26 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+ assertDecoded();
+ }
+
+
+ public void testDecode254() throws DecoderException
+ {
+ generateData( 254 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+ assertDecoded();
+ }
+
+
+ public void testDecode256() throws DecoderException
+ {
+ generateData( 256 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+ assertDecoded();
+ }
+
+
+ public void testDecode258() throws DecoderException
+ {
+ generateData( 258 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+ assertDecoded();
+ }
+
+
+ public void testDecode2048() throws DecoderException
+ {
+ generateData( 2048 );
+ decoder.decode( ByteBuffer.wrap( encoded ) );
+ assertDecoded();
+ }
+
+
+ public void testPartialDecode2() throws DecoderException
+ {
+ generateData( 2 );
+
+ decoder.decode( ByteBuffer.wrap( encoded, 0, 1 ) );
+
+ try
+ {
+ assertDecoded();
+ fail( "should not get here" ) ;
+ }
+ catch( NullPointerException e )
+ {
+ }
+
+ decoder.decode( ByteBuffer.wrap( encoded, 1, 1 ) );
+
+ assertDecoded();
+ }
+
+
+ public void testPartialDecode30() throws DecoderException
+ {
+ generateData( 30 );
+
+ for ( int ii = 0; ii < 30; ii += 3 )
+ {
+ decoder.decode( ByteBuffer.wrap( encoded, ii, 3 ) );
+ }
+
+ assertDecoded();
+ }
+
+
+ public void testPartialDecode300() throws DecoderException
+ {
+ generateData( 300 );
+
+ for ( int ii = 0; ii < 300; ii += 5 )
+ {
+ decoder.decode( ByteBuffer.wrap( encoded, ii, 5 ) );
+ }
+
+ assertDecoded();
+ }
+
+
+ private void assertDecoded()
+ {
+ if ( decoded.length != original.length )
+ {
+ fail( "decoded length of " + decoded.length
+ + " did not match expected original data length of "
+ + original.length ) ;
+ }
+
+ for ( int ii = 0; ii < decoded.length; ii++ )
+ {
+ if ( decoded[ii] != original[ii] )
+ {
+ fail( "decode failed - decoded array does not match" ) ;
+ }
+ }
+ }
+}
Added: incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/HexEncoderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/codec-stateful/src/test/org/apache/commons/codec/stateful/examples/HexEncoderTest.java Mon Jul 5 20:42:13 2004
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.commons.codec.stateful.examples;
+
+import junit.framework.TestCase;
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.stateful.EncoderCallback;
+import org.apache.commons.codec.stateful.StatefulEncoder;
+
+import java.util.Random;
+import java.nio.ByteBuffer;
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class HexEncoderTest extends TestCase implements EncoderCallback
+{
+ HexEncoder encoder = null;
+ byte[] encoded = null;
+ byte[] data = null;
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ encoder = new HexEncoder();
+ encoder.setCallback( this );
+ }
+
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ data = null;
+ encoder = null;
+ encoded = null;
+ }
+
+
+ private void generateData( int amount )
+ {
+ Random rand = new Random(System.currentTimeMillis()) ;
+ data = new byte[amount];
+ rand.nextBytes( data );
+ }
+
+
+ public void encodeOccurred( StatefulEncoder encoder, Object encodedObj )
+ {
+ ByteBuffer encodedBuf = ( ByteBuffer ) encodedObj ;
+
+ if ( encoded == null )
+ {
+ encoded = new byte[encodedBuf.remaining()];
+ encodedBuf.get( encoded ) ;
+ }
+ else
+ {
+ byte[] temp = encoded ;
+ encoded = new byte[encodedBuf.remaining() + temp.length];
+ System.arraycopy( temp, 0, encoded, 0, temp.length );
+ encodedBuf.get( encoded, temp.length, encodedBuf.remaining() );
+ }
+ }
+
+
+ public void testEncode0() throws EncoderException
+ {
+ generateData( 0 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ if ( encoded == null )
+ {
+ encoded = new byte[0];
+ }
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode1() throws EncoderException
+ {
+ generateData( 1 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode25() throws EncoderException
+ {
+ generateData( 25 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode63() throws EncoderException
+ {
+ generateData( 63 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode64() throws EncoderException
+ {
+ generateData( 64 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode65() throws EncoderException
+ {
+ generateData( 65 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode66() throws EncoderException
+ {
+ generateData( 66 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ public void testEncode512() throws EncoderException
+ {
+ generateData( 512 );
+ encoder.encode( ByteBuffer.wrap( data ) );
+ assertEncoded( encoded, Hex.encodeHex( data ) );
+ }
+
+
+ private void assertEncoded( byte[] encoded, char[] hex )
+ {
+ if ( encoded.length != hex.length )
+ {
+ fail( "encoded length of " + encoded.length
+ + " did not match expected hex char length of "
+ + hex.length ) ;
+ }
+
+ for ( int ii = 0; ii < encoded.length; ii++ )
+ {
+ if ( encoded[ii] != hex[ii] )
+ {
+ fail( "encoding failed - encoded array does not match" ) ;
+ }
+ }
+ }
+}