@Override
  public void writeAsSerializedByteArray(Object v) throws IOException {
    if (v instanceof HeapDataOutputStream) {
      HeapDataOutputStream other = (HeapDataOutputStream) v;
      InternalDataSerializer.writeArrayLength(other.size(), this);
      other.sendTo((ByteBufferWriter) this);
      other.rewind();
      return;
    }
    if (overflowBuf != null) {
      overflowBuf.writeAsSerializedByteArray(v);
      return;
    }
    if (isOverflowMode()) {
      // we must have recursed
      int remainingSpace = buffer.capacity() - buffer.position();
      if (remainingSpace < 5) {
        // we don't even have room to write the length field so just create the overflowBuf
        overflowBuf = new HeapDataOutputStream(
            buffer.capacity() - Connection.MSG_HEADER_BYTES, KnownVersion.CURRENT);
        overflowBuf.writeAsSerializedByteArray(v);
        return;
      }
    } else {
      // need 5 bytes for length plus enough room for an 'average' small object. I pulled 1024 as
      // the average out of thin air.
      ensureCapacity(5 + 1024);
    }
    int lengthPos = buffer.position();
    buffer.position(lengthPos + 5);
    enableOverflowMode();
    boolean finished = false;
    try {
      try {
        DataSerializer.writeObject(v, this);
      } catch (IOException e) {
        throw new IllegalArgumentException("An Exception was thrown while serializing.", e);
      }
      int baLength = buffer.position() - (lengthPos + 5);
      HeapDataOutputStream overBuf = overflowBuf;
      if (overBuf != null) {
        baLength += overBuf.size();
      }
      buffer.put(lengthPos, StaticSerialization.INT_ARRAY_LEN);
      buffer.putInt(lengthPos + 1, baLength);
      disableOverflowMode();
      finished = true;
      if (overBuf != null && !isOverflowMode()) {
        overBuf.sendTo((ByteBufferWriter) this);
      }
    } finally {
      if (!finished) {
        // reset buffer and act as if we did nothing
        buffer.position(lengthPos);
        disableOverflowMode();
      }
    }
  }
Attempt to fit v into the current buffer as a serialized byte array. This is done by reserving
5 bytes for the length and then starting the serialization. If all the bytes fit then the
length is fixed up and we are done. If it doesn't fit then we need to serialize the remainder
to a temporary HeapDataOutputStream and then fix the length flush the first chunk and then send
the contents of the HeapDataOutputStream to this streamer. All of this is done to prevent an
extra copy when the serialized form will all fit into our current buffer.
geode-core/src/main/java/org/apache/geode/internal/tcp/MsgStreamer.java