bool ReadByte_Length(byte b) { if (_bytesExpected == 0) { if ((b & 0x80) != 0) { _bytesExpected = (b & 0x7F) + 1; } else { _bytesExpected = 1; } if (_bytesExpected > 5) { ThrowError(104, "Number of length octets out of bounds"); } } _bytesRead++; if (_bytesRead == _bytesExpected) { var input = new BerMemoryInput(_buffer); if (Type == 0) { OuterLength = BerEncoding.DecodeLength(input); if (OuterLength == 0) { ThrowError(102, "Zero outer length encountered"); } ResetState(DecodeState.Tag); } else { Length = BerEncoding.DecodeLength(input); var isEofOK = Length == 0; if (IsContainer) { ResetState(DecodeState.Tag); OnNewContainer(); PushContainer(); DisposeCurrentTlv(); return(isEofOK); } if (Length == 0) { OnValueReady(); } else { ResetState(DecodeState.Value); _buffer.Capacity = (int)Length; } return(isEofOK); } } return(false); }
/// <summary> /// Read the next TLTLV and publishes information like <see cref="BerLib.BerReaderBase.Tag" />, /// <see cref="BerLib.BerReaderBase.Length" />, <see cref="BerLib.BerReaderBase.Type" /> and /// <see cref="BerLib.BerReaderBase.IsContainer" />. /// Use one of the Get() functions of BerLib.BerReaderBase to retrieve the Value. /// </summary> /// <returns>True if a valid TLTLV has been read, otherwise false.</returns> public bool Read() { Debug.Assert(_input != null); var typeTag = BerTag.Zero; DisposeCurrentTlv(); if (_parentReader != null && // non top-level read? this.Eof) { HandleEof(); return(false); } Tag = BerEncoding.DecodeTag(this); if (Tag.IsZero) { // terminator of indefinite length field: 4 zeros (outer length AND inner length must be indefinite if (ReadByte() == 0 && ReadByte() == 0 && ReadByte() == 0) { HandleEof(); return(false); } else { ThrowError(10, "Invalid zero tag: 0x00"); } } OuterLength = BerEncoding.DecodeLength(this); if (OuterLength == 0) { ThrowError(13, "Zero outer length encountered"); } if (Tag.IsContainer && Tag.Class != BerClass.Universal) { typeTag = BerEncoding.DecodeTag(this); Length = BerEncoding.DecodeLength(this); if ((Length == BerDefinitions.IndefiniteLength) != (OuterLength == BerDefinitions.IndefiniteLength)) { ThrowError(12, "Outer and inner tag must use the same length form"); } } else { ThrowError(14, "Implicit tag or universal outer tag found"); } IsContainer = typeTag.IsContainer; Tag = Tag.ToPrimitive(); // clear container flag Type = typeTag.NumberAsType; if (Length == BerDefinitions.IndefiniteLength && IsContainer == false) { ThrowError(11, "Indefinite length form is only allowed on containers"); } if (IsContainer == false && Length > 0) { var value = new byte[Length]; for (int index = 0; index < Length; index++) { value[index] = ReadByte(); } Value = value; } return(true); }