protected void HandleAnd(Element element, XmlNode node, ElementRelation relation) { foreach (ElementRelation r in relation.relations) { HandleElementRelation(element, node, r); } }
protected void HandleZeroOrMore(Element element, XmlNode node, ElementRelation relation) { // TODO - Improve how we select number of nodes to generate! int cnt = 0; switch (random.Next(1)) { case 0: cnt = random.Next(10); break; case 1: cnt = random.Next(100); break; } if (relation.relations.Count > 1) { throw new ApplicationException("Relations larger than expected!"); } for (int i = 0; i < cnt; i++) { HandleElementRelation(element, node, relation.relations[0]); } }
protected void HandleElementRelation(Element element, XmlNode node, ElementRelation relation) { switch (relation.type) { case ElementRelationType.And: HandleAnd(element, node, relation); break; case ElementRelationType.Or: HandleOr(element, node, relation); break; case ElementRelationType.One: node.AppendChild(GenerateXmlNode(relation.element)); break; case ElementRelationType.OneOrMore: HandleOneOrMore(element, node, relation); break; case ElementRelationType.ZeroOrMore: HandleZeroOrMore(element, node, relation); break; case ElementRelationType.ZeroOrOne: HandleZeroOrOne(element, node, relation); break; case ElementRelationType.PCDATA: if (element.defaultValues.Count > 0) { node.InnerText = element.defaultValues[0]; } else { node.InnerText = "Peach"; } break; default: throw new NotImplementedException("Relation type '" + relation.type.ToString() + "' not supported yet."); } }
protected void HandleZeroOrOne(Element element, XmlNode node, ElementRelation relation) { if (random.Next(1) == 0) { return; } if (relation.element != null) { node.AppendChild(GenerateXmlNode(relation.element)); } else { if (relation.relations.Count > 1) { throw new ApplicationException("Relations larger than expected!"); } HandleElementRelation(element, node, relation.relations[0]); } }
protected ElementRelation handleElementDataBlock(string data, ref int pos) { ElementRelation relation; char token; int indexOfComma = data.IndexOf(',', pos); int indexOfPipe = data.IndexOf('|', pos); int indexOfParenClose = data.IndexOf(')', pos); if ((indexOfComma < indexOfPipe && indexOfComma != -1) || indexOfPipe == -1) { token = ','; relation = new ElementRelation(ElementRelationType.And); } else { token = '|'; relation = new ElementRelation(ElementRelationType.Or); } if (indexOfParenClose == -1) { throw new ApplicationException("Error, didn't find closing paren!"); } int indexOfToken = data.IndexOf(token, pos); if (indexOfParenClose < indexOfToken && data.IndexOf(token, pos) != -1) { relation = null; } string name = null; char c; ElementRelation r = null; for (; pos < data.Length; pos++) { c = data[pos]; if (c == ',' || c == '|' || c == ')') { if (r == null) { r = new ElementRelation(ElementRelationType.One); } if (name != null) { if (name == "#PCDATA") { r.type = ElementRelationType.PCDATA; } else { r.element = elements[name]; } } if (relation == null) { relation = r; } else { relation.relations.Add(r); } if (c == ')') { // We shouldn't have Or/And with a single // relation as child. If we do, remove usless // abstraction. if ((relation.type == ElementRelationType.Or || relation.type == ElementRelationType.And) && relation.relations.Count == 1) { relation = relation.relations[0]; } // Look ahead for ?, +, * if ((pos + 1) < data.Length) { pos++; char nextC = data[pos]; switch (nextC) { case '?': r = new ElementRelation(ElementRelationType.ZeroOrOne); r.relations.Add(relation); relation = r; break; case '+': r = new ElementRelation(ElementRelationType.OneOrMore); r.relations.Add(relation); relation = r; break; case '*': r = new ElementRelation(ElementRelationType.ZeroOrMore); r.relations.Add(relation); relation = r; break; default: // Backup if we don't locate // a parsable character. pos--; break; } } return(relation); } r = null; name = null; } else if (c == '+') { ElementRelation oldR = r; r = new ElementRelation(ElementRelationType.OneOrMore); if (oldR != null) { r.relations.Add(r); } } else if (c == '*') { ElementRelation oldR = r; r = new ElementRelation(ElementRelationType.ZeroOrMore); if (oldR != null) { r.relations.Add(r); } } else if (c == '?') { ElementRelation oldR = r; r = new ElementRelation(ElementRelationType.ZeroOrOne); if (oldR != null) { r.relations.Add(r); } } else if (c == '(') { pos++; r = handleElementDataBlock(data, ref pos); } else if (char.IsWhiteSpace(c)) { continue; } else { if (c == ',') { Debugger.Break(); } if (name == null) { name = c.ToString(); } else { name += c; } } } throw new ApplicationException("Whoops, we shouldn't be here!"); }
protected void HandleOr(Element element, XmlNode node, ElementRelation relation) { int pick = random.Next(relation.relations.Count - 1); HandleElementRelation(element, node, relation.relations[pick]); }