1 using System; 2 using System.Collections.Generic; 3 using Lextm.SharpSnmpLib.Mib.Elements.Types; 4 5 namespace Lextm.SharpSnmpLib.Mib.Elements.Entities 6 { 7 public sealed class ObjectType : EntityBase, ITypeReferrer 8 { 9 private ITypeAssignment _syntax; 10 private string _units; 11 private MaxAccess _access; 12 private Status _status; 13 private string _description; 14 private string _reference; 15 private IList<string> _indices; 16 private string _augments; 17 private string _defVal; 18 ObjectType(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols)19 public ObjectType(IModule module, SymbolList preAssignSymbols, ISymbolEnumerator symbols) 20 : base(module, preAssignSymbols, symbols) 21 { 22 ParseProperties(preAssignSymbols); 23 } 24 ParseProperties(SymbolList header)25 private void ParseProperties(SymbolList header) 26 { 27 ISymbolEnumerator headerSymbols = header.GetSymbolEnumerator(); 28 Symbol temp = headerSymbols.NextNonEOLSymbol(); 29 30 // Skip name 31 temp = headerSymbols.NextNonEOLSymbol(); 32 temp.Expect(Symbol.ObjectType); 33 34 _syntax = ParseSyntax (Module, headerSymbols); 35 _units = ParseUnits (headerSymbols); 36 _access = ParseAccess (headerSymbols); 37 _status = ParseStatus (headerSymbols); 38 _description = ParseDescription (headerSymbols); 39 _reference = ParseReference (headerSymbols); 40 _indices = ParseIndices (headerSymbols); 41 _augments = ParseAugments (headerSymbols); 42 _defVal = ParseDefVal (headerSymbols); 43 } 44 ParseAugments(ISymbolEnumerator symbols)45 private static string ParseAugments(ISymbolEnumerator symbols) 46 { 47 Symbol current = symbols.NextNonEOLSymbol(); 48 49 if (current == Symbol.Augments) 50 { 51 string augment = null; 52 53 current = symbols.NextNonEOLSymbol(); 54 current.Expect(Symbol.OpenBracket); 55 56 current = symbols.NextNonEOLSymbol(); 57 augment = current.ToString(); 58 59 current = symbols.NextNonEOLSymbol(); 60 current.Expect(Symbol.CloseBracket); 61 62 return augment; 63 } 64 else if (current != null) 65 { 66 symbols.PutBack(current); 67 } 68 69 return null; 70 } 71 ParseDefVal(ISymbolEnumerator symbols)72 private static string ParseDefVal(ISymbolEnumerator symbols) 73 { 74 Symbol current = symbols.NextNonEOLSymbol(); 75 76 if (current == Symbol.DefVal) 77 { 78 current = symbols.NextNonEOLSymbol(); 79 current.Expect(Symbol.OpenBracket); 80 81 string defVal = null; 82 current = symbols.NextNonEOLSymbol(); 83 84 if (current == Symbol.OpenBracket) 85 { 86 int depth = 1; 87 // TODO: decode this. 88 while (depth > 0) 89 { 90 current = symbols.NextNonEOLSymbol(); 91 if (current == Symbol.OpenBracket) 92 { 93 depth++; 94 } 95 else if (current == Symbol.CloseBracket) 96 { 97 depth--; 98 } 99 } 100 } 101 else 102 { 103 defVal = current.ToString(); 104 current = symbols.NextNonEOLSymbol(); 105 current.Expect(Symbol.CloseBracket); 106 } 107 108 return defVal; 109 } 110 else if (current != null) 111 { 112 symbols.PutBack(current); 113 } 114 115 return null; 116 } 117 ParseIndices(ISymbolEnumerator symbols)118 private static IList<string> ParseIndices(ISymbolEnumerator symbols) 119 { 120 Symbol current = symbols.NextNonEOLSymbol(); 121 122 if (current == Symbol.Index) 123 { 124 current = symbols.NextNonEOLSymbol(); 125 current.Expect(Symbol.OpenBracket); 126 127 List<string> indices = new List<string>(); 128 129 while (current != Symbol.CloseBracket) 130 { 131 current = symbols.NextNonEOLSymbol(); 132 133 bool lastIndex = false; 134 if (current == Symbol.Implied) 135 { 136 current = symbols.NextNonEOLSymbol(); 137 lastIndex = true; // 'IMPLIED' may only be used for last index 138 } 139 140 current.Assert((current != Symbol.Comma) && (current != Symbol.CloseBracket), "Expected index name but found symbol!"); 141 indices.Add(current.ToString()); 142 143 current = symbols.NextNonEOLSymbol(); 144 if (lastIndex) 145 { 146 current.Expect(Symbol.CloseBracket); 147 } 148 else 149 { 150 current.Expect(Symbol.Comma, Symbol.CloseBracket); 151 } 152 } 153 154 return indices; 155 } 156 else if (current != null) 157 { 158 symbols.PutBack(current); 159 } 160 161 return null; 162 } 163 ParseReference(ISymbolEnumerator symbols)164 private static string ParseReference(ISymbolEnumerator symbols) 165 { 166 Symbol current = symbols.NextNonEOLSymbol(); 167 168 if (current == Symbol.Reference) 169 { 170 return symbols.NextNonEOLSymbol().ToString(); 171 } 172 else if (current != null) 173 { 174 symbols.PutBack(current); 175 } 176 177 return null; 178 } 179 ParseDescription(ISymbolEnumerator symbols)180 private static string ParseDescription(ISymbolEnumerator symbols) 181 { 182 Symbol current = symbols.NextNonEOLSymbol(); 183 184 if (current == Symbol.Description) 185 { 186 return symbols.NextNonEOLSymbol().ToString().Trim(new char[] { '"' }); 187 } 188 else if (current != null) 189 { 190 symbols.PutBack(current); 191 } 192 193 return null; 194 } 195 ParseStatus(ISymbolEnumerator symbols)196 private static Status ParseStatus(ISymbolEnumerator symbols) 197 { 198 Status status = Status.obsolete; 199 200 Symbol current = symbols.NextNonEOLSymbol(); 201 current.Expect(Symbol.Status); 202 203 current = symbols.NextNonEOLSymbol(); 204 try 205 { 206 status = (Status)Enum.Parse(typeof(Status), current.ToString()); 207 } 208 catch (ArgumentException) 209 { 210 current.Assert(false, "Invalid/Unknown status"); 211 } 212 213 return status; 214 } 215 ParseAccess(ISymbolEnumerator symbols)216 private static MaxAccess ParseAccess(ISymbolEnumerator symbols) 217 { 218 MaxAccess access = MaxAccess.notAccessible; 219 220 Symbol current = symbols.NextNonEOLSymbol(); 221 current.Expect(Symbol.MaxAccess, Symbol.Access); 222 223 current = symbols.NextNonEOLSymbol(); 224 switch (current.ToString()) 225 { 226 case "not-accessible": 227 access = MaxAccess.notAccessible; 228 break; 229 case "accessible-for-notify": 230 access = MaxAccess.accessibleForNotify; 231 break; 232 case "read-only": 233 access = MaxAccess.readOnly; 234 break; 235 case "read-write": 236 access = MaxAccess.readWrite; 237 break; 238 case "read-create": 239 access = MaxAccess.readCreate; 240 break; 241 case "write-only": 242 access = MaxAccess.readWrite; 243 break; 244 default: 245 current.Assert(false, "Invalid/Unknown access"); 246 break; 247 } 248 249 return access; 250 } 251 ParseUnits(ISymbolEnumerator symbols)252 private static string ParseUnits(ISymbolEnumerator symbols) 253 { 254 Symbol current = symbols.NextNonEOLSymbol(); 255 256 if (current == Symbol.Units) 257 { 258 return symbols.NextNonEOLSymbol().ToString(); 259 } 260 else if (current != null) 261 { 262 symbols.PutBack(current); 263 } 264 265 return null; 266 } 267 ParseSyntax(IModule module, ISymbolEnumerator symbols)268 private static ITypeAssignment ParseSyntax(IModule module, ISymbolEnumerator symbols) 269 { 270 Symbol current = symbols.NextNonEOLSymbol(); 271 current.Expect(Symbol.Syntax); 272 273 return Lexer.ParseBasicTypeDef(module, String.Empty, symbols, isMacroSyntax: true); 274 } 275 IsProperty(Symbol sym)276 private static bool IsProperty(Symbol sym) 277 { 278 string s = sym.ToString(); 279 return s == "SYNTAX" || s == "MAX-ACCESS" || s == "STATUS" || s == "DESCRIPTION"; 280 } 281 282 public ITypeAssignment Syntax 283 { 284 get { return _syntax; } 285 internal set { _syntax = value; } 286 } 287 288 public override string Description 289 { 290 get { return _description; } 291 } 292 293 public MaxAccess Access 294 { 295 get { return _access; } 296 } 297 298 public IList<string> Indices 299 { 300 get { return _indices; } 301 } 302 303 public string Augments 304 { 305 get { return _augments; } 306 } 307 308 #region ITypeReferrer Member 309 310 public ITypeAssignment ReferredType 311 { 312 get { return _syntax; } 313 set { _syntax = value; } 314 } 315 316 public ITypeAssignment BaseType 317 { 318 get 319 { 320 ITypeReferrer tr = this; 321 ITypeAssignment result = null; 322 323 while ((tr != null) && (tr.ReferredType != null)) 324 { 325 result = tr.ReferredType; 326 tr = tr.ReferredType as ITypeReferrer; 327 } 328 329 return result; 330 } 331 } 332 333 #endregion 334 335 } 336 }