package org.couchbase.mock.memcached.client;
import org.couchbase.mock.memcached.protocol.CommandCode;
import org.couchbase.mock.memcached.protocol.ErrorCode;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Created by mnunberg on 1/15/14.
*/
public class ClientResponse {
private CommandCode code;
private ErrorCode status;
private byte[] extras;
private byte[] key;
private byte[] value;
private byte[] body;
private int opaque;
private byte opcode;
long cas;
public long getCas() {
return cas;
}
public long getOpaque() {
return opaque;
}
public String getKey() {
return new String(key);
}
public String getValue() {
return new String(value);
}
public ByteBuffer getRawValue() {
return ByteBuffer.wrap(value);
}
public byte[] getExtras() {
return extras;
}
public ErrorCode getStatus() {
return status;
}
public byte getOpcode() {
return opcode;
}
public CommandCode getComCode() {
return code;
}
public boolean success() { return status == ErrorCode.SUCCESS; }
public static ClientResponse read(InputStream input) throws IOException {
byte[] header = new byte[24];
int remaining = header.length;
while (remaining > 0) {
int nr = input.read(header, header.length-remaining, remaining);
if (nr == -1) {
break;
}
remaining -= nr;
}
if (remaining > 0) {
throw new IOException("Incomplete read before stream closed");
}
ByteBuffer buf = ByteBuffer.wrap(header);
byte magic = buf.get();
if (magic != (byte)0x81) {
throw new IOException("Illegal magic: " + magic);
}
ClientResponse ret = new ClientResponse();
ret.opcode = buf.get();
ret.code = CommandCode.valueOf(ret.opcode);
short keylen = buf.getShort();
byte extlen = buf.get();
buf.get(); // ignore datatype
ret.status = ErrorCode.valueOf(buf.getShort());
int totalLen = buf.getInt();
ret.opaque = buf.getInt();
ret.cas = buf.getLong();
ret.body = new byte[totalLen];
remaining = ret.body.length;
while (remaining > 0) {
int nr = input.read(ret.body, ret.body.length-remaining, remaining);
if (nr < 0) {
throw new IOException("Incomplete read");
}
remaining -= nr;
}
ret.extras = Arrays.copyOfRange(ret.body, 0, extlen);
ret.key = Arrays.copyOfRange(ret.body, extlen, extlen + keylen);
ret.value = Arrays.copyOfRange(ret.body, extlen + keylen, ret.body.length);
return ret;
}
}