Exemple #1
0
        /// <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);
        }