use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.
the class Asn1Decoder method isTLVDecoded.
/**
* Check if the TLV tree is fully decoded
*
* @param container The container
* @return <code>true</code> if the TLV has been decoded
*/
private boolean isTLVDecoded(Asn1Container container) {
TLV current = container.getCurrentTLV();
TLV parent = current.getParent();
while (parent != null) {
if (parent.getExpectedLength() != 0) {
return false;
}
parent = parent.getParent();
}
BerValue value = current.getValue();
if ((value != null) && (value.getData() != null)) {
return current.getExpectedLength() == value.getData().length;
} else {
return current.getExpectedLength() == 0;
}
}
use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.
the class Asn1Decoder method treatValuePendingState.
/**
* Treat a pending Value when we get more bytes in the buffer.
*
* @param stream The ByteBuffer containing the PDU to decode
* @param container The container that stores the current state,
* the result and other informations.
* @return <code>MORE</code> if some bytes remain in the buffer when the
* value has been decoded, <code>END</code> if whe still need to get some
* more bytes.
*/
private boolean treatValuePendingState(ByteBuffer stream, Asn1Container container) {
TLV currentTlv = container.getCurrentTLV();
int length = currentTlv.getLength();
int currentLength = currentTlv.getValue().getCurrentLength();
int nbBytes = stream.remaining();
if ((currentLength + nbBytes) < length) {
currentTlv.getValue().addData(stream);
container.setState(TLVStateEnum.VALUE_STATE_PENDING);
return END;
} else {
int remaining = length - currentLength;
byte[] data = new byte[remaining];
stream.get(data, 0, remaining);
currentTlv.getValue().addData(data);
container.setState(TLVStateEnum.TLV_STATE_DONE);
return MORE;
}
}
use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.
the class Asn1Decoder method treatLengthEndState.
/**
* The Length is fully decoded. We have to call an action to check the size.
*
* @param container The container that stores the current state,
* the result and other informations.
* @throws DecoderException Thrown if anything went wrong
*/
private void treatLengthEndState(Asn1Container container) throws DecoderException {
TLV tlv = container.getCurrentTLV();
if (tlv == null) {
String msg = I18n.err(I18n.ERR_01002_TLV_NULL);
LOG.error(msg);
throw new DecoderException(msg);
}
int length = tlv.getLength();
// We will check the length here. What we must control is
// that the enclosing constructed TLV expected length is not
// exceeded by the current TLV.
TLV parentTLV = container.getParentTLV();
if (IS_DEBUG) {
LOG.debug(I18n.msg(I18n.MSG_01003_PARENT_LENGTH, getParentLength(parentTLV)));
}
if (parentTLV == null) {
// This is the first TLV, so we can't check anything. We will
// just store this TLV as the root of the PDU
tlv.setExpectedLength(length);
container.setParentTLV(tlv);
if (IS_DEBUG) {
LOG.debug(I18n.msg(I18n.MSG_01004_ROOT_TLV, Integer.valueOf(length)));
}
} else {
// We have a parent, so we will check that its expected length is
// not exceeded.
int expectedLength = parentTLV.getExpectedLength();
int currentLength = tlv.getSize();
if (expectedLength < currentLength) {
// current TLV. This is an error...
if (IS_DEBUG) {
LOG.debug(I18n.msg(I18n.MSG_01005_TLV, Integer.valueOf(expectedLength), Integer.valueOf(currentLength)));
}
throw new DecoderException(I18n.err(I18n.ERR_01003_VALUE_LENGTH_ABOVE_EXPECTED_LENGTH, Integer.valueOf(currentLength), Integer.valueOf(expectedLength)));
}
// completed.
if (expectedLength == currentLength) {
parentTLV.setExpectedLength(0);
// to the parent's parent TLV.
if (tlv.isConstructed()) {
// the parents which length is null.
if (length == 0) {
// is not null, and it will become the new parent TLV
while (parentTLV != null) {
if (parentTLV.getExpectedLength() != 0) {
// stop the recursion right here
break;
} else {
parentTLV = parentTLV.getParent();
}
}
container.setParentTLV(parentTLV);
} else {
// The new Parent TLV is this Constructed TLV
container.setParentTLV(tlv);
}
tlv.setParent(parentTLV);
tlv.setExpectedLength(length);
} else {
tlv.setExpectedLength(length);
// a tlv which is not complete.
while (parentTLV != null) {
if (parentTLV.getExpectedLength() != 0) {
// stop the recursion right here
break;
} else {
parentTLV = parentTLV.getParent();
}
}
container.setParentTLV(parentTLV);
}
} else {
// Renew the expected Length.
parentTLV.setExpectedLength(expectedLength - currentLength);
tlv.setExpectedLength(length);
if (tlv.isConstructed()) {
// We have a constructed tag, so we must switch the
// parentTLV
tlv.setParent(parentTLV);
container.setParentTLV(tlv);
}
}
}
if (IS_DEBUG) {
LOG.debug(I18n.msg(I18n.MSG_01006_LENGTH_DECODED, Integer.valueOf(length)));
}
if (length == 0) {
// The length is 0, so we can't expect a value.
container.setState(TLVStateEnum.TLV_STATE_DONE);
} else {
// Go ahead and decode the value part
container.setState(TLVStateEnum.VALUE_STATE_START);
}
}
use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.
the class Asn1Decoder method treatLengthPendingState.
/**
* This function is called when a Length is in the process of being decoded,
* but the lack of bytes in the buffer stopped the process.
*
* @param stream The ByteBuffer containing the PDU to decode
* @param container The container that stores the current state,
* the result and other informations.
* @return <code>true</code> if there are more bytes to read, <code>false
* </code> otherwise
*/
private boolean treatLengthPendingState(ByteBuffer stream, Asn1Container container) {
if (stream.hasRemaining()) {
TLV tlv = container.getCurrentTLV();
int length = tlv.getLength();
while (tlv.getLengthBytesRead() < tlv.getLengthNbBytes()) {
byte octet = stream.get();
if (IS_DEBUG) {
LOG.debug(I18n.msg(I18n.MSG_01002_CURRENT_BYTE, Asn1StringUtils.dumpByte(octet)));
}
tlv.incLengthBytesRead();
length = (length << 8) | (octet & 0x00FF);
if (!stream.hasRemaining()) {
tlv.setLength(length);
if (tlv.getLengthBytesRead() < tlv.getLengthNbBytes()) {
container.setState(TLVStateEnum.LENGTH_STATE_PENDING);
return END;
} else {
container.setState(TLVStateEnum.LENGTH_STATE_END);
return MORE;
}
}
}
tlv.setLength(length);
container.setState(TLVStateEnum.LENGTH_STATE_END);
return MORE;
} else {
return END;
}
}
use of org.apache.directory.api.asn1.ber.Asn1Container in project directory-ldap-api by apache.
the class Asn1Decoder method dumpTLVTree.
/**
* Dump the current TLV tree
*
* @param container The container
*/
private void dumpTLVTree(Asn1Container container) {
StringBuilder sb = new StringBuilder();
TLV current = container.getCurrentTLV();
sb.append("TLV").append(Asn1StringUtils.dumpByte(current.getTag())).append("(").append(current.getExpectedLength()).append(")");
current = current.getParent();
while (current != null) {
sb.append("-TLV").append(Asn1StringUtils.dumpByte(current.getTag())).append("(").append(current.getExpectedLength()).append(")");
current = current.getParent();
}
if (IS_DEBUG) {
LOG.debug(I18n.msg(I18n.MSG_01001_TLV_TREE, sb.toString()));
}
}
Aggregations