⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ber.cs

📁 用C#写的一个OPC CLIENT的工具
💻 CS
📖 第 1 页 / 共 2 页
字号:
					k = 24;
				}
			}
		}
		public Universal(string s)
		{
			type = new BERtag(UniversalType.OctetString);
			e = true;
			b = (new ASCIIEncoding()).GetBytes(s);
			len = (uint) b.Length;
		}
		public Universal(uint[] oid)
		{
			type = new BERtag(UniversalType.ObjectIdentifier);
			e = true;
			uint ln = 0;
			int j;
			for (j=1;j<oid.Length;j++)
				ln += (uint)LengthOIDEl(oid[j]);
			b = new byte[ln];
			len = 0;
			if (oid[0]!=1 || oid[1]!=3)
				throw(new Exception("OID must begin with .1.3"));
			PutOIDEl(43);
			for (j=2;j<oid.Length;j++)
				PutOIDEl(oid[j]);
		}
		public Universal(ArrayList a)
		{
			type = new BERtag(0,true,0);
			e = true;
			ArrayList al = new ArrayList(a.Count);
			val = al;
			for (int j=0;j<a.Count;j++)
			{
				object o = a[j];
				if (o is bool)
					al.Add(new Universal((bool)o));
				else if (o is int)
					al.Add(new Universal((int)o));
				else if (o is BitSet)
					al.Add(new Universal((BitSet)o));
				else if (o is string)
					al.Add(new Universal((string)o));
				else if (o is uint[])
					al.Add(new Universal((uint[])o));
			}
		}
		public Universal(BERtag t,params Universal[] obs)
		{
			type = t;
			e = true;
			val = obs;
		}
		public Universal(params Universal[] obs) : this(new BERtag(0,true,16),obs) {}
		protected bool Children(Stream s) // handle SEQUENCE, set len field
		{
			if (type.isEndMarker)
				return true;
			byte x = ReadByte(s);
			if (x==0x80) // use end-of-contents marker
			{
				ArrayList al = new ArrayList();
				val = al;
				Universal bb;
				do
				{
					bb = Creator(s);
					al.Add(bb);
				} while (!bb.type.isEndMarker);
				return true;
			}
			len = (uint)ReadLength(s,x);
			b = new byte[len];
			if (type.comp) 
			{
				ArrayList c = new ArrayList();
				ulong n = 0;
				Universal d;
				do
				{
					d = Creator(s);
					n += d.Length+LengthLength(d.Length)+1+d.type.ExtLength();
					c.Add(d);
				} while (n<len);
				Universal[] obs = Creators(c.Count);
				for (int i=0;i<c.Count;i++)
					obs[i] = (Universal)c[i];
				val = obs;
				return true;
			}
			return false;
		}
		public Universal(Stream s)
		{
			e = false;
			type = CreateTag(s);
			if (Children(s)) 
			{
				if(type.tag!=0x10)
					CombineValues();
				return;
			}
			if (len>0)
				s.Read(b,0,(int)len);
			ValueOf(len);
		}
		protected ulong ReadLength(Stream s,byte x) // x is initial octet
		{
			if ((x&0x80)==0)
				return (ulong)x;
			ulong u = 0;
			int n = (int)(x&0x7f);
			for (int j=0;j<n;j++)
			{
				x = ReadByte(s);
				u = (u<<8) + (ulong)x;	
			}
			return u;
		}
		protected void WriteLength(Stream s,ulong a) // excluding initial octet
		{
			if (a==0)
			{
				s.WriteByte(0);
				return;
			}
			byte[] c = new byte[16];
			int j = 0;
			while (a>0) 
			{
				c[j++] = (byte)(a&0xff);
				a = a>>8;
			}
			s.WriteByte((byte)(0x80|j));
			while (j>0) 
			{
				int x = c[--j];
				s.WriteByte((byte)x);
			}
		}
		protected uint LengthLength(ulong a) // excluding initial octet
		{
			uint j=0;
			while (a>0)
			{
				j++;
				a = a>>8;
			}
			return j;
		}
		void CombineValues() // handle some special cases
		{
			Universal[] a = (Universal[])val;
			int j;
			switch ((UniversalType)(type.ToByte()))
			{
				case UniversalType.BitString: // 8.6.3
					BitSet r = (BitSet)a[0].val;
					for (j=1;j<a.Length;j++)
						r = r.Cat((BitSet)a[j].val);
					val = r; break;
				case UniversalType.OctetString: // 8.7.3
					string s = (string)a[0].val;
					for (j=1;j<a.Length;j++)
						s += (string)a[j].val;
					val = s; break;
			}
		}
		protected virtual bool ValueOf(uint n)
		{					  
			int j=0;
			switch ((UniversalType)(type.ToByte()))
			{
				case UniversalType.Boolean: val = (b[0]>0); break;
				case UniversalType.Integer: 
					val = (int)new Integer(b); break;
				case UniversalType.BitString:
					byte r = b[0];
					BitSet bs = new BitSet(n*8-r); // 8.6.2
					for (j=0;j<bs.size;j++) 
						bs.bits[j] = (b[4*j]<<24)|(b[4*j+1]<<16)|(b[4*j+2]<<8)|b[4*j+3];
					val = bs; break;
				case UniversalType.OctetString:
					if (n==8||n==11) // may be a date
					{
						uint yr = b[0];
						yr = yr*256 + b[1];
						uint mo = b[2];
						uint dy = b[3];
						if (yr<2005&&yr>1990 && mo<13 && dy<32) 
						{
							val = ""+dy+"/"+mo+"/"+yr; break;
						}
					}
					val = (new ASCIIEncoding()).GetString(b,0,(int)n); break;
				case UniversalType.Null:
					val = null;
					break;
				case UniversalType.ObjectIdentifier:
					ArrayList al = new ArrayList();
					int p = 0;
					while (p<n)
						al.Add(GetOIDEl(ref p));
					uint[] oid;
					if (((uint)al[0])==43) 
					{
						oid = new uint[al.Count+1];
						oid[0] = 1;
						oid[1] = 3;
						for (j=1;j<al.Count;j++)
							oid[j+1] = (uint)al[j];
					} 
					else // can happen that oid is .0??
					{
						//				throw(new Exception("OID must begin with .1.3"));
						oid = new uint[al.Count];
						for (j=0;j<al.Count;j++)
							oid[j] = (uint)al[j];
					}
					val = oid; break;
				case UniversalType.Real:
					val = (double)new Real(b); break;
				default:
					val = type.ToString()+" unimplemented"; break;
			}
			return true;
		}
		public ulong Length
		{
			get 
			{
				if (e && val is Universal[]) 
				{
					ulong r = 0;
					Universal[] a = (Universal[])val;
					for (int j=0;j<a.Length;j++) 
					{
						Universal u = a[j];
						r += u.Length+LengthLength(u.Length)+1+u.type.ExtLength();
					}
					return r;
				} 
				else
					return len;
			}
		}
		public void Send(Stream s) // create the external representation
		{
			type.Send(s);
			WriteLength(s,Length);
			if (e && val is Universal[])
			{
				Universal[] a = (Universal[])val;
				for (int j=0;j<a.Length;j++) 
					a[j].Send(s);
			} 
			else 
				s.Write(b,0,(int)Length);
		}
		protected void PutOIDEl(uint a) 
		{
			if (a==0)
			{
				b[len++] = 0;
				return;
			}
			byte[] c = new byte[16];
			int j = 0;
			while (a>0) 
			{
				c[j++] = (byte)(a&0x7f);
				a = a>>7;
			}
			while (j>0) 
			{
				int x = c[--j];
				if (j>0)
					x |= 0x80;
				b[len++] = (byte)x;
			}
		}
		protected uint GetOIDEl(ref int p)
		{
			uint r = 0;
			byte x;
			do 
			{
				x = b[p++];
				r = (r<<7) + (uint)x&0x7f;	
			} while ((x&0x80)!=0);
			return r;
		}
		uint LengthOIDEl(uint a)
		{
			uint j = 0;
			if (a==0)
				return 1;
			while (a>0)
			{
				j++;
				a = a>>7;
			}
			return j;
		}
		public object Value { get { return val; }}
		public string Type()
		{
			string r = type.ToString();
			if (type.comp) 
			{
				r += "{\n";
				Universal[] al = (Universal[])val;
				for (int j=0;j<al.Length;j++) 
				{
					r += al[j].Type();
					if (j<al.Length-1)
						r += ",\n";
				}
				r += "}";
			} 
			return r;
		}
		public override string ToString()
		{
			string r = "";
			if (type.comp) 
			{
				r += "{\n";
				Universal[] al = (Universal[])val;
				for (int j=0;j<al.Length;j++) 
				{
					r += al[j].ToString();
					if (j<al.Length-1)
						r += ",\n";
				}
				r += "}";
			} 
			else 
			{
				if (val==null)
					ValueOf(len);
				switch ((UniversalType)type.tag) 
				{
					case UniversalType.BitString:
						r += "["+val.ToString()+"]";
						break;
					case UniversalType.ObjectIdentifier:
						uint[] oid = (uint[])val;
						for (int k=0;k<oid.Length;k++) 
							r += "."+oid[k];
						break;
					case UniversalType.OctetString:
						r += "\""+val.ToString()+"\"";
						break;
					case UniversalType.Null:
						r += "NULL"; break;
					default:
						r += val.ToString();
						break;
				}
			}
			return r;
		}
		public void Dump()
		{
			string[] r = ToString().Split('\n');
			for (int i=0;i<r.Length;i++)
				System.Console.WriteLine(r[i]);
		}
		public Universal this[int ix] 
		{
			get 
			{
				Universal[] ls = (Universal[])Value;
				return ls[ix];
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -