public CdrElement ParseTlvObject(TlvObject tlv) { CdrElement element = CdrElement.CreateFromTlv(tlv); this.ParseElement(element); return element; }
public void AddTlv(TlvObject tlvChild) { if (_tagValue == null) { _tagValue = new TlvObjectList(1); } tlvChild._tagPath = String.Concat(this._tagPath, ".", tlvChild._tagPath); tlvChild.UpdateAllPaths(); (_tagValue as TlvObjectList).Add(tlvChild); }
// 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; }
public static CdrElement CreateFromTlv(TlvObject tlv) { CdrElement element = new CdrElement(); element._offset = tlv.Offset; element._path = tlv.Path; element._name = tlv.Path; element._isConstructed = tlv.IsConstructed; if (!tlv.IsEmpty) { if (tlv.IsConstructed) { List<CdrElement> val = new List<CdrElement>((tlv.Value as List<TlvObject>).Count); foreach (TlvObject ch in (tlv.Value as List<TlvObject>)) { val.Add(CdrElement.CreateFromTlv(ch)); }; element._value = val; } else { byte[] src = (tlv.Value as byte[]); byte[] dst = new byte[src.Length]; Array.Copy(src, dst, src.Length); element._value = dst; } } return element; }
// 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); }