001    /* IntBuffer.java -- 
002       Copyright (C) 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package java.nio;
040    
041    /**
042     * @since 1.4
043     */
044    public abstract class IntBuffer extends Buffer
045      implements Comparable<IntBuffer>
046    {
047      int array_offset;
048      int[] backing_buffer;
049    
050      IntBuffer (int capacity, int limit, int position, int mark)
051      {
052        super (capacity, limit, position, mark);
053        array_offset = 0;
054      }
055    
056      /**
057       * Allocates a new <code>IntBuffer</code> object with a given capacity.
058       */
059      public static IntBuffer allocate (int capacity)
060      {
061        return new IntBufferImpl (capacity);
062      }
063    
064      /**
065       * Wraps a <code>int</code> array into a <code>IntBuffer</code>
066       * object.
067       *
068       * @exception IndexOutOfBoundsException If the preconditions on the offset
069       * and length parameters do not hold
070       */
071      public static final IntBuffer wrap (int[] array, int offset, int length)
072      {
073        return new IntBufferImpl (array, 0, array.length, offset + length, offset, -1, false);
074      }
075    
076      /**
077       * Wraps a <code>int</code> array into a <code>IntBuffer</code>
078       * object.
079       */
080      public static final IntBuffer wrap (int[] array)
081      {
082        return wrap (array, 0, array.length);
083      }
084      
085      /**
086       * This method transfers <code>int</code>s from this buffer into the given
087       * destination array. Before the transfer, it checks if there are fewer than
088       * length <code>int</code>s remaining in this buffer. 
089       *
090       * @param dst The destination array
091       * @param offset The offset within the array of the first <code>int</code>
092       * to be written; must be non-negative and no larger than dst.length.
093       * @param length The maximum number of bytes to be written to the given array;
094       * must be non-negative and no larger than dst.length - offset.
095       *
096       * @exception BufferUnderflowException If there are fewer than length
097       * <code>int</code>s remaining in this buffer.
098       * @exception IndexOutOfBoundsException If the preconditions on the offset
099       * and length parameters do not hold.
100       */
101      public IntBuffer get (int[] dst, int offset, int length)
102      {
103        checkArraySize(dst.length, offset, length);
104        checkForUnderflow(length);
105    
106        for (int i = offset; i < offset + length; i++)
107          {
108            dst [i] = get ();
109          }
110    
111        return this;
112      }
113    
114      /**
115       * This method transfers <code>int</code>s from this buffer into the given
116       * destination array.
117       *
118       * @param dst The byte array to write into.
119       *
120       * @exception BufferUnderflowException If there are fewer than dst.length
121       * <code>int</code>s remaining in this buffer.
122       */
123      public IntBuffer get (int[] dst)
124      {
125        return get (dst, 0, dst.length);
126      }
127    
128      /**
129       * Writes the content of the the <code>IntBUFFER</code> src
130       * into the buffer. Before the transfer, it checks if there is fewer than
131       * <code>src.remaining()</code> space remaining in this buffer.
132       *
133       * @param src The source data.
134       *
135       * @exception BufferOverflowException If there is insufficient space in this
136       * buffer for the remaining <code>int</code>s in the source buffer.
137       * @exception IllegalArgumentException If the source buffer is this buffer.
138       * @exception ReadOnlyBufferException If this buffer is read-only.
139       */
140      public IntBuffer put (IntBuffer src)
141      {
142        if (src == this)
143          throw new IllegalArgumentException ();
144    
145        checkForOverflow(src.remaining ());
146    
147        if (src.remaining () > 0)
148          {
149            int[] toPut = new int [src.remaining ()];
150            src.get (toPut);
151            put (toPut);
152          }
153    
154        return this;
155      }
156    
157      /**
158       * Writes the content of the the <code>int array</code> src
159       * into the buffer. Before the transfer, it checks if there is fewer than
160       * length space remaining in this buffer.
161       *
162       * @param src The array to copy into the buffer.
163       * @param offset The offset within the array of the first byte to be read;
164       * must be non-negative and no larger than src.length.
165       * @param length The number of bytes to be read from the given array;
166       * must be non-negative and no larger than src.length - offset.
167       * 
168       * @exception BufferOverflowException If there is insufficient space in this
169       * buffer for the remaining <code>int</code>s in the source array.
170       * @exception IndexOutOfBoundsException If the preconditions on the offset
171       * and length parameters do not hold
172       * @exception ReadOnlyBufferException If this buffer is read-only.
173       */
174      public IntBuffer put (int[] src, int offset, int length)
175      {
176        checkArraySize(src.length, offset, length);
177        checkForOverflow(length);
178    
179        for (int i = offset; i < offset + length; i++)
180          put (src [i]);
181    
182        return this;
183      }
184    
185      /**
186       * Writes the content of the the <code>int array</code> src
187       * into the buffer.
188       *
189       * @param src The array to copy into the buffer.
190       * 
191       * @exception BufferOverflowException If there is insufficient space in this
192       * buffer for the remaining <code>int</code>s in the source array.
193       * @exception ReadOnlyBufferException If this buffer is read-only.
194       */
195      public final IntBuffer put (int[] src)
196      {
197        return put (src, 0, src.length);
198      }
199    
200      /**
201       * Tells whether ot not this buffer is backed by an accessible
202       * <code>int</code> array.
203       */
204      public final boolean hasArray ()
205      {
206        return (backing_buffer != null
207                && !isReadOnly ());
208      }
209    
210      /**
211       * Returns the <code>int</code> array that backs this buffer.
212       *
213       * @exception ReadOnlyBufferException If this buffer is read-only.
214       * @exception UnsupportedOperationException If this buffer is not backed
215       * by an accessible array.
216       */
217      public final int[] array ()
218      {
219        if (backing_buffer == null)
220          throw new UnsupportedOperationException ();
221    
222        checkIfReadOnly();
223        
224        return backing_buffer;
225      }
226    
227      /**
228       * Returns the offset within this buffer's backing array of the first element.
229       *
230       * @exception ReadOnlyBufferException If this buffer is read-only.
231       * @exception UnsupportedOperationException If this buffer is not backed
232       * by an accessible array.
233       */
234      public final int arrayOffset ()
235      {
236        if (backing_buffer == null)
237          throw new UnsupportedOperationException ();
238    
239        checkIfReadOnly();
240        
241        return array_offset;
242      }
243    
244      /**
245       * Calculates a hash code for this buffer.
246       *
247       * This is done with <code>int</code> arithmetic,
248       * where ** represents exponentiation, by this formula:<br>
249       * <code>s[position()] + 31 + (s[position()+1] + 30)*31**1 + ... +
250       * (s[limit()-1]+30)*31**(limit()-1)</code>.
251       * Where s is the buffer data. Note that the hashcode is dependent
252       * on buffer content, and therefore is not useful if the buffer
253       * content may change.
254       *
255       * @return the hash code
256       */
257      public int hashCode ()
258      {
259        int hashCode = get(position()) + 31;
260        int multiplier = 1;
261        for (int i = position() + 1; i < limit(); ++i)
262          {
263              multiplier *= 31;
264              hashCode += (get(i) + 30)*multiplier;
265          }
266        return hashCode;
267      }
268    
269      /**
270       * Checks if this buffer is equal to obj.
271       */
272      public boolean equals (Object obj)
273      {
274        if (obj instanceof IntBuffer)
275          {
276            return compareTo ((IntBuffer) obj) == 0;
277          }
278    
279        return false;
280      }
281    
282      /**
283       * Compares two <code>IntBuffer</code> objects.
284       *
285       * @exception ClassCastException If obj is not an object derived from
286       * <code>IntBuffer</code>.
287       */
288      public int compareTo (IntBuffer other)
289      {
290        int num = Math.min(remaining(), other.remaining());
291        int pos_this = position();
292        int pos_other = other.position();
293        
294        for (int count = 0; count < num; count++)
295          {
296             int a = get(pos_this++);
297             int b = other.get(pos_other++);
298             
299             if (a == b)
300               continue;
301               
302             if (a < b)
303               return -1;
304               
305             return 1;
306          }
307          
308         return remaining() - other.remaining();
309      }
310    
311      /**
312       * Returns the byte order of this buffer.
313       */
314      public abstract ByteOrder order ();
315    
316      /**
317       * Reads the <code>int</code> at this buffer's current position,
318       * and then increments the position.
319       *
320       * @exception BufferUnderflowException If there are no remaining
321       * <code>int</code>s in this buffer.
322       */
323      public abstract int get ();
324    
325      /**
326       * Writes the <code>int</code> at this buffer's current position,
327       * and then increments the position.
328       *
329       * @exception BufferOverflowException If there no remaining 
330       * <code>int</code>s in this buffer.
331       * @exception ReadOnlyBufferException If this buffer is read-only.
332       */
333      public abstract IntBuffer put (int b);
334    
335      /**
336       * Absolute get method.
337       *
338       * @exception IndexOutOfBoundsException If index is negative or not smaller
339       * than the buffer's limit.
340       */
341      public abstract int get (int index);
342      
343      /**
344       * Absolute put method.
345       *
346       * @exception IndexOutOfBoundsException If index is negative or not smaller
347       * than the buffer's limit.
348       * @exception ReadOnlyBufferException If this buffer is read-only.
349       */
350      public abstract IntBuffer put (int index, int b);
351    
352      /**
353       * Compacts this buffer.
354       * 
355       * @exception ReadOnlyBufferException If this buffer is read-only.
356       */
357      public abstract IntBuffer compact ();
358    
359      /**
360       * Tells wether or not this buffer is direct.
361       */
362      public abstract boolean isDirect ();
363    
364      /**
365       * Creates a new <code>IntBuffer</code> whose content is a shared
366       * subsequence of this buffer's content.
367       */
368      public abstract IntBuffer slice ();
369    
370      /**
371       * Creates a new <code>IntBuffer</code> that shares this buffer's
372       * content.
373       */
374      public abstract IntBuffer duplicate ();
375    
376      /**
377       * Creates a new read-only <code>IntBuffer</code> that shares this
378       * buffer's content.
379       */
380      public abstract IntBuffer asReadOnlyBuffer ();
381    }