public void writeArray(double[] ref, int off, int len) throws IOException {
   if (TIME_DATA_SERIALIZATION) {
     timer.start();
   }
   writeArrayDouble(ref, off, len);
   if (TIME_DATA_SERIALIZATION) {
     timer.stop();
   }
 }
 public void writeByteBuffer(ByteBuffer value) throws IOException {
   if (TIME_DATA_SERIALIZATION) {
     timer.start();
   }
   internalWriteByteBuffer(value);
   if (TIME_DATA_SERIALIZATION) {
     timer.stop();
   }
 }
 /**
  * Writes a double value to the accumulator.
  *
  * @param value The double value to write.
  * @exception IOException on IO error.
  */
 public void writeDouble(double value) throws IOException {
   if (TIME_DATA_SERIALIZATION) {
     timer.start();
   }
   if (NO_ARRAY_BUFFERS) {
     out.writeDouble(value);
   } else {
     if (double_index == double_buffer.length) {
       internalFlush();
     }
     double_buffer[double_index++] = value;
   }
   if (DEBUG && logger.isDebugEnabled()) {
     logger.debug("wrote double " + value);
   }
   if (TIME_DATA_SERIALIZATION) {
     timer.stop();
   }
 }
 /**
  * Writes a int value to the accumulator.
  *
  * @param value The int value to write.
  * @exception IOException on IO error.
  */
 public void writeInt(int value) throws IOException {
   if (TIME_DATA_SERIALIZATION) {
     timer.start();
   }
   if (NO_ARRAY_BUFFERS) {
     out.writeInt(value);
   } else {
     if (int_index == int_buffer.length) {
       internalFlush();
     }
     int_buffer[int_index++] = value;
   }
   if (DEBUG && logger.isDebugEnabled()) {
     logger.debug("wrote int[HEX] " + value + "[0x" + Integer.toHexString(value) + "]");
   }
   if (TIME_DATA_SERIALIZATION) {
     timer.stop();
   }
 }
 /**
  * Writes a boolean value to the accumulator.
  *
  * @param value The boolean value to write.
  * @exception IOException on IO error.
  */
 public void writeBoolean(boolean value) throws IOException {
   if (TIME_DATA_SERIALIZATION) {
     timer.start();
   }
   if (NO_ARRAY_BUFFERS) {
     out.writeBoolean(value);
   } else {
     if (byte_index == byte_buffer.length) {
       internalFlush();
     }
     byte_buffer[byte_index++] = (byte) (value ? 1 : 0);
   }
   if (DEBUG && logger.isDebugEnabled()) {
     logger.debug("wrote boolean " + value);
   }
   if (TIME_DATA_SERIALIZATION) {
     timer.stop();
   }
 }
  public void writeUTF(String str) throws IOException {
    if (TIME_DATA_SERIALIZATION) {
      timer.start();
    }
    if (str == null) {
      writeInt(-1);
      if (TIME_DATA_SERIALIZATION) {
        timer.stop();
      }
      return;
    }

    if (DEBUG && logger.isDebugEnabled()) {
      logger.debug("write UTF " + str);
    }
    int len = str.length();

    // writeInt(len);
    // writeArray(str.toCharArray(), 0, len);

    int bn = 0;

    for (int i = 0; i < len; i++) {
      int c = str.charAt(i); // widening char to int zero-extends
      if (c > 0x0000 && c <= 0x007f) {
        bn++;
      } else if (c <= 0x07ff) {
        bn += 2;
      } else {
        bn += 3;
      }
    }

    byte[] b = new byte[bn];
    bn = 0;

    for (int i = 0; i < len; i++) {
      int c = str.charAt(i); // widening char to int zero-extends
      if (c > 0x0000 && c <= 0x007f) {
        b[bn++] = (byte) c;
      } else if (c <= 0x07ff) {
        b[bn++] = (byte) (0xc0 | (0x1f & (c >> 6)));
        b[bn++] = (byte) (0x80 | (0x3f & c));
      } else {
        b[bn++] = (byte) (0xe0 | (0x0f & (c >> 12)));
        b[bn++] = (byte) (0x80 | (0x3f & (c >> 6)));
        b[bn++] = (byte) (0x80 | (0x3f & c));
      }
    }
    if (DEBUG && logger.isDebugEnabled()) {
      logger.debug("writeUTF: len = " + bn);
      for (int i = 0; i < bn; i++) {
        logger.debug("writeUTF: b[" + i + "] = " + (b[i] & 0xff));
      }
    }

    writeInt(bn);
    writeArrayByte(b, 0, bn);
    if (TIME_DATA_SERIALIZATION) {
      timer.stop();
    }
  }
  private void internalFlush() throws IOException {

    if (DEBUG && logger.isDebugEnabled()) {
      logger.debug("doing a flush()");
    }

    if (TIME_DATA_SERIALIZATION) {
      timer.suspend();
    }

    if (!NO_ARRAY_BUFFERS) {
      flushBuffers();

      /* Retain the order in which the arrays were pushed. This
       * costs a cast at receive time.
       */
      for (int i = 0; i < array_index; i++) {
        ArrayDescriptor a = array[i];
        switch (a.type) {
          case Constants.TYPE_BOOLEAN:
            out.writeArray((boolean[]) a.array, a.offset, a.len);
            break;
          case Constants.TYPE_BYTE:
            if (a.array instanceof ByteBuffer) {
              out.writeByteBuffer((ByteBuffer) a.array);
            } else {
              out.writeArray((byte[]) a.array, a.offset, a.len);
            }
            break;
          case Constants.TYPE_CHAR:
            out.writeArray((char[]) a.array, a.offset, a.len);
            break;
          case Constants.TYPE_SHORT:
            out.writeArray((short[]) a.array, a.offset, a.len);
            break;
          case Constants.TYPE_INT:
            out.writeArray((int[]) a.array, a.offset, a.len);
            break;
          case Constants.TYPE_LONG:
            out.writeArray((long[]) a.array, a.offset, a.len);
            break;
          case Constants.TYPE_FLOAT:
            out.writeArray((float[]) a.array, a.offset, a.len);
            break;
          case Constants.TYPE_DOUBLE:
            out.writeArray((double[]) a.array, a.offset, a.len);
            break;
        }
        a.array = null;
      }

      array_index = 0;
    }

    out.flush();

    if (TIME_DATA_SERIALIZATION) {
      timer.resume();
    }

    if (!NO_ARRAY_BUFFERS && !out.finished()) {
      indices_short = new short[Constants.PRIMITIVE_TYPES];
      if (touched[Constants.TYPE_BYTE]) {
        byte_buffer = new byte[BYTE_BUFFER_SIZE];
      }
      if (touched[Constants.TYPE_CHAR]) {
        char_buffer = new char[CHAR_BUFFER_SIZE];
      }
      if (touched[Constants.TYPE_SHORT]) {
        short_buffer = new short[SHORT_BUFFER_SIZE];
      }
      if (touched[Constants.TYPE_INT]) {
        int_buffer = new int[INT_BUFFER_SIZE];
      }
      if (touched[Constants.TYPE_LONG]) {
        long_buffer = new long[LONG_BUFFER_SIZE];
      }
      if (touched[Constants.TYPE_FLOAT]) {
        float_buffer = new float[FLOAT_BUFFER_SIZE];
      }
      if (touched[Constants.TYPE_DOUBLE]) {
        double_buffer = new double[DOUBLE_BUFFER_SIZE];
      }
      // unfinished++;
    }

    for (int i = 0; i < Constants.PRIMITIVE_TYPES; i++) {
      touched[i] = false;
    }
  }