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 }