gt:          char c = str.charAt(i);
context: /*
   * Copyright (c) 2007-2008, Sun Microsystems, Inc.
   *
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   *     * Redistributions of source code must retain the above copyright
   *       notice, this list of conditions and the following disclaimer.
   *     * Redistributions in binary form must reproduce the above copyright
   *       notice, this list of conditions and the following disclaimer in
   *       the documentation and/or other materials provided with the
   *       distribution.
   *     * Neither the name of Sun Microsystems, Inc. nor the names of its
   *       contributors may be used to endorse or promote products derived
   *       from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  package com.sun.sgs.impl.sharedutil;
  
  import java.io.UTFDataFormatException;
  
  /**
   * A buffer for composing/decomposing messages.
   * 
   * <p>
   * Strings are encoded in modified UTF-8 format as described in
   * {@link java.io.DataInput}.
   */
  public class MessageBuffer {
  
     private final byte[] buf;
  
     private final int capacity;
  
     private int pos = 0;
  
     private int limit;
  
     /**
      * Returns the size of the specified string, encoded in modified UTF-8
      * format.
      * 
      * @param str
      *           a string
      * @return the size of the specified string, encoded in modified UTF-8 format
      */
     public static int getSize(String str) {
  
        // Note: code adapted from java.io.DataOutputStream.writeUTF
  
        int utfLen = 0;
  
        for (int i = 0; i < str.length(); i++) {
           int c = str.charAt(i);
           if ((c >= 0x0001) && (c <= 0x007F)) {
              utfLen++;
           }
           else if (c > 0x07FF) {
              utfLen += 3;
           }
           else {
              utfLen += 2;
           }
        }
  
        return utfLen + 2;
     }
  
     /**
      * Constructs an empty message buffer with the specified capacity.
      * 
      * @param capacity
      *           the buffer's capacity
      */
     public MessageBuffer(int capacity) {
        this(new byte[capacity]);
        if (capacity == 0) {
           throw new IllegalArgumentException("capacity must be greater than 0");
        }
        this.limit = 1;
     }
  
     /**
      * Constructs a message buffer using the specified byte array as the byte
      * array that backs this buffer. Intializes this buffer's capacity and limit
      * to the length of the specified byte array.
      * 
      * @param buf
      *           the byte array to back this buffer
      */
     public MessageBuffer(byte[] buf) {
        this.buf = buf;
        this.capacity = buf.length;
        this.limit = buf.length;
     }
  
     /**
      * Returns the capacity of this buffer. The capacity is the number of
      * elements this buffer contains.
      * 
      * @return this buffer's capacity
      */
     public int capacity() {
        return capacity;
     }
  
     /**
      * Returns the limit of this buffer. The limit is the index of the first
      * element that should not be written or read. The limit is never negative
      * and is never greater than the buffer's capacity.
      * 
      * @return this buffer's limit
      */
     public int limit() {
        return limit;
     }
  
     /**
      * Returns the position of this buffer. The position is the index of the next
      * element to be written or read.
      * 
      * @return this buffer's position
      */
     public int position() {
        return pos;
     }
  
     /**
      * Sets the position of this buffer to zero, making this buffer ready for
      * re-reading of its elements.
      */
     public void rewind() {
        pos = 0;
     }
  
     /**
      * Puts the specified byte in this buffer's current position, and advances
      * the buffer's position and limit by one.
      * 
      * @param b
      *           a byte
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the byte to the buffer would overflow the buffer
      */
     public MessageBuffer putByte(int b) {
        if (pos == capacity) {
           throw new IndexOutOfBoundsException();
        }
        buf[pos++] = (byte) b;
        limit = (pos == capacity ? pos : pos + 1);
        return this;
     }
  
     /**
      * Puts into this buffer a short representing the length of the specified
      * byte array followed by the bytes from the specified byte array, starting
      * at the buffer's current position. The buffer's position and limit are
      * advanced by the length of the specified byte array plus two.
      * 
      * @param bytes
      *           a byte array
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the bytes to this buffer would overflow the buffer
      */
     public MessageBuffer putByteArray(byte[] bytes) {
        if (pos + 2 + bytes.length > capacity) {
           throw new IndexOutOfBoundsException();
        }
        putShort(bytes.length);
        putBytes(bytes);
        return this;
     }
  
     /**
      * Puts the bytes from the specified byte array in this buffer, starting at
      * the buffer's current position. The buffer's position and limit are
      * advanced by the length of the specified byte array.
      * 
      * @param bytes
      *           a byte array
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the bytes to this buffer would overflow the buffer
      */
     public MessageBuffer putBytes(byte[] bytes) {
        if (pos + bytes.length > capacity) {
           throw new IndexOutOfBoundsException();
        }
        for (byte b : bytes) {
           putByte(b);
        }
        return this;
     }
  
     /**
      * Puts the specified char as a two-byte value (high byte first) starting in
      * the buffer's current position, and advances the buffer's position and
      * limit by two.
      * 
      * @param v
      *           a char value
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the char to this buffer would overflow the buffer
      */
     public MessageBuffer putChar(int v) {
        if (pos + 2 > capacity) {
           throw new IndexOutOfBoundsException();
        }
        putByte((v >>> 8) & 0xFF);
        putByte((v >>> 0) & 0xFF);
        return this;
     }
  
     /**
      * Puts the specified short as a two-byte value (high byte first) starting in
      * the buffer's current position, and advances the buffer's position and
      * limit by two.
      * 
      * @param v
      *           a short value
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the short to this buffer would overflow the buffer
      */
     public MessageBuffer putShort(int v) {
        if (pos + 2 > capacity) {
           throw new IndexOutOfBoundsException();
        }
        putByte((v >>> 8) & 0xFF);
        putByte((v >>> 0) & 0xFF);
        return this;
     }
  
     /**
      * Puts the specified int as four bytes (high byte first) starting in the
      * buffer's current position, and advances the buffer's position and limit by
      * 4.
      * 
      * @param v
      *           an int value
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the int to this buffer would overflow the buffer
      */
     public MessageBuffer putInt(int v) {
        if (pos + 4 > capacity) {
           throw new IndexOutOfBoundsException();
        }
        putByte((v >>> 24) & 0xff);
        putByte((v >>> 16) & 0xff);
        putByte((v >>> 8) & 0xff);
        putByte((v >>> 0) & 0xff);
        return this;
     }
  
     /**
      * Puts the specified long as eight bytes (high byte first) starting in the
      * buffer's current position, and advances the buffer's position and limit by
      * 8.
      * 
      * @param v
      *           a long value
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the long to this buffer would overflow the buffer
      */
     public MessageBuffer putLong(long v) {
        if (pos + 8 > capacity) {
           throw new IndexOutOfBoundsException();
        }
        putByte((byte) (v >>> 56));
        putByte((byte) (v >>> 48));
        putByte((byte) (v >>> 40));
        putByte((byte) (v >>> 32));
        putByte((byte) (v >>> 24));
        putByte((byte) (v >>> 16));
        putByte((byte) (v >>> 8));
        putByte((byte) (v >>> 0));
        return this;
     }
  
     /**
      * Puts the specified string, encoded in modified UTF-8 format, in the buffer
      * starting in the buffer's the current position, and advances the buffer's
      * position and limit by the size of the encoded string.
      * 
      * @param str
      *           a string
      * @return this buffer
      * @throws IndexOutOfBoundsException
      *            if adding the encoded string to this buffer would overflow the
      *            buffer
      */
     public MessageBuffer putString(String str) {
  
        // Note: code adapted from java.io.DataOutputStream.writeUTF
  
        int size = getSize(str);
        if (pos + size > capacity) {
           throw new IndexOutOfBoundsException();
        }
  
        /*
         * Put length of modified UTF-8 encoded string, as two bytes.
         */
        putShort(size - 2);
  
        /*
         * Now, encode string, and put in buffer.
         */
        int strlen = str.length();
        int i = 0;
  
        for (i = 0; i < strlen; i++) {
  