001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.nio;
019:
020: /**
021: * A buffer of <code>short</code>s.
022: * <p>
023: * A short buffer can be created in either of the following ways:
024: * <ul>
025: * <li>{@link #allocate(int) Allocate} a new short array and create a buffer
026: * based on it;</li>
027: * <li>{@link #wrap(short[]) Wrap} an existing short array to create a new
028: * buffer;</li>
029: * <li>Use {@link java.nio.ByteBuffer#asShortBuffer() ByteBuffer.asShortBuffer}
030: * to create a short buffer based on a byte buffer.</li>
031: * </ul>
032: * </p>
033: */
034: public abstract class ShortBuffer extends Buffer implements
035: Comparable<ShortBuffer> {
036:
037: /**
038: * Creates a short buffer based on a new allocated short array.
039: *
040: * @param capacity
041: * The capacity of the new buffer
042: * @return The created short buffer
043: * @throws IllegalArgumentException
044: * If <code>capacity</code> is less than zero
045: */
046: public static ShortBuffer allocate(int capacity) {
047: if (capacity < 0) {
048: throw new IllegalArgumentException();
049: }
050: return BufferFactory.newShortBuffer(capacity);
051: }
052:
053: /**
054: * Creates a new short buffer by wrapping the given short array.
055: * <p>
056: * Calling this method has the same effect as
057: * <code>wrap(array, 0, array.length)</code>.
058: * </p>
059: *
060: * @param array
061: * The short array which the new buffer will be based on
062: * @return The created short buffer
063: */
064: public static ShortBuffer wrap(short[] array) {
065: return wrap(array, 0, array.length);
066: }
067:
068: /**
069: * Creates new a short buffer by wrapping the given short array.
070: * <p>
071: * The new buffer's position will be <code>start</code>, limit will be
072: * <code>start + len</code>, capacity will be the length of the array.
073: * </p>
074: *
075: * @param array
076: * The short array which the new buffer will be based on
077: * @param start
078: * The start index, must be no less than zero and no greater than
079: * <code>array.length</code>
080: * @param len
081: * The length, must be no less than zero and no greater than
082: * <code>array.length - start</code>
083: * @return The created short buffer
084: * @exception IndexOutOfBoundsException
085: * If either <code>start</code> or <code>len</code> is
086: * invalid
087: */
088: public static ShortBuffer wrap(short[] array, int start, int len) {
089: if (array == null) {
090: throw new NullPointerException();
091: }
092: if (start < 0 || len < 0
093: || (long) start + (long) len > array.length) {
094: throw new IndexOutOfBoundsException();
095: }
096:
097: ShortBuffer buf = BufferFactory.newShortBuffer(array);
098: buf.position = start;
099: buf.limit = start + len;
100:
101: return buf;
102: }
103:
104: /**
105: * Constructs a <code>ShortBuffer</code> with given capacity.
106: *
107: * @param capacity
108: * The capacity of the buffer
109: */
110: ShortBuffer(int capacity) {
111: super (capacity);
112: }
113:
114: /**
115: * Returns the short array which this buffer is based on, if there's one.
116: *
117: * @return The short array which this buffer is based on
118: * @exception ReadOnlyBufferException
119: * If this buffer is based on an array, but it is readonly
120: * @exception UnsupportedOperationException
121: * If this buffer is not based on an array
122: */
123: public final short[] array() {
124: return protectedArray();
125: }
126:
127: /**
128: * Returns the offset of the short array which this buffer is based on, if
129: * there's one.
130: * <p>
131: * The offset is the index of the array corresponds to the zero position of
132: * the buffer.
133: * </p>
134: *
135: * @return The offset of the short array which this buffer is based on
136: * @exception ReadOnlyBufferException
137: * If this buffer is based on an array, but it is readonly
138: * @exception UnsupportedOperationException
139: * If this buffer is not based on an array
140: */
141: public final int arrayOffset() {
142: return protectedArrayOffset();
143: }
144:
145: /**
146: * Returns a readonly buffer that shares content with this buffer.
147: * <p>
148: * The returned buffer is guaranteed to be a new instance, even this buffer
149: * is readonly itself. The new buffer's position, limit, capacity and mark
150: * are the same as this buffer.
151: * </p>
152: * <p>
153: * The new buffer shares content with this buffer, which means this buffer's
154: * change of content will be visible to the new buffer. The two buffer's
155: * position, limit and mark are independent.
156: * </p>
157: *
158: * @return A readonly version of this buffer.
159: */
160: public abstract ShortBuffer asReadOnlyBuffer();
161:
162: /**
163: * Compacts this short buffer.
164: * <p>
165: * The remaining <code>short</code>s will be moved to the head of the
166: * buffer, staring from position zero. Then the position is set to
167: * <code>remaining()</code>; the limit is set to capacity; the mark is
168: * cleared.
169: * </p>
170: *
171: * @return This buffer
172: * @exception ReadOnlyBufferException
173: * If no changes may be made to the contents of this buffer
174: */
175: public abstract ShortBuffer compact();
176:
177: /**
178: * Compare the remaining <code>short</code>s of this buffer to another
179: * short buffer's remaining <code>short</code>s.
180: *
181: * @param otherBuffer
182: * Another short buffer
183: * @return a negative value if this is less than <code>other</code>; 0 if
184: * this equals to <code>other</code>; a positive value if this is
185: * greater than <code>other</code>
186: * @exception ClassCastException
187: * If <code>other</code> is not a short buffer
188: */
189: public int compareTo(ShortBuffer otherBuffer) {
190: int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
191: : otherBuffer.remaining();
192: int this Pos = position;
193: int otherPos = otherBuffer.position;
194: short this Byte, otherByte;
195: while (compareRemaining > 0) {
196: this Byte = get(this Pos);
197: otherByte = otherBuffer.get(otherPos);
198: if (this Byte != otherByte) {
199: return this Byte < otherByte ? -1 : 1;
200: }
201: this Pos++;
202: otherPos++;
203: compareRemaining--;
204: }
205: return remaining() - otherBuffer.remaining();
206: }
207:
208: /**
209: * Returns a duplicated buffer that shares content with this buffer.
210: * <p>
211: * The duplicated buffer's position, limit, capacity and mark are the same
212: * as this buffer. The duplicated buffer's readonly property and byte order
213: * are same as this buffer too.
214: * </p>
215: * <p>
216: * The new buffer shares content with this buffer, which means either
217: * buffer's change of content will be visible to the other. The two buffer's
218: * position, limit and mark are independent.
219: * </p>
220: *
221: * @return A duplicated buffer that shares content with this buffer.
222: */
223: public abstract ShortBuffer duplicate();
224:
225: /**
226: * Tests whether this short buffer equals to another object.
227: * <p>
228: * If <code>other</code> is not a short buffer, then false is returned.
229: * </p>
230: * <p>
231: * Two short buffers are equals if, and only if, their remaining
232: * <code>short</code>s are exactly the same. Position, limit, capacity
233: * and mark are not considered.
234: * </p>
235: *
236: * @param other
237: * the object to be compared against
238: * @return Whether this short buffer equals to another object.
239: */
240: @Override
241: public boolean equals(Object other) {
242: if (!(other instanceof ShortBuffer)) {
243: return false;
244: }
245: ShortBuffer otherBuffer = (ShortBuffer) other;
246:
247: if (remaining() != otherBuffer.remaining()) {
248: return false;
249: }
250:
251: int myPosition = position;
252: int otherPosition = otherBuffer.position;
253: boolean equalSoFar = true;
254: while (equalSoFar && (myPosition < limit)) {
255: equalSoFar = get(myPosition++) == otherBuffer
256: .get(otherPosition++);
257: }
258:
259: return equalSoFar;
260: }
261:
262: /**
263: * Returns the short at the current position and increase the position by 1.
264: *
265: * @return The short at the current position.
266: * @exception BufferUnderflowException
267: * If the position is equal or greater than limit
268: */
269: public abstract short get();
270:
271: /**
272: * Reads <code>short</code>s from the current position into the specified
273: * short array and increase the position by the number of <code>short</code>s
274: * read.
275: * <p>
276: * Calling this method has the same effect as
277: * <code>get(dest, 0, dest.length)</code>.
278: * </p>
279: *
280: * @param dest
281: * The destination short array
282: * @return This buffer
283: * @exception BufferUnderflowException
284: * if <code>dest.length</code> is greater than
285: * <code>remaining()</code>
286: */
287: public ShortBuffer get(short[] dest) {
288: return get(dest, 0, dest.length);
289: }
290:
291: /**
292: * Reads <code>short</code>s from the current position into the specified
293: * short array, starting from the specified offset, and increase the
294: * position by the number of <code>short</code>s read.
295: *
296: * @param dest
297: * The target short array
298: * @param off
299: * The offset of the short array, must be no less than zero and
300: * no greater than <code>dest.length</code>
301: * @param len
302: * The number of <code>short</code>s to read, must be no less
303: * than zero and no greater than <code>dest.length - off</code>
304: * @return This buffer
305: * @exception IndexOutOfBoundsException
306: * If either <code>off</code> or <code>len</code> is
307: * invalid
308: * @exception BufferUnderflowException
309: * If <code>len</code> is greater than
310: * <code>remaining()</code>
311: */
312: public ShortBuffer get(short[] dest, int off, int len) {
313: int length = dest.length;
314: if (off < 0 || len < 0 || (long) off + (long) len > length) {
315: throw new IndexOutOfBoundsException();
316: }
317: if (len > remaining()) {
318: throw new BufferUnderflowException();
319: }
320: for (int i = off; i < off + len; i++) {
321: dest[i] = get();
322: }
323: return this ;
324: }
325:
326: /**
327: * Returns a short at the specified index, and the position is not changed.
328: *
329: * @param index
330: * The index, must be no less than zero and less than limit
331: * @return A short at the specified index.
332: * @exception IndexOutOfBoundsException
333: * If index is invalid
334: */
335: public abstract short get(int index);
336:
337: /**
338: * Returns whether this buffer is based on a short array and is read/write.
339: * <p>
340: * If this buffer is readonly, then false is returned.
341: * </p>
342: *
343: * @return Whether this buffer is based on a short array and is read/write.
344: */
345: public final boolean hasArray() {
346: return protectedHasArray();
347: }
348:
349: /**
350: * Hash code is calculated from the remaining <code>short</code>s.
351: * <p>
352: * Position, limit, capacity and mark don't affect the hash code.
353: * </p>
354: *
355: * @return The hash code calculated from the remaining <code>short</code>s.
356: */
357: @Override
358: public int hashCode() {
359: int myPosition = position;
360: int hash = 0;
361: while (myPosition < limit) {
362: hash = hash + get(myPosition++);
363: }
364: return hash;
365: }
366:
367: /**
368: * Returns true if this buffer is direct.
369: * <p>
370: * A direct buffer will try its best to take advantage of native memory APIs
371: * and it may not stay in java heap, thus not affected by GC.
372: * </p>
373: * <p>
374: * A short buffer is direct, if it is based on a byte buffer and the byte
375: * buffer is direct.
376: * </p>
377: *
378: * @return True if this buffer is direct.
379: */
380: public abstract boolean isDirect();
381:
382: /**
383: * Returns the byte order used by this buffer when converting
384: * <code>short</code>s from/to <code>byte</code>s.
385: * <p>
386: * If this buffer is not based on a byte buffer, then always return the
387: * platform's native byte order.
388: * </p>
389: *
390: * @return The byte order used by this buffer when converting
391: * <code>short</code>s from/to <code>byte</code>s.
392: */
393: public abstract ByteOrder order();
394:
395: /**
396: * Child class implements this method to realize <code>array()</code>.
397: *
398: * @return see <code>array()</code>
399: */
400: abstract short[] protectedArray();
401:
402: /**
403: * Child class implements this method to realize <code>arrayOffset()</code>.
404: *
405: * @return see <code>arrayOffset()</code>
406: */
407: abstract int protectedArrayOffset();
408:
409: /**
410: * Child class implements this method to realize <code>hasArray()</code>.
411: *
412: * @return see <code>hasArray()</code>
413: */
414: abstract boolean protectedHasArray();
415:
416: /**
417: * Writes the given short to the current position and increase the position
418: * by 1.
419: *
420: * @param s
421: * The short to write
422: * @return This buffer
423: * @exception BufferOverflowException
424: * If position is equal or greater than limit
425: * @exception ReadOnlyBufferException
426: * If no changes may be made to the contents of this buffer
427: */
428: public abstract ShortBuffer put(short s);
429:
430: /**
431: * Writes <code>short</code>s in the given short array to the current
432: * position and increase the position by the number of <code>short</code>s
433: * written.
434: * <p>
435: * Calling this method has the same effect as
436: * <code>put(src, 0, src.length)</code>.
437: * </p>
438: *
439: * @param src
440: * The source short array
441: * @return This buffer
442: * @exception BufferOverflowException
443: * If <code>remaining()</code> is less than
444: * <code>src.length</code>
445: * @exception ReadOnlyBufferException
446: * If no changes may be made to the contents of this buffer
447: */
448: public final ShortBuffer put(short[] src) {
449: return put(src, 0, src.length);
450: }
451:
452: /**
453: * Writes <code>short</code>s in the given short array, starting from the
454: * specified offset, to the current position and increase the position by
455: * the number of <code>short</code>s written.
456: *
457: * @param src
458: * The source short array
459: * @param off
460: * The offset of short array, must be no less than zero and no
461: * greater than <code>src.length</code>
462: * @param len
463: * The number of <code>short</code>s to write, must be no less
464: * than zero and no greater than <code>src.length - off</code>
465: * @return This buffer
466: * @exception BufferOverflowException
467: * If <code>remaining()</code> is less than
468: * <code>len</code>
469: * @exception IndexOutOfBoundsException
470: * If either <code>off</code> or <code>len</code> is
471: * invalid
472: * @exception ReadOnlyBufferException
473: * If no changes may be made to the contents of this buffer
474: */
475: public ShortBuffer put(short[] src, int off, int len) {
476: int length = src.length;
477: if (off < 0 || len < 0 || (long) off + (long) len > length) {
478: throw new IndexOutOfBoundsException();
479: }
480:
481: if (len > remaining()) {
482: throw new BufferOverflowException();
483: }
484: for (int i = off; i < off + len; i++) {
485: put(src[i]);
486: }
487: return this ;
488: }
489:
490: /**
491: * Writes all the remaining <code>short</code>s of the <code>src</code>
492: * short buffer to this buffer's current position, and increase both
493: * buffers' position by the number of <code>short</code>s copied.
494: *
495: * @param src
496: * The source short buffer
497: * @return This buffer
498: * @exception BufferOverflowException
499: * If <code>src.remaining()</code> is greater than this
500: * buffer's <code>remaining()</code>
501: * @exception IllegalArgumentException
502: * If <code>src</code> is this buffer
503: * @exception ReadOnlyBufferException
504: * If no changes may be made to the contents of this buffer
505: */
506: public ShortBuffer put(ShortBuffer src) {
507: if (src == this ) {
508: throw new IllegalArgumentException();
509: }
510: if (src.remaining() > remaining()) {
511: throw new BufferOverflowException();
512: }
513: short[] contents = new short[src.remaining()];
514: src.get(contents);
515: put(contents);
516: return this ;
517: }
518:
519: /**
520: * Write a short to the specified index of this buffer and the position is
521: * not changed.
522: *
523: * @param index
524: * The index, must be no less than zero and less than the limit
525: * @param s
526: * The short to write
527: * @return This buffer
528: * @exception IndexOutOfBoundsException
529: * If index is invalid
530: * @exception ReadOnlyBufferException
531: * If no changes may be made to the contents of this buffer
532: */
533: public abstract ShortBuffer put(int index, short s);
534:
535: /**
536: * Returns a sliced buffer that shares content with this buffer.
537: * <p>
538: * The sliced buffer's capacity will be this buffer's
539: * <code>remaining()</code>, and its zero position will correspond to
540: * this buffer's current position. The new buffer's position will be 0,
541: * limit will be its capacity, and its mark is unset. The new buffer's
542: * readonly property and byte order are same as this buffer.
543: * </p>
544: * <p>
545: * The new buffer shares content with this buffer, which means either
546: * buffer's change of content will be visible to the other. The two buffer's
547: * position, limit and mark are independent.
548: * </p>
549: *
550: * @return A sliced buffer that shares content with this buffer.
551: */
552: public abstract ShortBuffer slice();
553:
554: /**
555: * Returns a string represents the state of this short buffer.
556: *
557: * @return A string represents the state of this short buffer.
558: */
559: @Override
560: public String toString() {
561: StringBuffer buf = new StringBuffer();
562: buf.append(getClass().getName());
563: buf.append(", status: capacity="); //$NON-NLS-1$
564: buf.append(capacity());
565: buf.append(" position="); //$NON-NLS-1$
566: buf.append(position());
567: buf.append(" limit="); //$NON-NLS-1$
568: buf.append(limit());
569: return buf.toString();
570: }
571: }
|