1 /* 2 * Created by SharpDevelop. 3 * User: lextm 4 * Date: 2008/5/17 5 * Time: 17:38 6 * 7 * To change this template use Tools | Options | Coding | Edit Standard Headers. 8 */ 9 10 using System; 11 using System.Collections.Generic; 12 using Lextm.SharpSnmpLib.Mib.Elements; 13 using Lextm.SharpSnmpLib.Mib.Elements.Entities; 14 using Lextm.SharpSnmpLib.Mib.Elements.Types; 15 16 namespace Lextm.SharpSnmpLib.Mib 17 { 18 /// <summary> 19 /// MIB module class. 20 /// </summary> 21 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mib")] 22 public sealed class MibModule : IModule 23 { 24 private readonly string _name; 25 private readonly Imports _imports; 26 private readonly Exports _exports; 27 private readonly List<IElement> _tokens = new List<IElement>(); 28 29 /// <summary> 30 /// Creates a <see cref="MibModule"/> with a specific <see cref="Lexer"/>. 31 /// </summary> 32 /// <param name="name">Module name</param> 33 /// <param name="symbols">Lexer</param> 34 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "lexer")] MibModule(ISymbolEnumerator symbols)35 public MibModule(ISymbolEnumerator symbols) 36 { 37 if (symbols == null) 38 { 39 throw new ArgumentNullException("lexer"); 40 } 41 42 Symbol temp = symbols.NextNonEOLSymbol(); 43 temp.AssertIsValidIdentifier(); 44 _name = temp.ToString().ToUpperInvariant(); // all module names are uppercase 45 46 temp = symbols.NextNonEOLSymbol(); 47 temp.Expect(Symbol.Definitions); 48 49 temp = symbols.NextNonEOLSymbol(); 50 temp.Expect(Symbol.Assign); 51 52 temp = symbols.NextSymbol(); 53 temp.Expect(Symbol.Begin); 54 55 temp = symbols.NextNonEOLSymbol(); 56 if (temp == Symbol.Imports) 57 { 58 _imports = ParseDependents(symbols); 59 } 60 else if (temp == Symbol.Exports) 61 { 62 _exports = ParseExports(symbols); 63 } 64 else 65 { 66 symbols.PutBack(temp); 67 } 68 69 ParseEntities(symbols); 70 } 71 72 #region Accessors 73 74 /// <summary> 75 /// Module name. 76 /// </summary> 77 public string Name 78 { 79 get { return _name; } 80 } 81 82 public Exports Exports 83 { 84 get { return _exports; } 85 } 86 87 public Imports Imports 88 { 89 get { return _imports; } 90 } 91 92 public List<IElement> Tokens 93 { 94 get { return this._tokens; } 95 } 96 97 /// <summary> 98 /// Entities + Types + all other elements implementing IDeclaration 99 /// </summary> 100 public IList<IDeclaration> Declarations 101 { 102 get 103 { 104 IList<IDeclaration> result = new List<IDeclaration>(); 105 foreach (IElement e in _tokens) 106 { 107 IDeclaration decl = e as IDeclaration; 108 if (decl != null) 109 { 110 result.Add(decl); 111 } 112 } 113 114 return result; 115 } 116 } 117 118 /// <summary> 119 /// OID nodes. 120 /// </summary> 121 public IList<IEntity> Entities 122 { 123 get 124 { 125 IList<IEntity> result = new List<IEntity>(); 126 foreach (IElement e in _tokens) 127 { 128 IEntity entity = e as IEntity; 129 if (entity != null) 130 { 131 result.Add(entity); 132 } 133 } 134 135 return result; 136 } 137 } 138 139 public IList<ITypeAssignment> Types 140 { 141 get 142 { 143 IList<ITypeAssignment> result = new List<ITypeAssignment>(); 144 foreach (IElement e in _tokens) 145 { 146 ITypeAssignment type = e as ITypeAssignment; 147 if (type != null) 148 { 149 result.Add(type); 150 } 151 } 152 153 return result; 154 } 155 } 156 157 #endregion 158 159 #region Parsing of Symbols 160 ParseExports(ISymbolEnumerator symbols)161 private Exports ParseExports(ISymbolEnumerator symbols) 162 { 163 return new Exports(this, symbols); 164 } 165 ParseDependents(ISymbolEnumerator symbols)166 private Imports ParseDependents(ISymbolEnumerator symbols) 167 { 168 return new Imports(this, symbols); 169 } 170 ParseEntities(ISymbolEnumerator symbols)171 private void ParseEntities(ISymbolEnumerator symbols) 172 { 173 Symbol temp = symbols.NextNonEOLSymbol(); 174 SymbolList buffer = new SymbolList(); 175 176 while (temp != Symbol.End) 177 { 178 if (temp == Symbol.Assign) 179 { 180 ParseEntity(buffer, symbols); 181 buffer.Clear(); 182 // skip linebreaks behind an entity 183 temp = symbols.NextNonEOLSymbol(); 184 } 185 else 186 { 187 buffer.Add(temp); 188 temp = symbols.NextSymbol(); 189 } 190 } 191 } 192 ParseEntity(SymbolList preAssignSymbols, ISymbolEnumerator symbols)193 private void ParseEntity(SymbolList preAssignSymbols, ISymbolEnumerator symbols) 194 { 195 if ((preAssignSymbols == null) || (preAssignSymbols.Count == 0)) 196 { 197 Symbol s = symbols.NextSymbol(); 198 if (s != null) 199 { 200 s.Assert(false, "Invalid Entity declaration"); 201 } 202 else 203 { 204 throw new MibException("Invalid Entity declaration"); 205 } 206 } 207 208 // check for a valid identifier 209 preAssignSymbols[0].AssertIsValidIdentifier(); 210 211 if (preAssignSymbols.Count == 1) 212 { 213 // its a typedef 214 _tokens.Add(Lexer.ParseBasicTypeDef(this, preAssignSymbols[0].ToString(), symbols, isMacroSyntax: false)); 215 return; 216 } 217 218 ISymbolEnumerator preAssignSymbolsEnumerator = preAssignSymbols.GetSymbolEnumerator(); 219 preAssignSymbolsEnumerator.NextNonEOLSymbol(); // returns identifier 220 Symbol type = preAssignSymbolsEnumerator.NextNonEOLSymbol(); 221 222 // parse declarations 223 if (type == Symbol.Object) 224 { 225 Symbol next = preAssignSymbolsEnumerator.NextNonEOLSymbol(); 226 227 if (next == Symbol.Identifier) 228 { 229 _tokens.Add(new OidValueAssignment(this, preAssignSymbols, symbols)); 230 return; 231 } 232 else if (next != null) 233 { 234 preAssignSymbolsEnumerator.PutBack(next); 235 } 236 } 237 if (type == Symbol.ModuleIdentity) 238 { 239 _tokens.Add(new ModuleIdentity(this, preAssignSymbols, symbols)); 240 return; 241 } 242 if (type == Symbol.ObjectType) 243 { 244 _tokens.Add(new ObjectType(this, preAssignSymbols, symbols)); 245 return; 246 } 247 if (type == Symbol.ObjectGroup) 248 { 249 _tokens.Add(new ObjectGroup(this, preAssignSymbols, symbols)); 250 return; 251 } 252 if (type == Symbol.NotificationGroup) 253 { 254 _tokens.Add(new NotificationGroup(this, preAssignSymbols, symbols)); 255 return; 256 } 257 if (type == Symbol.ModuleCompliance) 258 { 259 _tokens.Add(new ModuleCompliance(this, preAssignSymbols, symbols)); 260 return; 261 } 262 if (type == Symbol.NotificationType) 263 { 264 _tokens.Add(new NotificationType(this, preAssignSymbols, symbols)); 265 return; 266 } 267 if (type == Symbol.ObjectIdentity) 268 { 269 _tokens.Add(new ObjectIdentity(this, preAssignSymbols, symbols)); 270 return; 271 } 272 if (type == Symbol.Macro) 273 { 274 _tokens.Add(new Macro(this, preAssignSymbols, symbols)); 275 return; 276 } 277 if (type == Symbol.TrapType) 278 { 279 _tokens.Add(new TrapType(this, preAssignSymbols, symbols)); 280 return; 281 } 282 if (type == Symbol.AgentCapabilities) 283 { 284 _tokens.Add(new AgentCapabilities(this, preAssignSymbols, symbols)); 285 return; 286 } 287 288 preAssignSymbols[1].Assert(false, "Unknown/Invalid declaration"); 289 } 290 291 #endregion 292 293 } 294 }