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    // GCJ LOCAL: Change gnu.classpath.Pointer to RawData
042    import gnu.gcj.RawData;
043    
044    /**
045     * @since 1.4
046     */
047    public abstract class IntBuffer extends Buffer
048      implements Comparable<IntBuffer>
049    {
050      final int array_offset;
051      final int[] backing_buffer;
052    
053      IntBuffer (int capacity, int limit, int position, int mark,
054                  RawData address, int[] backing_buffer, int array_offset)
055      {
056        super (capacity, limit, position, mark, address);
057        this.backing_buffer = backing_buffer;
058        this.array_offset = array_offset;
059      }
060    
061      /**
062       * Allocates a new <code>IntBuffer</code> object with a given capacity.
063       */
064      public static IntBuffer allocate (int capacity)
065      {
066        return new IntBufferImpl (capacity);
067      }
068    
069      /**
070       * Wraps a <code>int</code> array into a <code>IntBuffer</code>
071       * object.
072       *
073       * @exception IndexOutOfBoundsException If the preconditions on the offset
074       * and length parameters do not hold
075       */
076      public static final IntBuffer wrap (int[] array, int offset, int length)
077      {
078        return new IntBufferImpl (array, 0, array.length, offset + length, offset,
079                                  -1, false);
080      }
081    
082      /**
083       * Wraps a <code>int</code> array into a <code>IntBuffer</code>
084       * object.
085       */
086      public static final IntBuffer wrap (int[] array)
087      {
088        return wrap (array, 0, array.length);
089      }
090      
091      /**
092       * This method transfers <code>int</code>s from this buffer into the given
093       * destination array. Before the transfer, it checks if there are fewer than
094       * length <code>int</code>s remaining in this buffer. 
095       *
096       * @param dst The destination array
097       * @param offset The offset within the array of the first <code>int</code>
098       * to be written; must be non-negative and no larger than dst.length.
099       * @param length The maximum number of bytes to be written to the given array;
100       * must be non-negative and no larger than dst.length - offset.
101       *
102       * @exception BufferUnderflowException If there are fewer than length
103       * <code>int</code>s remaining in this buffer.
104       * @exception IndexOutOfBoundsException If the preconditions on the offset
105       * and length parameters do not hold.
106       */
107      public IntBuffer get (int[] dst, int offset, int length)
108      {
109        checkArraySize(dst.length, offset, length);
110        checkForUnderflow(length);
111    
112        for (int i = offset; i < offset + length; i++)
113          {
114            dst [i] = get ();
115          }
116    
117        return this;
118      }
119    
120      /**
121       * This method transfers <code>int</code>s from this buffer into the given
122       * destination array.
123       *
124       * @param dst The byte array to write into.
125       *
126       * @exception BufferUnderflowException If there are fewer than dst.length
127       * <code>int</code>s remaining in this buffer.
128       */
129      public IntBuffer get (int[] dst)
130      {
131        return get (dst, 0, dst.length);
132      }
133    
134      /**
135       * Writes the content of the the <code>IntBUFFER</code> src
136       * into the buffer. Before the transfer, it checks if there is fewer than
137       * <code>src.remaining()</code> space remaining in this buffer.
138       *
139       * @param src The source data.
140       *
141       * @exception BufferOverflowException If there is insufficient space in this
142       * buffer for the remaining <code>int</code>s in the source buffer.
143       * @exception IllegalArgumentException If the source buffer is this buffer.
144       * @exception ReadOnlyBufferException If this buffer is read-only.
145       */
146      public IntBuffer put (IntBuffer src)
147      {
148        if (src == this)
149          throw new IllegalArgumentException ();
150    
151        checkForOverflow(src.remaining ());
152    
153        if (src.remaining () > 0)
154          {
155            int[] toPut = new int [src.remaining ()];
156            src.get (toPut);
157            put (toPut);
158          }
159    
160        return this;
161      }
162    
163      /**
164       * Writes the content of the the <code>int array</code> src
165       * into the buffer. Before the transfer, it checks if there is fewer than
166       * length space remaining in this buffer.
167       *
168       * @param src The array to copy into the buffer.
169       * @param offset The offset within the array of the first byte to be read;
170       * must be non-negative and no larger than src.length.
171       * @param length The number of bytes to be read from the given array;
172       * must be non-negative and no larger than src.length - offset.
173       * 
174       * @exception BufferOverflowException If there is insufficient space in this
175       * buffer for the remaining <code>int</code>s in the source array.
176       * @exception IndexOutOfBoundsException If the preconditions on the offset
177       * and length parameters do not hold
178       * @exception ReadOnlyBufferException If this buffer is read-only.
179       */
180      public IntBuffer put (int[] src, int offset, int length)
181      {
182        checkArraySize(src.length, offset, length);
183        checkForOverflow(length);
184    
185        for (int i = offset; i < offset + length; i++)
186          put (src [i]);
187    
188        return this;
189      }
190    
191      /**
192       * Writes the content of the the <code>int array</code> src
193       * into the buffer.
194       *
195       * @param src The array to copy into the buffer.
196       * 
197       * @exception BufferOverflowException If there is insufficient space in this
198       * buffer for the remaining <code>int</code>s in the source array.
199       * @exception ReadOnlyBufferException If this buffer is read-only.
200       */
201      public final IntBuffer put (int[] src)
202      {
203        return put (src, 0, src.length);
204      }
205    
206      /**
207       * Tells whether ot not this buffer is backed by an accessible
208       * <code>int</code> array.
209       */
210      public final boolean hasArray ()
211      {
212        return (backing_buffer != null
213                && !isReadOnly ());
214      }
215    
216      /**
217       * Returns the <code>int</code> array that backs this buffer.
218       *
219       * @exception ReadOnlyBufferException If this buffer is read-only.
220       * @exception UnsupportedOperationException If this buffer is not backed
221       * by an accessible array.
222       */
223      public final int[] array ()
224      {
225        if (backing_buffer == null)
226          throw new UnsupportedOperationException ();
227    
228        checkIfReadOnly();
229        
230        return backing_buffer;
231      }
232    
233      /**
234       * Returns the offset within this buffer's backing array of the first element.
235       *
236       * @exception ReadOnlyBufferException If this buffer is read-only.
237       * @exception UnsupportedOperationException If this buffer is not backed
238       * by an accessible array.
239       */
240      public final int arrayOffset ()
241      {
242        if (backing_buffer == null)
243          throw new UnsupportedOperationException ();
244    
245        checkIfReadOnly();
246        
247        return array_offset;
248      }
249    
250      /**
251       * Calculates a hash code for this buffer.
252       *
253       * This is done with <code>int</code> arithmetic,
254       * where ** represents exponentiation, by this formula:<br>
255       * <code>s[position()] + 31 + (s[position()+1] + 30)*31**1 + ... +
256       * (s[limit()-1]+30)*31**(limit()-1)</code>.
257       * Where s is the buffer data. Note that the hashcode is dependent
258       * on buffer content, and therefore is not useful if the buffer
259       * content may change.
260       *
261       * @return the hash code
262       */
263      public int hashCode ()
264      {
265        int hashCode = get(position()) + 31;
266        int multiplier = 1;
267        for (int i = position() + 1; i < limit(); ++i)
268          {
269              multiplier *= 31;
270              hashCode += (get(i) + 30)*multiplier;
271          }
272        return hashCode;
273      }
274    
275      /**
276       * Checks if this buffer is equal to obj.
277       */
278      public boolean equals (Object obj)
279      {
280        if (obj instanceof IntBuffer)
281          {
282            return compareTo ((IntBuffer) obj) == 0;
283          }
284    
285        return false;
286      }
287    
288      /**
289       * Compares two <code>IntBuffer</code> objects.
290       *
291       * @exception ClassCastException If obj is not an object derived from
292       * <code>IntBuffer</code>.
293       */
294      public int compareTo (IntBuffer other)
295      {
296        int num = Math.min(remaining(), other.remaining());
297        int pos_this = position();
298        int pos_other = other.position();
299        
300        for (int count = 0; count < num; count++)
301          {
302             int a = get(pos_this++);
303             int b = other.get(pos_other++);
304             
305             if (a == b)
306               continue;
307               
308             if (a < b)
309               return -1;
310               
311             return 1;
312          }
313          
314         return remaining() - other.remaining();
315      }
316    
317      /**
318       * Returns the byte order of this buffer.
319       */
320      public abstract ByteOrder order ();
321    
322      /**
323       * Reads the <code>int</code> at this buffer's current position,
324       * and then increments the position.
325       *
326       * @exception BufferUnderflowException If there are no remaining
327       * <code>int</code>s in this buffer.
328       */
329      public abstract int get ();
330    
331      /**
332       * Writes the <code>int</code> at this buffer's current position,
333       * and then increments the position.
334       *
335       * @exception BufferOverflowException If there no remaining 
336       * <code>int</code>s in this buffer.
337       * @exception ReadOnlyBufferException If this buffer is read-only.
338       */
339      public abstract IntBuffer put (int b);
340    
341      /**
342       * Absolute get method.
343       *
344       * @exception IndexOutOfBoundsException If index is negative or not smaller
345       * than the buffer's limit.
346       */
347      public abstract int get (int index);
348      
349      /**
350       * Absolute put method.
351       *
352       * @exception IndexOutOfBoundsException If index is negative or not smaller
353       * than the buffer's limit.
354       * @exception ReadOnlyBufferException If this buffer is read-only.
355       */
356      public abstract IntBuffer put (int index, int b);
357    
358      /**
359       * Compacts this buffer.
360       * 
361       * @exception ReadOnlyBufferException If this buffer is read-only.
362       */
363      public abstract IntBuffer compact ();
364    
365      /**
366       * Tells wether or not this buffer is direct.
367       */
368      public abstract boolean isDirect ();
369    
370      /**
371       * Creates a new <code>IntBuffer</code> whose content is a shared
372       * subsequence of this buffer's content.
373       */
374      public abstract IntBuffer slice ();
375    
376      /**
377       * Creates a new <code>IntBuffer</code> that shares this buffer's
378       * content.
379       */
380      public abstract IntBuffer duplicate ();
381    
382      /**
383       * Creates a new read-only <code>IntBuffer</code> that shares this
384       * buffer's content.
385       */
386      public abstract IntBuffer asReadOnlyBuffer ();
387    }