use of org.apache.directory.api.asn1.ber.tlv.TLV 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.tlv.TLV 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.tlv.TLV 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()));
}
}
use of org.apache.directory.api.asn1.ber.tlv.TLV in project directory-ldap-api by apache.
the class Asn1Decoder method treatValueStartState.
/**
* Treat the Value part. We will distinguish two cases : - if the Tag is a
* Primitive one, we will get the value. - if the Tag is a Constructed one,
* nothing will be done.
*
* @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 treatValueStartState(ByteBuffer stream, Asn1Container container) {
TLV currentTlv = container.getCurrentTLV();
if (TLV.isConstructed(currentTlv.getTag()) && !container.isGathering()) {
container.setState(TLVStateEnum.TLV_STATE_DONE);
return MORE;
} else {
int length = currentTlv.getLength();
int nbBytes = stream.remaining();
if (nbBytes < length) {
currentTlv.getValue().init(length);
currentTlv.getValue().setData(stream);
container.setState(TLVStateEnum.VALUE_STATE_PENDING);
return END;
} else {
currentTlv.getValue().init(length);
stream.get(currentTlv.getValue().getData(), 0, length);
container.setState(TLVStateEnum.TLV_STATE_DONE);
return MORE;
}
}
}
use of org.apache.directory.api.asn1.ber.tlv.TLV in project directory-ldap-api by apache.
the class AddControl method action.
/**
* {@inheritDoc}
*/
public void action(ControlsContainer container) throws DecoderException {
TLV tlv = container.getCurrentTLV();
// We have to handle the special case of a 0 length OID
if (tlv.getLength() == 0) {
String msg = I18n.err(I18n.ERR_04097_NULL_CONTROL_OID);
LOG.error(msg);
// This will generate a PROTOCOL_ERROR
throw new DecoderException(msg);
}
byte[] value = tlv.getValue().getData();
String oidValue = Strings.asciiBytesToString(value);
// The OID is encoded as a String, not an Object Id
if (!Oid.isOid(oidValue)) {
String msg = I18n.err(I18n.ERR_04098_INVALID_CONTROL_OID, oidValue);
LOG.error(msg);
// This will generate a PROTOCOL_ERROR
throw new DecoderException(msg);
}
CodecControl<?> control = container.getLdapCodecService().newControl(oidValue);
container.setCurrentControl(control);
container.addControl(control);
// We can have an END transition
container.setGrammarEndAllowed(true);
if (IS_DEBUG) {
LOG.debug("Control OID : {}", oidValue);
}
}
Aggregations