001    
002    
003    import java.io.IOException;
004    import java.io.ByteArrayOutputStream;
005    import java.io.ByteArrayInputStream;
006    import java.io.ObjectOutputStream;
007    import java.io.ObjectInputStream;
008    
009    import java.nio.ByteBuffer;
010    
011    
012    /**
013     * A wraper class to java.nio.ByteBuffer for handling objects.
014     * The internal ByteBuffer is used for storing and retrieving objects.
015     * The ByteBuffer may be direct or a heap buffer.
016     * There are no bulk get / put methods since an object array can also 
017     * be get / put as single object.
018     * @author Heinz Kredel.
019     */
020    
021    public class ObjectBuffer {
022    
023        /*
024         * The data structure.
025         */
026        private ByteBuffer bb;
027    
028    
029        /**
030         * Wrap an existing ByteBuffer as Object Buffer.
031         */
032        public ObjectBuffer(ByteBuffer bb) {
033            this.bb = bb;
034        }
035    
036    
037        /**
038         * Get and remove the next Object form the ByteBuffer.
039         * If only a partial object remains in the buffer an 
040         * BufferUnderFlowException is thrown.
041         * @return the next object from the buffer.
042         */
043        public Object get() throws IOException, ClassNotFoundException {
044            int pos;
045            int rem;
046            byte[] cont;
047            if ( bb.hasArray() ) {
048               cont = bb.array();
049               pos = bb.position();
050               rem = bb.remaining();
051            } else {  // could be inefficient
052               bb.mark();
053               ByteBuffer bba = ByteBuffer.allocate( bb.remaining() );
054               bba.clear();
055               bba.put( bb );
056               bba.rewind();
057               cont = bba.array();
058               pos = bba.position();
059               rem = bba.remaining();
060               bb.reset();
061            }
062            ByteArrayInputStream is  
063                = new ByteArrayInputStream( cont, pos, rem );
064            int read = is.available();
065            ObjectInputStream ois = new ObjectInputStream( is );
066            Object obj = ois.readObject();
067            ois.close();
068            read = read - is.available();
069            //System.out.println("read = " + read);
070            bb.position( bb.position() + read );
071            //System.out.println("g-bb = " + bb);
072            return obj;
073        }
074    
075    
076        /**
077         * Put an Object to the ByteBuffer.
078         * If the object does not fit into the buffer a 
079         * BufferOverflowException is thrown.
080         * @param obj the object to be put into the buffer.
081         */
082        public void put( Object obj ) throws IOException {
083            ByteArrayOutputStream os  = new ByteArrayOutputStream();
084            ObjectOutputStream oos = new ObjectOutputStream( os );
085            oos.writeObject( obj );
086            oos.close();
087            //System.out.println("write = " + os.size());
088            bb.put( os.toByteArray() );
089            //System.out.println("p-bb = " + bb);
090        }
091    
092    
093        /**
094         * to String
095         */
096        public String toString() {
097            return "ObjectBuffer[" + bb.toString() + "]";
098        }
099    
100    }