m_chunked = false;
byte byt = buffer[offset];
int version = (byt & DimeCommon.VERSION_MASK);
if (version != DimeCommon.VERSION_VALUE) {
s_logger.error("Invalid DIME version: " + version);
throw new IOException("Invalid DIME version");
}
if ((byt & DimeCommon.MESSAGE_BEGIN_FLAG) != 0) {
if (m_messageState == DimeCommon.MESSAGE_START) {
m_messageState = DimeCommon.MESSAGE_MIDDLE;
} else {
s_logger.error("Unexpected MB (Message Begin) DIME record");
throw new IOException("Unexpected MB (Message Begin) DIME record");
}
} else if (m_messageState == DimeCommon.MESSAGE_START) {
s_logger.error("Missing expected MB (Message Begin) DIME record");
throw new IOException("Missing expected MB (Message Begin) DIME record");
}
if ((byt & DimeCommon.CHUNK_FLAG) != 0) {
m_chunked = true;
if (m_messageState == DimeCommon.MESSAGE_MIDDLE) {
m_messageState = DimeCommon.MESSAGE_CHUNK;
} else if (m_messageState == DimeCommon.MESSAGE_CHUNK) {
first = false;
} else {
s_logger.error("Invalid CF (Chunk Flag) DIME record");
throw new IOException("Invalid CF (Chunk Flag) DIME record");
}
} else if (m_messageState == DimeCommon.MESSAGE_CHUNK) {
m_messageState = DimeCommon.MESSAGE_MIDDLE;
first = false;
}
if ((byt & DimeCommon.MESSAGE_END_FLAG) != 0) {
if (m_messageState == DimeCommon.MESSAGE_MIDDLE) {
m_messageState = DimeCommon.MESSAGE_END;
} else {
s_logger.error("Unexpected ME (Message End) DIME record");
throw new IOException("Unexpected ME (Message End) DIME record");
}
}
// validate type code and fixed part of second byte
byt = buffer[offset + 1];
if (!first) {
if (byt != 0) {
s_logger.error("DIME chunk record read with non-zero type or reserved field");
throw new IOException("DIME chunk record read with non-zero type or reserved field");
}
} else {
m_partTypeCode = byt & DimeCommon.TYPE_FORMAT_MASK;
if ((byt & ~DimeCommon.TYPE_FORMAT_MASK) != 0) {
s_logger.error("DIME record read with non-zero reserved field");
throw new IOException("DIME record read with non-zero reserved field");
}
}
// get the variable-length field sizes
int optlength = buildShort(offset + 2);
int idlength = buildShort(offset + 4);
int typelength = buildShort(offset + 6);
int length = (buildShort(offset + 8) << 16) + buildShort(offset + 10);
if (first) {
// read the actual variable-length fields
int optpadded = (optlength + 3) & -4;
int idpadded = (idlength + 3) & -4;
int typepadded = (typelength + 3) & -4;
m_byteBuffer.require(length + optpadded + idpadded + typepadded);
buffer = m_byteBuffer.getBuffer();
start = m_byteBuffer.getOffset();
offset = start + retain + m_paddingNeeded + DimeCommon.HEADER_SIZE + optpadded;
if (idlength > 0) {
m_partIdentifier = new String(buffer, offset, idlength, "UTF-8");
offset += idpadded;
} else {
m_partIdentifier = null;
}
if (typelength > 0) {
m_partTypeText = new String(buffer, offset, typelength, "UTF-8");
offset += typepadded;
} else {
m_partTypeText = null;
}
} else {
if (optlength != 0 || idlength != 0 || typelength != 0) {
s_logger.error("DIME chunk record read with non-zero field length(s)");
throw new IOException("DIME chunk record read with non-zero field length(s)");
}
offset += DimeCommon.HEADER_SIZE;
}
// move retained data up in buffer to overwrite header