Added ifdef for TARGET_JVM.
[mono.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap.Asn1 / Asn1Identifier.cs
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:
11
12 * The above copyright notice and this permission notice shall be included in 
13 * all copies or substantial portions of the Software.
14
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 *******************************************************************************/
23 //
24 // Novell.Directory.Ldap.Asn1.Asn1Identifier.cs
25 //
26 // Author:
27 //   Sunil Kumar (Sunilk@novell.com)
28 //
29 // (C) 2003 Novell, Inc (http://www.novell.com)
30 //
31
32 using System;
33
34 namespace Novell.Directory.Ldap.Asn1
35 {
36         
37         /// <summary> This class is used to encapsulate an ASN.1 Identifier.
38         /// 
39         /// An Asn1Identifier is composed of three parts:
40         /// <li> a class type,</li>
41         /// <li> a form, and</li>
42         /// <li> a tag.</li>
43         /// 
44         /// The class type is defined as:
45         /// <pre>
46         /// bit 8 7 TAG CLASS
47         /// ------- -----------
48         /// 0 0 UNIVERSAL
49         /// 0 1 APPLICATION
50         /// 1 0 CONTEXT
51         /// 1 1 PRIVATE
52         /// </pre>
53         ///  The form is defined as:
54         /// <pre>
55         /// bit 6 FORM
56         /// ----- --------
57         /// 0 PRIMITIVE
58         /// 1 CONSTRUCTED
59         /// </pre>
60         /// 
61         ///  Note: CONSTRUCTED types are made up of other CONSTRUCTED or PRIMITIVE
62         /// types.
63         /// 
64         ///  The tag is defined as:
65         /// <pre>
66         /// bit 5 4 3 2 1 TAG
67         /// ------------- ---------------------------------------------
68         /// 0 0 0 0 0
69         /// . . . . .
70         /// 1 1 1 1 0 (0-30) single octet tag
71         /// 
72         /// 1 1 1 1 1 (> 30) multiple octet tag, more octets follow
73         /// </pre>
74         /// </summary>
75 #if !TARGET_JVM 
76         [CLSCompliantAttribute(true)]
77 #endif
78         public class Asn1Identifier:System.Object, System.ICloneable
79         {
80                 /// <summary> Returns the CLASS of this Asn1Identifier as an int value.
81                 /// 
82                 /// </summary>
83                 /// <seealso cref="UNIVERSAL">
84                 /// </seealso>
85                 /// <seealso cref="APPLICATION">
86                 /// </seealso>
87                 /// <seealso cref="CONTEXT">
88                 /// </seealso>
89                 /// <seealso cref="PRIVATE">
90                 /// </seealso>
91                 virtual public int Asn1Class
92                 {
93                         get
94                         {
95                                 return tagClass;
96                         }
97                         
98                 }
99                 /// <summary> Return a boolean indicating if the constructed bit is set.
100                 /// 
101                 /// </summary>
102                 /// <returns> true if constructed and false if primitive.
103                 /// </returns>
104                 virtual public bool Constructed
105                 {
106                         get
107                         {
108                                 return constructed;
109                         }
110                         
111                 }
112                 /// <summary> Returns the TAG of this Asn1Identifier.</summary>
113                 virtual public int Tag
114                 {
115                         get
116                         {
117                                 return tag;
118                         }
119                         
120                 }
121                 /// <summary> Returns the encoded length of this Asn1Identifier.</summary>
122                 virtual public int EncodedLength
123                 {
124                         get
125                         {
126                                 return encodedLength;
127                         }
128                         
129                 }
130                 /// <summary> Returns a boolean value indicating whether or not this Asn1Identifier
131                 /// has a TAG CLASS of UNIVERSAL.
132                 /// 
133                 /// </summary>
134                 /// <seealso cref="UNIVERSAL">
135                 /// </seealso>
136                 [CLSCompliantAttribute(false)]
137                 virtual public bool Universal
138                 {
139                         get
140                         {
141                                 return tagClass == UNIVERSAL;
142                         }
143                         
144                 }
145                 /// <summary> Returns a boolean value indicating whether or not this Asn1Identifier
146                 /// has a TAG CLASS of APPLICATION.
147                 /// 
148                 /// </summary>
149                 /// <seealso cref="APPLICATION">
150                 /// </seealso>
151                 [CLSCompliantAttribute(false)]
152                 virtual public bool Application
153                 {
154                         get
155                         {
156                                 return tagClass == APPLICATION;
157                         }
158                         
159                 }
160                 /// <summary> Returns a boolean value indicating whether or not this Asn1Identifier
161                 /// has a TAG CLASS of CONTEXT-SPECIFIC.
162                 /// 
163                 /// </summary>
164                 /// <seealso cref="CONTEXT">
165                 /// </seealso>
166                 [CLSCompliantAttribute(false)]
167                 virtual public bool Context
168                 {
169                         get
170                         {
171                                 return tagClass == CONTEXT;
172                         }
173                         
174                 }
175                 /// <summary> Returns a boolean value indicating whether or not this Asn1Identifier
176                 /// has a TAG CLASS of PRIVATE.
177                 /// 
178                 /// </summary>
179                 /// <seealso cref="PRIVATE"></seealso>
180                 [CLSCompliantAttribute(false)]
181                 virtual public bool Private
182                 {
183                         get
184                         {
185                                 return tagClass == PRIVATE;
186                         }
187                         
188                 }
189                 
190                 /// <summary> Universal tag class.
191                 /// 
192                 ///  UNIVERSAL = 0 
193                 /// </summary>
194                 public const int UNIVERSAL = 0;
195                 
196                 /// <summary> Application-wide tag class.
197                 /// 
198                 ///  APPLICATION = 1 
199                 /// </summary>
200                 public const int APPLICATION = 1;
201                 
202                 /// <summary> Context-specific tag class.
203                 /// 
204                 ///  CONTEXT = 2 
205                 /// </summary>
206                 public const int CONTEXT = 2;
207                 
208                 /// <summary> Private-use tag class.
209                 /// 
210                 ///  PRIVATE = 3 
211                 /// </summary>
212                 public const int PRIVATE = 3;
213                 
214                 
215                 /* Private variables
216                 */
217                 
218                 private int tagClass;
219                 private bool constructed;
220                 private int tag;
221                 private int encodedLength;
222                 
223                 /* Constructors for Asn1Identifier
224                 */
225                 
226                 /// <summary> Constructs an Asn1Identifier using the classtype, form and tag.
227                 /// 
228                 /// </summary>
229                 /// <param name="tagClass">As defined above.
230                 /// 
231                 /// </param>
232                 /// <param name="constructed">Set to true if constructed and false if primitive.
233                 /// 
234                 /// </param>
235                 /// <param name="tag">The tag of this identifier
236                 /// </param>
237                 public Asn1Identifier(int tagClass, bool constructed, int tag)
238                 {
239                         this.tagClass = tagClass;
240                         this.constructed = constructed;
241                         this.tag = tag;
242                 }
243                 
244                 /// <summary> Decode an Asn1Identifier directly from an InputStream and
245                 /// save the encoded length of the Asn1Identifier.
246                 /// 
247                 /// </summary>
248                 /// <param name="in">The input stream to decode from.
249                 /// </param>
250                 public Asn1Identifier(System.IO.Stream in_Renamed)
251                 {
252                         int r = in_Renamed.ReadByte();
253                         encodedLength++;
254                         if (r < 0)
255                                 throw new System.IO.EndOfStreamException("BERDecoder: decode: EOF in Identifier");
256                         tagClass = r >> 6;
257                         constructed = (r & 0x20) != 0;
258                         tag = r & 0x1F; // if tag < 30 then its a single octet identifier.
259                         if (tag == 0x1F)
260                         // if true, its a multiple octet identifier.
261                                 tag = decodeTagNumber(in_Renamed);
262                         return ;
263                 }
264                 
265                 public Asn1Identifier()
266                 {
267                         return ;
268                 }
269                 
270                 /// <summary> Decode an Asn1Identifier directly from an InputStream and
271                 /// save the encoded length of the Asn1Identifier, but reuse the object.
272                 /// 
273                 /// </summary>
274                 /// <param name="in">The input stream to decode from.
275                 /// </param>
276                 public void  reset(System.IO.Stream in_Renamed)
277                 {
278                         encodedLength = 0;
279                         int r = in_Renamed.ReadByte();
280                         encodedLength++;
281                         if (r < 0)
282                                 throw new System.IO.EndOfStreamException("BERDecoder: decode: EOF in Identifier");
283                         tagClass = r >> 6;
284                         constructed = (r & 0x20) != 0;
285                         tag = r & 0x1F; // if tag < 30 then its a single octet identifier.
286                         if (tag == 0x1F)
287                         // if true, its a multiple octet identifier.
288                                 tag = decodeTagNumber(in_Renamed);
289                 }
290                 
291                 /// <summary> In the case that we have a tag number that is greater than 30, we need
292                 /// to decode a multiple octet tag number.
293                 /// </summary>
294                 private int decodeTagNumber(System.IO.Stream in_Renamed)
295                 {
296                         int n = 0;
297                         while (true)
298                         {
299                                 int r = in_Renamed.ReadByte();
300                                 encodedLength++;
301                                 if (r < 0)
302                                         throw new System.IO.EndOfStreamException("BERDecoder: decode: EOF in tag number");
303                                 n = (n << 7) + (r & 0x7F);
304                                 if ((r & 0x80) == 0)
305                                         break;
306                         }
307                         return n;
308                 }
309                 
310                 /* Convenience methods
311                 */
312                 
313                 /// <summary> Creates a duplicate, not a true clone, of this object and returns
314                 /// a reference to the duplicate.
315                 /// 
316                 /// </summary>
317                 public System.Object Clone()
318                 {
319                         try
320                         {
321                                 return base.MemberwiseClone();
322                         }
323                         catch (System.Exception ce)
324                         {
325                                 throw new System.SystemException("Internal error, cannot create clone");
326                         }
327                 }
328         }
329 }