• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 using System;
2 
3 namespace Lextm.SharpSnmpLib.Mib.Elements.Types
4 {
5     public sealed class TextualConvention : ITypeAssignment, ITypeReferrer
6     {
7         private IModule _module;
8         private string _name;
9         private DisplayHint _displayHint;
10         private Status _status;
11         private string _description;
12         private string _reference;
13         private ITypeAssignment _syntax;
14 
15         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "module")]
TextualConvention(IModule module, string name, ISymbolEnumerator symbols)16         public TextualConvention(IModule module, string name, ISymbolEnumerator symbols)
17         {
18             _module = module;
19             _name = name;
20 
21             _displayHint = ParseDisplayHint(symbols);
22             _status      = ParseStatus(symbols);
23             _description = ParseDescription(symbols);
24             _reference   = ParseReference(symbols);
25             _syntax      = ParseSyntax(module, symbols);
26         }
27 
ParseDisplayHint(ISymbolEnumerator symbols)28         private static DisplayHint ParseDisplayHint(ISymbolEnumerator symbols)
29         {
30             Symbol current = symbols.NextNonEOLSymbol();
31 
32             if (current == Symbol.DisplayHint)
33             {
34                 return new DisplayHint(symbols.NextNonEOLSymbol().ToString().Trim(new char[] { '"' }));
35             }
36 
37             symbols.PutBack(current);
38             return null;
39         }
40 
ParseStatus(ISymbolEnumerator symbols)41         private static Status ParseStatus(ISymbolEnumerator symbols)
42         {
43             Symbol current = symbols.NextNonEOLSymbol();
44             current.Expect(Symbol.Status);
45 
46             try
47             {
48                 return (Status)Enum.Parse(typeof(Status), symbols.NextNonEOLSymbol().ToString());
49             }
50             catch (ArgumentException)
51             {
52                 current.Assert(false, "Invalid/Unknown status");
53             }
54 
55             return Status.current;
56         }
57 
ParseDescription(ISymbolEnumerator symbols)58         private static string ParseDescription(ISymbolEnumerator symbols)
59         {
60             Symbol current = symbols.NextNonEOLSymbol();
61             current.Expect(Symbol.Description);
62 
63             return symbols.NextNonEOLSymbol().ToString().Trim(new char[] { '"' });
64         }
65 
ParseReference(ISymbolEnumerator symbols)66         private static string ParseReference(ISymbolEnumerator symbols)
67         {
68             Symbol current = symbols.NextNonEOLSymbol();
69 
70             if (current == Symbol.Reference)
71             {
72                 string reference = symbols.NextNonEOLSymbol().ToString();
73                 if ((reference.Length >= 2) && reference.StartsWith("\"") && reference.EndsWith("\""))
74                 {
75                     return reference.Substring(1, reference.Length-2);
76                 }
77 
78                 return reference;
79             }
80 
81             symbols.PutBack(current);
82             return null;
83         }
84 
ParseSyntax(IModule module, ISymbolEnumerator symbols)85         private static ITypeAssignment ParseSyntax(IModule module, ISymbolEnumerator symbols)
86         {
87             Symbol current = symbols.NextNonEOLSymbol();
88             current.Expect(Symbol.Syntax);
89 
90             /*
91              * RFC2579 definition:
92              *       Syntax ::=   -- Must be one of the following:
93              *                    -- a base type (or its refinement), or
94              *                    -- a BITS pseudo-type
95              *               type
96              *             | "BITS" "{" NamedBits "}"
97              *
98              * From section 3.5:
99              *      The data structure must be one of the alternatives defined
100              *      in the ObjectSyntax CHOICE or the BITS construct.  Note
101              *      that this means that the SYNTAX clause of a Textual
102              *      Convention can not refer to a previously defined Textual
103              *      Convention.
104              *
105              *      The SYNTAX clause of a TEXTUAL CONVENTION macro may be
106              *      sub-typed in the same way as the SYNTAX clause of an
107              *      OBJECT-TYPE macro.
108              *
109              * Therefore the possible values are (grouped by underlying type):
110              *      INTEGER, Integer32
111              *      OCTET STRING, Opaque
112              *      OBJECT IDENTIFIER
113              *      IpAddress
114              *      Counter64
115              *      Unsigned32, Counter32, Gauge32, TimeTicks
116              *      BITS
117              * With appropriate sub-typing.
118              */
119 
120             return Lexer.ParseBasicTypeDef(module, String.Empty, symbols, isMacroSyntax: true);
121         }
122 
123         public IModule Module
124         {
125             get { return _module; }
126         }
127 
128         public string Name
129         {
130             get { return _name; }
131         }
132 
133         public string DisplayHint
134         {
135             get { return _displayHint == null ? null : _displayHint.ToString(); }
136         }
137 
138         public Status Status
139         {
140             get { return _status; }
141         }
142 
143         public string Description
144         {
145             get { return _description; }
146         }
147 
148         public string Reference
149         {
150             get { return _reference; }
151         }
152 
153         public ITypeAssignment Syntax
154         {
155             get { return _syntax; }
156         }
157 
158         //internal object Decode(Variable v)
159         //{
160         //    if (_syntax is IntegerType)
161         //    {
162         //        Integer32 i = v.Data as Integer32;
163         //        if (i == null || (_syntax as IntegerType).IsEnumeration)
164         //        {
165         //            return null;
166         //        }
167         //        else if (_displayHint != null)
168         //        {
169         //            return _displayHint.Decode(i.ToInt32());
170         //        }
171         //        else
172         //        {
173         //            return i.ToInt32();
174         //        }
175         //    }
176         //    else if (_syntax is UnsignedType)
177         //    {
178         //        Integer32 i = v.Data as Integer32;
179         //        if (i == null)
180         //        {
181         //            return null;
182         //        }
183         //        else if (_displayHint != null)
184         //        {
185         //            return _displayHint.Decode(i.ToInt32());
186         //        }
187         //        else
188         //        {
189         //            return i.ToInt32();
190         //        }
191         //    }
192         //    else if (_syntax is OctetStringType)
193         //    {
194         //        OctetString o = v.Data as OctetString;
195         //        if (o == null)
196         //        {
197         //            return null;
198         //        }
199         //        else
200         //        {
201         //            // TODO: Follow the format specifier for octet strings.
202         //            return null;
203         //        }
204         //    }
205         //    else
206         //    {
207         //        return null;
208         //    }
209         //}
210 
211         #region ITypeReferrer Member
212 
213         public ITypeAssignment ReferredType
214         {
215             get { return _syntax; }
216             set { _syntax = value; }
217         }
218 
219         public ITypeAssignment BaseType
220         {
221             get
222             {
223                 ITypeReferrer   tr     = this;
224                 ITypeAssignment result = this;
225 
226                 while ((tr != null) && (tr.ReferredType != null))
227                 {
228                     result = tr.ReferredType;
229                     tr = tr.ReferredType as ITypeReferrer;
230                 }
231 
232                 return result;
233             }
234         }
235 
236         #endregion
237     }
238 }