1 //****************************************************************************** 2 // 3 // File: CharacterBuf.java 4 // Package: edu.rit.mp 5 // Unit: Class edu.rit.mp.CharacterBuf 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.CharacterArrayBuf; 45 import edu.rit.mp.buf.CharacterArrayBuf_1; 46 import edu.rit.mp.buf.CharacterItemBuf; 47 import edu.rit.mp.buf.CharacterMatrixBuf; 48 import edu.rit.mp.buf.CharacterMatrixBuf_1; 49 import edu.rit.mp.buf.EmptyCharacterBuf; 50 import edu.rit.mp.buf.SharedCharacterArrayBuf; 51 import edu.rit.mp.buf.SharedCharacterArrayBuf_1; 52 import edu.rit.mp.buf.SharedCharacterBuf; 53 import edu.rit.pj.reduction.SharedCharacter; 54 import edu.rit.pj.reduction.SharedCharacterArray; 55 import edu.rit.util.Arrays; 56 import edu.rit.util.Range; 57 58 /** 59 * Class CharacterBuf is the abstract base class for a buffer of character items 60 * sent or received using the Message Protocol (MP). In a message, a character 61 * item is represented as two 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 CharacterBuf, call one of the following static factory methods: 80 * <UL> 81 * <LI><code>emptyBuffer()</code> 82 * <LI><code>buffer()</code> 83 * <LI><code>buffer (char)</code> 84 * <LI><code>buffer (char[])</code> 85 * <LI><code>sliceBuffer (char[], Range)</code> 86 * <LI><code>sliceBuffers (char[], Range[])</code> 87 * <LI><code>buffer (char[][])</code> 88 * <LI><code>rowSliceBuffer (char[][], Range)</code> 89 * <LI><code>rowSliceBuffers (char[][], Range[])</code> 90 * <LI><code>colSliceBuffer (char[][], Range)</code> 91 * <LI><code>colSliceBuffers (char[][], Range[])</code> 92 * <LI><code>patchBuffer (char[][], Range, Range)</code> 93 * <LI><code>patchBuffers (char[][], Range[], Range[])</code> 94 * <LI><code>buffer (SharedCharacter)</code> 95 * <LI><code>buffer (SharedCharacterArray)</code> 96 * <LI><code>sliceBuffer (SharedCharacterArray, Range)</code> 97 * <LI><code>sliceBuffers (SharedCharacterArray, Range[])</code> 98 * </UL> 99 * 100 * @author Alan Kaminsky 101 * @version 03-May-2008 102 */ 103 public abstract class CharacterBuf 104 extends Buf { 105 106 // Hidden constructors. 107 /** 108 * Construct a new character buffer. 109 * 110 * @param theLength Number of items. 111 * @exception IllegalArgumentException (unchecked exception) Thrown if 112 * <code>theLength</code> < 0. 113 */ 114 protected CharacterBuf(int theLength) { 115 super(Constants.TYPE_CHARACTER, 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 character. 122 * 123 * @return Empty buffer. 124 */ 125 public static CharacterBuf emptyBuffer() { 126 return new EmptyCharacterBuf(); 127 } 128 129 /** 130 * Create a buffer for a character item. The item is stored in the 131 * <code>item</code> field of the buffer. 132 * 133 * @return Buffer. 134 */ 135 public static CharacterItemBuf buffer() { 136 return new CharacterItemBuf(); 137 } 138 139 /** 140 * Create a buffer for a character item with the given initial value. The 141 * item 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 CharacterItemBuf buffer(char item) { 147 return new CharacterItemBuf(item); 148 } 149 150 /** 151 * Create a buffer for the entire given character 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 CharacterBuf buffer(char[] theArray) { 160 if (theArray == null) { 161 throw new NullPointerException("CharacterBuf.buffer(): theArray is null"); 162 } 163 int nr = Arrays.length(theArray); 164 return new CharacterArrayBuf_1(theArray, new Range(0, nr - 1)); 165 } 166 167 /** 168 * Create a buffer for one slice of the given character 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 CharacterBuf sliceBuffer(char[] theArray, 182 Range theRange) { 183 if (theArray == null) { 184 throw new NullPointerException("CharacterBuf.sliceBuffer(): theArray is null"); 185 } 186 int nr = Arrays.length(theArray); 187 if (0 > theRange.lb() || theRange.ub() >= nr) { 188 throw new IndexOutOfBoundsException("CharacterBuf.sliceBuffer(): theArray index range = 0.." 189 + (nr - 1) + ", theRange = " + theRange); 190 } 191 if (theRange.stride() == 1) { 192 return new CharacterArrayBuf_1(theArray, theRange); 193 } else { 194 return new CharacterArrayBuf(theArray, theRange); 195 } 196 } 197 198 /** 199 * Create an array of buffers for multiple slices of the given character 200 * array. 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 CharacterBuf[] sliceBuffers(char[] theArray, 216 Range[] theRanges) { 217 int n = theRanges.length; 218 CharacterBuf[] result = new CharacterBuf[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 character matrix. The returned 227 * buffer 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 CharacterBuf buffer(char[][] theMatrix) { 236 if (theMatrix == null) { 237 throw new NullPointerException("CharacterBuf.buffer(): theMatrix is null"); 238 } 239 int nr = Arrays.rowLength(theMatrix); 240 int nc = Arrays.colLength(theMatrix, 0); 241 return new CharacterMatrixBuf_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 character matrix. The 246 * returned buffer encompasses <code>theRowRange</code> of rows, and all the 247 * columns, in <code>theMatrix</code>. The range's stride may be 1 or greater 248 * than 1. 249 * 250 * @param theMatrix Matrix. 251 * @param theRowRange Range of rows to include. 252 * @return Buffer. 253 * @exception NullPointerException (unchecked exception) Thrown if 254 * <code>theMatrix</code> is null or 255 * <code>theRowRange</code> is null. 256 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 257 * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code>. 258 */ 259 public static CharacterBuf rowSliceBuffer(char[][] theMatrix, 260 Range theRowRange) { 261 if (theMatrix == null) { 262 throw new NullPointerException("CharacterBuf.rowSliceBuffer(): theMatrix is null"); 263 } 264 int nr = Arrays.rowLength(theMatrix); 265 if (0 > theRowRange.lb() || theRowRange.ub() >= nr) { 266 throw new IndexOutOfBoundsException("CharacterBuf.rowSliceBuffer(): theMatrix row index range = 0.." 267 + (nr - 1) + ", theRowRange = " + theRowRange); 268 } 269 int nc = Arrays.colLength(theMatrix, theRowRange.lb()); 270 if (theRowRange.stride() == 1) { 271 return new CharacterMatrixBuf_1(theMatrix, theRowRange, new Range(0, nc - 1)); 272 } else { 273 return new CharacterMatrixBuf(theMatrix, theRowRange, new Range(0, nc - 1)); 274 } 275 } 276 277 /** 278 * Create an array of buffers for multiple row slices of the given character 279 * matrix. The returned buffer array has the same length as 280 * <code>theRowRanges</code>. Each element [<I>i</I>] of the returned buffer 281 * array encompasses the rows of <code>theMatrix</code> specified by 282 * <code>theRowRanges[i]</code> and all the columns of <code>theMatrix</code>. Each 283 * range's stride may be 1 or greater than 1. 284 * 285 * @param theMatrix Matrix. 286 * @param theRowRanges Array of ranges of rows to include. 287 * @return Array of buffers. 288 * @exception NullPointerException (unchecked exception) Thrown if 289 * <code>theMatrix</code> is null or 290 * <code>theRowRanges</code> or any element thereof is null. 291 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 292 * <code>theMatrix</code>'s allocation does not include any element of 293 * <code>theRowRanges</code>. 294 */ 295 public static CharacterBuf[] rowSliceBuffers(char[][] theMatrix, 296 Range[] theRowRanges) { 297 int n = theRowRanges.length; 298 CharacterBuf[] result = new CharacterBuf[n]; 299 for (int i = 0; i < n; ++i) { 300 result[i] = rowSliceBuffer(theMatrix, theRowRanges[i]); 301 } 302 return result; 303 } 304 305 /** 306 * Create a buffer for one column slice of the given character matrix. The 307 * returned buffer encompasses all the rows, and <code>theColRange</code> of 308 * columns, in <code>theMatrix</code>. The range's stride may be 1 or greater 309 * than 1. 310 * 311 * @param theMatrix Matrix. 312 * @param theColRange Range of columns to include. 313 * @return Buffer. 314 * @exception NullPointerException (unchecked exception) Thrown if 315 * <code>theMatrix</code> is null or 316 * <code>theColRange</code> is null. 317 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 318 * <code>theMatrix</code>'s allocation does not include <code>theColRange</code>. 319 */ 320 public static CharacterBuf colSliceBuffer(char[][] theMatrix, 321 Range theColRange) { 322 if (theMatrix == null) { 323 throw new NullPointerException("CharacterBuf.colSliceBuffer(): theMatrix is null"); 324 } 325 int nr = Arrays.rowLength(theMatrix); 326 int nc = Arrays.colLength(theMatrix, 0); 327 if (0 > theColRange.lb() || theColRange.ub() >= nc) { 328 throw new IndexOutOfBoundsException("CharacterBuf.colSliceBuffer(): theMatrix column index range = 0.." 329 + (nc - 1) + ", theColRange = " + theColRange); 330 } 331 if (theColRange.stride() == 1) { 332 return new CharacterMatrixBuf_1(theMatrix, new Range(0, nr - 1), theColRange); 333 } else { 334 return new CharacterMatrixBuf(theMatrix, new Range(0, nr - 1), theColRange); 335 } 336 } 337 338 /** 339 * Create an array of buffers for multiple column slices of the given 340 * character matrix. The returned buffer array has the same length as 341 * <code>theColRanges</code>. Each element [<I>i</I>] of the returned buffer 342 * array encompasses all the rows of <code>theMatrix</code> and the columns of 343 * <code>theMatrix</code> specified by <code>theColRanges[i]</code>. Each range's 344 * stride may be 1 or greater than 1. 345 * 346 * @param theMatrix Matrix. 347 * @param theColRanges Array of ranges of columns to include. 348 * @return Array of buffers. 349 * @exception NullPointerException (unchecked exception) Thrown if 350 * <code>theMatrix</code> is null or 351 * <code>theColRanges</code> or any element thereof is null. 352 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 353 * <code>theMatrix</code>'s allocation does not include any element of 354 * <code>theColRanges</code>. 355 */ 356 public static CharacterBuf[] colSliceBuffers(char[][] theMatrix, 357 Range[] theColRanges) { 358 int n = theColRanges.length; 359 CharacterBuf[] result = new CharacterBuf[n]; 360 for (int i = 0; i < n; ++i) { 361 result[i] = colSliceBuffer(theMatrix, theColRanges[i]); 362 } 363 return result; 364 } 365 366 /** 367 * Create a buffer for one patch of the given character matrix. The returned 368 * buffer encompasses <code>theRowRange</code> of rows, and <code>theColRange</code> 369 * of columns, in <code>theMatrix</code>. Each range's stride may be 1 or 370 * greater than 1. 371 * 372 * @param theMatrix Matrix. 373 * @param theRowRange Range of rows to include. 374 * @param theColRange Range of columns to include. 375 * @return Buffer. 376 * @exception NullPointerException (unchecked exception) Thrown if 377 * <code>theMatrix</code> is null, 378 * <code>theRowRange</code> is null, or <code>theColRange</code> is null. 379 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 380 * <code>theMatrix</code>'s allocation does not include <code>theRowRange</code> and 381 * <code>theColRange</code>. 382 */ 383 public static CharacterBuf patchBuffer(char[][] theMatrix, 384 Range theRowRange, 385 Range theColRange) { 386 if (theMatrix == null) { 387 throw new NullPointerException("CharacterBuf.patchBuffer(): theMatrix is null"); 388 } 389 int nr = Arrays.rowLength(theMatrix); 390 if (0 > theRowRange.lb() || theRowRange.ub() >= nr) { 391 throw new IndexOutOfBoundsException("CharacterBuf.patchBuffer(): theMatrix row index range = 0.." 392 + (nr - 1) + ", theRowRange = " + theRowRange); 393 } 394 int nc = Arrays.colLength(theMatrix, theRowRange.lb()); 395 if (0 > theColRange.lb() || theColRange.ub() >= nc) { 396 throw new IndexOutOfBoundsException("CharacterBuf.patchBuffer(): theMatrix column index range = 0.." 397 + (nc - 1) + ", theColRange = " + theColRange); 398 } 399 if (theRowRange.stride() == 1 && theColRange.stride() == 1) { 400 return new CharacterMatrixBuf_1(theMatrix, theRowRange, theColRange); 401 } else { 402 return new CharacterMatrixBuf(theMatrix, theRowRange, theColRange); 403 } 404 } 405 406 /** 407 * Create an array of buffers for multiple patches of the given character 408 * matrix. The length of the returned buffer array is equal to the length of 409 * <code>theRowRanges</code> times the length of <code>theColRanges</code>. Each 410 * element of the returned buffer array encompasses the rows given in one 411 * element of <code>theRowRanges</code> array, and the columns given in one 412 * element of <code>theColRanges</code> array, in all possible combinations, of 413 * <code>theMatrix</code>. Each range's stride may be 1 or greater than 1. 414 * 415 * @param theMatrix Matrix. 416 * @param theRowRanges Array of ranges of rows to include. 417 * @param theColRanges Array of ranges of columns to include. 418 * @return Array of buffers. 419 * @exception NullPointerException (unchecked exception) Thrown if 420 * <code>theMatrix</code> is null, 421 * <code>theRowRanges</code> or any element thereof is null, or 422 * <code>theColRanges</code> or any element thereof is null. 423 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 424 * <code>theMatrix</code>'s allocation does not include any element of 425 * <code>theRowRanges</code> or 426 * <code>theColRanges</code>. 427 */ 428 public static CharacterBuf[] patchBuffers(char[][] theMatrix, 429 Range[] theRowRanges, 430 Range[] theColRanges) { 431 int m = theRowRanges.length; 432 int n = theColRanges.length; 433 CharacterBuf[] result = new CharacterBuf[m * n]; 434 int k = 0; 435 for (int i = 0; i < m; ++i) { 436 Range rowrange = theRowRanges[i]; 437 for (int j = 0; j < n; ++j) { 438 result[k++] 439 = patchBuffer(theMatrix, rowrange, theColRanges[j]); 440 } 441 } 442 return result; 443 } 444 445 /** 446 * Create a buffer for a shared character item. The item is wrapped in an 447 * instance of class {@linkplain edu.rit.pj.reduction.SharedCharacter 448 * SharedCharacter}. Use the methods of the SharedCharacter object to access 449 * the actual item. 450 * 451 * @param item SharedCharacter object that wraps the item. 452 * @exception NullPointerException (unchecked exception) Thrown if 453 * <code>item</code> is null. 454 * @return a {@link edu.rit.mp.CharacterBuf} object. 455 */ 456 public static CharacterBuf buffer(SharedCharacter item) { 457 if (item == null) { 458 throw new NullPointerException("CharacterBuf.buffer(): item is null"); 459 } 460 return new SharedCharacterBuf(item); 461 } 462 463 /** 464 * Create a buffer for the entire given shared character array. The returned 465 * buffer encompasses all the elements in <code>theArray</code>. 466 * 467 * @param theArray Array. 468 * @return Buffer. 469 * @exception NullPointerException (unchecked exception) Thrown if 470 * <code>theArray</code> is null. 471 */ 472 public static CharacterBuf buffer(SharedCharacterArray theArray) { 473 if (theArray == null) { 474 throw new NullPointerException("CharacterBuf.buffer(): theArray is null"); 475 } 476 int nr = theArray.length(); 477 return new SharedCharacterArrayBuf_1(theArray, new Range(0, nr - 1)); 478 } 479 480 /** 481 * Create a buffer for one slice of the given shared character array. The 482 * returned buffer encompasses <code>theRange</code> of elements in 483 * <code>theArray</code>. The range's stride may be 1 or greater than 1. 484 * 485 * @param theArray Array. 486 * @param theRange Range of elements to include. 487 * @return Buffer. 488 * @exception NullPointerException (unchecked exception) Thrown if 489 * <code>theArray</code> is null or 490 * <code>theRange</code> is null. 491 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 492 * <code>theArray</code> does not include all the indexes in <code>theRange</code>. 493 */ 494 public static CharacterBuf sliceBuffer(SharedCharacterArray theArray, 495 Range theRange) { 496 if (theArray == null) { 497 throw new NullPointerException("CharacterBuf.sliceBuffer(): theArray is null"); 498 } 499 int nr = theArray.length(); 500 if (0 > theRange.lb() || theRange.ub() >= nr) { 501 throw new IndexOutOfBoundsException("CharacterBuf.sliceBuffer(): theArray index range = 0.." 502 + (nr - 1) + ", theRange = " + theRange); 503 } 504 if (theRange.stride() == 1) { 505 return new SharedCharacterArrayBuf_1(theArray, theRange); 506 } else { 507 return new SharedCharacterArrayBuf(theArray, theRange); 508 } 509 } 510 511 /** 512 * Create an array of buffers for multiple slices of the given shared 513 * character array. The returned buffer array has the same length as 514 * <code>theRanges</code>. Each element [<I>i</I>] of the returned buffer array 515 * encompasses the elements of <code>theArray</code> specified by 516 * <code>theRanges[i]</code>. Each range's stride may be 1 or greater than 1. 517 * 518 * @param theArray Array. 519 * @param theRanges Array of ranges of elements to include. 520 * @return Array of buffers. 521 * @exception NullPointerException (unchecked exception) Thrown if 522 * <code>theArray</code> is null or 523 * <code>theRanges</code> or any element thereof is null. 524 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if 525 * <code>theArray</code>'s allocation does not include any element of 526 * <code>theRanges</code>. 527 */ 528 public static CharacterBuf[] sliceBuffers(SharedCharacterArray theArray, 529 Range[] theRanges) { 530 int n = theRanges.length; 531 CharacterBuf[] result = new CharacterBuf[n]; 532 for (int i = 0; i < n; ++i) { 533 result[i] = sliceBuffer(theArray, theRanges[i]); 534 } 535 return result; 536 } 537 538 /** 539 * Obtain the given item from this buffer. 540 * <P> 541 * The <code>get()</code> method must not block the calling thread; if it does, 542 * all message I/O in MP will be blocked. 543 * 544 * @param i Item index in the range 0 .. <code>length()</code>-1. 545 * @return Item at index <code>i</code>. 546 */ 547 public abstract char get(int i); 548 549 /** 550 * Store the given item in this buffer. 551 * <P> 552 * The <code>put()</code> method must not block the calling thread; if it does, 553 * all message I/O in MP will be blocked. 554 * 555 * @param i Item index in the range 0 .. <code>length()</code>-1. 556 * @param item Item to be stored at index <code>i</code>. 557 */ 558 public abstract void put(int i, 559 char item); 560 561 /** 562 * {@inheritDoc} 563 * 564 * Copy items from the given buffer to this buffer. The number of items 565 * copied is this buffer's length or <code>theSrc</code>'s length, whichever is 566 * smaller. If <code>theSrc</code> is this buffer, the <code>copy()</code> method 567 * does nothing. 568 * <P> 569 * The default implementation of the <code>copy()</code> method calls the 570 * <code>defaultCopy()</code> method. A subclass can override the 571 * <code>copy()</code> method to use a more efficient algorithm. 572 * @exception ClassCastException (unchecked exception) Thrown if 573 * <code>theSrc</code>'s item data type is not the same as this buffer's item 574 * data type. 575 */ 576 public void copy(Buf theSrc) { 577 if (theSrc != this) { 578 defaultCopy((CharacterBuf) theSrc, this); 579 } 580 } 581 582 /** 583 * {@inheritDoc} 584 * 585 * Fill this buffer with the given item. The <code>item</code> is assigned to 586 * each element in this buffer. 587 * <P> 588 * The <code>item</code> must be an instance of class Character. If the 589 * <code>item</code> is null, <code>'\u0000'</code> is assigned to each element in 590 * this buffer. 591 * @exception ClassCastException (unchecked exception) Thrown if the 592 * <code>item</code>'s data type is not the same as this buffer's item data 593 * type. 594 */ 595 public void fill(Object item) { 596 char value = item == null ? '\u0000' : ((Character) item).charValue(); 597 for (int i = 0; i < myLength; ++i) { 598 put(i, value); 599 } 600 } 601 602 /** 603 * Create a temporary buffer with the same type of items and the same length 604 * as this buffer. The new buffer items are stored in a newly created array, 605 * separate from the storage for this buffer's items. 606 * 607 * @return a {@link edu.rit.mp.Buf} object. 608 */ 609 public Buf getTemporaryBuf() { 610 return buffer(new char[myLength]); 611 } 612 613 // Hidden operations. 614 /** 615 * Skip as many items as possible from the given byte buffer. 616 * 617 * @param num Number of items to skip. 618 * @param buffer Buffer. 619 * 620 * @return Number of items actually skipped. 621 */ 622 int skipItems(int num, 623 ByteBuffer buffer) { 624 int n = Math.min(num, buffer.remaining() / 2); 625 buffer.position(buffer.position() + 2 * n); 626 return n; 627 } 628 629 /** 630 * Copy items from the given source buffer to the given destination buffer. 631 * The number of items copied is <code>theSrc</code>'s length or 632 * <code>theDst</code>'s length, whichever is smaller. Each item is copied 633 * individually using the <code>get()</code> and <code>put()</code> methods. It is 634 * assumed that <code>theSrc</code> is not the same as <code>theDst</code>. 635 * 636 * @param theSrc Source of items to copy. 637 * @param theDst Destination of items to copy. 638 */ 639 protected static void defaultCopy(CharacterBuf theSrc, 640 CharacterBuf theDst) { 641 int n = Math.min(theSrc.myLength, theDst.myLength); 642 for (int i = 0; i < n; ++i) { 643 theDst.put(i, theSrc.get(i)); 644 } 645 } 646 647 }