/**
  * Invoked prior to write to prepare the WSABUF array. Where necessary, it substitutes
  * non-direct buffers with direct buffers.
  */
 void prepareBuffers() {
   shadow = new ByteBuffer[numBufs];
   long address = writeBufferArray;
   for (int i = 0; i < numBufs; i++) {
     ByteBuffer src = bufs[i];
     int pos = src.position();
     int lim = src.limit();
     assert (pos <= lim);
     int rem = (pos <= lim ? lim - pos : 0);
     long a;
     if (!(src instanceof DirectBuffer)) {
       // substitute with direct buffer
       ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
       bb.put(src);
       bb.flip();
       src.position(pos); // leave heap buffer untouched for now
       shadow[i] = bb;
       a = ((DirectBuffer) bb).address();
     } else {
       shadow[i] = src;
       a = ((DirectBuffer) src).address() + pos;
     }
     unsafe.putAddress(address + OFFSETOF_BUF, a);
     unsafe.putInt(address + OFFSETOF_LEN, rem);
     address += SIZEOF_WSABUF;
   }
 }
 /**
  * Invoked prior to read to prepare the WSABUF array. Where necessary, it substitutes non-direct
  * buffers with direct buffers.
  */
 void prepareBuffers() {
   shadow = new ByteBuffer[numBufs];
   long address = readBufferArray;
   for (int i = 0; i < numBufs; i++) {
     ByteBuffer dst = bufs[i];
     int pos = dst.position();
     int lim = dst.limit();
     assert (pos <= lim);
     int rem = (pos <= lim ? lim - pos : 0);
     long a;
     if (!(dst instanceof DirectBuffer)) {
       // substitute with direct buffer
       ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
       shadow[i] = bb;
       a = ((DirectBuffer) bb).address();
     } else {
       shadow[i] = dst;
       a = ((DirectBuffer) dst).address() + pos;
     }
     unsafe.putAddress(address + OFFSETOF_BUF, a);
     unsafe.putInt(address + OFFSETOF_LEN, rem);
     address += SIZEOF_WSABUF;
   }
 }