/// <summary> /// Pre-encodes the BER header and returns the byte length of the encoded node. /// Overridden to recursively pre-encode all descendants. /// </summary> /// <returns>The length of the encoded node.</returns> internal override int Update() { var output = new BerMemoryOutput(); var implicitTag = BerType.IsApplicationDefined(BerTypeNumber) ? new BerTag(BerClass.Application, BerTypeNumber & ~BerType.ApplicationFlag, true) : new BerTag(BerClass.Universal, BerTypeNumber, true); _childrenLength = 0; foreach (var child in _nodes) { _childrenLength += child.IsDirty ? child.Update() : child.EncodedLength; } var implicitLength = _childrenLength + BerEncoding.GetHeaderLength(implicitTag, _childrenLength); BerEncoding.EncodeTag(output, Tag.ToContainer()); BerEncoding.EncodeLength(output, implicitLength); BerEncoding.EncodeTag(output, implicitTag); BerEncoding.EncodeLength(output, _childrenLength); _encodedHeader = output.ToArray(); EncodedLength = _childrenLength + _encodedHeader.Length; return(EncodedLength); }
bool ReadByte_Tag(byte b) { if (b == 0 && _bytesRead == 0) { ResetState(DecodeState.Terminator); return(false); } if (_bytesRead > 12) { ThrowError(103, "Number of tag octets out of bounds"); } if (_bytesRead == 0 && (b & 0x1F) != 0x1F || _bytesRead > 0 && (b & 0x80) == 0) { var input = new BerMemoryInput(_buffer); if (Tag.IsZero) { // no outer tag read yet -> read outer tag var tag = BerEncoding.DecodeTag(input); if (tag.Class == BerClass.Universal) { ThrowError(107, "Universal outer tag encountered"); } if (tag.IsContainer == false) { ThrowError(108, "Primitive outer tag encountered"); } Tag = tag.ToPrimitive(); // clear container flag } else { // outer tag already read -> read inner tag (type tag) var typeTag = BerEncoding.DecodeTag(input); var type = typeTag.NumberAsType; if (BerType.IsApplicationDefined(type) == false) { if (typeTag.Class != BerClass.Universal) { ThrowError(110, "Non-universal inner tag encountered"); } if (type == 0 || type >= BerType.LastUniversal) { ThrowError(109, "Invalid BER type encountered"); } } IsContainer = typeTag.IsContainer; Type = type; } ResetState(DecodeState.Length); return(false); } _bytesRead++; return(false); }