| | |
| | | |
| | | package org.forgerock.opendj.asn1; |
| | | |
| | | import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE; |
| | | import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_TYPE; |
| | | import static org.forgerock.opendj.asn1.ASN1Constants.ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | import static org.forgerock.opendj.ldap.CoreMessages.*; |
| | | |
| | | import java.io.IOException; |
| | |
| | | * An ASN1Reader that reads from an input stream. |
| | | */ |
| | | final class ASN1InputStreamReader extends AbstractASN1Reader implements ASN1Reader { |
| | | private int state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | private int state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | |
| | | private byte peekType = 0; |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean elementAvailable() throws IOException { |
| | | if ((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(false, false)) { |
| | | if ((state == ASN1.ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(false, false)) { |
| | | return false; |
| | | } |
| | | if ((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE) |
| | | if ((state == ASN1.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE) |
| | | && !needFirstLengthByteState(false, false)) { |
| | | return false; |
| | | } |
| | | if ((state == ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES) |
| | | if ((state == ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES) |
| | | && !needAdditionalLengthBytesState(false, false)) { |
| | | return false; |
| | | } |
| | |
| | | return (subSq.getSizeLimit() - subSq.getBytesRead() > 0); |
| | | } |
| | | |
| | | return (state != ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(true, false); |
| | | return (state != ASN1.ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(true, false); |
| | | } |
| | | |
| | | /** |
| | |
| | | peekType(); |
| | | |
| | | switch (state) { |
| | | case ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE: |
| | | case ASN1.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE: |
| | | needFirstLengthByteState(true, true); |
| | | break; |
| | | |
| | | case ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES: |
| | | case ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES: |
| | | needAdditionalLengthBytesState(true, true); |
| | | } |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte peekType() throws IOException { |
| | | if (state == ELEMENT_READ_STATE_NEED_TYPE) { |
| | | if (state == ASN1.ELEMENT_READ_STATE_NEED_TYPE) { |
| | | needTypeState(true, true); |
| | | } |
| | | |
| | |
| | | String.valueOf(readByte != 0x00))); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return readByte != 0x00; |
| | | } |
| | | |
| | |
| | | in = streamStack.removeFirst(); |
| | | |
| | | // Reset the state |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | | |
| | | /** |
| | |
| | | longValue = (longValue << 8) | (readByte & 0xFF); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return longValue; |
| | | } else { |
| | | int intValue = 0; |
| | |
| | | intValue)); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return intValue; |
| | | } |
| | | } |
| | |
| | | peekType, peekLength)); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | | |
| | | /** |
| | |
| | | peekLength(); |
| | | |
| | | if (peekLength == 0) { |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ByteString.empty(); |
| | | } |
| | | |
| | |
| | | "READ ASN.1 OCTETSTRING(type=0x%x, length=%d)", peekType, peekLength)); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ByteString.wrap(value); |
| | | } |
| | | |
| | |
| | | peekLength(); |
| | | |
| | | if (peekLength == 0) { |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return builder; |
| | | } |
| | | |
| | |
| | | "READ ASN.1 OCTETSTRING(type=0x%x, length=%d)", peekType, peekLength)); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return builder; |
| | | } |
| | | |
| | |
| | | peekLength(); |
| | | |
| | | if (peekLength == 0) { |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ""; |
| | | } |
| | | |
| | |
| | | bytesNeeded -= bytesRead; |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | |
| | | String str; |
| | | try { |
| | |
| | | in = subStream; |
| | | |
| | | // Reset the state |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | | |
| | | /** |
| | |
| | | final LocalizableMessage message = ERR_ASN1_SKIP_TRUNCATED_VALUE.get(peekLength); |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return this; |
| | | } |
| | | |
| | |
| | | while (lengthBytesNeeded > 0) { |
| | | readByte = in.read(); |
| | | if (readByte == -1) { |
| | | state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | if (throwEofException) { |
| | | final LocalizableMessage message = |
| | | ERR_ASN1_TRUNCATED_LENGTH_BYTES.get(lengthBytesNeeded); |
| | |
| | | .get(peekLength, maxElementSize); |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | state = ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | return true; |
| | | } |
| | | |
| | |
| | | peekLength = 0x00; |
| | | |
| | | if (!isBlocking && (in.available() < lengthBytesNeeded)) { |
| | | state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | return false; |
| | | } |
| | | |
| | | while (lengthBytesNeeded > 0) { |
| | | readByte = in.read(); |
| | | if (readByte == -1) { |
| | | state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | if (throwEofException) { |
| | | final LocalizableMessage message = |
| | | ERR_ASN1_TRUNCATED_LENGTH_BYTES.get(lengthBytesNeeded); |
| | |
| | | .get(peekLength, maxElementSize); |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | state = ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | return true; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | peekType = (byte) type; |
| | | state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE; |
| | | return true; |
| | | } |
| | | } |