@Override
  public final void handleRead(ByteBuffer b) {
    assert currentKey != null;
    assert data != null;
    // This will be the case, because we'll clear them when it's not.
    assert readOffset <= data.length : "readOffset is " + readOffset
        + " data.length is " + data.length;

    getLogger().debug("readOffset: %d, length: %d", readOffset, data.length);
    // If we're not looking for termination, we're still looking for data
    if (lookingFor == '\0') {
      int toRead = data.length - readOffset;
      int available = b.remaining();
      toRead = Math.min(toRead, available);
      getLogger().debug("Reading %d bytes", toRead);
      b.get(data, readOffset, toRead);
      readOffset += toRead;
    }
    // Transition us into a ``looking for \r\n'' kind of state if we've
    // read enough and are still in a data state.
    if (readOffset == data.length && lookingFor == '\0') {
      // The callback is most likely a get callback. If it's not, then
      // it's a gets callback.
      OperationCallback cb = getCallback();
      if (cb instanceof GetOperation.Callback) {
        GetOperation.Callback gcb = (GetOperation.Callback) cb;
        gcb.gotData(currentKey, currentFlags, data);
      } else if (cb instanceof GetsOperation.Callback) {
        GetsOperation.Callback gcb = (GetsOperation.Callback) cb;
        gcb.gotData(currentKey, currentFlags, casValue, data);
      } else if (cb instanceof GetlOperation.Callback) {
        GetlOperation.Callback gcb = (GetlOperation.Callback) cb;
        gcb.gotData(currentKey, currentFlags, casValue, data);
      } else if (cb instanceof GetAndTouchOperation.Callback) {
        GetAndTouchOperation.Callback gcb = (GetAndTouchOperation.Callback) cb;
        gcb.gotData(currentKey, currentFlags, casValue, data);
      } else {
        throw new ClassCastException("Couldn't convert " + cb
            + "to a relevent op");
      }
      lookingFor = '\r';
    }
    // If we're looking for an ending byte, let's go find it.
    if (lookingFor != '\0' && b.hasRemaining()) {
      do {
        byte tmp = b.get();
        assert tmp == lookingFor : "Expecting " + lookingFor + ", got "
            + (char) tmp;
        switch (lookingFor) {
        case '\r':
          lookingFor = '\n';
          break;
        case '\n':
          lookingFor = '\0';
          break;
        default:
          assert false : "Looking for unexpected char: " + (char) lookingFor;
        }
      } while (lookingFor != '\0' && b.hasRemaining());
      // Completed the read, reset stuff.
      if (lookingFor == '\0') {
        currentKey = null;
        data = null;
        readOffset = 0;
        currentFlags = 0;
        getLogger().debug("Setting read type back to line.");
        setReadType(OperationReadType.LINE);
      }
    }
  }
Get the keys this GetOperation is looking for.
src/main/java/net/spy/memcached/protocol/ascii/BaseGetOpImpl.java