byte[] version = new byte[Constants.SCMP_VERSION_LENGTH_IN_HEADLINE];
this.readBufferFromStream(is, version);
SCMPMessage.SCMP_VERSION.isSupported(version);
is.skip(1); // read LF
SCMPMessage scmpMsg = null;
// evaluating header key and creating corresponding SCMP type
SCMPHeaderKey headerKey = SCMPHeaderKey.getKeyByHeadline(headline);
switch (headerKey) {
case KRS:
case KRQ:
scmpMsg = new SCMPKeepAlive();
return scmpMsg;
case PRQ:
case PRS:
// no poll request
scmpMsg = new SCMPPart(false);
break;
case PAC:
// poll request
scmpMsg = new SCMPPart(true);
break;
case EXC:
scmpMsg = new SCMPMessageFault();
break;
case UNDEF:
throw new EncodingDecodingException("wrong protocol in message not possible to decode");
default:
scmpMsg = new SCMPMessage();
}
// parse headerSize & bodySize
int scmpHeaderSize = SCMPFrameDecoder.parseHeaderSize(headline);
int scmpBodySize = SCMPFrameDecoder.parseMessageSize(headline) - scmpHeaderSize;
// storing header fields in meta map
Map<String, String> metaMap = new HashMap<String, String>();
byte[] header = new byte[scmpHeaderSize];
int readBytes = this.readBufferFromStream(is, header);
int keyOff = 0;
// decoding header
for (int index = 0; index < readBytes; index++) {
// looping until <=> found, looking for key value pair
if (header[index] == Constants.SCMP_EQUAL) {
// <=> found
for (int inLoopIndex = index; inLoopIndex < readBytes; inLoopIndex++) {
// looping until <LF> got found
if (header[inLoopIndex] == Constants.SCMP_LF) {
// <LF> found
metaMap.put(new String(header, keyOff, (index - keyOff), Constants.SC_CHARACTER_SET), new String(header,
index + 1, (inLoopIndex - 1) - index, Constants.SC_CHARACTER_SET));
// updating outer loop index
index = inLoopIndex;
// updating offset for next key, +1 for <LF>
keyOff = inLoopIndex + 1;
// key value pair found, stop inner loop
break;
}
}
// key value pair found, continue looking for next pair
continue;
}
// looping until <LF> found, looking for header flag
if (header[index] == Constants.SCMP_LF) {
// <LF> found
metaMap.put(new String(header, keyOff, (index - keyOff), Constants.SC_CHARACTER_SET), null);
// updating offset for next key, +1 for <LF>
keyOff = index + 1;
}
}
scmpMsg.setHeader(metaMap);
// message logging
MessageLogger.logInputMessage(headerKey, scmpMsg);
if (scmpBodySize <= 0) {
// no body found stop decoding
return scmpMsg;
}
// decoding body - depends on body type
String scmpBodyTypeString = metaMap.get(SCMPHeaderAttributeKey.BODY_TYPE.getValue());
SCMPBodyType scmpBodyType = SCMPBodyType.getBodyType(scmpBodyTypeString);
try {
byte[] body = new byte[scmpBodySize];
int bodySize = this.readBufferFromStream(is, body);
if (scmpMsg.getHeaderFlag(SCMPHeaderAttributeKey.COMPRESSION)) {
if (AppContext.isScEnvironment() == false) {
// message decompression required
Inflater decompresser = new Inflater();
decompresser.setInput(body, 0, bodySize);
ByteArrayOutputStream bos = new ByteArrayOutputStream(Constants.MAX_MESSAGE_SIZE);
byte[] buf = new byte[Constants.MAX_MESSAGE_SIZE];
bodySize = 0;
while (!decompresser.finished()) {
int count = decompresser.inflate(buf);
bodySize += count;
bos.write(buf, 0, count);
}
bos.close();
decompresser.end();
body = bos.toByteArray();
} else {
// is an SC environment - body is compressed - below switch is irrelevant
scmpMsg.setBody(body, 0, bodySize);
return scmpMsg;
}
}
switch (scmpBodyType) {
case BINARY:
case INPUT_STREAM:
case UNDEFINED:
scmpMsg.setBody(body, 0, bodySize);
return scmpMsg;
case TEXT:
scmpMsg.setBody(new String(body, 0, bodySize));
return scmpMsg;
default:
throw new EncodingDecodingException("unknown body type of SCMP type=" + scmpBodyTypeString);
}
} catch (Exception ex) {