[interp] run regression with all combinations of available optimizations (#17644)
[mono-project.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap.Asn1 / LBERDecoder.cs
bloba95aa4967797ffc10546258c467e752fdfc0d723
1 /******************************************************************************
2 * The MIT License
3 * Copyright (c) 2003 Novell Inc. www.novell.com
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *******************************************************************************/
24 // Novell.Directory.Ldap.Asn1.LBERDecoder.cs
26 // Author:
27 // Sunil Kumar (Sunilk@novell.com)
29 // (C) 2003 Novell, Inc (http://www.novell.com)
32 using System;
34 namespace Novell.Directory.Ldap.Asn1
37 /// <summary> This class provides LBER decoding routines for ASN.1 Types. LBER is a
38 /// subset of BER as described in the following taken from 5.1 of RFC 2251:
39 ///
40 /// 5.1. Mapping Onto BER-based Transport Services
41 ///
42 /// The protocol elements of Ldap are encoded for exchange using the
43 /// Basic Encoding Rules (BER) [11] of ASN.1 [3]. However, due to the
44 /// high overhead involved in using certain elements of the BER, the
45 /// following additional restrictions are placed on BER-encodings of Ldap
46 /// protocol elements:
47 ///
48 /// <li>(1) Only the definite form of length encoding will be used.</li>
49 ///
50 /// <li>(2) OCTET STRING values will be encoded in the primitive form only.</li>
51 ///
52 /// <li>(3) If the value of a BOOLEAN type is true, the encoding MUST have
53 /// its contents octets set to hex "FF".</li>
54 ///
55 /// <li>(4) If a value of a type is its default value, it MUST be absent.
56 /// Only some BOOLEAN and INTEGER types have default values in this
57 /// protocol definition.
58 ///
59 /// These restrictions do not apply to ASN.1 types encapsulated inside of
60 /// OCTET STRING values, such as attribute values, unless otherwise
61 /// noted.</li>
62 ///
63 /// [3] ITU-T Rec. X.680, "Abstract Syntax Notation One (ASN.1) -
64 /// Specification of Basic Notation", 1994.
65 ///
66 /// [11] ITU-T Rec. X.690, "Specification of ASN.1 encoding rules: Basic,
67 /// Canonical, and Distinguished Encoding Rules", 1994.
68 ///
69 /// </summary>
70 public class LBERDecoder : Asn1Decoder
72 public LBERDecoder()
74 InitBlock();
76 public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
80 private void InitBlock()
82 asn1ID = new Asn1Identifier();
83 asn1Len = new Asn1Length();
85 //used to speed up decode, so it doesn't need to recreate an identifier every time
86 //instead just reset is called CANNOT be static for multiple connections
87 private Asn1Identifier asn1ID;
88 private Asn1Length asn1Len;
91 /* Generic decode routines
94 /// <summary> Decode an LBER encoded value into an Asn1Type from a byte array.</summary>
95 [CLSCompliantAttribute(false)]
96 public virtual Asn1Object decode(sbyte[] value_Renamed)
98 Asn1Object asn1 = null;
100 System.IO.MemoryStream in_Renamed = new System.IO.MemoryStream(SupportClass.ToByteArray(value_Renamed));
103 asn1 = decode(in_Renamed);
105 catch (System.IO.IOException ioe)
108 return asn1;
111 /// <summary> Decode an LBER encoded value into an Asn1Type from an InputStream.</summary>
112 public virtual Asn1Object decode(System.IO.Stream in_Renamed)
114 int[] len = new int[1];
115 return decode(in_Renamed, len);
118 /// <summary> Decode an LBER encoded value into an Asn1Object from an InputStream.
119 ///
120 /// This method also returns the total length of this encoded
121 /// Asn1Object (length of type + length of length + length of content)
122 /// in the parameter len. This information is helpful when decoding
123 /// structured types.
124 /// </summary>
125 public virtual Asn1Object decode(System.IO.Stream in_Renamed, int[] len)
127 asn1ID.reset(in_Renamed);
128 asn1Len.reset(in_Renamed);
130 int length = asn1Len.Length;
131 len[0] = asn1ID.EncodedLength + asn1Len.EncodedLength + length;
133 if (asn1ID.Universal)
135 switch (asn1ID.Tag)
138 case Asn1Sequence.TAG:
139 return new Asn1Sequence(this, in_Renamed, length);
141 case Asn1Set.TAG:
142 return new Asn1Set(this, in_Renamed, length);
144 case Asn1Boolean.TAG:
145 return new Asn1Boolean(this, in_Renamed, length);
147 case Asn1Integer.TAG:
148 return new Asn1Integer(this, in_Renamed, length);
150 case Asn1OctetString.TAG:
151 return new Asn1OctetString(this, in_Renamed, length);
153 case Asn1Enumerated.TAG:
154 return new Asn1Enumerated(this, in_Renamed, length);
156 case Asn1Null.TAG:
157 return new Asn1Null(); // has no content to decode.
158 /* Asn1 TYPE NOT YET SUPPORTED
159 case Asn1BitString.TAG:
160 return new Asn1BitString(this, in, length);
161 case Asn1ObjectIdentifier.TAG:
162 return new Asn1ObjectIdentifier(this, in, length);
163 case Asn1Real.TAG:
164 return new Asn1Real(this, in, length);
165 case Asn1NumericString.TAG:
166 return new Asn1NumericString(this, in, length);
167 case Asn1PrintableString.TAG:
168 return new Asn1PrintableString(this, in, length);
169 case Asn1TeletexString.TAG:
170 return new Asn1TeletexString(this, in, length);
171 case Asn1VideotexString.TAG:
172 return new Asn1VideotexString(this, in, length);
173 case Asn1IA5String.TAG:
174 return new Asn1IA5String(this, in, length);
175 case Asn1GraphicString.TAG:
176 return new Asn1GraphicString(this, in, length);
177 case Asn1VisibleString.TAG:
178 return new Asn1VisibleString(this, in, length);
179 case Asn1GeneralString.TAG:
180 return new Asn1GeneralString(this, in, length);
184 default:
185 throw new System.IO.EndOfStreamException("Unknown tag"); // !!! need a better exception
189 else
191 // APPLICATION or CONTEXT-SPECIFIC tag
192 return new Asn1Tagged(this, in_Renamed, length, (Asn1Identifier) asn1ID.Clone());
196 /* Decoders for ASN.1 simple type Contents
199 /// <summary> Decode a boolean directly from a stream.</summary>
200 public System.Object decodeBoolean(System.IO.Stream in_Renamed, int len)
202 sbyte[] lber = new sbyte[len];
204 int i = SupportClass.ReadInput(in_Renamed, ref lber, 0, lber.Length);
206 if (i != len)
207 throw new System.IO.EndOfStreamException("LBER: BOOLEAN: decode error: EOF");
209 return (lber[0] == 0x00)?false:true;
212 /// <summary> Decode a Numeric type directly from a stream. Decodes INTEGER
213 /// and ENUMERATED types.
214 /// </summary>
215 public System.Object decodeNumeric(System.IO.Stream in_Renamed, int len)
217 long l = 0;
218 int r = in_Renamed.ReadByte();
220 if (r < 0)
221 throw new System.IO.EndOfStreamException("LBER: NUMERIC: decode error: EOF");
223 if ((r & 0x80) != 0)
225 // check for negative number
226 l = - 1;
229 l = (l << 8) | r;
231 for (int i = 1; i < len; i++)
233 r = in_Renamed.ReadByte();
234 if (r < 0)
235 throw new System.IO.EndOfStreamException("LBER: NUMERIC: decode error: EOF");
236 l = (l << 8) | r;
238 return (System.Int64) l;
241 /// <summary> Decode an OctetString directly from a stream.</summary>
242 public System.Object decodeOctetString(System.IO.Stream in_Renamed, int len)
244 sbyte[] octets = new sbyte[len];
245 int totalLen = 0;
247 while (totalLen < len)
249 // Make sure we have read all the data
250 int inLen = SupportClass.ReadInput(in_Renamed, ref octets, totalLen, len - totalLen);
251 totalLen += inLen;
254 return octets;
257 /// <summary> Decode a CharacterString directly from a stream.</summary>
258 public System.Object decodeCharacterString(System.IO.Stream in_Renamed, int len)
260 sbyte[] octets = new sbyte[len];
262 for (int i = 0; i < len; i++)
264 int ret = in_Renamed.ReadByte(); // blocks
265 if (ret == - 1)
266 throw new System.IO.EndOfStreamException("LBER: CHARACTER STRING: decode error: EOF");
267 octets[i] = (sbyte) ret;
269 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
270 char[] dchar = encoder.GetChars(SupportClass.ToByteArray(octets));
271 string rval = new String(dchar);
273 return rval;//new String( "UTF8");