/* * Copyright 2011 Couchbase, Inc.. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * under the License. */ package org.couchbase.mock.memcached.protocol; import org.couchbase.mock.memcached.MutationInfoWriter; import org.couchbase.mock.memcached.MutationStatus; import java.nio.ByteBuffer; /** * @author Trond Norbye */ public class BinaryResponse { private static final byte MAGIC = (byte) 0x81; private static final byte DATA_TYPE = 0; final ByteBuffer buffer; BinaryResponse(final ByteBuffer buffer) { this.buffer = buffer; } BinaryResponse(BinaryCommand command, ErrorCode errorCode, int extraLength, int keyLength, int dataLength, long cas) { buffer = createAndRewind(command, errorCode, extraLength, keyLength, dataLength, cas); } public BinaryResponse(BinaryCommand command, ErrorCode errorCode) { buffer = createAndRewind(command, errorCode, 0, 0, 0, 0); } public BinaryResponse(BinaryCommand command, MutationStatus ms, MutationInfoWriter miw, long cas) { this(command, ms, miw, cas, null); } public static BinaryResponse createWithValue(BinaryCommand command, byte[] value, long cas) { return createWithValue(ErrorCode.SUCCESS, command, value, cas); } public static BinaryResponse createWithValue(ErrorCode ec, BinaryCommand command, byte[] value, long cas) { int vallen = value == null ? 0 : value.length; BinaryResponse resp = new BinaryResponse(command, ec, 0, 0, vallen, cas); if (vallen > 0) { resp.buffer.position(24); resp.buffer.put(value); } resp.buffer.rewind(); return resp; } public BinaryResponse(BinaryCommand command, MutationStatus ms, MutationInfoWriter miw, long cas, byte[] value) { int extlen = 0; int valLen = 0; if (value != null) { valLen = value.length; } boolean shouldWrite = false; if (ms.getStatus().value() == ErrorCode.SUCCESS.value()) { extlen = miw.extrasLength(); shouldWrite = true; } buffer = createAndRewind(command, ms.getStatus(), extlen, 0, valLen, cas); buffer.position(24); if (shouldWrite && extlen != 0) { miw.write(buffer, ms.getCoords()); } if (value != null) { buffer.position(extlen + 24); buffer.put(value); } buffer.rewind(); } private static ByteBuffer createAndRewind(BinaryCommand command, ErrorCode errorCode, int extraLength, int keyLength, int dataLength, long cas) { ByteBuffer message = create(command, errorCode, extraLength, keyLength, dataLength, cas); message.rewind(); return message; } static ByteBuffer create(BinaryCommand command, ErrorCode errorCode, int extraLength, int keyLength, int dataLength, long cas) { ByteBuffer message = ByteBuffer.allocate(24 + extraLength + keyLength + dataLength); message.put(MAGIC); message.put(command.getOpcode()); message.putShort((short)keyLength); message.put((byte)extraLength); message.put(DATA_TYPE); message.putShort(errorCode.value()); message.putInt(dataLength + keyLength + extraLength); message.putInt(command.getOpaque()); message.putLong(cas); return message; } public ByteBuffer getBuffer() { return buffer; } }