use of com.ms.silverking.id.UUIDBase in project SilverKing by Morgan-Stanley.
the class IncomingMessageGroup method readFromChannel.
public ReadResult readFromChannel(SocketChannel channel) throws IOException {
int numRead;
int readErrors;
readErrors = 0;
lastNumRead = 0;
do {
if (debug) {
Log.fine(readState);
}
try {
switch(readState) {
case INIT_PREAMBLE_SEARCH:
if (debug) {
Log.fine("leadingBuffer.clear()");
}
leadingBuffer.clear();
readState = ReadState.PREAMBLE_SEARCH;
// break; fall through to PREAMBLE_SEARCH
case PREAMBLE_SEARCH:
numRead = channel.read(leadingBuffer);
if (debug) {
/*
byte[] p;
p = new byte[preambleLengthTypeContextBuffer.capacity()];
preambleLengthTypeContextBuffer.get(p);
*/
Log.fine(numRead + "\t" + leadingBuffer);
// +"\t"+ StringUtil.byteArrayToHexString(p));
}
if (numRead < 0) {
return ReadResult.CHANNEL_CLOSED;
}
lastNumRead += numRead;
if (leadingBuffer.hasRemaining()) {
if (debug) {
Log.fine("Incomplete read result");
}
return ReadResult.INCOMPLETE;
} else {
byte[] candidatePreamble;
if (debug) {
Log.fine("Checking preamble match");
}
// if (Arrays.matchesStart(preamble, candidatePreamble)) {
if (matchesStart(MessageGroupGlobals.preamble, leadingBuffer)) {
long uuidMSL;
long uuidLSL;
if (debug) {
Log.fine("preamble match found");
}
readState = ReadState.HEADER_LENGTH;
if (leadingBuffer.get(MessageFormat.protocolVersionOffset) != MessageGroupGlobals.protocolVersion) {
throw new RuntimeException("Unexpected protocolVersion: " + MessageGroupGlobals.protocolVersion);
}
allocateBufferLengthsBuffer(leadingBuffer.getInt(MessageFormat.lengthOffset));
messageType = EnumValues.messageType[leadingBuffer.get(MessageFormat.typeOffset)];
// only support one byte of options presently; ignore the other 2
options = leadingBuffer.get(MessageFormat.optionsOffset);
uuidMSL = leadingBuffer.getLong(MessageFormat.uuidMSLOffset);
uuidLSL = leadingBuffer.getLong(MessageFormat.uuidLSLOffset);
uuid = new UUIDBase(uuidMSL, uuidLSL);
if (debug) {
Log.fine("messageType: " + messageType);
}
context = leadingBuffer.getLong(MessageFormat.contextOffset);
if (debug) {
System.out.printf("context %x\n", context);
Log.fine("context: " + context);
}
originator = new byte[ValueCreator.BYTES];
leadingBuffer.position(MessageFormat.originatorOffset);
leadingBuffer.get(originator);
deadlineRelativeMillis = leadingBuffer.getInt(MessageFormat.deadlineRelativeMillisOffset);
// For debugging
// System.out.printf("%x:%x %s deadlineRelativeMillis %d\n",
// uuidMSL, uuidLSL,
// IPAddrUtil.addrAndPortToString(originator), deadlineRelativeMillis);
forward = EnumValues.forwardingMode[leadingBuffer.get(MessageFormat.forwardOffset)];
readState = ReadState.BUFFER_LENGTHS;
// FIXME - ADD FALLTHROUGH FOR THIS CASE
} else {
// if (debug) {
Log.warningAsync("*** No preamble match ***");
/*
// mismatch - search for real preamble
leadingBuffer.clear();
//if (candidatePreamble[1] == preamble[0]) {
if (leadingBuffer.get(1) == MessageGroupGlobals.preamble[0]) {
leadingBuffer.put(MessageGroupGlobals.preamble[0]);
}
*/
return ReadResult.ERROR;
}
}
break;
case BUFFER_LENGTHS:
if (bufferLengthsBuffer.remaining() <= 0) {
throw new IOException("bufferLengthsBuffer.remaining() <= 0");
}
numRead = channel.read(bufferLengthsBuffer);
if (debug) {
Log.fine("numRead ", numRead);
}
if (numRead < 0) {
return ReadResult.CHANNEL_CLOSED;
} else if (numRead == 0) {
return ReadResult.INCOMPLETE;
} else {
lastNumRead += numRead;
if (bufferLengthsBuffer.remaining() == 0) {
allocateBuffers();
readState = ReadState.BUFFERS;
}
break;
}
case BUFFERS:
ByteBuffer curBuffer;
// FIXME - MERGE THESE READS EVENTUALLY
curBuffer = buffers[curBufferIndex];
// }
if (curBuffer.remaining() > 0) {
numRead = channel.read(curBuffer);
} else {
numRead = 0;
}
if (debug) {
Log.fine("numRead ", numRead);
}
if (numRead < 0) {
return ReadResult.CHANNEL_CLOSED;
} else if (numRead == 0) {
if (curBuffer.remaining() > 0) {
return ReadResult.INCOMPLETE;
} else {
curBufferIndex++;
assert curBufferIndex <= buffers.length;
if (curBufferIndex == buffers.length) {
readState = ReadState.DONE;
return ReadResult.COMPLETE;
} else {
break;
}
}
} else {
lastNumRead += numRead;
if (curBuffer.remaining() == 0) {
curBufferIndex++;
assert curBufferIndex <= buffers.length;
if (curBufferIndex == buffers.length) {
readState = ReadState.DONE;
return ReadResult.COMPLETE;
} else {
break;
}
} else {
break;
}
}
case DONE:
if (debug) {
Log.info("IncomingBufferedData.DONE");
}
return ReadResult.COMPLETE;
case CHANNEL_CLOSED:
throw new IOException("Channel closed");
default:
throw new RuntimeException("panic");
}
} catch (IOException ioe) {
if (debug) {
Log.logErrorWarning(ioe);
}
if (ioe.getMessage().startsWith("Connection reset")) {
readState = ReadState.CHANNEL_CLOSED;
return ReadResult.CHANNEL_CLOSED;
} else {
readErrors++;
if (readErrors <= errorTolerance) {
Log.logErrorWarning(ioe, "Ignoring read error " + readErrors);
leadingBuffer.clear();
readState = ReadState.INIT_PREAMBLE_SEARCH;
return ReadResult.INCOMPLETE;
} else {
throw ioe;
}
}
}
} while (true);
}
Aggregations