// Fetch out BER-encoded data until EOF or error
        protected BerDecoderResult DecodeTlv(Stream asnStream, out TlvObject tlvObj, ref long offset, byte level, byte maxLevel)
        {
            BerDecoderResult procResult = BerDecoderResult.Finished;
            tlvObj = null;

            byte[] tlvBuffer = new byte[32];
            byte tlvBuffer_Length = 0;
            int octet;

            int tlvTag = 0;
            int tlvTag_Length = 0;

            // Decode the TLV tag
            while (tlvTag_Length == 0)
            {
                // Get the next byte from the input stream
                octet = asnStream.ReadByte();
                if (octet == -1)
                {
                    return BerDecoderResult.EOF;
                }

                // Skip the fillers between billing records (TLV with level == 0)
                if ((level == 0) && ((octet == 0xFF) || (octet == 0)))
                {
                    offset++;
                    continue;
                }

                tlvBuffer[tlvBuffer_Length++] = (byte)octet;
                tlvTag_Length = FetchTlvTag(tlvBuffer, tlvBuffer_Length, ref tlvTag);
                switch (tlvTag_Length)
                {
                    case -1:
                        return BerDecoderResult.Failed;
                    case 0:
                        continue;   // More data expected
                }
            }

            long tlvOffset = offset;
            offset += tlvTag_Length;

            bool _constructed = ((tlvBuffer[0] & 0x20) == 0x20);

            int tlvLength = 0;
            int tlvLength_Length = 0;

            // Decode the TLV length
            while (tlvLength_Length == 0)
            {
                // Get the next byte from the input stream
                octet = asnStream.ReadByte();
                if (octet == -1)
                {
                    return BerDecoderResult.EOF;
                }

                tlvBuffer[tlvBuffer_Length++] = (byte)octet;
                tlvLength_Length = FetchTlvLength(_constructed, tlvBuffer, tlvTag_Length, tlvBuffer_Length - tlvTag_Length, ref tlvLength);
                switch (tlvLength_Length)
                {
                    case -1:
                        return BerDecoderResult.Failed;
                    case 0:
                        continue;   // More data expected
                }
            }
            offset += tlvLength_Length;
            tlvObj = new TlvObject(tlvTag >> 2, (AsnTagClass)(tlvBuffer[0] & 0xC0), _constructed, tlvOffset);

            if (tlvLength > 0)
            {
                if (_constructed)
                {
                    if (level < maxLevel)
                    {
                        long _vLength = offset + tlvLength;
                        BerDecoderResult _pr;
                        while (offset < _vLength)
                        {
                            TlvObject _childObj;
                            _pr = this.DecodeTlv(asnStream, out _childObj, ref offset, (byte)(level + 1), maxLevel);
                            if (_pr != BerDecoderResult.Finished)
                            {
                                break;
                            }
                            tlvObj.AddTlv(_childObj);
                        }
                    }
                    else
                    {
                        // Stop processing for TLV with level > maxLevel, and skip content.
                        offset += tlvLength;
                        asnStream.Seek(tlvLength, SeekOrigin.Current);
                    }
                }
                else
                {
                    int _readOffset = tlvObj.ReadValue(asnStream, tlvLength);
                    offset += _readOffset;
                    if (_readOffset != tlvLength)
                    {
                        return BerDecoderResult.Failed;
                    }
                }
            }
            return procResult;
        }
示例#2
0
        // Fetch out BER-encoded data until EOF or error
        protected BerDecoderResult DecodeTlv(Stream asnStream, out TlvObject tlvObj, ref long offset, byte level, byte maxLevel)
        {
            BerDecoderResult procResult = BerDecoderResult.Finished;

            tlvObj = null;

            byte[] tlvBuffer        = new byte[32];
            byte   tlvBuffer_Length = 0;
            int    octet;

            int tlvTag        = 0;
            int tlvTag_Length = 0;

            // Decode the TLV tag
            while (tlvTag_Length == 0)
            {
                // Get the next byte from the input stream
                octet = asnStream.ReadByte();
                if (octet == -1)
                {
                    return(BerDecoderResult.EOF);
                }

                // Skip the fillers between billing records (TLV with level == 0)
                if ((level == 0) && ((octet == 0xFF) || (octet == 0)))
                {
                    offset++;
                    continue;
                }

                tlvBuffer[tlvBuffer_Length++] = (byte)octet;
                tlvTag_Length = FetchTlvTag(tlvBuffer, tlvBuffer_Length, ref tlvTag);
                switch (tlvTag_Length)
                {
                case -1:
                    return(BerDecoderResult.Failed);

                case 0:
                    continue;       // More data expected
                }
            }

            long tlvOffset = offset;

            offset += tlvTag_Length;

            bool _constructed = ((tlvBuffer[0] & 0x20) == 0x20);

            int tlvLength        = 0;
            int tlvLength_Length = 0;

            // Decode the TLV length
            while (tlvLength_Length == 0)
            {
                // Get the next byte from the input stream
                octet = asnStream.ReadByte();
                if (octet == -1)
                {
                    return(BerDecoderResult.EOF);
                }

                tlvBuffer[tlvBuffer_Length++] = (byte)octet;
                tlvLength_Length = FetchTlvLength(_constructed, tlvBuffer, tlvTag_Length, tlvBuffer_Length - tlvTag_Length, ref tlvLength);
                switch (tlvLength_Length)
                {
                case -1:
                    return(BerDecoderResult.Failed);

                case 0:
                    continue;       // More data expected
                }
            }
            offset += tlvLength_Length;
            tlvObj  = new TlvObject(tlvTag >> 2, (AsnTagClass)(tlvBuffer[0] & 0xC0), _constructed, tlvOffset);

            if (tlvLength > 0)
            {
                if (_constructed)
                {
                    if (level < maxLevel)
                    {
                        long             _vLength = offset + tlvLength;
                        BerDecoderResult _pr;
                        while (offset < _vLength)
                        {
                            TlvObject _childObj;
                            _pr = this.DecodeTlv(asnStream, out _childObj, ref offset, (byte)(level + 1), maxLevel);
                            if (_pr != BerDecoderResult.Finished)
                            {
                                break;
                            }
                            tlvObj.AddTlv(_childObj);
                        }
                    }
                    else
                    {
                        // Stop processing for TLV with level > maxLevel, and skip content.
                        offset += tlvLength;
                        asnStream.Seek(tlvLength, SeekOrigin.Current);
                    }
                }
                else
                {
                    int _readOffset = tlvObj.ReadValue(asnStream, tlvLength);
                    offset += _readOffset;
                    if (_readOffset != tlvLength)
                    {
                        return(BerDecoderResult.Failed);
                    }
                }
            }
            return(procResult);
        }