// /** // * File: ASN1Value.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Collections.Generic; using System.IO; using ln.snmp.types; using ln.logging; namespace ln.snmp.asn1 { public class ASN1Value { public Identifier Identifier { get; set; } private byte[] octets; private List items; public ASN1Value(byte[] source) :this(new MemoryStream(source)) { } public ASN1Value(Stream stream) { Identifier = BasicEncodingRules.ReadIdentifier(stream); int length = BasicEncodingRules.ReadLength(stream); if (Identifier.Constructed) { items = new List(); long next = stream.Position + length; while (stream.Position < next) items.Add(new ASN1Value(stream)); } else { octets = new byte[length]; stream.Read(octets, 0, length); } } public ASN1Value(Identifier identifier) { Identifier = identifier; if (Identifier.Constructed) items = new List(); else octets = new byte[0]; } public byte[] AsByteArray { get { if (Identifier.Constructed) { byte[][] binaryItems = new byte[items.Count][]; int length = 0; for (int n = 0; n < binaryItems.Length; n++) { binaryItems[n] = items[n].AsByteArray; length += binaryItems[n].Length; } MemoryStream stream = new MemoryStream(); BasicEncodingRules.WriteIdentifier(stream, Identifier); BasicEncodingRules.WriteLength(stream, length); for (int n = 0; n < binaryItems.Length; n++) stream.Write(binaryItems[n], 0, binaryItems[n].Length); return stream.ToArray(); } else { MemoryStream stream = new MemoryStream(); BasicEncodingRules.WriteIdentifier(stream, Identifier); BasicEncodingRules.WriteLength(stream, octets.Length); stream.Write(octets, 0, octets.Length); return stream.ToArray(); } } } public byte[] Bytes { get { if (!Identifier.Constructed) { return octets; } else { byte[][] binaryItems = new byte[items.Count][]; int length = 0; for (int n = 0; n < binaryItems.Length; n++) { binaryItems[n] = items[n].AsByteArray; length += binaryItems[n].Length; } byte[] bytes = new byte[length]; int offset = 0; for (int n = 0; n < binaryItems.Length; n++) { Array.Copy(binaryItems[n], 0, bytes, offset, binaryItems[n].Length); offset += binaryItems[n].Length; } return bytes; } } set { if (!Identifier.Constructed) { octets = value; } else { throw new NotImplementedException(); } } } public ASN1Value[] Items { get { if (!Identifier.Constructed) throw new ArgumentOutOfRangeException("ASN1Value is not constructed"); return items.ToArray(); } set { if (!Identifier.Constructed) throw new ArgumentOutOfRangeException("ASN1Value is not constructed"); items = new List(value); } } public void Add(ASN1Value item) { if (!Identifier.Constructed) throw new ArgumentOutOfRangeException("ASN1Value is not constructed"); items.Add(item); } public override string ToString() { return String.Format("[ASN1Value Identifier={0}]",Identifier); } public void Dump() { Dump(""); } public void Dump(string prefix) { if (Identifier.Constructed) { Logging.Log(LogLevel.DEBUG, "{1}{0}", this.Identifier, prefix); foreach (ASN1Value item in items) item.Dump(prefix + " "); } else { Logging.Log(LogLevel.DEBUG, "{2}{0} {1}",this.Identifier,BitConverter.ToString(Bytes),prefix); } } } }