View Javadoc
1   //******************************************************************************
2   //
3   // File:    FloatBuf.java
4   // Package: edu.rit.mp
5   // Unit:    Class edu.rit.mp.FloatBuf
6   //
7   // This Java source file is copyright (C) 2007 by Alan Kaminsky. All rights
8   // reserved. For further information, contact the author, Alan Kaminsky, at
9   // ark@cs.rit.edu.
10  //
11  // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
12  // software; you can redistribute it and/or modify it under the terms of the GNU
13  // General Public License as published by the Free Software Foundation; either
14  // version 3 of the License, or (at your option) any later version.
15  //
16  // PJ is distributed in the hope that it will be useful, but WITHOUT ANY
17  // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18  // A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19  //
20  // Linking this library statically or dynamically with other modules is making a
21  // combined work based on this library. Thus, the terms and conditions of the GNU
22  // General Public License cover the whole combination.
23  //
24  // As a special exception, the copyright holders of this library give you
25  // permission to link this library with independent modules to produce an
26  // executable, regardless of the license terms of these independent modules, and
27  // to copy and distribute the resulting executable under terms of your choice,
28  // provided that you also meet, for each linked independent module, the terms
29  // and conditions of the license of that module. An independent module is a module
30  // which is not derived from or based on this library. If you modify this library,
31  // you may extend this exception to your version of the library, but you are not
32  // obligated to do so. If you do not wish to do so, delete this exception
33  // statement from your version.
34  //
35  // A copy of the GNU General Public License is provided in the file gpl.txt. You
36  // may also obtain a copy of the GNU General Public License on the World Wide
37  // Web at http://www.gnu.org/licenses/gpl.html.
38  //
39  //******************************************************************************
40  package edu.rit.mp;
41  
42  import java.nio.ByteBuffer;
43  
44  import edu.rit.mp.buf.EmptyFloatBuf;
45  import edu.rit.mp.buf.FloatArrayBuf;
46  import edu.rit.mp.buf.FloatArrayBuf_1;
47  import edu.rit.mp.buf.FloatItemBuf;
48  import edu.rit.mp.buf.FloatMatrixBuf;
49  import edu.rit.mp.buf.FloatMatrixBuf_1;
50  import edu.rit.mp.buf.SharedFloatArrayBuf;
51  import edu.rit.mp.buf.SharedFloatArrayBuf_1;
52  import edu.rit.mp.buf.SharedFloatBuf;
53  import edu.rit.pj.reduction.SharedFloat;
54  import edu.rit.pj.reduction.SharedFloatArray;
55  import edu.rit.util.Arrays;
56  import edu.rit.util.Range;
57  
58  /**
59   * Class FloatBuf is the abstract base class for a buffer of float items sent or
60   * received using the Message Protocol (MP). In a message, a float item is
61   * represented as four bytes, most significant byte first.
62   * <P>
63   * A buffer may be used to send one or more messages at the same time in
64   * multiple threads. If a buffer is being used to send a message or messages,
65   * the buffer must not be used to receive a message at the same time.
66   * <P>
67   * A buffer may be used to receive one message at a time. If a buffer is being
68   * used to receive a message, the buffer must not be used to receive another
69   * message in a different thread, and the buffer must not be used to send a
70   * message or messages.
71   * <P>
72   * A buffer is a conduit for retrieving and storing data in some underlying data
73   * structure. If the underlying data structure is multiple thread safe, then one
74   * thread can be retrieving or storing data via the buffer at the same time as
75   * other threads are accessing the data structure. If the underlying data
76   * structure is not multiple thread safe, then other threads must not access the
77   * data structure while one thread is retrieving or storing data via the buffer.
78   * <P>
79   * To create a FloatBuf, call one of the following static factory methods:
80   * <UL>
81   * <LI><code>emptyBuffer()</code>
82   * <LI><code>buffer()</code>
83   * <LI><code>buffer (float)</code>
84   * <LI><code>buffer (float[])</code>
85   * <LI><code>sliceBuffer (float[], Range)</code>
86   * <LI><code>sliceBuffers (float[], Range[])</code>
87   * <LI><code>buffer (float[][])</code>
88   * <LI><code>rowSliceBuffer (float[][], Range)</code>
89   * <LI><code>rowSliceBuffers (float[][], Range[])</code>
90   * <LI><code>colSliceBuffer (float[][], Range)</code>
91   * <LI><code>colSliceBuffers (float[][], Range[])</code>
92   * <LI><code>patchBuffer (float[][], Range, Range)</code>
93   * <LI><code>patchBuffers (float[][], Range[], Range[])</code>
94   * <LI><code>buffer (SharedFloat)</code>
95   * <LI><code>buffer (SharedFloatArray)</code>
96   * <LI><code>sliceBuffer (SharedFloatArray, Range)</code>
97   * <LI><code>sliceBuffers (SharedFloatArray, Range[])</code>
98   * </UL>
99   *
100  * @author Alan Kaminsky
101  * @version 03-May-2008
102  */
103 public abstract class FloatBuf
104         extends Buf {
105 
106 // Hidden constructors.
107     /**
108      * Construct a new float buffer.
109      *
110      * @param theLength Number of items.
111      * @exception IllegalArgumentException (unchecked exception) Thrown if
112      * <code>theLength</code> &lt; 0.
113      */
114     protected FloatBuf(int theLength) {
115         super(Constants.TYPE_FLOAT, theLength);
116     }
117 
118 // Exported operations.
119     /**
120      * Create an empty buffer. The buffer's length is 0. The buffer's item type
121      * is float.
122      *
123      * @return Empty buffer.
124      */
125     public static FloatBuf emptyBuffer() {
126         return new EmptyFloatBuf();
127     }
128 
129     /**
130      * Create a buffer for a float item. The item is stored in the
131      * <code>item</code> field of the buffer.
132      *
133      * @return Buffer.
134      */
135     public static FloatItemBuf buffer() {
136         return new FloatItemBuf();
137     }
138 
139     /**
140      * Create a buffer for a float item with the given initial value. The item
141      * is stored in the <code>item</code> field of the buffer.
142      *
143      * @param item Initial value of the <code>item</code> field.
144      * @return Buffer.
145      */
146     public static FloatItemBuf buffer(float item) {
147         return new FloatItemBuf(item);
148     }
149 
150     /**
151      * Create a buffer for the entire given float array. The returned buffer
152      * encompasses all the elements in <code>theArray</code>.
153      *
154      * @param theArray Array.
155      * @return Buffer.
156      * @exception NullPointerException (unchecked exception) Thrown if
157      * <code>theArray</code> is null.
158      */
159     public static FloatBuf buffer(float[] theArray) {
160         if (theArray == null) {
161             throw new NullPointerException("FloatBuf.buffer(): theArray is null");
162         }
163         int nr = Arrays.length(theArray);
164         return new FloatArrayBuf_1(theArray, new Range(0, nr - 1));
165     }
166 
167     /**
168      * Create a buffer for one slice of the given float array. The returned
169      * buffer encompasses <code>theRange</code> of elements in <code>theArray</code>.
170      * The range's stride may be 1 or greater than 1.
171      *
172      * @param theArray Array.
173      * @param theRange Range of elements to include.
174      * @return Buffer.
175      * @exception NullPointerException (unchecked exception) Thrown if
176      * <code>theArray</code> is null or
177      * <code>theRange</code> is null.
178      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
179      * <code>theArray</code> does not include all the indexes in <code>theRange</code>.
180      */
181     public static FloatBuf sliceBuffer(float[] theArray,
182             Range theRange) {
183         if (theArray == null) {
184             throw new NullPointerException("FloatBuf.sliceBuffer(): theArray is null");
185         }
186         int nr = Arrays.length(theArray);
187         if (0 > theRange.lb() || theRange.ub() >= nr) {
188             throw new IndexOutOfBoundsException("FloatBuf.sliceBuffer(): theArray index range = 0.."
189                     + (nr - 1) + ", theRange = " + theRange);
190         }
191         if (theRange.stride() == 1) {
192             return new FloatArrayBuf_1(theArray, theRange);
193         } else {
194             return new FloatArrayBuf(theArray, theRange);
195         }
196     }
197 
198     /**
199      * Create an array of buffers for multiple slices of the given float array.
200      * The returned buffer array has the same length as
201      * <code>theRanges</code>. Each element [<I>i</I>] of the returned buffer array
202      * encompasses the elements of <code>theArray</code> specified by
203      * <code>theRanges[i]</code>. Each range's stride may be 1 or greater than 1.
204      *
205      * @param theArray Array.
206      * @param theRanges Array of ranges of elements to include.
207      * @return Array of buffers.
208      * @exception NullPointerException (unchecked exception) Thrown if
209      * <code>theArray</code> is null or
210      * <code>theRanges</code> or any element thereof is null.
211      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
212      * <code>theArray</code>'s allocation does not include any element of
213      * <code>theRanges</code>.
214      */
215     public static FloatBuf[] sliceBuffers(float[] theArray,
216             Range[] theRanges) {
217         int n = theRanges.length;
218         FloatBuf[] result = new FloatBuf[n];
219         for (int i = 0; i < n; ++i) {
220             result[i] = sliceBuffer(theArray, theRanges[i]);
221         }
222         return result;
223     }
224 
225     /**
226      * Create a buffer for the entire given float matrix. The returned buffer
227      * encompasses all the rows and all the columns in
228      * <code>theMatrix</code>.
229      *
230      * @param theMatrix Matrix.
231      * @return Buffer.
232      * @exception NullPointerException (unchecked exception) Thrown if
233      * <code>theMatrix</code> is null.
234      */
235     public static FloatBuf buffer(float[][] theMatrix) {
236         if (theMatrix == null) {
237             throw new NullPointerException("FloatBuf.buffer(): theMatrix is null");
238         }
239         int nr = Arrays.rowLength(theMatrix);
240         int nc = Arrays.colLength(theMatrix, 0);
241         return new FloatMatrixBuf_1(theMatrix, new Range(0, nr - 1), new Range(0, nc - 1));
242     }
243 
244     /**
245      * Create a buffer for one row slice of the given float matrix. The returned
246      * buffer encompasses <code>theRowRange</code> of rows, and all the columns, in
247      * <code>theMatrix</code>. The range's stride may be 1 or greater than 1.
248      *
249      * @param theMatrix Matrix.
250      * @param theRowRange Range of rows to include.
251      * @return Buffer.
252      * @exception NullPointerException (unchecked exception) Thrown if
253      * <code>theMatrix</code> is null or
254      * <code>theRowRange</code> is null.
255      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
256      * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code>.
257      */
258     public static FloatBuf rowSliceBuffer(float[][] theMatrix,
259             Range theRowRange) {
260         if (theMatrix == null) {
261             throw new NullPointerException("FloatBuf.rowSliceBuffer(): theMatrix is null");
262         }
263         int nr = Arrays.rowLength(theMatrix);
264         if (0 > theRowRange.lb() || theRowRange.ub() >= nr) {
265             throw new IndexOutOfBoundsException("FloatBuf.rowSliceBuffer(): theMatrix row index range = 0.."
266                     + (nr - 1) + ", theRowRange = " + theRowRange);
267         }
268         int nc = Arrays.colLength(theMatrix, theRowRange.lb());
269         if (theRowRange.stride() == 1) {
270             return new FloatMatrixBuf_1(theMatrix, theRowRange, new Range(0, nc - 1));
271         } else {
272             return new FloatMatrixBuf(theMatrix, theRowRange, new Range(0, nc - 1));
273         }
274     }
275 
276     /**
277      * Create an array of buffers for multiple row slices of the given float
278      * matrix. The returned buffer array has the same length as
279      * <code>theRowRanges</code>. Each element [<I>i</I>] of the returned buffer
280      * array encompasses the rows of <code>theMatrix</code> specified by
281      * <code>theRowRanges[i]</code> and all the columns of <code>theMatrix</code>. Each
282      * range's stride may be 1 or greater than 1.
283      *
284      * @param theMatrix Matrix.
285      * @param theRowRanges Array of ranges of rows to include.
286      * @return Array of buffers.
287      * @exception NullPointerException (unchecked exception) Thrown if
288      * <code>theMatrix</code> is null or
289      * <code>theRowRanges</code> or any element thereof is null.
290      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
291      * <code>theMatrix</code>'s allocation does not include any element of
292      * <code>theRowRanges</code>.
293      */
294     public static FloatBuf[] rowSliceBuffers(float[][] theMatrix,
295             Range[] theRowRanges) {
296         int n = theRowRanges.length;
297         FloatBuf[] result = new FloatBuf[n];
298         for (int i = 0; i < n; ++i) {
299             result[i] = rowSliceBuffer(theMatrix, theRowRanges[i]);
300         }
301         return result;
302     }
303 
304     /**
305      * Create a buffer for one column slice of the given float matrix. The
306      * returned buffer encompasses all the rows, and <code>theColRange</code> of
307      * columns, in <code>theMatrix</code>. The range's stride may be 1 or greater
308      * than 1.
309      *
310      * @param theMatrix Matrix.
311      * @param theColRange Range of columns to include.
312      * @return Buffer.
313      * @exception NullPointerException (unchecked exception) Thrown if
314      * <code>theMatrix</code> is null or
315      * <code>theColRange</code> is null.
316      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
317      * <code>theMatrix</code>'s allocation does not include <code>theColRange</code>.
318      */
319     public static FloatBuf colSliceBuffer(float[][] theMatrix,
320             Range theColRange) {
321         if (theMatrix == null) {
322             throw new NullPointerException("FloatBuf.colSliceBuffer(): theMatrix is null");
323         }
324         int nr = Arrays.rowLength(theMatrix);
325         int nc = Arrays.colLength(theMatrix, 0);
326         if (0 > theColRange.lb() || theColRange.ub() >= nc) {
327             throw new IndexOutOfBoundsException("FloatBuf.colSliceBuffer(): theMatrix column index range = 0.."
328                     + (nc - 1) + ", theColRange = " + theColRange);
329         }
330         if (theColRange.stride() == 1) {
331             return new FloatMatrixBuf_1(theMatrix, new Range(0, nr - 1), theColRange);
332         } else {
333             return new FloatMatrixBuf(theMatrix, new Range(0, nr - 1), theColRange);
334         }
335     }
336 
337     /**
338      * Create an array of buffers for multiple column slices of the given float
339      * matrix. The returned buffer array has the same length as
340      * <code>theColRanges</code>. Each element [<I>i</I>] of the returned buffer
341      * array encompasses all the rows of <code>theMatrix</code> and the columns of
342      * <code>theMatrix</code> specified by <code>theColRanges[i]</code>. Each range's
343      * stride may be 1 or greater than 1.
344      *
345      * @param theMatrix Matrix.
346      * @param theColRanges Array of ranges of columns to include.
347      * @return Array of buffers.
348      * @exception NullPointerException (unchecked exception) Thrown if
349      * <code>theMatrix</code> is null or
350      * <code>theColRanges</code> or any element thereof is null.
351      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
352      * <code>theMatrix</code>'s allocation does not include any element of
353      * <code>theColRanges</code>.
354      */
355     public static FloatBuf[] colSliceBuffers(float[][] theMatrix,
356             Range[] theColRanges) {
357         int n = theColRanges.length;
358         FloatBuf[] result = new FloatBuf[n];
359         for (int i = 0; i < n; ++i) {
360             result[i] = colSliceBuffer(theMatrix, theColRanges[i]);
361         }
362         return result;
363     }
364 
365     /**
366      * Create a buffer for one patch of the given float matrix. The returned
367      * buffer encompasses <code>theRowRange</code> of rows, and <code>theColRange</code>
368      * of columns, in <code>theMatrix</code>. Each range's stride may be 1 or
369      * greater than 1.
370      *
371      * @param theMatrix Matrix.
372      * @param theRowRange Range of rows to include.
373      * @param theColRange Range of columns to include.
374      * @return Buffer.
375      * @exception NullPointerException (unchecked exception) Thrown if
376      * <code>theMatrix</code> is null,
377      * <code>theRowRange</code> is null, or <code>theColRange</code> is null.
378      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
379      * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code> and
380      * <code>theColRange</code>.
381      */
382     public static FloatBuf patchBuffer(float[][] theMatrix,
383             Range theRowRange,
384             Range theColRange) {
385         if (theMatrix == null) {
386             throw new NullPointerException("FloatBuf.patchBuffer(): theMatrix is null");
387         }
388         int nr = Arrays.rowLength(theMatrix);
389         if (0 > theRowRange.lb() || theRowRange.ub() >= nr) {
390             throw new IndexOutOfBoundsException("FloatBuf.patchBuffer(): theMatrix row index range = 0.."
391                     + (nr - 1) + ", theRowRange = " + theRowRange);
392         }
393         int nc = Arrays.colLength(theMatrix, theRowRange.lb());
394         if (0 > theColRange.lb() || theColRange.ub() >= nc) {
395             throw new IndexOutOfBoundsException("FloatBuf.patchBuffer(): theMatrix column index range = 0.."
396                     + (nc - 1) + ", theColRange = " + theColRange);
397         }
398         if (theRowRange.stride() == 1 && theColRange.stride() == 1) {
399             return new FloatMatrixBuf_1(theMatrix, theRowRange, theColRange);
400         } else {
401             return new FloatMatrixBuf(theMatrix, theRowRange, theColRange);
402         }
403     }
404 
405     /**
406      * Create an array of buffers for multiple patches of the given float
407      * matrix. The length of the returned buffer array is equal to the length of
408      * <code>theRowRanges</code> times the length of <code>theColRanges</code>. Each
409      * element of the returned buffer array encompasses the rows given in one
410      * element of <code>theRowRanges</code> array, and the columns given in one
411      * element of <code>theColRanges</code> array, in all possible combinations, of
412      * <code>theMatrix</code>. Each range's stride may be 1 or greater than 1.
413      *
414      * @param theMatrix Matrix.
415      * @param theRowRanges Array of ranges of rows to include.
416      * @param theColRanges Array of ranges of columns to include.
417      * @return Array of buffers.
418      * @exception NullPointerException (unchecked exception) Thrown if
419      * <code>theMatrix</code> is null,
420      * <code>theRowRanges</code> or any element thereof is null, or
421      * <code>theColRanges</code> or any element thereof is null.
422      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
423      * <code>theMatrix</code>'s allocation does not include any element of
424      * <code>theRowRanges</code> or
425      * <code>theColRanges</code>.
426      */
427     public static FloatBuf[] patchBuffers(float[][] theMatrix,
428             Range[] theRowRanges,
429             Range[] theColRanges) {
430         int m = theRowRanges.length;
431         int n = theColRanges.length;
432         FloatBuf[] result = new FloatBuf[m * n];
433         int k = 0;
434         for (int i = 0; i < m; ++i) {
435             Range rowrange = theRowRanges[i];
436             for (int j = 0; j < n; ++j) {
437                 result[k++]
438                         = patchBuffer(theMatrix, rowrange, theColRanges[j]);
439             }
440         }
441         return result;
442     }
443 
444     /**
445      * Create a buffer for a shared float item. The item is wrapped in an
446      * instance of class {@linkplain edu.rit.pj.reduction.SharedFloat
447      * SharedFloat}. Use the methods of the SharedFloat object to access the
448      * actual item.
449      *
450      * @param item SharedFloat object that wraps the item.
451      * @exception NullPointerException (unchecked exception) Thrown if
452      * <code>item</code> is null.
453      * @return a {@link edu.rit.mp.FloatBuf} object.
454      */
455     public static FloatBuf buffer(SharedFloat item) {
456         if (item == null) {
457             throw new NullPointerException("FloatBuf.buffer(): item is null");
458         }
459         return new SharedFloatBuf(item);
460     }
461 
462     /**
463      * Create a buffer for the entire given shared float array. The returned
464      * buffer encompasses all the elements in <code>theArray</code>.
465      *
466      * @param theArray Array.
467      * @return Buffer.
468      * @exception NullPointerException (unchecked exception) Thrown if
469      * <code>theArray</code> is null.
470      */
471     public static FloatBuf buffer(SharedFloatArray theArray) {
472         if (theArray == null) {
473             throw new NullPointerException("FloatBuf.buffer(): theArray is null");
474         }
475         int nr = theArray.length();
476         return new SharedFloatArrayBuf_1(theArray, new Range(0, nr - 1));
477     }
478 
479     /**
480      * Create a buffer for one slice of the given shared float array. The
481      * returned buffer encompasses <code>theRange</code> of elements in
482      * <code>theArray</code>. The range's stride may be 1 or greater than 1.
483      *
484      * @param theArray Array.
485      * @param theRange Range of elements to include.
486      * @return Buffer.
487      * @exception NullPointerException (unchecked exception) Thrown if
488      * <code>theArray</code> is null or
489      * <code>theRange</code> is null.
490      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
491      * <code>theArray</code> does not include all the indexes in <code>theRange</code>.
492      */
493     public static FloatBuf sliceBuffer(SharedFloatArray theArray,
494             Range theRange) {
495         if (theArray == null) {
496             throw new NullPointerException("FloatBuf.sliceBuffer(): theArray is null");
497         }
498         int nr = theArray.length();
499         if (0 > theRange.lb() || theRange.ub() >= nr) {
500             throw new IndexOutOfBoundsException("FloatBuf.sliceBuffer(): theArray index range = 0.."
501                     + (nr - 1) + ", theRange = " + theRange);
502         }
503         if (theRange.stride() == 1) {
504             return new SharedFloatArrayBuf_1(theArray, theRange);
505         } else {
506             return new SharedFloatArrayBuf(theArray, theRange);
507         }
508     }
509 
510     /**
511      * Create an array of buffers for multiple slices of the given shared float
512      * array. The returned buffer array has the same length as
513      * <code>theRanges</code>. Each element [<I>i</I>] of the returned buffer array
514      * encompasses the elements of <code>theArray</code> specified by
515      * <code>theRanges[i]</code>. Each range's stride may be 1 or greater than 1.
516      *
517      * @param theArray Array.
518      * @param theRanges Array of ranges of elements to include.
519      * @return Array of buffers.
520      * @exception NullPointerException (unchecked exception) Thrown if
521      * <code>theArray</code> is null or
522      * <code>theRanges</code> or any element thereof is null.
523      * @exception IndexOutOfBoundsException (unchecked exception) Thrown if
524      * <code>theArray</code>'s allocation does not include any element of
525      * <code>theRanges</code>.
526      */
527     public static FloatBuf[] sliceBuffers(SharedFloatArray theArray,
528             Range[] theRanges) {
529         int n = theRanges.length;
530         FloatBuf[] result = new FloatBuf[n];
531         for (int i = 0; i < n; ++i) {
532             result[i] = sliceBuffer(theArray, theRanges[i]);
533         }
534         return result;
535     }
536 
537     /**
538      * Obtain the given item from this buffer.
539      * <P>
540      * The <code>get()</code> method must not block the calling thread; if it does,
541      * all message I/O in MP will be blocked.
542      *
543      * @param i Item index in the range 0 .. <code>length()</code>-1.
544      * @return Item at index <code>i</code>.
545      */
546     public abstract float get(int i);
547 
548     /**
549      * Store the given item in this buffer.
550      * <P>
551      * The <code>put()</code> method must not block the calling thread; if it does,
552      * all message I/O in MP will be blocked.
553      *
554      * @param i Item index in the range 0 .. <code>length()</code>-1.
555      * @param item Item to be stored at index <code>i</code>.
556      */
557     public abstract void put(int i,
558             float item);
559 
560     /**
561      * {@inheritDoc}
562      *
563      * Copy items from the given buffer to this buffer. The number of items
564      * copied is this buffer's length or <code>theSrc</code>'s length, whichever is
565      * smaller. If <code>theSrc</code> is this buffer, the <code>copy()</code> method
566      * does nothing.
567      * <P>
568      * The default implementation of the <code>copy()</code> method calls the
569      * <code>defaultCopy()</code> method. A subclass can override the
570      * <code>copy()</code> method to use a more efficient algorithm.
571      * @exception ClassCastException (unchecked exception) Thrown if
572      * <code>theSrc</code>'s item data type is not the same as this buffer's item
573      * data type.
574      */
575     public void copy(Buf theSrc) {
576         if (theSrc != this) {
577             defaultCopy((FloatBuf) theSrc, this);
578         }
579     }
580 
581     /**
582      * {@inheritDoc}
583      *
584      * Fill this buffer with the given item. The <code>item</code> is assigned to
585      * each element in this buffer.
586      * <P>
587      * The <code>item</code> must be an instance of class Float. If the
588      * <code>item</code> is null, 0.0f is assigned to each element in this buffer.
589      * @exception ClassCastException (unchecked exception) Thrown if the
590      * <code>item</code>'s data type is not the same as this buffer's item data
591      * type.
592      */
593     public void fill(Object item) {
594         float value = item == null ? 0.0f : ((Float) item).floatValue();
595         for (int i = 0; i < myLength; ++i) {
596             put(i, value);
597         }
598     }
599 
600     /**
601      * Create a temporary buffer with the same type of items and the same length
602      * as this buffer. The new buffer items are stored in a newly created array,
603      * separate from the storage for this buffer's items.
604      *
605      * @return a {@link edu.rit.mp.Buf} object.
606      */
607     public Buf getTemporaryBuf() {
608         return buffer(new float[myLength]);
609     }
610 
611 // Hidden operations.
612     /**
613      * Skip as many items as possible from the given byte buffer.
614      *
615      * @param num Number of items to skip.
616      * @param buffer Buffer.
617      *
618      * @return Number of items actually skipped.
619      */
620     int skipItems(int num,
621             ByteBuffer buffer) {
622         int n = Math.min(num, buffer.remaining() / 4);
623         buffer.position(buffer.position() + 4 * n);
624         return n;
625     }
626 
627     /**
628      * Copy items from the given source buffer to the given destination buffer.
629      * The number of items copied is <code>theSrc</code>'s length or
630      * <code>theDst</code>'s length, whichever is smaller. Each item is copied
631      * individually using the <code>get()</code> and <code>put()</code> methods. It is
632      * assumed that <code>theSrc</code> is not the same as <code>theDst</code>.
633      *
634      * @param theSrc Source of items to copy.
635      * @param theDst Destination of items to copy.
636      */
637     protected static void defaultCopy(FloatBuf theSrc,
638             FloatBuf theDst) {
639         int n = Math.min(theSrc.myLength, theDst.myLength);
640         for (int i = 0; i < n; ++i) {
641             theDst.put(i, theSrc.get(i));
642         }
643     }
644 
645 }