Source for java.nio.Buffer

   1: /* Buffer.java -- 
   2:    Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.nio;
  40: 
  41: import gnu.classpath.Pointer;
  42: 
  43: /**
  44:  * @since 1.4
  45:  */
  46: public abstract class Buffer
  47: {
  48:   int cap = 0;
  49:   int limit = 0;
  50:   int pos = 0;
  51:   int mark = -1;
  52:   Pointer address;
  53: 
  54:   /**
  55:    * Creates a new Buffer.
  56:    *
  57:    * Should be package private.
  58:    */
  59:   Buffer (int capacity, int limit, int position, int mark)
  60:   {
  61:     if (capacity < 0)
  62:       throw new IllegalArgumentException ();
  63:     
  64:     cap = capacity;
  65:     limit (limit);
  66:     position (position);
  67:     
  68:     if (mark >= 0)
  69:     {
  70:       if (mark > pos)
  71:         throw new IllegalArgumentException ();
  72:       
  73:       this.mark = mark;
  74:     }
  75:   }
  76:   
  77:   /**
  78:    * Retrieves the capacity of the buffer.
  79:    *
  80:    * @return the capacity of the buffer
  81:    */
  82:   public final int capacity ()
  83:   {
  84:     return cap;
  85:   }
  86: 
  87:   /**
  88:    * Clears the buffer.
  89:    *
  90:    * @return this buffer
  91:    */
  92:   public final Buffer clear ()
  93:   {
  94:     limit = cap;
  95:     pos = 0;
  96:     mark = -1;
  97:     return this;
  98:   }
  99:     
 100:   /**
 101:    * Flips the buffer.
 102:    *
 103:    * @return this buffer
 104:    */
 105:   public final Buffer flip ()
 106:   {
 107:     limit = pos;
 108:     pos = 0;
 109:     mark = -1;
 110:     return this;
 111:   }
 112:     
 113:   /**
 114:    * Tells whether the buffer has remaining data to read or not.
 115:    *
 116:    * @return true if the buffer contains remaining data to read,
 117:    * false otherwise
 118:    */
 119:   public final boolean hasRemaining ()
 120:   {
 121:     return remaining() > 0;
 122:   }
 123: 
 124:   /**
 125:    * Tells whether this buffer is read only or not.
 126:    *
 127:    * @return true if the buffer is read only, false otherwise
 128:    */
 129:   public abstract boolean isReadOnly ();
 130: 
 131:   /**
 132:    * Retrieves the current limit of the buffer.
 133:    *
 134:    * @return the limit of the buffer
 135:    */
 136:   public final int limit ()
 137:   {
 138:     return limit;
 139:   }
 140: 
 141:   /**
 142:    * Sets this buffer's limit.
 143:    * 
 144:    * @param newLimit The new limit value; must be non-negative and no larger
 145:    * than this buffer's capacity.
 146:    *
 147:    * @return this buffer
 148:    *
 149:    * @exception IllegalArgumentException If the preconditions on newLimit
 150:    * do not hold.
 151:    */
 152:   public final Buffer limit (int newLimit)
 153:   {
 154:     if ((newLimit < 0) || (newLimit > cap))
 155:       throw new IllegalArgumentException ();
 156: 
 157:     if (newLimit < mark)
 158:         mark = -1;
 159: 
 160:     if (pos > newLimit)
 161:         pos = newLimit;
 162: 
 163:     limit = newLimit;
 164:     return this;
 165:   }
 166: 
 167:   /**
 168:    * Sets this buffer's mark at its position.
 169:    *
 170:    * @return this buffer
 171:    */
 172:   public final Buffer mark ()
 173:   {
 174:     mark = pos;
 175:     return this;
 176:   }
 177: 
 178:   /**
 179:    * Retrieves the current position of this buffer.
 180:    *
 181:    * @return the current position of this buffer
 182:    */
 183:   public final int position ()
 184:   {
 185:     return pos;
 186:   }
 187:     
 188:   /**
 189:    * Sets this buffer's position. If the mark is defined and larger than the
 190:    * new position then it is discarded.
 191:    * 
 192:    * @param newPosition The new position value; must be non-negative and no
 193:    * larger than the current limit.
 194:    *
 195:    * @return this buffer
 196:    *
 197:    * @exception IllegalArgumentException If the preconditions on newPosition
 198:    * do not hold
 199:    */
 200:   public final Buffer position (int newPosition)
 201:   {
 202:     if ((newPosition < 0) || (newPosition > limit))
 203:       throw new IllegalArgumentException ();
 204: 
 205:     if (newPosition <= mark)
 206:         mark = -1;
 207: 
 208:     pos = newPosition;
 209:     return this;
 210:   }
 211: 
 212:   /**
 213:    * Returns the number of elements between the current position and the limit.
 214:    *
 215:    * @return the number of remaining elements
 216:    */
 217:   public final int remaining()
 218:   {
 219:     return limit - pos;
 220:   }
 221: 
 222:   /**
 223:    * Resets this buffer's position to the previously-marked position.
 224:    *
 225:    * @return this buffer
 226:    *
 227:    * @exception InvalidMarkException If the mark has not been set.
 228:    */
 229:   public final Buffer reset()
 230:   {
 231:     if (mark == -1)
 232:       throw new InvalidMarkException ();
 233: 
 234:     pos = mark;
 235:     return this;
 236:   }
 237: 
 238:   /**
 239:    * Rewinds this buffer. The position is set to zero and the mark
 240:    * is discarded.
 241:    *
 242:    * @return this buffer
 243:    */
 244:   public final Buffer rewind()
 245:   {
 246:     pos = 0;
 247:     mark = -1;
 248:     return this;
 249:   }
 250: 
 251:   /**
 252:    * Checks for underflow. This method is used internally to check
 253:    * whether a buffer has enough elements left to satisfy a read 
 254:    * request.
 255:    *
 256:    * @exception BufferUnderflowException If there are no remaining
 257:    * elements in this buffer.
 258:    */
 259:   final void checkForUnderflow()
 260:   {
 261:     if (!hasRemaining())
 262:       throw new BufferUnderflowException();
 263:   }
 264: 
 265:   /**
 266:    * Checks for underflow. This method is used internally to check
 267:    * whether a buffer has enough elements left to satisfy a read 
 268:    * request for a given number of elements.
 269:    *
 270:    * @param length The length of a sequence of elements.
 271:    *
 272:    * @exception BufferUnderflowException If there are not enough 
 273:    * remaining elements in this buffer.
 274:    */
 275:   final void checkForUnderflow(int length)
 276:   {
 277:     if (remaining() < length)
 278:       throw new BufferUnderflowException();
 279:   }
 280: 
 281:   /**
 282:    * Checks for overflow. This method is used internally to check
 283:    * whether a buffer has enough space left to satisfy a write 
 284:    * request.
 285:    *
 286:    * @exception BufferOverflowException If there is no remaining
 287:    * space in this buffer.
 288:    */
 289:   final void checkForOverflow()
 290:   {
 291:     if (!hasRemaining())
 292:       throw new BufferOverflowException();
 293:   }
 294: 
 295:   /**
 296:    * Checks for overflow. This method is used internally to check
 297:    * whether a buffer has enough space left to satisfy a write 
 298:    * request for a given number of elements.
 299:    *
 300:    * @param length The length of a sequence of elements.
 301:    *
 302:    * @exception BufferUnderflowException If there is not enough 
 303:    * remaining space in this buffer.
 304:    */
 305:   final void checkForOverflow(int length)
 306:   {
 307:     if (remaining() < length)
 308:       throw new BufferOverflowException();
 309:   }
 310: 
 311:   /**
 312:    * Checks if index is negative or not smaller than the buffer's 
 313:    * limit. This method is used internally to check whether
 314:    * an indexed request can be fulfilled.
 315:    *
 316:    * @param index The requested position in the buffer.
 317:    *
 318:    * @exception IndexOutOfBoundsException If index is negative or not smaller
 319:    * than the buffer's limit.
 320:    */
 321:   final void checkIndex(int index)
 322:   {
 323:     if (index < 0
 324:         || index >= limit ())
 325:       throw new IndexOutOfBoundsException ();
 326:   }
 327: 
 328:   /**
 329:    * Checks if buffer is read-only. This method is used internally to
 330:    * check if elements can be put into a buffer.
 331:    *
 332:    * @exception ReadOnlyBufferException If this buffer is read-only.
 333:    */
 334:   final void checkIfReadOnly() 
 335:   {
 336:     if (isReadOnly())
 337:       throw new ReadOnlyBufferException ();
 338:   }
 339: 
 340:   /**
 341:    * Checks whether an array is large enough to hold the given number of
 342:    * elements at the given offset. This method is used internally to
 343:    * check if an array is big enough.
 344:    *
 345:    * @param arraylength The length of the array.
 346:    * @param offset The offset within the array of the first byte to be read;
 347:    * must be non-negative and no larger than arraylength.
 348:    * @param length The number of bytes to be read from the given array;
 349:    * must be non-negative and no larger than arraylength - offset.
 350:    *
 351:    * @exception IndexOutOfBoundsException If the preconditions on the offset
 352:    * and length parameters do not hold
 353:    */
 354:   static final void checkArraySize(int arraylength, int offset, int length)
 355:   {
 356:     if ((offset < 0) ||
 357:         (length < 0) ||
 358:         (arraylength < length + offset))
 359:       throw new IndexOutOfBoundsException ();
 360:   }
 361: }