SnmpTreeNode.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. * 3. The name of the author may not be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  17. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  19. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  20. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  21. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  24. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  25. * OF SUCH DAMAGE.
  26. *
  27. * This file is part of the lwIP TCP/IP stack.
  28. *
  29. * Author: Martin Hentschel <info@cl-soft.de>
  30. *
  31. */
  32. using System;
  33. using System.Collections.Generic;
  34. using System.Text;
  35. using CCodeGeneration;
  36. namespace LwipSnmpCodeGeneration
  37. {
  38. public class SnmpTreeNode: SnmpScalarAggregationNode
  39. {
  40. private readonly List<SnmpNode> childNodes = new List<SnmpNode>();
  41. private readonly List<SnmpScalarNode> childScalarNodes = new List<SnmpScalarNode>();
  42. private string fullOid = "";
  43. public SnmpTreeNode(SnmpTreeNode parentNode)
  44. : base(parentNode)
  45. {
  46. }
  47. public override string FullNodeName
  48. {
  49. get { return this.Name.ToLowerInvariant() + "_treenode"; }
  50. }
  51. public string FullOid
  52. {
  53. get { return this.fullOid; }
  54. set { this.fullOid = value; }
  55. }
  56. public List<SnmpNode> ChildNodes
  57. {
  58. get { return this.childNodes; }
  59. }
  60. protected override IEnumerable<SnmpScalarNode> AggregatedScalarNodes
  61. {
  62. get { return this.childScalarNodes; }
  63. }
  64. private void GenerateAggregatedCode(MibCFile mibFile, bool generateDeclarations, bool generateImplementations)
  65. {
  66. VariableType instanceType = new VariableType("instance", LwipDefs.Vt_StNodeInstance, "*");
  67. base.GenerateAggregatedCode(
  68. mibFile,
  69. instanceType,
  70. String.Format("{0}->node->oid", instanceType.Name),
  71. generateDeclarations,
  72. generateImplementations);
  73. }
  74. private void GenerateAggregateMethodDeclarations(MibCFile mibFile)
  75. {
  76. if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1))
  77. {
  78. GenerateAggregatedCode(mibFile, true, false);
  79. }
  80. }
  81. public override void GenerateCode(MibCFile mibFile)
  82. {
  83. string nodeInitialization;
  84. if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1))
  85. {
  86. GenerateAggregatedCode(mibFile, false, true);
  87. }
  88. // create and add node declaration
  89. if (this.childNodes.Count > 0)
  90. {
  91. StringBuilder subnodeArrayInitialization = new StringBuilder();
  92. for (int i=0; i<this.childNodes.Count; i++)
  93. {
  94. subnodeArrayInitialization.Append(" &");
  95. subnodeArrayInitialization.Append(this.childNodes[i].FullNodeName);
  96. subnodeArrayInitialization.Append(".node");
  97. if (!(this.childNodes[i] is SnmpTreeNode))
  98. {
  99. subnodeArrayInitialization.Append(".node");
  100. }
  101. if (i < (this.childNodes.Count - 1))
  102. {
  103. subnodeArrayInitialization.Append(",\n");
  104. }
  105. }
  106. VariableDeclaration subnodeArray = new VariableDeclaration(
  107. new VariableType(this.Name.ToLowerInvariant() + "_subnodes", LwipDefs.Vt_StNode, "*", ConstType.Both, String.Empty),
  108. "{\n" + subnodeArrayInitialization + "\n}",
  109. isStatic: true);
  110. mibFile.Declarations.Add(subnodeArray);
  111. nodeInitialization = String.Format("SNMP_CREATE_TREE_NODE({0}, {1})", this.Oid, subnodeArray.Type.Name);
  112. }
  113. else
  114. {
  115. nodeInitialization = String.Format("SNMP_CREATE_EMPTY_TREE_NODE({0})", this.Oid);
  116. }
  117. mibFile.Declarations.Add(new VariableDeclaration(
  118. new VariableType(this.FullNodeName, LwipDefs.Vt_StTreeNode, null, ConstType.Value),
  119. nodeInitialization,
  120. isStatic: true));
  121. }
  122. public override void Analyze()
  123. {
  124. this.childScalarNodes.Clear();
  125. // delegate analyze (don't use enumerator because the child node may change our child collection by e.g. removing or replacing itself)
  126. for (int i=this.ChildNodes.Count-1; i>=0; i--)
  127. {
  128. this.ChildNodes[i].Analyze();
  129. }
  130. // collect scalar nodes
  131. foreach (SnmpNode childNode in this.childNodes)
  132. {
  133. SnmpScalarNode scalarNode = childNode as SnmpScalarNode;
  134. if (scalarNode != null)
  135. {
  136. this.childScalarNodes.Add(scalarNode);
  137. }
  138. }
  139. base.Analyze();
  140. // check if we can merge this node to a scalar array node (all childs need to be scalars)
  141. if (this.childNodes.Count > 0)
  142. {
  143. if (LwipOpts.GenerateScalarArrays && (this.childScalarNodes.Count == this.childNodes.Count) && (this.ParentNode != null))
  144. {
  145. SnmpScalarArrayNode scalarArrayNode = new SnmpScalarArrayNode(this.childScalarNodes, this.ParentNode);
  146. scalarArrayNode.Oid = this.Oid;
  147. scalarArrayNode.Name = this.Name;
  148. scalarArrayNode.Analyze();
  149. for (int i=0; i<this.ParentNode.ChildNodes.Count; i++)
  150. {
  151. if (this.ParentNode.ChildNodes[i] == this)
  152. {
  153. this.ParentNode.ChildNodes.RemoveAt(i);
  154. this.ParentNode.ChildNodes.Insert(i, scalarArrayNode);
  155. break;
  156. }
  157. }
  158. }
  159. else if (LwipOpts.GenerateSingleAccessMethodsForTreeNodeScalars && (this.childScalarNodes.Count > 1))
  160. {
  161. foreach (SnmpScalarNode scalarNode in this.childScalarNodes)
  162. {
  163. scalarNode.UseExternalMethods = true;
  164. scalarNode.ExternalGetMethod = this.GetMethodName;
  165. scalarNode.ExternalTestMethod = this.TestMethodName;
  166. scalarNode.ExternalSetMethod = this.SetMethodName;
  167. }
  168. }
  169. }
  170. else // if (this.childNodes.Count == 0)
  171. {
  172. if (!LwipOpts.GenerateEmptyFolders && (this.ParentNode != null))
  173. {
  174. // do not generate this empty folder because it only waste (static) memory
  175. for (int i=0; i<this.ParentNode.ChildNodes.Count; i++)
  176. {
  177. if (this.ParentNode.ChildNodes[i] == this)
  178. {
  179. this.ParentNode.ChildNodes.RemoveAt(i);
  180. break;
  181. }
  182. }
  183. }
  184. }
  185. }
  186. public override void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile)
  187. {
  188. // generate code of child nodes
  189. foreach (SnmpNode childNode in this.childNodes)
  190. {
  191. if (childNode is SnmpTreeNode)
  192. {
  193. childNode.Generate(generatedFile, generatedHeaderFile);
  194. }
  195. }
  196. Comment dividerComment = new Comment(
  197. String.Format("--- {0} {1} -----------------------------------------------------", this.Name, this.fullOid),
  198. singleLine: true);
  199. generatedFile.Declarations.Add(dividerComment);
  200. generatedFile.Implementation.Add(dividerComment);
  201. this.GenerateAggregateMethodDeclarations(generatedFile);
  202. foreach (SnmpNode childNode in this.childNodes)
  203. {
  204. if (!(childNode is SnmpTreeNode))
  205. {
  206. childNode.Generate(generatedFile, generatedHeaderFile);
  207. }
  208. }
  209. base.Generate(generatedFile, generatedHeaderFile);
  210. }
  211. }
  212. }