001package com.hfg.util.io;
002
003import java.io.IOException;
004import java.io.RandomAccessFile;
005import java.nio.BufferUnderflowException;
006import java.nio.ByteBuffer;
007
008import com.hfg.exception.ProgrammingException;
009
010//------------------------------------------------------------------------------
011/**
012 * Abstraction to normalize RandomAccessFiles and byte[].
013 *
014 * @author J. Alex Taylor, hairyfatguy.com
015 */
016//------------------------------------------------------------------------------
017// com.hfg XML/HTML Coding Library
018//
019// This library is free software; you can redistribute it and/or
020// modify it under the terms of the GNU Lesser General Public
021// License as published by the Free Software Foundation; either
022// version 2.1 of the License, or (at your option) any later version.
023//
024// This library is distributed in the hope that it will be useful,
025// but WITHOUT ANY WARRANTY; without even the implied warranty of
026// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
027// Lesser General Public License for more details.
028//
029// You should have received a copy of the GNU Lesser General Public
030// License along with this library; if not, write to the Free Software
031// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
032//
033// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
034// jataylor@hairyfatguy.com
035//------------------------------------------------------------------------------
036
037public class ByteSource
038{
039   private ByteBuffer mByteBuffer;
040   private RandomAccessFile mRandomAccessFile;
041
042
043   //###########################################################################
044   // CONSTRUCTORS
045   //###########################################################################
046
047   //---------------------------------------------------------------------------
048   public ByteSource(byte[] inBytes)
049   {
050      mByteBuffer = ByteBuffer.wrap(inBytes);
051   }
052
053   //---------------------------------------------------------------------------
054   public ByteSource(ByteBuffer inByteBuffer)
055   {
056      mByteBuffer = inByteBuffer;
057   }
058
059   //---------------------------------------------------------------------------
060   public ByteSource(RandomAccessFile inRandomAccessFile)
061   {
062      mRandomAccessFile = inRandomAccessFile;
063   }
064
065
066   //###########################################################################
067   // PUBLIC METHODS
068   //###########################################################################
069
070   //---------------------------------------------------------------------------
071   public void seek(long inPosition)
072         throws IOException
073   {
074      if (mByteBuffer != null)
075      {
076         mByteBuffer.position((int) inPosition);
077      }
078      else if (mRandomAccessFile != null)
079      {
080         mRandomAccessFile.seek(inPosition);
081      }
082      else
083      {
084         throw new ProgrammingException("Unsupported byte source!");
085      }
086   }
087
088   //---------------------------------------------------------------------------
089   public int read() throws IOException
090   {
091      int theByte;
092      if (mByteBuffer != null)
093      {
094         theByte = mByteBuffer.get();
095      }
096      else if (mRandomAccessFile != null)
097      {
098         theByte = mRandomAccessFile.read();
099      }
100      else
101      {
102         throw new ProgrammingException("Unsupported byte source!");
103      }
104
105      return theByte;
106   }
107
108   //---------------------------------------------------------------------------
109   public int read(byte inByteDest[], int inOffset, int inLength)
110         throws IOException
111   {
112      int numBytesRead;
113      if (mByteBuffer != null)
114      {
115         int remaining = mByteBuffer.remaining();
116         try
117         {
118            mByteBuffer.get(inByteDest, inOffset, inLength);
119            numBytesRead = inLength;
120         }
121         catch (BufferUnderflowException e)
122         {
123            numBytesRead = remaining;
124         }
125      }
126      else if (mRandomAccessFile != null)
127      {
128         mRandomAccessFile.readFully(inByteDest, inOffset, inLength);
129         numBytesRead = inLength;
130      }
131      else
132      {
133         throw new ProgrammingException("Unsupported byte source!");
134      }
135
136      return numBytesRead;
137   }
138
139   //---------------------------------------------------------------------------
140   public int read(byte inByteDest[])
141         throws IOException
142   {
143      return read(inByteDest, 0, inByteDest.length);
144   }
145
146   //---------------------------------------------------------------------------
147   /**
148    * Reads a signed 32-bit integer from this souce. This method reads 4
149    * bytes from the source, starting at the current pointer.
150    */
151   public final int readInt()
152         throws IOException
153   {
154      int theInt;
155      if (mByteBuffer != null)
156      {
157         theInt = mByteBuffer.getInt();
158      }
159      else if (mRandomAccessFile != null)
160      {
161         theInt = mRandomAccessFile.readInt();
162      }
163      else
164      {
165         throw new ProgrammingException("Unsupported byte source!");
166      }
167
168      return theInt;
169   }
170}